我在将 double (例如 N)转换为 p/q 形式(有理数形式)时遇到问题,为此我有以下策略:
- 将双 N 乘以一个大数,比如 $k = 10^{10}$
- 然后
p = y*k
和q = k
- 接
gcd(p,q)
并找到p = p/gcd(p,q)
和q = p/gcd(p,q)
当N = 8.2
,如果我们用笔和纸来解决,答案是正确的,但是作为8.2
表示为 8.19999999
在N
(double),它会导致有理数形式转换出现问题。
我尝试了其他方式:(我使用了一个大号 10^k 而不是 100)
if(abs(y*100 - round(y*100)) < 0.000001) y = round(y*100)/100
但是这种方法也不能始终给出正确的表示。
有什么方法可以进行从 double 到 p/q 的等效转换?
最佳答案
浮点运算非常困难。正如评论中所提到的,部分困难在于您需要用二进制表示您的数字。
例如,数字 0.125 可以用二进制表示:
0.125 = 2^-3 = 0b0.001
但数字 0.12 不能。
至11位有效数字:
0.12 = 0b0.00011110101
如果将其转换回十进制,则错误变得很明显:
0b0.00011110101 = 0.11962890625
所以如果你写:
double a = 0.2;
机器实际做的是找到它可以在 double 据类型中保存的最接近 0.2 的二进制表示。这是一个近似值,因为正如我们在上面看到的那样,0.2 不能用二进制精确表示。
一种可能的方法是定义一个“epsilon”,它确定您的数字与最接近的可表示二进制 float 的接近程度。
这是一篇关于 float 的好文章:
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
关于c++ - 将十进制数转换为有理数时的精度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48730844/