2017-02-05 8 views
1

정확한 비트 패턴을 유지하면서 정확히 동일한 너비의 부호없는 정수로 값 유형을 변환하고 싶습니다. 예를 들어 64 비트 부동 소수점은 ulong으로 입력되지만 비트 패턴은 동일합니다. 입력 유형은 지정되지 않았지만 일반적인 D 정수 유형 중 하나에 들어 맞는 입력 값보다 큰 입력 값을 처리 할 필요가 없으므로 집계 또는 메모리 내 개체가 필요하지 않습니다.D 형 강제 변환에서 캐스팅 : 값 변환없이 비트 패턴 유지

  1. 내가 제대로이 작업을 수행하는 방법에 대한 제안을 할 수있는, 최초의 부호없는 정수의 어떤 종류의 유형을 생성에서 이동 했어, 내가 const와 처리에 대한 몇 가지 결정을 내려야한다고 같은과 입력 유형의 불변성.

  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; 
} 

그렇지 않으면 고아를하는 경우 : 위의 때문에 서로 다른 폭 (플로트/이중 변환)의 기능에 비해, 그렇지 않으면 값이 될 수도, 거기에 다른 뭔가를 올바른 형식을 사용 난 당신뿐만 아니라 당신이 이러한 부분을 조작 할 수 std.bitmanip.FloatRep 또는 std.bitmanip.DoubleRep

을 사용할 수 있습니다 얻을 또는 부동 또는 이중의 비율, 지수 및 기호를 설정하는 실제로, 사용은 다음과 같이 될 것이다 :

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; 
} 
같은 뭔가를 할 수