如何获得long long(64位)值a和b从double(64位)值d,使得(double)a / b更多或更少的平等d?这可能吗(不会失去精确度)?
我已经尝试过这个但是它没有得到任何地方,所以我想也许我有错误的想法:
union ieee754_double u;
u.d = d;
long long a = (long long)u.ieee.mantissa0 << 32 | u.ieee.mantissa1;
long long b = (long long)1 << (u.ieee.exponent + IEEE754_DOUBLE_BIAS);
Run Code Online (Sandbox Code Playgroud)
除了无穷大和NaN之外,每个浮点数都可以精确地表示为两个整数的比率.一些双精度浮点数确实需要大于64位的整数 - 例如,1e-300将转换为6032057205060441 / (2 ** 1049).但是,近似范围内的浮点数(2**-40, 2**63)可以无损地转换为两个64位整数的一小部分.
这种转换函数的一个例子是Python的as_integer_ratio()float对象方法.从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;
}
Run Code Online (Sandbox Code Playgroud)
此代码不依赖于位的确切布局,而仅取决于C89所需的frexp和floor函数.应用于浮点值0.1,它生成正确的值3602879701896397和36028797018963968.
| 归档时间: |
|
| 查看次数: |
276 次 |
| 最近记录: |