【问题标题】:Fixed-point number format specifier rounding of doubles?双精度数的定点数格式说明符舍入?
【发布时间】:2015-12-24 12:59:32
【问题描述】:

我对 IEEE 754 有相当的了解,所以这不是“为什么将数字 a 和数字 b 相加会导致...”的问题之一。

我想问一下我是否正确理解了定点数字格式说明符,因为它的行为与我对某些双精度值的预期不同。

例如:

double d = 0x3FffffFFFFfffe * (1.0 / 0x3FffffFFFFffff);
Console.WriteLine(d.ToString("R"));
Console.WriteLine(d.ToString("G20"));
Console.WriteLine(d.ToString("F20"));

"R" 和 "G" 说明符都打印出相同的内容 - 正确的值:0.99999999999999989 但无论我告诉它包含多少个小数,"F" 说明符总是向上舍入到 1.0 .即使我告诉它打印最大 99 位小数 ("F99"),它仍然只输出“1”-后跟 99 个零。

那么我的理解是否被破坏了,有人可以指出规范中的相关部分,还是这种行为被破坏了? (这对我来说不会破坏交易,我只是想知道。)

Here 是我看过的,但我没有看到任何解释。

(这是.Net4.0)

【问题讨论】:

    标签: c# rounding number-formatting


    【解决方案1】:

    用户“w.b”链接到另一个问题,我怀疑这个问题可能有最好的答案......尽管细节和文档有些模糊。 (不幸的是,评论被删除了。)

    链接的问题是Formatting doubles for output in C#。

    简而言之,除非您使用 G 或 R 说明符,否则在自定义格式之前,输出始终会减少到小数点后 15 位。在该问题中,任何人都能链接到的最佳文档是this MSDN page。细节和措辞并不像我希望的那样清晰,但正如我所说,我认为这是我能找到的最好的。

    【讨论】:

    • 从链接中看不太清楚的两个 cmets。 1) 数学是以 2 为基数进行的,因此会发生从十进制到二进制再回到十进制的转换,这会影响结果的四舍五入。 2) 可以使用 PC 微处理器内的浮点硬件或通过 C# 编译器中的模拟来执行数学运算。因此,有时您会得到不同的答案,具体取决于您是使用调试文件夹中的可执行文件还是使用发布文件夹中的可执行文件。
    • @jdweng 您提到的最后一部分不是 JIT 的实现细节吗?无论如何,如果您可以链接到任何规范或其他文档,我很乐意阅读它。 :)
    • 如果我自己没记错的话,规范允许以更高的精度执行中间计算。换句话说,只要该值仍在 cpu 寄存器中,它就可能具有高于规定的精度。 (如果写回内存,则会丢失额外的精度。)这并不总是可取的,因此您可以使用强制转换语法通过强制转换为相同的类型来截断额外的精度。换句话说,这段代码:float x = /*some calculation*/; bool isIdentical = x == (float)x; 可能并不总是像预期的那样返回 true...(如果我没记错规范).
    • 调试编译只是提供了更好的变量可见性,但代价是执行速度较慢。 PC 中的芯片非常复杂,在调试过程中并非所有芯片中的连接都可以访问。编译器在调试期间模拟连接。与芯片中的浮点单元的连接是有时被模拟(或部分模拟)的这些项目之一。例如,下溢、溢出、除以零是发布可执行文件中处理器中的异常。在调试期间,您可能不希望发生异常,而是检查状态寄存器。
    猜你喜欢
    • 1970-01-01
    • 2018-06-04
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    相关资源
    最近更新 更多