将int转换为double时,会向上舍入、向下舍入还是四舍五入到最近的double?

16
简单问题:将一个整数,比如100,转换为双精度浮点数时,会“向上”或“向下”舍入到下一个双精度浮点数,还是总是舍入到最近的一个(最小增量)?
例如,对于static_cast<double>(100)

Casting from int to double

如果d2 < d1,它会向哪个方向转换?

奖励问题:我是否可以通过使用特殊函数来强制处理器“向下”或“向上”舍入到最接近的双精度数?据我所见,不幸的是没有floor<double>ceil<double>


6
假设 int 是32位,它将始终转换为精确的 double 值(再次假设为64位IEEE-754 double)。有关其他情况下的规则,请参见实浮点整数转换 - Alan Birtles
6
对于小于 ~2^53 (9007199254740992) 的值,没有问题 - 它们可以在 double 中精确表示(请参见此处:https://dev59.com/G3I-5IYBdhLWcg3wc3-w)。然而,对于大于该值的值(您将需要一个 64 位整数),问题仍然存在。 - wohlstad
1
@wohlstad 我认为你所说的“完全表示”是指往返转换将产生完全相同的整数值。只有2的幂次方可以在浮点类型中被准确表示。 - glades
4
@glades,你为什么认为只有2的幂次方可以被精确表示?一个double类型通常有53位的尾数。你可以至少精确地表示约2^53个值,不仅仅是2的幂次方(例如通过将指数设置为2^0)。 - wohlstad
7
不仅仅是2的幂,任何不超过2^53的整数都可以被准确表示,接着是每隔2个整数直到2^54,每隔4个整数直到2^55等。 - Alan Birtles
显示剩余6条评论
1个回答

14

请注意,32位的int可以被64位IEEE 754 double精确表示(实际上它可以精确地表示高达53位的整数)。

如果您使用的整数大于浮点类型所能表示的范围,则适用于Real floating-integer conversions的规则:

  • 如果该值可以被表示但无法精确表示,则结果是最接近的更高或更低的值(换句话说,舍入方向是实现定义的),尽管如果支持IEEE算术,则四舍五入到最近。在这种情况下,未指定是否会引发FE_INEXACT。
  • 如果该值无法表示,则行为是未定义的,尽管如果支持IEEE算术,则会引发FE_INVALID并且结果值未指定。

没有C++标准函数来控制舍入模式,大多数实现将使用IEEE四舍五入。


第一个项目符号上的括号注释与前面的文本意义不同。前面的文本会容许实现以未指定的方式在产生下一个较高或较低值之间进行选择,这可能在两个值均能很好地工作时允许一些优化。 - supercat
@supercat 不确定你的意思?这个引用直接来自 cppreference。 - Alan Birtles
1
@AlanBirtles:无论它来自哪里,这都是懒散的写作。短语“换句话说”应该出现在意思相同但用不同的词语表达的文本之间。如果前后文本没有这种关系,那么这个短语就是多余的。如果实现需要在所有情况下记录它们将如何选择舍入方向,那么文本应该说:“此外,舍入上取整或下取整的选择必须以实现定义的方式进行”,如果实现不需要精确记录这些事情,那么选择是未指定的,并且声明它是... - supercat
"implementation-defined" 会是错误的。 - supercat
@supercat 的标准措辞是“它是一个实现定义的选择,可以选择下一个更低或更高的可表示值” - 我已经调整了 cppreference 来更接近这个措辞。 - Cubbi
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接