在启用 UBSAN 的情况下将 double 转换为 long long 时超出可表示值的范围

Outside the range of representable values when casting double to long long with UBSAN enabled

在启用 UBSAN 的情况下编译以下代码会导致此错误:

Runtime error: value 9.22337e+18 is outside the range of representable values of type 'long long'

double a = (double)LLONG_MAX; // or (double)LLONG_MAX - 1
long long b = (long long)a;

这是一个已知问题吗?我的理解是这个值不在范围之外。

您所看到的是预期的行为。

LLONG_MAX 在您的系统上是一个 64 位整数,需要 63 位来完整表示它的值(因为一位用于保存符号)。典型的双精度数(使用 IEEE 算法)只有 53 位精度。

当您将整数分配给双精度数时,整数值需要 converted 给双精度数。当整数需要比双精度存储更多的位来表示其值时,此转换将导致值的某些精度丢失,这是通过舍入实现的。这是向上舍入还是向下舍入的实现细节,但根据 IEEE 算法规则,舍入将最接近。

因为在您的系统上 long 值被四舍五入,生成的 double 值不能存储在 long long 中,导致您的运行时错误。