以下是简化后的代码:
int i = 1;
double a = i;
double b = i;
“
a == b
是 true”这个说法是否保证正确?以下是简化后的代码:
int i = 1;
double a = i;
double b = i;
a == b
是 true”这个说法是否保证正确?可以。32位整数可以精确地表示为64位浮点数。
2^52 - 1
的整数...或者可能更多。我不是完全确定。 - Ian Henryi
是某个“偏离”值,您已将a
和b
设置为它们,因此它们具有相同的(潜在不正确的)值。这就像问double a = 1; double b = a;
,那么a == b
吗?双精度误差可能很讨厌,但不会像这样。即使您从long
转换为double
,并且失去了精度,a
和b
也都具有相同的“不正确”值--在规范中找到这一点可能是一个更有趣的问题。 - Ian Henry0000010101101b
)将被表示为1.010110100000b*2^7
,这是准确的。4.0/2.0 == 8.0/4.0
也保证是正确的。x/2^y
并且x
适合52位(例如3/4
5/8
345/1024
),则保证准确地表示数字。如果对这些数字进行操作,也是精确的,前提是y
可以对两个操作数都相等,所以即使:
123456789/1024/1024/1024/1024 ==
(23456789/1024/1024/1024/1024 +
100000000/1024/1024/1024/1024)
保证为真。
有趣的事实是,您可以安全地对54位有符号整数执行操作。这是因为在开头有一个附加位,其含义由指数编码,另外还有一位用于表示符号。现在,在54位有符号整数的情况下,-2 ^ 53(如果是MIN_INT)无法适应尾数,但指数将在尾数填满零的情况下完成此工作。
double
(64位浮点数)中,而不会丢失精度。double
执行计算,您很可能会引入舍入误差,即精度损失。这些错误可能足够小,以便在将double
值强制转换回int
时被四舍五入-但是错误确实存在,请注意。double
的“分数”部分中(其宽度为52位,足以容纳32位整数)。 “指数”部分可以设置为0,因为不需要。int i = 5;
double t = i;
double k = i;
MessageBox.Show((i == t).ToString()); //true
MessageBox.Show((k == t).ToString()); //true
i += 5;
t += 5;
k = i;
MessageBox.Show((i == t).ToString()); //true
MessageBox.Show((k == t).ToString()); //true
i += (int)Math.Round(5.6);
t += 5.6;
t = (int)Math.Round(t);
k = i;
MessageBox.Show((i == t).ToString()); //true
MessageBox.Show((k == t).ToString()); //true
i = int.MaxValue - 5438;
t = int.MaxValue - 5438;
k = i;
MessageBox.Show((i == t).ToString()); //true
MessageBox.Show((k == t).ToString()); //true
i = (int)Math.Round(double.MaxValue);
t = Math.Round(double.MaxValue);
k = i;
MessageBox.Show((i == t).ToString()); //false
MessageBox.Show((k == t).ToString()); //false
i = (int)Math.Round(double.MaxValue);
t = i;
k = i;
MessageBox.Show((i == t).ToString()); //true
MessageBox.Show((k == t).ToString()); //true
结果是两个消息框都显示“真”字。
我猜结论就是:是的,你可以保证它是真的。
编辑:我对我的测试进行了扩展。唯一返回 false 的测试是在 double.MaxValue 的测试,但我怀疑您不会使用那么大的数字。
i /= 2; t /= 2;
。其次,在等式测试中显式地进行强制转换:i == (int)t
很可能总是会得到 true
,因为微小的浮点舍入误差被舍去了。另一方面,由于上述除以 2,(double)i == t
将得到 false
。-- 结论:虽然您可以在 double
中存储整数而不会失去精度,但一旦开始进行计算,就会引入舍入误差! - stakx - no longer contributingdouble
到int
的隐式转换,对于变量t
(和k
)。但是:i
和t
通常不相等!你只能“看到”相等,因为你舍入了小差异!尝试将这些值作为double
进行比较,看看会发生什么。 - stakx - no longer contributing