san*_*ity 2 java floating-point rational-numbers
可能的重复:
如何将浮点数转换为由字节分子和分母表示的最接近的分数?
我想在 Java 中使用任意浮点数或双精度数并将其转换为有理数 - 即。a/b 形式的数字,其中 a 和 b 是长整数。我怎样才能以合理有效的方式做到这一点?
(顺便说一句 - 我已经有了用于简化分数的代码,所以 a/b 是否处于最简单的形式并不重要)。
首先看看IEEE-754 规则是如何构造double (或 float 但我在下面仅指 double )的:
然后使用Double.doubleToLongBits. 使用此方法计算分数1 + bit_0 * 2^(-1) + bit_1 * 2^(-2) ...。将结果与指数(2^(exponent)准确地说)和一个符号相乘。
这是代码:
double number = -0.15625;
// Code below doesn't work for 0 and NaN - just check before
long bits = Double.doubleToLongBits(number);
long sign = bits >>> 63;
long exponent = ((bits >>> 52) ^ (sign << 11)) - 1023;
long fraction = bits << 12; // bits are "reversed" but that's not a problem
long a = 1L;
long b = 1L;
for (int i = 63; i >= 12; i--) {
a = a * 2 + ((fraction >>> i) & 1);
b *= 2;
}
if (exponent > 0)
a *= 1 << exponent;
else
b *= 1 << -exponent;
if (sign == 1)
a *= -1;
// Here you have to simplify the fraction
System.out.println(a + "/" + b);
Run Code Online (Sandbox Code Playgroud)
但要小心 - 对于大指数,您可能会遇到不适合您的变量的数字。事实上,您可以考虑沿分数存储指数,并且仅在指数足够小时才将其相乘。如果不是,并且您必须向用户显示分数,您可以使用科学记数法(这需要求解方程2^n = x * 10^m,其中 m 是您的十进制指数,x 是您必须与分数相乘的数字。但这是另一个问题的问题……)。
| 归档时间: |
|
| 查看次数: |
6455 次 |
| 最近记录: |