int main()
{
int64_t iaVal = (int64_t)9007199258935295;
double daVal = (double)iaVal;
std::cout << "original " << iaVal << "tAfter conversion " << (std::int64_t)daVal << std::endl;
}
输出:
Original 9007199258935295
After conversion 9007199258935296
如何从double中获得正确的值?
来自双精度浮点格式:IEEE 754双精度二进制浮点格式:binary64[emphasismine]:
双精度二进制浮点是PC上常用的格式,尽管其性能和带宽成本较高,但其范围比单精度浮点更广。它通常简称为double。IEEE 754标准规定二进制64具有:
- 符号位:1位
- 指数:11位
- 显著精度:53位(52位显式存储(
符合IEEE 754的双精度二进制浮点的有效位精度为53位,而64位的带符号整数(int64_t
(的精度自然为64位,这意味着前者将无法表示后者的所有值。此外,C++中的浮点甚至不能保证符合IEE 754(定义了实现(,但对于它们是的实现来说
#include <limits>
static_assert(std::numeric_limits<double>::is_iec559, "");
根据上面的有效自变量,double
将能够表示32位整数的所有数字。
如何从double中获得正确的值?
您不能。当您将值转换为无法精确表示它的类型时,该值已丢失。请考虑类似的情况:我已将int
值42转换为bool
值true
。当我将其转换回整数时,它会将其值更改为1。如何转换为正确的值?(我不能(
您有以下选项:
- 仅使用可表示为
double
的值。9007199258935295不能表示为64位二进制浮点(IEEE-754(1。所有32位整数都是可表示的 - 请改用
long double
。x86 80位扩展浮点和128位IEEE-754浮点都可以表示所有64位整数 - 使用任意精度的算术运算代替有限精度,在这种情况下,您不需要担心精度不足。C++标准库不提供任意精度算术的实现
1尽管IEE-754标准无处不在,但从技术上讲,无起泡点类型的精度是由C++语言定义的。它是由语言实现定义的。