';美丽';通过适当地四舍五入错误的数字进行编号

本文关键字:数字 编号 错误 美丽 四舍五入 | 更新日期: 2023-09-27 18:23:57

我想要我的蛋糕并吃掉它。我想在不影响其他计算准确性的情况下,最大限度地美化(舍入)数字。我在C#中使用了doubles(还有一些字符串转换操作)。

问题来了。我理解double数字表示的固有局限性(所以请不要解释)。然而,我想以某种方式对数字进行四舍五入,以使最终用户看起来美观(我正在制作一个计算器)。问题是,按X有效数字四舍五入在一种情况下有效,但在另一种情况中无效,而按小数位数四舍五进在另一情况中有效,但不是第一种情况。

观察:

  • 案例A:Math.Sin(Math.Pi)=0.000000000000000122460635382238
  • 情况B:0.000000000000001/3=0.000000000000000333333333333333

对于第一种情况,我想按小数位数进行四舍五入。这会给我一个漂亮的零分球,我正在寻找。按Sig数字取整意味着我也会保留错误的数字。

然而,对于第二种情况,我想按显著数字四舍五入,因为如果我只按小数点四入,我会损失大量的准确性。

有没有一种通用的方法可以满足这两种类型的计算?

';美丽';通过适当地四舍五入错误的数字进行编号

我认为对结果本身这样做是不可行的,精度与此无关。

考虑这个输入:(1+3)/2^3。您可以通过将结果显示为sin(30)cos(60)1/2以及许多其他解释来"美化"它。选择错误的"美化"可能会误导用户,让他们认为自己的功能与sin(x)有关。

如果你的计算器将所有初始输入作为变量,你可以将所有操作推迟到你需要结果,然后确保你简化结果,直到它符合你的需求。你需要考虑使用有理数,e、Pi和其他无理数可能不那么容易处理。

最好的解决方案是保留计算过程中可以得到的每一位,并将显示格式留给最终用户。考虑到计算的性质和结果的使用,用户应该知道在他们的情况下有多少有效数字是有意义的。

对于内部使用的浮点格式的一些计算,默认为合理数量的有效数字-如果使用双精度,则约为12。如果用户更改了格式,请立即以新格式重新显示。

最好的解决方案是使用任意精度和/或符号算术,尽管这会导致代码更加复杂和速度减慢。但是,由于性能对于计算器来说并不重要(如果是按钮计算器,而不是您输入表达式进行计算的计算器),您可以在不发出的情况下使用它们

无论如何,有一个很好的折衷方案,那就是使用十进制浮点。您需要限制输入/输出精度,但对内部表示使用更高的精度,这样您就可以像上面的sin情况一样丢弃非常接近零的值。为了获得更好的结果,您可以检测一些边缘情况,如45度倍数的正弦/余弦。。。并直接返回准确的结果。

编辑:刚刚找到了一个好的解决方案,但还没有机会尝试。

我敢打赌你从来没有想过,这是有充分理由的:浮点数是如何被呈现为文本字符串的?这是一个令人惊讶的棘手问题,但自1990年以来,人们一直认为它基本上得到了解决。

在Steele和White的";"如何准确地打印浮点数";,printf和类似的渲染函数的实现尽了最大努力来渲染浮点数字,但它们的性能差异很大。例如,像1.3这样的数字可能会被呈现为1.29999999,或者如果一个数字被写出来并被其书面表示读回的反馈循环,每个连续的结果可能会越来越偏离原始结果。

2010年,Florian Loitsch在PLDI发表了一篇精彩的论文;用整数快速准确地打印浮点数";,这代表了20年来该领域迈出的最大一步:他主要学会了如何使用机器整数进行精确渲染!为什么我要说";大部分是";?因为尽管Loitsch的";Grisu3〃;算法非常快,它放弃了大约0.5%的数字,在这种情况下,你必须回到Dragon4或衍生

龙来了:你甚至不知道自己有的问题的进展