从大双精度数静态转换为整数时的奇怪行为

发布于 2024-12-08 21:48:22 字数 477 浏览 0 评论 0原文

这是我的简单代码:

int main() {
  double d1 = 10000000000.0;
  const double d2 = 10000000000.0;

  cout << static_cast<int>(d1) << endl;
  cout << static_cast<int>(d2) << endl;
  cout << static_cast<int>(10000000000.0) << endl;
}

输出是:

-2147483648
2147483647
2147483647

这让我非常惊讶。为什么正 double 有时会被转换为负 int?

我正在使用 g++:GCC 版本 4.4.3(Ubuntu 4.4.3-4ubuntu5)。

Here 's my simple code:

int main() {
  double d1 = 10000000000.0;
  const double d2 = 10000000000.0;

  cout << static_cast<int>(d1) << endl;
  cout << static_cast<int>(d2) << endl;
  cout << static_cast<int>(10000000000.0) << endl;
}

The output is:

-2147483648
2147483647
2147483647

This surprised me grealy. Why would a positive double sometimes get casted to a negative int?

I'm using g++: GCC version 4.4.3 (Ubuntu 4.4.3-4ubuntu5).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴者 2024-12-15 21:48:22

int 不足以容纳该值时,将 double 转换为 int 会产生未定义的行为

[n3290: 4.9/1]: 浮点类型的纯右值可以转换
为整数类型的纯右值。转换截断;那是,
小数部分被丢弃。 如果以下情况,则行为未定义
截断值无法在目标类型中表示。

此行为源自 C:

[C99: 6.3.1.4/1]: 当实数浮点类型的有限值为
转换为_Bool以外的整数类型,小数部分为
被丢弃(即,该值被截断为零)。 如果值
整数部分不能用整数类型表示,
行为未定义。

对您来说,int 显然不够大。

  • 并且,在第一种情况下,对于您来说,这恰好会导致符号位被设置。
  • 在第二种和第三种情况下,同样对您来说,可能是优化导致了不同的行为。

但不要依赖此代码中的任一(或者实际上任何)行为。

Casting a double to an int when int isn't big enough to hold the value yields undefined behaviour.

[n3290: 4.9/1]: A prvalue of a floating point type can be converted
to a prvalue of an integer type. The conversion truncates; that is,
the fractional part is discarded. The behavior is undefined if the
truncated value cannot be represented in the destination type.

This behaviour is derived from C:

[C99: 6.3.1.4/1]: When a finite value of real floating type is
converted to an integer type other than _Bool, the fractional part is
discarded (i.e., the value is truncated toward zero). If the value of
the integral part cannot be represented by the integer type, the
behavior is undefined.

For you, int clearly isn't big enough.

  • And, in the first case, for you this just so happens to result in the sign bit being set.
  • In the second and third cases, again for you, it's probably optimisations that happen to result in different behaviour.

But don't rely on either (or, indeed, any) behaviour in this code.

在梵高的星空下 2024-12-15 21:48:22

来自 C 标准(1999):
6.3.1.4 实数浮点数和整数
1 当实浮点类型的有限值转换为_Bool以外的整数类型时,
小数部分被丢弃(即,该值被截断为零)。如果值
整数部分不能用整数类型表示,行为未定义。

来自 C++ 标准 (2003):
4.9 浮点积分转换 [conv.fpint]
1 浮点类型的右值可以转换为整数类型的右值。转换截断;
即小数部分被丢弃。如果不能截断值,则行为未定义
以目标类型表示。 [注:如果目标类型为 bool,请参见 4.12。 ]

很可能你的 double 太大而无法正确转换为 int。

From the C standard (1999):
6.3.1.4 Real floating and integer
1 When a finite value of real floating type is converted to an integer type other than _Bool,
the fractional part is discarded (i.e., the value is truncated toward zero). If the value of
the integral part cannot be represented by the integer type, the behavior is undefined.

From the C++ standard (2003):
4.9 Floating-integral conversions [conv.fpint]
1 An rvalue of a floating point type can be converted to an rvalue of an integer type. The conversion truncates;
that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be
represented in the destination type. [Note: If the destination type is bool, see 4.12. ]

Most likely your double is too big to be converted correctly to int.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文