简体   繁体   English

在C ++中如何定义从整数到浮点的精度损失?

[英]How is the precision loss from integer to float defined in C++?

I've a question to the code snippet below: 我对以下代码段有疑问:

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

The long value cannot be represanted exactly according to the IEEE754. 根据IEEE754,不能完全表示long值。

My Question is how is the lossy conversion handled: 我的问题是如何处理有损转换:

  1. Is the nearest floating point representation taken? 是否采用最近的浮点表示形式?
  2. Is the next smaller/bigger representation taken? 是否会采用下一个较小/较大的表示形式?
  3. Or is an other approach is taken? 还是采用其他方法?

I'm aware of this question what happens at background when convert int to float but this does not anwser my question. 我知道这个问题,将int转换为float时在后台会发生什么,但这并不能解决我的问题。

See here : 这里

A prvalue of integer or unscoped enumeration type can be converted to a prvalue of any floating-point type. 整数或无作用域枚举类型的prvalue可以转换为任何浮点类型的prvalue。 If the value cannot be represented correctly, it is implementation defined whether the closest higher or the closest lower representable value will be selected, although if IEEE arithmetic is supported, rounding defaults to nearest. 如果不能正确表示该值,则由实现方式定义是选择最接近的较高值还是最接近的较低可表示值,尽管如果支持IEEE算术,则四舍五入默认为最近值。 If the value cannot fit into the destination type, 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. 如果源类型为bool,则将值false转换为零,将值true转换为1。

As for the rounding rules of IEEE 754, there seem to be five of them . 至于IEEE 754的舍入规则,似乎有五个 I couldn't find any information on which ones are used in which situation, though. 但是,我找不到有关在哪种情况下使用哪种信息的任何信息。 It looks like it's up to the implementation however, you can set the rounding mode in a C++ program as described here . 看起来这取决于实现,但是,您可以按此处所述 C ++程序中设置舍入模式。

C++ defines the conversion like this (quoting latest standard draft): C ++这样定义转换(引用最新的标准草案):

[conv.fpint] [conf.fpint]

A prvalue of an integer type or of an unscoped enumeration type can be converted to a prvalue of a floating-point type. 可以将整数类型或无作用域枚举类型的prvalue转换为浮点类型的prvalue。 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. 如果源类型为bool,则将值false转换为零,将值true转换为1。

The IEEE 754 standard defines conversion like this: IEEE 754标准定义了如下转换:

5.4.1 Arithmetic operations 5.4.1算术运算

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. 如果转换后的值不能以目标格式精确表示,则根据适用的取整方向属性确定结果,并且如算术运算一样,会出现第7章中指定的不精确或浮点溢出异常。 The signs of integer zeros are preserved. 整数零的符号被保留。 Integer zeros without signs are converted to +0. 无符号的整数零将转换为+0。 The preferred exponent is 0. 首选指数为0。

Rounding modes are specified as: 舍入模式指定为:

4.3.1 Rounding-direction attributes to nearest 4.3.1舍入方向属性最接近

  • roundTiesToEven, the floating-point number nearest to the infinitely precise result shall be delivered; roundTiesToEven,应交付最接近无限精确结果的浮点数; 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; roundTiesToAway,应交付最接近无限精确结果的浮点数; 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 4.3.2有向舍入属性

  • roundTowardPositive, the result shall be the format's floating-point number (possibly +∞) closest to and no less than the infinitely precise result roundTowardPositive,结果应为格式的浮点数(可能为+∞),最接近且不小于无限精确的结果

  • roundTowardNegative, the result shall be the format's floating-point number (possibly −∞) closest to and no greater than the infinitely precise result roundTowardNegative,结果应为格式的浮点数(可能为-∞),最接近且不大于无限精确的结果

  • roundTowardZero, the result shall be the format's floating-point number closest to and no greater in magnitude than the infinitely precise result. roundTowardZero,结果应为格式的浮点数,该浮点数最接近且大小不超过无限精确的结果。

4.3.3 Rounding attribute requirements 4.3.3舍入属性要求

The roundTiesToEven rounding-direction attribute shall be the default rounding-direction attribute for results in binary formats. roundTiesToEven取整方向属性应为二进制格式结果的默认取整方向属性。

So by default, your suggestion 1 would apply, but only if another mode hasn't been selected. 因此,默认情况下,建议1将适用,但前提是未选择其他模式。


The C++ standard library inherits <cfenv> from the C standard. C ++标准库从C标准继承<cfenv> This header offers macros, functions and types for interacting with the floating point environment, including the rounding modes. 该标头提供了与浮点环境进行交互的宏,函数和类型,包括舍入模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM