【发布时间】:2019-01-21 23:01:59
【问题描述】:
我有一个接受数字的 StreamTokenizer。但是解析出来的数字和输入的不一样。
示例代码:
String str = "1000000000000.0000000000000";
double initial = 1000000000000.0000000000000;
InputStream in = new ByteArrayInputStream(str.getBytes());
StreamTokenizer input = new StreamTokenizer(new BufferedReader(new InputStreamReader(in)));
input.parseNumbers();
int n = input.nextToken();
if (n == StreamTokenizer.TT_NUMBER) {
System.out.println("Original: " + str);
System.out.println("Parsed: " + input.nval);
System.out.println(initial + " == " + input.nval + " -> " + (initial == input.nval));
}
输出:
Original: 1000000000000.0000000000000
Parsed: 9.999999999999999E11
1.0E12 == 9.999999999999999E11 -> false
如何防止这种情况使两个double 值相等?
编辑:链接的问题讨论了为什么会出现此问题。我在问有哪些可能的方法来避免这个问题。
【问题讨论】:
-
对
StreamTokenizer::nextToken的粗略检查表明,它尝试将double中所有无小数点的数字的值累加,然后根据位数除以十的幂小数点的右边以获得正确的值。因此,“1000000000000.0000000000000”计算为10000000000000000000000000. / 10000000000000。这会导致有效数字中的位过多,并且会丢失精度。我能看到的唯一解决方案是避免StreamTokenizer。 -
@ElliottFrisch 这个问题不是那个问题的重复。
-
@ElliottFrisch 这一切都很好,但在这种情况下,唯一以浮点表示的值是整数。在这种情况下问题就不同了。