ノート
[ENHANCEMENT] 8374202: Simplify significand normalization in BigDecimal(double, MathContext) constructor
BigDecimal(double, MathContext) の仮数部の正規化処理を簡潔にしました。
概要#
BigDecimal(double, MathContext) コンストラクタでは,double の仮数部(significand)を正規化する処理があります1。
修正前は,仮数部が偶数である間,1 ビットずつ右シフトしながら指数を 1 ずつ増やすループになっていました。
while ((significand & 1) == 0) { // i.e., significand is even
significand >>= 1;
exponent++;
}
この処理は,仮数部の右端に連続する 0 ビットの数を数え,その分だけまとめてシフトすれば同じ結果になります(なるらしいです)。
そこで,Long.numberOfTrailingZeros を使って trailing zero の数を求め,1 回のシフトと加算で正規化する形に変更しました2。
int nTrailingZeros = Long.numberOfTrailingZeros(significand);
significand >>= nTrailingZeros;
exponent += nTrailingZeros;
挙動は維持したまま,ループをなくして処理を簡潔にする変更です。
2026/03/18 JBS で発見#
本件を JBS で発見し BigDecimal(double, MathContext) の実装を確認しました。
対象箇所では,仮数部の下位ビットが 0 である限りループを回して正規化していました。
しかし,Java には既に Long.numberOfTrailingZeros があり,この用途にそのまま使えます。
significand が 0 の場合はこの正規化処理に入る前に処理済みであるため,ここでは trailing zero の数を求めてまとめて反映できます。
PR では,ループによる正規化を Long.numberOfTrailingZeros に置き換え,BigDecimal.java 1 ファイルだけを変更しました3。
2026/03/19 レビューコメント#
Raffaello Giulietti 氏4から,ほぼ同じ提案が 2025 年 12 月に core-libs-dev へ送られていたものの,その時点では進まなかったというコメントをいただきました5。
すでに近い提案があったという意味では,筋のよい変更だったのだと思います。 一方で,既存の提案が流れてしまうこともあるので,小さな変更でも PR として形にすることには意味があると感じました。
2026/03/27 レビュー#
Giulietti 氏4にレビューをいただき,Approve されました。 ただし,統合前に 24 時間待つようコメントをいただきました。
そのため,すぐには統合せず,翌日に /integrate を行いました。
2026/03/30 統合#
Giulietti 氏4に /sponsor をしていただいて d58fb1e6 として JDK へ統合されました。
Footnotes#
-
jdk/src/java.base/share/classes/java/math/BigDecimal.java at f3069680e48712a7cacc4208550816300f68fbf4 · openjdk/jdkJDK main-line development https://openjdk.org/projects/jdk - jdk/src/java.base/share/classes/java/math/BigDecimal.java at f3069680e48712a7cacc4208550816300f68fbf4 · openjdk/jdkGitHub
↩
-
8374202: Simplify significand normalization in BigDecimal(double, MathContext) constructor by PeyaPeyaPeyang · Pull Req…Replace loop-based normalisation with Long.numberOfTrailingZeros in BigDecimal(double, MathContext) constructor. Compute the number of trailing(rightmost) zero bits in the signifi…GitHub
↩
-
8374202: Simplify significand normalization in BigDecimal(double, MathContext) constructor by PeyaPeyaPeyang · Pull Req…JDK main-line development https://openjdk.org/projects/jdk - 8374202: Simplify significand normalization in BigDecimal(double, MathContext) constructor by PeyaPeyaPeyang · Pull Re…GitHub
↩
-
https://openjdk.org/census#rgiuliettiopenjdk.org↩ ↩2 ↩3
-
https://mail.openjdk.org/pipermail/core-libs-dev/2025-December/156816.htmlmail.openjdk.org↩
-
8374202: Simplify significand normalization in BigDecimal(double, Mat… · openjdk/jdk@d58fb1eJDK main-line development https://openjdk.org/projects/jdk - 8374202: Simplify significand normalization in BigDecimal(double, Mat… · openjdk/jdk@d58fb1eGitHub
↩