【问题标题】:int64_t conversion to 'long double' issueint64_t 转换为“long double”问题
【发布时间】:2012-08-20 06:13:09
【问题描述】:

以下代码产生了所示的输出,我很困惑......我正在使用英特尔编译器版本 2013 beta update 2 /opt/intel/composer_xe_2013.0.030/bin/intel64/icpc

// all good
int64_t fops_count1 = 719508467815;
long double fops_count2 = boost::static_cast<long double>(fops_count1);
printf("%" PRIu64 "\n", fops_count1); // OK outputs 719508467815
printf("%Le\n", fops_count2);         // OK outputs 7.195085e+11

// bad! why this?
int64_t fops_count1 = 18446743496931269238;
long double fops_count2 = boost::static_cast<long double>(fops_count1);
printf("%" PRIu64 "\n", fops_count1); // OK outputs 18446743496931269238
printf("%Le\n", fops_count2);         // FAIL outputs -5.767783e+11 <<<<<<<<<<<<<<<<< WHY?

【问题讨论】:

  • 也许这个值对于长双倍来说也太大了?
  • 这是什么boost::static_cast?您不能使用关键字作为名称。
  • @H2CO3:它应该适合long double 就好了;但不在int64_t
  • 我假设这是针对 i386 或 x86_64 平台的,其中 long double 具有 80 位精度。 (在许多平台上,大小各不相同。在某些平台上,long double 不比 double 宽。为了完整起见,我提到这一点。)

标签: c++


【解决方案1】:

忽略boost::static_cast,我看不懂,64位有符号整数不能代表你显示的数字,但是

18446743496931269238 - 264 = -576778282378

即这是一个二进制补码 64 位有符号整数回绕时得到的值。

现在boost::static_cast 是什么?

【讨论】:

  • @Giovanni:谢谢,但是虽然这涉及到static_cast,但它不能是 OP 正在使用的。 OP 的语法在标准 C++ 中无效。 static_cast 是关键字;它不能用作名称。
【解决方案2】:
int64_t fops_count1 = 18446743496931269238;

这是有符号溢出,也就是UB。 int64_t 的最大值约为 2^63,绝对小于这个值。似乎您的处理器实现了环绕,给出了您看到的负值。

【讨论】:

  • 技术上the result is implementation-defined or an implementation-defined signal is raised,不是未定义的。
  • 真的吗?我认为签名溢出完全是 UB。
  • @DeadMG:如果一个表达式的结果不能用表达式的类型表示(5/4),那就是UB;但是,如果无法表示结果,则整数转换会给出实现定义的值 (4.7/3)。
  • @Dave:您引用的是 C 标准;在 C++ 中,它只是“值是实现定义的”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-30
  • 2015-08-23
  • 2019-05-20
  • 2021-12-03
  • 2021-10-02
  • 2013-01-20
相关资源
最近更新 更多