【发布时间】:2012-02-14 03:44:12
【问题描述】:
在一个非常高性能的应用程序中,我们发现 CPU 计算长算法的速度明显快于双精度数。但是,在我们的系统中,我们确定我们永远不需要超过 9 个小数位的精度。所以我们对所有精度为 9 点的浮点运算都使用 long。
但是,在系统的某些部分,由于使用双打的可读性,它更方便。因此,我们必须将假定小数点后 9 位的 long 值转换为 double。
我们发现简单地取 long 并除以 10 的 9 次方或乘以 1 除以 10 的 9 次方会在 double 中给出不精确的表示。
为了解决我们使用Math.Round(value,9) 给出精确值的问题。
但是,Math.Round() 的性能非常慢。
所以我们目前的想法是直接将尾数和指数转换为双精度的二进制格式——这样就不需要四舍五入了。
我们已经在网上学习了如何检查双精度数的位以获取尾数和指数,但弄清楚如何反转它以获取尾数和指数并使用这些位制造双精度是令人困惑的。
有什么建议吗?
[Test]
public unsafe void ChangeBitsInDouble()
{
var original = 1.0D;
long bits;
double* dptr = &original;
//bits = *(long*) dptr;
bits = BitConverter.DoubleToInt64Bits(original);
var negative = (bits < 0);
var exponent = (int) ((bits >> 52) & 0x7ffL);
var mantissa = bits & 0xfffffffffffffL;
if( exponent == 0)
{
exponent++;
}
else
{
mantissa = mantissa | (1L << 52);
}
exponent -= 1075;
if( mantissa == 0)
{
return;
}
while ((mantissa & 1) == 0)
{
mantissa >>= 1;
exponent++;
}
Console.WriteLine("Mantissa " + mantissa + ", exponent " + exponent);
}
【问题讨论】:
-
您确定您拥有的值在
double中完全可以表示吗? -
也许这会有所帮助,我不想为了帮助你而阅读全部内容:P steve.hollasch.net/cgindex/coding/ieeefloat.html
标签: c# floating-point double exponent mantissa