如何处理大多数小数部分无法用二进制精确表示的事实?

时间:2009-11-02 17:15:35

标签: c# floating-point double decimal

因此,我们知道像0.1这样的分数无法在二进制基数中准确表示,这会导致精确的问题(例如此处提到的Formatting doubles for output in C#)。

我们知道我们有十进制表示数字的十进制类型...但问题是,很多数学方法,不支持十进制类型,所以我们将它们转换为double,这再次破坏了数字

那我们该怎么办?

7 个答案:

答案 0 :(得分:7)

要全面了解执行浮点计算所涉及的挑战,请参阅以下文章:

每个计算机科学家应该知道的关于浮点运算的内容 http://docs.sun.com/source/806-3568/ncg_goldberg.html

答案 1 :(得分:4)

哦,对于大多数小数部分不能用二进制表示的事实我们该怎么办?或者就此而言,二进制分数不能用十进制表示?

或者,甚至,在任何计算机系统中都无法准确表示所有基数中的无穷大(实际上是不可数无穷大)的实数?

什么!回想一下陈旧的陈词滥调,你可以近距离接触政府工作......事实上,你可以接近任何工作......计算机可以产生的准确度没有限制,它不能无限,(这是数字表示方案能够表示 每个 可能的实数)所需的内容

您可以看到,对于您可以设计的每个数字表示方案,在任何计算机中,它只能表示 有限 数量的不同的不同实数,准确度为100.00%。在每对相邻数字之间(那些可以100%精确度表示的数字),总会有一个无穷大的其他数字,它不能100%准确地表示。

答案 2 :(得分:3)

  

那我们该怎么办?

我们只是继续呼吸。这确实不是一个结构性问题。我们的精度有限,但通常绰绰有余。你只需要记住在提供数字时格式化/舍入。

以下代码段中的问题是WriteLine(),不在计算中:

double x = 6.9 - 10 * 0.69;
Console.WriteLine("x = {0}", x);

如果您遇到特定问题,请发布。通常有一些方法可以防止精度损失。如果您确实需要> = 30个十进制数字,则需要一个特殊的库。

答案 3 :(得分:3)

请注意,您需要的精确度以及所需的舍入规则将取决于您的问题域。

如果你正在编写控制核反应堆的软件,或者在大爆炸之后模拟宇宙中第一个十亿分之一(我的朋友真的这样做了),你需要比计算销售时更高的精度税(我为生活而做的事)。

例如,在金融领域,隐式或明确地对精度有特定要求。一些美国税务司法管辖区将税率指定为小数点后的5位数。您的舍入方案需要允许那么高的精度。当西欧大部分地区转变为欧元时,有一种非常具体的四舍五入方法被写入法律。在过渡期间,必须完全按照要求进行整理。

了解您的域名规则,并测试您的舍入方案是否符合这些规则。

答案 4 :(得分:2)

我想每个人都暗示: 反转稀疏矩阵? “有一个应用程序”等等

数值计算是一匹训练有素的马。如果你遇到问题,它可能会在1970年之前或更早的时候放到牧场,通过图书馆或片段将片段推进到未来。

答案 5 :(得分:1)

您可以移动小数点以使数字为整数,然后进行64位整数运算,然后将其移回。然后你只需要担心溢出问题。

答案 6 :(得分:1)

  

我们知道我们有十进制类型   用于十进制表示   数字...但问题是,很多   数学方法,不支持   十进制类型,所以我们已经转换它们   加倍,这破坏了数字   试。

Math methods 做了支持decimalAbsCeilingFloorMaxMinRoundSignTruncate。这些功能的共同点是它们会返回准确的结果。这与decimal的目的一致:使用基数为10的数字进行精确算术。

trig和Exp / Log / Pow函数返回近似答案,那么“精确”算术类型的重载会是什么意思?