非常に高性能なアプリでは、CPU が long 演算を double よりも大幅に高速に計算できることがわかりました。ただし、私たちのシステムでは、小数点以下 9 桁を超える精度は必要ないと判断されました。したがって、すべての浮動小数点演算に long を使用し、9 ポイントの精度を理解しました。
ただし、システムの特定の部分では、double を使用した方が読みやすいため、より便利です。そのため、小数点以下 9 桁を想定した long 値を double に変換する必要があります。
long を単純に 10 で割って 9 乗するか、1 を 10 で割って 9 乗すると、double で不正確な表現が得られることがわかります。
それを解決するために、 を使用しMath.Round(value,9)
て正確な値を提供します。
ただし、Math.Round()
パフォーマンスが恐ろしく遅いです。
したがって、現時点では、仮数と指数を double のバイナリ形式に直接変換することを考えています。この方法では、丸めの必要がなくなるからです。
double のビットを調べて仮数と指数を取得する方法をオンラインで学習しましたが、それを逆にして仮数と指数を取得し、ビットを使用して double を作成する方法を理解するのは混乱します。
助言がありますか?
[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);
}