D型双关
我正试图将这项臭名昭著的技术从C语言翻译成D语言。一个必要的步骤是将长位存储在整数中:D型双关,d,D,我正试图将这项臭名昭著的技术从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 = num
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;
}
您真正需要做的就是使用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;
}
使用
联合
也可以实现同样的效果,另外还有一个好处,那就是现在它可以变得@安全
,并且眼睛更容易看到:
float Q_rsqrt(浮点数)@safe{
联盟五{
int i;
浮动y;
}
V V;
浮动x2;
常数浮点三分之一=1.5F;
x2=数量*0.5F;
附(v){
y=数量;
i=0x5f3759df-(i>>1);
y=y*(三分之一-(x2*y*y));
y=y*(三分之一-(x2*y*y));//第二次迭代
返回y;
}
}
int main(){
书面记录(Q_rsqrt(0.1562F));
//产出:2.52981
返回0;
}
启用优化后,它将生成与指针强制转换实现相同的程序集(至少在LDC和GDC中)。您是否尝试过在D中执行与在C中完全相同的操作?它应该有用。。。(好吧,除了C long稍有不同之外,您可以使用d
int
表示float
)这是一个很好的建议。我会测试和回应。人们通常如何引用所使用的操作?@AdamD.Ruppe不幸的是,*(*)语法似乎抛出了一个解析错误。你知道那个操作的名字吗?你想做的就是“类型双关”。在C中这样做要小心——如果不遵循严格的别名规则,就会调用未定义的行为。我不知道类型双关的D语言语义,但它应该在语言参考资料中得到很好的记录。哦,D需要在parens之前使用关键字cast
。就像*cast(int*)&y代码>