每一个浮点数,除了无穷大和NaN可以精确地表示为两个整数的比率。一些双精度浮点数需要整数大于64位 - 例如,1e-300
将转换为6032057205060441/(2 ** 1049)
。但是,大致在范围(2**-40, 2**63)
内的浮点数可以无损地转换为两个64位整数的一部分。
这样的转换函数的一个例子是Python的浮点对象的as_integer_ratio()
方法。在Python/C-ESE翻译,代码如下所示:
#include <math.h>
#include <stdlib.h>
void double_as_ratio(double flt, long long *numerator, long long *denominator)
{
double float_part;
int exponent;
long long long_exponent;
int i;
float_part = frexp(flt, &exponent); /* flt == float_part * 2**exponent exactly */
for (i=0; i<300 && float_part != floor(float_part) ; i++) {
float_part *= 2.0;
exponent--;
}
/* flt == float_part * 2**exponent exactly and float_part is integral. */
*numerator = (long long) float_part; /* can overflow */
long_exponent = 1LL << labs((long) exponent); /* can overflow */
if (exponent > 0) {
*numerator *= long_exponent;
*denominator = 1;
}
else
*denominator = long_exponent;
}
这个代码不依赖于位的精确布局,只有依赖于C89所需的frexp
和floor
功能。应用于浮点值0.1
,它会生成正确的值3602879701896397
和36028797018963968
。
[续分](http://en.wikipedia.org/wiki/Continued_fraction) – 2013-04-30 10:22:05
您需要在尾数中缺少隐式前导1。 – 2013-04-30 10:28:39
找到两个整数“p”和“q”是可能的(而且确实很容易),使得它们之间的比率恰好等于双倍(除了NaN和无穷大外)。但通常其中一个会比64位长。 – harold 2013-04-30 10:37:03