2017-02-05 3 views
1

正確なビットパターンを保持している同じ幅の符号なし整数に値の型を変換したいと思います。たとえば、64ビットの浮動小数点型はulongとして型付けされますが、ビットパターンは同じです。入力型は不特定ですが、通常のD整数型の1つに収まる入力値よりも大きな入力値を処理する必要はないため、集計やメモリ内オブジェクトはありません。私はconst性に対処についてのいくつかの意思決定を行うべきとのように、適切にこれを行う方法の提案を行うことができ、最初の符号なし整数のいくつかの種類であるタイプの生成に行くを持っていたD型強制でキャスティング:値の変換を行わずにビットパターンを保持する

  1. 入力型の不変性。

  2. 、私は、生成されたコードを検討した、

    (* cast(const T_uint_result *) & input_val)動作しているようです

のようなものを実行して値の変換を避けるために、コンパイラを強制しますが、私はその後、適切なタイプを得ましたこれに非常に不満を抱いています。多くの場合、ストレートキャストは問題ありませんが、コンパイラがビットパターンを変更する可能性があるため、一般的に私の目的には安全ではありません。

答えて

1

あなたが投稿した回避策以外には、組み込みの方法はありません。

pragma(inline, true) 
T bitCast(T, Orig)(scope Orig val) pure nothrow @nogc @system { 
    return *(cast(T*) &val); 
} 

このような用途:あなたはあなたが実際に確認する必要がありかかわら

float f = 4.5f; 
uint i = f.bitCast!uint; 
writeln(i); // 1083179008 

安全な代替には、労働組合を使用してどうなるかあなたができることは、あなたがこのようにすることを行うための機能を書いています

union DoubleLong { 
    double value; 
    long integer; 
} 

そうでない場合は、あなたのゴアの場合:上記の理由は、異なる幅(フロート/ダブルコンバージョン)の機能に比べて、そうでない場合、値があるかもしれない、そこに何かを正しい型を使用しますlは、あなたにもあなたも、これらの部品を操作することができますがありstd.bitmanip.FloatRepまたはstd.bitmanip.DoubleRep

を使用する場合があり、floatまたはdoubleの分数、指数及び符号を取得または設定し、実際に使用方法は次のようになります:

FloatRep fr; 
fr.value = 4.5f; // your float here 
fr.exponent = fr.exponent - 1; // reduces exponent, it's a property, so no unary operators 
writeln(fr.value); // 2.25, it's divided by 2 because it's binary 
1

unionを使用できます。例えば

union U 
{ 
    float f; 
    uint i; 
} 
U u; 
u.f = input; 
output = u.i; 

そして、あなたはそれの外に機能をしたい場合、あなたは

import std.algorithm; 

auto reinterpretAsInteger(T)(T t) 
    if([1, 2, 4, 8].canFind(T.sizeof)) 
{ 
    union U 
    { 
     T input; 
     static if(T.sizeof == 1) 
      ubyte output; 
     else static if(T.sizeof == 2) 
      ushort output; 
     else static if(T.sizeof == 4) 
      uint output; 
     else static if(T.sizeof == 8) 
      ulong output; 
    } 

    U u; 
    u.input = t; 
    return u.output; 
} 
ような何かを行うことができます
関連する問題