C# 定点数字格式说明符双精度舍入?

C# 定点数字格式说明符双精度舍入?,c#,rounding,number-formatting,C#,Rounding,Number Formatting,我对IEEE754有相当好的理解,所以这不是那种“为什么增加数字a和数字b会导致…”类型的问题 相反,我想问的是,我是否正确理解了定点数字格式说明符,因为它的行为与我预期的某些双精度值不同 例如: double d = 0x3FffffFFFFfffe * (1.0 / 0x3FffffFFFFffff); Console.WriteLine(d.ToString("R")); Console.WriteLine(d.ToString("G20")); Console.WriteLine(d.T

我对IEEE754有相当好的理解,所以这不是那种“为什么增加数字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.99999999989
的正确值,但是
“F”
说明符总是四舍五入到
1.0
,无论我告诉它包含多少个小数。即使我告诉它打印最大数量的99位小数(
“F99”
),它仍然只输出“1”-后跟99个零

那么,我的理解是否被破坏了,有人能告诉我规范中的相关部分吗,或者这种行为是否被破坏了?(对我来说,这不是交易的破坏者,我只是想知道。)

这就是我所看到的,但我看不到任何解释

(这是.Net4.0)

用户“w.b”链接到另一个问题,我怀疑这个问题有可能得到最好的答案。。。虽然在细节和文件上有些模糊。(遗憾的是,该评论已被删除。)

相关的问题是


简而言之,它似乎表明,除非使用
G
R
说明符,否则在自定义格式之前,输出总是减少到15位小数。在这个问题上,任何人都能找到的最好的医生是。细节和措辞并不像我希望的那样清晰,但正如我所说的,我认为这是我将要找到的最好的评论。

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