D equivalent of C++ reinterpret cast?

orgoton baberek sdf at sa.com
Sun Sep 19 10:47:25 PDT 2010


On 19/09/2010 18:39, Bradley Mitchell wrote:
> Hello,
>
> I'm trying to implement the Quake 3 fast inverse square root algorithm which
> requires casting from int to float without modifying the stored bits. A C++
> reinterpret cast seems to accomplish this just fine but so far I have had no
> success in D after trying quite a few different things. Here is the C++ I've
> written that currently works:
>
> #include<iostream>
>
> float fastInvSqrt( float x )
> {
>      const int INV_SQRT_N = 1597292357;
>      const float MULT = 1.000363245811462f;
>
>      float const mx = 0.5f * MULT * x;
>      int xi = *reinterpret_cast<int *>(&x );
>      xi = INV_SQRT_N - (xi>>  1);
>      x = *reinterpret_cast<float *>(&xi );
>      return x * (1.5f * MULT - mx * x * x);
> }
>
> int main()
> {
>      float a = fastInvSqrt( 9.0f );
>      std::cout<<  a<<  std::endl;
> }
>
> And here is my D code that doesn't work yet:
>
> module test;
>
> import std.stdio;
>
> float fastInvSqrt( float x )
> {
>      const int INV_SQRT_N = 1597292357;
>      const float MULT = 1.000363245811462f;
>
>      float mx = 0.5f * MULT * x;
>      int xi = cast(int)cast(void*)x;
>      xi = INV_SQRT_N - (xi>>  1);
>      x = xi;
>      x = cast(float)cast(void*)xi;
>      return x * (1.5f * MULT - mx * x * x);
> }
>
> void main(string[] args)
> {
>      float a = fastInvSqrt( 9.0f );
>      writefln("%f", a);
> }
>
> For further reference, the wikipedia article on this algorithm can be found here:
> http://en.wikipedia.org/wiki/Fast_inverse_square_root
>
> and my C++ code is based on a slightly modified version described here:
> http://www.ece.uwaterloo.ca/~dwharder/Algorithms_and_Data_Structures/Algorithms/Inverse_square_root/
>
> As you can see, I'm not trying to convert an integer to an equivalent floating
> point value but rather trying to coerce the variable to a float without
> modifying the underlying bit sequence. Any help would be greatly appreciated!!
>
> Thank you for your time,
> Brad

Use a union, which is the correct and safe way.

union convert
{
	float f;
	uint i;
}


convert.f = 1.0f;
writeln(convert.i);

will print 1065353216 (0x3f800000)


More information about the Digitalmars-d-learn mailing list