delphi – 我如何使信号NaN容易使用?
发布时间:2020-12-15 04:24:46 所属栏目:大数据 来源:网络整理
导读:IEEE754标准定义了两类NaN,安静的NaN,QNaN和信号NaN,SNaN.当SNaN加载到浮点寄存器中时,浮点单元产生异常. QNaN通过在Math中声明的常量名为NaN的Delphi代码可用.该常数的定义是: const NaN = 0.0 / 0.0; 我想要使??用类似的东西来声明一个常数,这是一个信号N
IEEE754标准定义了两类NaN,安静的NaN,QNaN和信号NaN,SNaN.当SNaN加载到浮点寄存器中时,浮点单元产生异常.
QNaN通过在Math中声明的常量名为NaN的Delphi代码可用.该常数的定义是: const NaN = 0.0 / 0.0; 我想要使??用类似的东西来声明一个常数,这是一个信号NaN,但还没有找到一个方法来做到这一点. 你可以写这段代码: function SNaN: Double; begin PInt64(@Result)^ := $7FF7FFFFFFFFFFFF;//this bit pattern specifies an SNaN end; 但是,浮点返回值的ABI意味着SNaN被加载到浮点寄存器,以便可以返回.自然会导致一个例外,而不是打败目的. 所以你被带领编写如下代码: procedure SetToSNaN(out D: Double); begin PInt64(@D)^ := $7FF7FFFFFFFFFFFF; end; 现在,这样做很有用,但这是非常不方便的.假设您需要将SNaN传递给另一个功能.理想情况下,你想写: Foo(SNaN) 而是你必须这样做: var SNaN: Double; .... SetToSNaN(SNaN); Foo(SNaN); 所以,在积累之后,这里是一个问题. 有没有办法写入x:= SNaN并且有浮点变量x分配一个值是一个信号NaN? 解决方法
此声明在编译时解决:
const iNaN : UInt64 = $7FF7FFFFFFFFFFFF; var SNaN : Double absolute iNaN; 编译器仍将SNaN视为常数. 尝试为SNaN分配一个值将给出编译时错误:E2064无法分配左侧. procedure DoSomething( var d : Double); begin d := 2.0; end; SNaN := 2.0; // <-- E2064 Left side cannot be assigned to DoSomething( SNaN); // <--E2197 Constant object cannot be passed as var parameter WriteLn(Math.IsNaN(SNaN)); // <-- Writes "true" 如果您有编译器指令$WRITEABLECONSTS ON(或$J),则可以临时关闭该命令,以确保不会更改SNaN. {$IFOPT J+} {$DEFINE UNDEFWRITEABLECONSTANTS} {$J-} {$ENDIF} const iNaN : UInt64 = $7FF7FFFFFFFFFFFF; var SNaN : Double ABSOLUTE iNaN; {$IFDEF UNDEFWRITEABLECONSTANTS} {$J+} {$ENDIF} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |