我正在编写一个计算PI值的函数,并将其作为double返回。到现在为止还挺好。但是一旦函数在小数位后达到14位,它就不能再保持。我假设这是因为双精度有限。如何在小数位后继续获得更多数字?
答案 0 :(得分:16)
我根本不会以浮点方式进行。
回想一下你的算法是:
(1 + 1 / (2 * 1 + 1)) *
(1 + 2 / (2 * 2 + 1)) *
(1 + 3 / (2 * 3 + 1)) *
(1 + 4 / (2 * 4 + 1)) *
(1 + 5 / (2 * 5 + 1)) *
(1 + 6 / (2 * 6 + 1)) *
(1 + 7 / (2 * 7 + 1)) * ...
您计算分数的每个阶段。为什么不简单地将该分数保持为分子/分母形式?您要计算的分数是:
(4 / 3) *
(7 / 5) *
(10 / 7) *
(13 / 9) * ...
顶部只有4 * 7 * 10 * 13 ......底部只有3 * 5 * 7 * 9。
获得一个BigInteger类(一个随System.Numerics中的4.0框架一起提供),您可以轻松地计算出你想要的分子和分母。那么你只是将商转换为十进制的问题。嗯,这很容易。大概你知道如何进行长时间划分。只需在分子和分母上实现一个长除法算法,该算法会吐出所需的位数。
答案 1 :(得分:8)
您需要多少精度?
使用decimal
将为您提供大约28个小数位:
decimal pi = 3.14159265358979323846264338327950288419716939937510m;
Console.WriteLine(pi); // 3.1415926535897932384626433833
如果这还不够,那么你需要搜索某种BigDecimal实现,或者查看其他技术来执行计算。
答案 2 :(得分:1)
答案 3 :(得分:1)
尝试decimal
而不是双倍。它不能存储大到double的数字,但我认为它在小数点后具有更高的精度。如果您需要更多,您可能必须使用String。
答案 4 :(得分:0)
是的,这是因为双倍的精确度有限。有许多不同的方法来计算pi的数字。我建议问你最喜欢的搜索引擎,“如何计算pi的数字”。
答案 5 :(得分:0)
您可以按照this answer中的建议使用J#BigDecimal
类型。