2009/11/01

C#で浮動小数点数のバイナリ表現(ビットパターン)を取得する

double型の値のバイト表現をlong型で得るために、BitConverter.DoubleToInt64Bitsを使う場合とunsafeで無理やりキャストするのではどちらが速いのか比較してみた。
手元の環境ではBitConverter.DoubleToInt64Bitsの方が速かった(経過時間が50%)けど、ほとんどのケースでは相対的に十分軽い処理になるだろうからどっちでもいい。ただキャストを使うやり方はunsafeの指定が必要だし、見た目もアレだからfloat型を相手にする場合以外は使わないと思う(BitConverter.FloatToInt32Bitsは存在しない)。ストップウォッチのリセットを忘れてた。処理速度に差はない。
そもそもdouble型と整数型との&演算子があればこんなことしなくていいのが残念。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace BinaryRepresentation
{
   
class Program
   
{
       
static void Main(string[] args)
       
{
           
var sw = new Stopwatch();
           
var random = new Random(0);
           
var num = 1000000;
           
var vals = new double[num];
           
for (var n = 0; n < vals.Length; n++)
                vals
[n] = random.NextDouble();

           
// BitConverter.DoubleToInt64Bits
           
var bc = new long[vals.Length];
           
{
                sw
.Reset();
                sw
.Start();
               
for (var n = 0; n < vals.Length; n++)
                    bc
[n] = BitConverter.DoubleToInt64Bits(vals[n]);
                sw
.Stop();
               
Console.WriteLine("BitConverter.DoubleToInt64Bits: {0}", sw.ElapsedMilliseconds);
           
}

           
// unsafe cast
           
var uc = new long[vals.Length];
           
unsafe
           
{
                sw
.Reset();
                sw
.Start();
               
for (var n = 0; n < vals.Length; n++)
               
{
                   
var val = vals[n];
                    uc
[n] = *(long*)&val;
               
}
                sw
.Stop();
               
Console.WriteLine("unsafe cast: {0}", sw.ElapsedMilliseconds);
           
}

           
// correctness
           
for (var n = 0; n < vals.Length; n++)
               
if (bc[n] != uc[n])
                   
Console.WriteLine("bc[{0}]: {1:X}, uc[{0}]: {2:X}", n, bc[n], uc[n]);
       
}
   
}
}
ksksts / junk / source — bitbucket.org

0 件のコメント: