双精度
Console.WriteLine("1/7的值是" + (double)1 / 7);
结果:0.14285714285714285
即使使用双精度浮点数,精确的位数也是有限的,如果想精确到小数点后100位,1000位,甚至更高哪?
朴素的除法
除数 余数 商,利用这三者的关系,可以无限度的计算下去。当然这个不能超过计算机的内存限制。
商=除数/被除数
余数 = 除数%被除数
迭代:
商 = (余数10)/被除数
余数 = (余数10)% 被除数
这就是小学数学的除法规则。基于此规则就可以不断迭代,提高精度,本文使用c#的long类型存储。用一个列表存储long。
代码实现
long的最大值是9223372036854775807 ,存在overflow的问题,因此 ,解决方案可以参见代码:
//计算1/7 除数 被除数
List<long> irrationalNumber(int divisor, int dividend) {List<long> longList = new List<long>();long final_result = 0;int result = 0;int remainder = 0;result = (int)divisor / dividend;remainder = (int)divisor% dividend;final_result += result;long tmp_result = 0;//这里以100为例while (longList.Count < 100){divisor = remainder * 10;result = (int)divisor / dividend;remainder = (int)divisor % dividend;tmp_result = final_result;final_result = tmp_result * 10 + result;//判断越界9223372036854775807 4285714285714285714 越界的话 变成什么不一定 有时候是5963654709723753910,有时候是负数if (final_result < 0 || (long)((final_result-result))/10 != tmp_result){longList.Add(tmp_result);tmp_result = 0;final_result = 0;remainder = (int)divisor / 10;continue;}}return longList;
}
var result =irrationalNumber(1,7);Console.Write("0.");
foreach (long item in result)
{Console.Write(item);
}
运行结果:
求16/19,只需要改为:
var result =irrationalNumber(16,19);Console.Write("0.");
foreach (long item in result)
{Console.Write(item);
}
最终结果:
写在最后
用这种方法,也可以求出Π比较高的精度。计算Π有很多方法,比如无穷级数方法,蒙特卡罗方法等
公众号
更多内容,欢迎关注我的微信公众号:半夏之夜的无情剑客。