我正在解第二个Java Puzzlers谜题。
public class Change {
public static void main(String args[]) {
System.out.println(2.00 - 1.10);
}
}
你可能认为答案是0.9。但实际上并不是。如果你计算一下,结果是0.8999999。解决方案如下:
System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.10")));
现在它将打印0.9。我理解为什么它打印0.89999。然而,在我好奇地调试BigDecimal类时,我发现有许多常数值被替换在大多数地方。我将列出所有这些并且希望了解背后的原因。 BigDecimal.java第394行。
while (len > 10 && Character.digit(c, 10) == 0) {
offset++;
c = in[offset];
len--;
}
Here Character.digit(c,10).
public static int digit(char ch, int radix) {
return digit((int)ch, radix);
}
这里将10作为基数传递。
Q1. 为什么要传递10?
BigDecimal.java第732行。
int sign = ((valBits >> 63)==0 ? 1 : -1);
int exponent = (int) ((valBits >> 52) & 0x7ffL);
long significand = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1
: (valBits & ((1L<<52) - 1)) | (1L<<52));
exponent -= 1075;
问题2:如果您深入研究代码,您就可以理解valBits是什么,但我无法理解为什么在某些地方使用了右移运算符?
问题3:在这里,您还可以看到像63、52之类的许多常数被使用。 为什么呢?
问题4:我可以理解在这里使用十六进制0x7ffL
将增加执行速度。 再次问一下,为什么要与十六进制常量使用按位 &
运算符。
希望我的问题很清楚。真诚感谢您的耐心。
char[]
表示。因此,使用了基数10。 - Arnaud Denoyelledouble
。 - user207421