c++ - C++中如何定义从整数到 float 的精度损失?

标签 c++ floating-point rounding static-cast

我对下面的代码片段有疑问:

long l=9223372036854775807L;
float f=static_cast<float>(l);

long 值不能完全按照 IEEE754 表示。

我的问题是如何处理有损转换:

  1. 是否采用最接近的浮点表示形式?
  2. 是否采用下一个更小/更大的代表?
  3. 或者是否采取了其他方法?

我知道这个问题 what happens at background when convert int to float但这并不能回答我的问题。

最佳答案

C++ 定义这样的转换(引用最新标准草案):

[conv.fpint]

A prvalue of an integer type or of an unscoped enumeration type can be converted to a prvalue of a floating-point type. The result is exact if possible. If the value being converted is in the range of values that can be represented but the value cannot be represented exactly, it is an implementation-defined choice of either the next lower or higher representable value. [ Note: Loss of precision occurs if the integral value cannot be represented exactly as a value of the floating-point type. — end note ] If the value being converted is outside the range of values that can be represented, the behavior is undefined. If the source type is bool, the value false is converted to zero and the value true is converted to one.

IEEE 754 标准定义的转换如下:

5.4.1 Arithmetic operations

It shall be possible to convert from all supported signed and unsigned integer formats to all supported arithmetic formats. Integral values are converted exactly from integer formats to floating-point formats whenever the value is representable in both formats. If the converted value is not exactly representable in the destination format, the result is determined according to the applicable rounding-direction attribute, and an inexact or floating-point overflow exception arises as specified in Clause 7, just as with arithmetic operations. The signs of integer zeros are preserved. Integer zeros without signs are converted to +0. The preferred exponent is 0.

舍入模式指定为:

4.3.1 Rounding-direction attributes to nearest

  • roundTiesToEven, the floating-point number nearest to the infinitely precise result shall be delivered; if the two nearest floating-point numbers bracketing an unrepresentable infinitely precise result are equally near, the one with an even least significant digit shall be delivered.

  • roundTiesToAway, the floating-point number nearest to the infinitely precise result shall be delivered; if the two nearest floating-point numbers bracketing an unrepresentable infinitely precise result are equally near, the one with larger magnitude shall be delivered.

4.3.2 Directed rounding attributes

  • roundTowardPositive, the result shall be the format’s floating-point number (possibly +∞) closest to and no less than the infinitely precise result

  • roundTowardNegative, the result shall be the format’s floating-point number (possibly −∞) closest to and no greater than the infinitely precise result

  • roundTowardZero, the result shall be the format’s floating-point number closest to and no greater in magnitude than the infinitely precise result.

4.3.3 Rounding attribute requirements

The roundTiesToEven rounding-direction attribute shall be the default rounding-direction attribute for results in binary formats.

因此,默认情况下,您的建议 1 将适用,但前提是尚未选择其他模式。

<小时/>

C++标准库继承<cfenv>来自C标准。该 header 提供了用于与浮点环境交互的宏、函数和类型,包括舍入模式。

关于c++ - C++中如何定义从整数到 float 的精度损失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57870372/

相关文章:

c++ - 使用 `boost::numeric::odeint` 时扩展系统的类型签名

c++ - 在c++中可以容纳什么最大的整数,可以将 float 加1?

Excel - float 不能求和

c - 如何在 C 语言中正确舍入 double ?

sql-server - SQL Server 2008 中的小数舍入

c++ - 什么是 C++ 中的标准延迟/终结器实现?

c++ - QProgressBar 连接类之间的进度 - "no matching function for call"

c++ - 使用默认值初始化 unique_ptr 的 vector (nullptr?)

c - 使用 float 而不是 double 时出现奇怪的输出

javascript - ViewModel 中的 double 在 JavaScript 数组中四舍五入为整数