Java是否等效于称为frexp的C/C++函数?如果您不熟悉,frexp是defined by Wikipedia,用于“将浮点数分解为尾数和指数”。
我正在寻找一种既具有速度又具有准确性的实现方式,但是如果我只能选择一种的话,我宁愿具有准确性。
这是来自第一个引用的代码示例。它应该使frexp契约(Contract)更清晰一些:
/* frexp example */
#include <stdio.h>
#include <math.h>
int main ()
{
double param, result;
int n;
param = 8.0;
result = frexp (param , &n);
printf ("%lf * 2^%d = %f\n", result, n, param);
return 0;
}
/* Will produce: 0.500000 * 2^4 = 8.000000 */
最佳答案
这个怎么样?
public static class FRexpResult
{
public int exponent = 0;
public double mantissa = 0.;
}
public static FRexpResult frexp(double value)
{
final FRexpResult result = new FRexpResult();
long bits = Double.doubleToLongBits(value);
double realMant = 1.;
// Test for NaN, infinity, and zero.
if (Double.isNaN(value) ||
value + value == value ||
Double.isInfinite(value))
{
result.exponent = 0;
result.mantissa = value;
}
else
{
boolean neg = (bits < 0);
int exponent = (int)((bits >> 52) & 0x7ffL);
long mantissa = bits & 0xfffffffffffffL;
if(exponent == 0)
{
exponent++;
}
else
{
mantissa = mantissa | (1L<<52);
}
// bias the exponent - actually biased by 1023.
// we are treating the mantissa as m.0 instead of 0.m
// so subtract another 52.
exponent -= 1075;
realMant = mantissa;
// normalize
while(realMant > 1.0)
{
mantissa >>= 1;
realMant /= 2.;
exponent++;
}
if(neg)
{
realMant = realMant * -1;
}
result.exponent = exponent;
result.mantissa = realMant;
}
return result;
}
这是“灵感”的,或者实际上几乎是从answer复制到相似的C#问题。它使用位,然后使尾数为1.0到0.0之间的数字。