论如何用计算机无精度丢失存储任意有理数(C++)

在数学中,有理数是整数(正整数、0、负整数)和分数的统称。C++语言提供了很多数据类型来存储部分有理数,如int ,long long ,float, double 等。但这些类型都有一个共同的特点,那就是精度有限。例如int的范围是-2147483648~2147483647,float大约只有6-7位是准确的。关于浮点数精度丢失的原因,大概是这样的:如果有一个最简分数 n m \frac{n}{m} mn,要以 k k k进制小数表示,如果 m m m的任意一个质因数不能被 k k k整除,这个分数就不能化成 k k k进制有限小数。如 7 12 \frac{7}{12} 127,在10进制中不能化成有限小数,因为12的一个质因数3不能被10整除,而在6进制中就可以化成有限小数。而计算机使用的是二进制,只要进制数 k k k不是2的整幂数,就不能化成二进制有限小数,如 1 5 \frac{1}{5} 51,在十进制中是0.2,但在二进制中是 0. 0 ˙ 01 1 ˙ 0.\dot{0}01\dot1{} 0.0˙011˙。计算机是没法存储无限循环小数的,所以会有精度丢失。
对于大整数的解决方案,就是使用大整数类。Java的库中包含大整数类,而C++没有,所以我们只能自己写。在此分享一下我的大整数类。至于浮点数的问题,我们可以采取使用分数类。但如果只用int等类型表示分子和分母,还是会出现精度不够的问题,如 1000000000000000000000000000 1000000000000000000000000001 \frac{1000000000000000000000000000}{1000000000000000000000000001} 10000000000000000000000000011000000000000000000000000000就无法表示。所以,我们必须把分数类和大整数类结合,组成一个大整数版的分数类,这样就能理论上实现毫无精度丢失保存任意有理数了。注意:在实际中计算机内存有限,有些非常非常大的数可能把内存占满,所以只是理论上可以保存。当然,实际中几乎不可能出现这么大的数,所以这种表示方法就足够了。

猜你喜欢

转载自blog.csdn.net/qq_54121864/article/details/119829934