C++浮点数转长整型

7
如果我使用C++编写代码:
long long d = 999999998.9999999994;
cout<<d;

我得到的输出是: 999999999 (四舍五入)

但是这段代码的输出结果是:

long long d = 999999998.9999994994;
cout<<d;

这里输出的是 999999998(向下取整)。

这可能与精度有关。您是否可以改变精度?floor()函数也会产生相同的结果。

我还注意到,如果将值8.99999949948.9999999994分配给d(上面的变量),输出为8


你可以明确地添加0.5并将double转换为long long。 - Oleksandr Verhun
C++11支持吗?用户定义的字面量可以帮助。 - Yakk - Adam Nevraumont
@OleksandrVerhun,你可以这样做,但如果你的目标是将浮点数四舍五入到最近的整数,你不应该这样做。https://www.frama-c.com/floating-point/2013/05/02/Harder-than-it-looks-rounding-float-to-nearest-integer-part-1.html - Pascal Cuoq
@OleksandrVerhun 如果你真的需要四舍五入到最近的整数,请使用lrint()函数族。它们是POSIX和C99标准,由glibc和Visual Studio 2013支持。http://linux.die.net/man/3/lrint - Severin Pappadeux
2个回答

11

999999998.9999999994double中无法精确表示,所以实际值是999999998.99999988079071044921875999999999(假设采用 IEEE-754 binary64格式),由实现方式决定选取哪个可表示的数字。大多数系统默认四舍五入,会得到999999999

因此,在这些系统中,当您写999999998.9999999994时,它与写999999999.0的效果完全相同。因此,随后的转换将产生999999999 - 从浮点数到整数的转换总是截断的,但在这里没有需要截断的部分。

对于999999998.9999994994,最接近的可表示数字为999999998.999999523162841796875999999998.99999940395355224609375。任意一个数字在截断后都会产生999999998。类似地,对于8.9999999994,最接近的可表示数字为8.9999999993999999503557774005457758903503417968758.9999999994000017267126168007962405681610107421875,任意一个数字在截断后都会产生8


4
long long d = 999999998.9999999994; 

999999998.9999999994 最近的 double 可以表示的值是 999999999.0 - 请记住浮点数具有有限精度 ;)
因此,截断小数位得到的值是 999999999,这就是保存在 d 中的值。
使用带有 L 后缀的字面量确实会导致 d 中保存了 999999998 - long double 具有更高的精度。
long long d = 999999998.9999994994;

double 能够表示的最接近 999999998.9999994994 的值实际上低于 999999999,在我的机器上大约是 999999998.999999523。随后截断小数位得到的是 999999998,并且存储在 d 中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接