【问题标题】:Precision loss from float to double, and from double to float?从浮点数到双精度以及从双精度到浮点数的精度损失?
【发布时间】:2016-04-25 21:34:45
【问题描述】:
float fv = orginal_value;  // original_value may be any float value
...
double dv = (double)fv;
...
fv = (float)dv;

fv 应该完全等于 original_value 吗?任何精度都可能丢失?

【问题讨论】:

  • 感谢您的 cmets。我认为这是不同的。后端的问题是:为简单起见,我想将浮点(32 位)值存储为双精度(64 位),但经过一些程序,从双精度存储值恢复原始浮点值。在你提到的问题中,我只看到它提到从双精度转换为浮点数)
  • original_value 的类型是什么?
  • 你要的是 C 还是 C++?
  • 对于这个问题,C和C++有什么区别吗?

标签: c++ c floating-accuracy


【解决方案1】:

fv 应该完全等于 original_value 吗?任何精度都可以 丢了?

是的,如果 dv 的值在两者之间没有变化。

来自 C99 规范中的 Conversion 6.3.1.5 Real Floating types 部分:

  1. 当浮点数提升为双精度或长双精度,或双精度 提升为 long double,其值不变
  2. 当双精度 降级为 float,long double 降级为 double 或 float,或 值以比要求更高的精度和范围表示 通过其语义类型(见 6.3.1.8)被显式转换为 语义类型,如果被转换的值可以准确表示 在新类型中,它是不变的。如果要转换的值在 可以表示但不能表示的值的范围 确切地说,结果要么是最近的高点,要么是最近的低点 可表示的值,以实现定义的方式选择。如果 正在转换的值超出了可以转换的值范围 表示,行为未定义

对于 C++,来自 4.6 又名 conv.fpprom 部分(使用的草稿:n337,我相信最终规范中也有类似的行)

float 类型的纯右值可以转换为 double 类型的纯右值。 值不变。这种转换称为浮点 推广。

4.8 又名 conv.double

部分

浮点类型的prvalue可以转换为prvalue 另一种浮点类型。 如果源值可以准确 在目标类型中表示,转换的结果是 那个确切的表示。如果源值在两个相邻的 目标值,转换的结果是 这些值中的任何一个的实现定义的选择。否则, 行为未定义。允许作为浮点数的转换 促销不包括在浮点转换集合中

所以值应该完全相等。

【讨论】:

  • 请务必注意,OP 在 sn-p 中添加为 ... 行的内容应该更改 @987654324 的值@,如果确实如此,则可能会丢失精度甚至 UB
  • Initial "应该 fv 完全等于 original_value?可能会丢失任何精度?"是 2 个问题,回答“是”仅适用于第一个问题 - 看来您希望对第二个问题“否”。建议进行小修改以澄清。
猜你喜欢
  • 2018-02-23
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
相关资源
最近更新 更多