从 int64_t 铸造到双倍再到 int64_t 再次改变它的价值

  • 本文关键字:int64 改变 c++
  • 更新时间 :
  • 英文 :

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转换为booltrue。当我将其转换回整数时,它会将其值更改为1。如何转换为正确的值?(我不能(

您有以下选项:

  • 仅使用可表示为double的值。9007199258935295不能表示为64位二进制浮点(IEEE-754(1。所有32位整数都是可表示的
  • 请改用long double。x86 80位扩展浮点和128位IEEE-754浮点都可以表示所有64位整数
  • 使用任意精度的算术运算代替有限精度,在这种情况下,您不需要担心精度不足。C++标准库不提供任意精度算术的实现

1尽管IEE-754标准无处不在,但从技术上讲,无起泡点类型的精度是由C++语言定义的。它是由语言实现定义的。

最新更新