BigDecimal
(を経由しない)に基づく別のソリューションを次に示しString
ます。
private static double[] method(double d) {
BigDecimal bd = new BigDecimal(d);
return new double[] { bd.intValue(),
bd.remainder(BigDecimal.ONE).doubleValue() };
}
0.6
お気づきのように、小数部分の出力はまだ得られません。0.6
( a に格納することさえできませんdouble
!) これは、数学的な実数 5.6 が、実際には 5.6 とまったく同じ double ではなく、5.599999 として表されるという事実によるものです...
あなたもできる
private static double[] method(double d) {
BigDecimal bd = BigDecimal.valueOf(d);
return new double[] { bd.intValue(),
bd.remainder(BigDecimal.ONE).doubleValue() };
}
これは実際に利回りを行い[5.0, 0.6]
ます。
ただし、ほとんどのBigDecimal.valueOf
JDK では (内部的に) への呼び出しによって実装されていますDouble.toString
。しかし、少なくとも文字列関連のものでコードが乱雑になることはありません:-)
コメントでの良いフォローアップの質問:
5.599999999... として表される場合、なぜDouble.toString(5.6)
正確に"5.6"
このDouble.toString
方法は実際には非常に洗練されています。のドキュメントからDouble.toString
:
[...]
m または a の小数部分は何桁で表示する必要がありますか? 小数部分を表すには少なくとも 1 桁が必要であり、それを超える桁数は、引数の値を double 型の隣接する値と一意に区別するために必要な数だけです。つまり、x が、有限の非ゼロ引数 d に対してこのメソッドによって生成された 10 進数表現によって表される正確な数学的値であるとします。この場合、d は x に最も近い double 値でなければなりません。または、2 つの double 値が x に等しく近い場合、d はそれらの 1 つでなければならず、d の仮数の最下位ビットは 0 でなければなりません。
[...]
"5.6"
文字を取得するコードは次のようになりFloatingDecimal.getChars
ます。
private int getChars(char[] result) {
assert nDigits <= 19 : nDigits; // generous bound on size of nDigits
int i = 0;
if (isNegative) { result[0] = '-'; i = 1; }
if (isExceptional) {
System.arraycopy(digits, 0, result, i, nDigits);
i += nDigits;
} else {
if (decExponent > 0 && decExponent < 8) {
// print digits.digits.
int charLength = Math.min(nDigits, decExponent);
System.arraycopy(digits, 0, result, i, charLength);
i += charLength;
if (charLength < decExponent) {
charLength = decExponent-charLength;
System.arraycopy(zero, 0, result, i, charLength);
i += charLength;
result[i++] = '.';
result[i++] = '0';
} else {
result[i++] = '.';
if (charLength < nDigits) {
int t = nDigits - charLength;
System.arraycopy(digits, charLength, result, i, t);
i += t;
} else {
result[i++] = '0';
}
}
} else if (decExponent <=0 && decExponent > -3) {
result[i++] = '0';
result[i++] = '.';
if (decExponent != 0) {
System.arraycopy(zero, 0, result, i, -decExponent);
i -= decExponent;
}
System.arraycopy(digits, 0, result, i, nDigits);
i += nDigits;
} else {
result[i++] = digits[0];
result[i++] = '.';
if (nDigits > 1) {
System.arraycopy(digits, 1, result, i, nDigits-1);
i += nDigits-1;
} else {
result[i++] = '0';
}
result[i++] = 'E';
int e;
if (decExponent <= 0) {
result[i++] = '-';
e = -decExponent+1;
} else {
e = decExponent-1;
}
// decExponent has 1, 2, or 3, digits
if (e <= 9) {
result[i++] = (char)(e+'0');
} else if (e <= 99) {
result[i++] = (char)(e/10 +'0');
result[i++] = (char)(e%10 + '0');
} else {
result[i++] = (char)(e/100+'0');
e %= 100;
result[i++] = (char)(e/10+'0');
result[i++] = (char)(e%10 + '0');
}
}
}
return i;
}