Hes*_*aqi 100 c c++ floating-point double rounding
让:
double d = 0.1;
float f = 0.1;
Run Code Online (Sandbox Code Playgroud)
应该表达
(f > d)
Run Code Online (Sandbox Code Playgroud)
回来true还是false?
根据经验,答案是true.但是,我期待它false.
如0.1不能在二进制完美表示,而双具有15以16十进制精度位数,并且浮体具有只7.所以,他们两个都不到0.1,而双人更接近0.1.
我需要一个确切的解释true.
ken*_*ytm 172
我想说转换时,答案取决于舍入模式double来float.float有24个二进制位的精度,并double有53.在二进制,0.1是:
0.1?? = 0.0001100110011001100110011001100110011001100110011…?
^ ^ ^ ^
1 10 20 24
Run Code Online (Sandbox Code Playgroud)
因此,如果我们圆了在第24位,我们会得到
0.1?? ~ 0.000110011001100110011001101
Run Code Online (Sandbox Code Playgroud)
它大于精确值,53位数的精确近似值.
Sve*_*ach 55
数字0.1将四舍五入到具有给定精度的最接近的浮点表示.这种近似可能大于或小于0.1,因此如果不查看实际值,则无法预测单精度或双精度近似是否更大.
这是双精度值四舍五入到的(使用Python解释器):
>>> "%.55f" % 0.1
'0.1000000000000000055511151231257827021181583404541015625'
Run Code Online (Sandbox Code Playgroud)
这是单精度值:
>>> "%.55f" % numpy.float32("0.1")
'0.1000000014901161193847656250000000000000000000000000000'
Run Code Online (Sandbox Code Playgroud)
所以你可以看到单精度近似更大.
sta*_*ast 19
如果您转换.1为二进制,您会得到:
0.000110011001100110011001100110011001100110011001100...
永远重复
映射到数据类型,您得到:
float(.1) = %.00011001100110011001101
^--- note rounding
double(.1) = %.0001100110011001100110011001100110011001100110011010
将其转换为基数10:
float(.1) = .10000002384185791015625 double(.1) = .100000000000000088817841970012523233890533447265625
这取自布鲁斯道森撰写的一篇文章.它可以在这里找到:
双打不是浮点数,所以不要比较它们
由于无法精确表示,因此比较以 2 为底的 1/10 就像比较以 10 为底的 1/7。
1/7 = 0.142857142857...但是在不同的基数 10 精度(3 位和 6 位小数)进行比较,我们有 0.143 > 0.142857。
我认为Eric Lippert对这个问题的评论实际上是最明确的解释,所以我会将其作为答案重新发布:
假设您计算1/3的3位十进制和6位十进制数.0.111 <0.111111,对吗?
现在假设您正在计算6/9.0.667> 0.666667,对吗?
您不能认为三位十进制中的6/9是0.666因为这不是最接近的3位小数到6/9!