在D

时间:2016-11-13 13:23:56

标签: d

我试图将臭名昭着的fast inverse square root技术从C转换为D编程语言。必要的步骤是将长位存储在整数中:

i  = * ( long * ) &y; 

在评论部分,Andrew建议将此操作称为类型惩罚。 有人知道如何在D中执行打字操作吗?

对于那些好奇的人,这里是代码的完整C代表:

float Q_rsqrt( float number ) {
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y  = number;
i  = * ( long * ) &y;    // the part in question
i  = 0x5f3759df - ( i >> 1 );
y  = * ( float * ) &i;   // again, but for floating points
y  = y * ( threehalfs - ( x2 * y * y ) );
return y;
}

2 个答案:

答案 0 :(得分:3)

你真正需要做的就是使用D风格的演员 - 这是D代码与C代码不同的唯一地方。

以下是工作计划:

import std.stdio;

float Q_rsqrt(float number) {
  int i;  // we use int here because int.sizeof == float.sizeof
  float x2, y;
  const float threehalfs = 1.5F;
  x2 = number * 0.5F;
  y  = number;
  i  = * cast(int*) &y;
  i  = 0x5f3759df - ( i >> 1 );
  y  = * cast(float*) &i;
  y  = y * ( threehalfs - ( x2 * y * y ) );
  y  = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration

  return y;
}

int main() {
  writeln(Q_rsqrt(0.15625f));
  // Output: 2.52981

  return 0;
}

答案 1 :(得分:2)

使用union可以实现同样的效果,现在可以制作@safe并且在眼睛上更容易一些:[/ p>

float Q_rsqrt(float number) @safe {
  union V {
    int i;
    float y;
  }
  V v;
  float x2;
  const float threehalfs = 1.5F;
  x2 = number * 0.5F;
  with (v) {
    y  = number;
    i  = 0x5f3759df - ( i >> 1 );
    y  = y * ( threehalfs - ( x2 * y * y ) );
    y  = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration
    return y;
  }
}

int main() {
  writeln(Q_rsqrt(0.15625f));
  // Output: 2.52981

  return 0;
}

通过优化,它会生成与使用指针强制转换的实现相同的程序集(至少在LDC和GDC中)。