這裏是基於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
在double
!)這是由於數學,實數,5.6實際上不是由雙完全一樣5.6但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
方法實際上是非常複雜。從documentation of Double.toString
:
[...]
多少位必須被打印的米或一個小數部分?必須至少有一位數字來表示小數部分,並且除此之外還需要多少位數,但只需要多少位數來唯一地區分參數值和類型爲double的相鄰值。也就是說,假設x是由該方法產生的十進制表示形式對於有限非零參數d所表示的精確數學值。那麼d必須是最接近x的double值;或者如果兩個雙值同樣接近x,那麼d必須它們中的一個和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;
}
用另一個建議更新了我的答案:-) – aioobe 2011-05-19 21:31:43