浮点数的打印方式不同,因为打印的目的不同,因此对如何进行打印有不同的选择。
打印浮点数是一种转换操作:以内部格式编码的值被转换为十进制数字。但是,有关于转换细节的选择。
(A)如果你在做精确的数学运算,并希望看到内部格式表示的实际值,那么转换必须是精确的:它必须产生一个与输入值完全相同的十进制数字。(每个浮点数正好代表一个数字。在 IEEE 754 标准中定义的浮点数不代表一个区间。)有时,这可能需要产生大量的数字。
(B)如果您不需要精确值但确实需要在内部格式和十进制之间来回转换,那么您需要将其准确地(且准确地)转换为十进制数字,以将其与任何其他结果区分开来。也就是说,您必须生成足够多的数字,以使结果与通过转换内部格式中相邻的数字所得到的结果不同。这可能需要产生大量的数字,但不能多到难以管理。
(C)如果您只想让读者了解数字,而不需要生成确切的值以使您的应用程序按预期运行,那么您只需生成您需要的数字即可特殊应用。
转换应该执行哪些操作?
不同的语言有不同的默认值,因为它们是为不同的目的而开发的,或者因为在开发过程中做所有必要的工作来产生准确的结果并不方便,或者由于各种其他原因。
(A) 需要仔细的代码,并且某些语言或它们的实现不提供或不保证提供这种行为。
(B) 是 Java 所要求的,我相信。然而,正如我们在最近的一个问题中看到的,它可能有一些意想不到的行为。(65.12
打印为“65.12”是因为后者有足够的数字可以将它与附近的值区分开来,但65.12-2
打印为“63.120000000000005”是因为它和 63.12 之间还有另一个浮点值,因此您需要额外的数字来区分它们。 )
(C) 是某些语言默认使用的。从本质上讲,这是错误的,因为没有一个单一的值可以适用于所有应用程序。事实上,几十年来我们已经看到,它主要是通过隐藏所涉及的真实值来助长对浮点数的持续误解。然而,它易于实现,因此对一些实现者很有吸引力。理想情况下,语言应该默认打印浮点数的正确值。如果要显示较少的数字,则数字的数量应仅由应用程序实现者选择,希望包括考虑适当的数字数量以产生所需的结果。
更糟糕的是,有些语言除了不显示实际值或足够多的数字来区分它外,甚至不保证产生的数字在某种意义上是正确的(例如通过将精确值四舍五入到数字而得到的值显示的数字)。在不提供有关此行为的保证的实现中进行编程时,您不是在进行工程设计。