Delphi:如何翻译这个C代码,它对IEEE浮点数进行低级访问?
以下C函数来自
fastapprox项目.
static inline float fasterlog2 (float x) { union { float f; uint32_t i; } vx = { x }; float y = vx.i; y *= 1.1920928955078125e-7f; return y - 126.94269504f; } 我知道C union可以翻译成Delphi变体记录,但是我仍然难以将这种低级C代码翻译成Delphi.我希望这里的Delphi专家愿意提供帮助. 更多信息 我稍后会添加此部分,这不是问题的一部分.本节为希望获得更高准确性的读者提供信息. >在fastapprox中,quicklog2()被故意设计为更简单,更快但不太准确的Log2功能.任何期望更高准确度的人都可以使用他们提供的更准确的功能,即fastlog2(). 解决方法
我想我会通过使用指针强制转换来对其进行编码以实现重新解释转换:
function fasterlog2(x: single): single; const c1: Single = 1.1920928955078125e-7; c2: Single = 126.94269504; var y: single; begin y := PCardinal(@x)^; Result := y * c1 - c2; end; 请注意,我使用了type类型的类型常量来确保与C代码完全匹配. 我真的不认为在Delphi实现中需要变量记录. 或者你可以使用纯粹的asm方法. x86版本如下所示: function fasterlog2asm(x: single): single; const c1: Single = 1.1920928955078125e-7; c2: Single = 126.94269504; asm FILD DWORD PTR [ESP+$08] FMUL c1 FSUB c2 FWAIT end; 对于x64,SSE实现将是 function fasterlog2asm64(x: single): single; const c1: double = 1.1920928955078125e-7; c2: double = 126.94269504; asm CVTDQ2PD xmm0,xmm0 MULSD xmm0,c1 SUBSD xmm0,c2 CVTSD2SS xmm0,xmm0 end; 在x64中,汇编版本的性能仅为纯pascal函数的两倍. x86汇编版本的性能超过了五倍 – 这完全是由于SSE与x87中类型转换(整数/单/双)的成本较高. 可以使用此方法的原因是浮点数表示为 significand * base^exponent 并且值2用作基础. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |