dnan的好处2

恕我直言,这是更好的方法,甚至不是异常,而是错误.
只要你有NaN值,程序就是无用和损坏的.
只要变量变为NaN,就应该抛它,而不仅是在操作时.
如下成立时它应该抛:
1,初化值为NaN并在操作中使用
2,在初化外,置值为NaN
3,从函数返回NaN
这解决所有问题,因为:
你永远不会在整个程序中传播NaN值,从而更易追踪它.
NaN严格告诉你,在使用某些值前,是错误的
无法有效地解决它,即你必须实际修复所有NaN.

D允许使用std.math.hardware.FloatingPointControl接口启用浮点异常.
当然,这些是硬件异常,因此你获得SIGFPE而不是带回溯的抛错误.要转换为D错误,需要安装信号处理器,就像etc.linux.memoryerror那样(或Windows上的等价物)

可惜,似乎在实践中不管用,因为仅在创建NaN时,而不是在传播时触发"无效"浮点异常.由于是在编译时而不是运行时创建默认初化float/double变量的初始NaN值,因此不会触发异常.
示例:

import std.math.hardware;

float div(float x, float y)
{
    return x / y;
}

void main()
{
    FloatingPointControl fpctrl;
    fpctrl.enableExceptions(FloatingPointControl.severeExceptions);

    float f = float.nan; // ok -无异常
    float g = div(0.0f, 0.0f); // SIGFPE崩溃.
}

NaN总是错误的.0.0无处不在.如果从不查看输出,则都不会注意其中错误.
你需要分析数据流.我没有把DFA放在前端,因为这会使它变慢而无好处.
不必害怕在输出中获得NaN.相反应该很高兴,因为你*知道*错误.
D是帮助程序员创建正确,健壮和无错误程序的工具.
检查整

你正在推广使用结构初值作为特征,而不是基本类型的初值.
不同在它必须为有意设置的字段值,并且仅针对该字段值.它不是默认值.

double compute_pop ()
   {
      double pop;
      // 忽略实现,偶遇nan
      pop = sqrt (-1.);
      pop += 0.;
      return pop;
   }

   int main ()
   {
      auto pop = compute_pop ();
      if (pop < .5)
         writeln ("不下雨");
      else
         writeln ("会下雨");
      return 0;
   }

前几天我玩isNaN.用它来检查访问函数中的初化,来缓存昂贵计算.在注意到发布版本出现故障前,这非常有效.过了一段时间,我才发现ldc为发布版本,提供了fastmath选项,它假定没有NaN,而这导致isNaN错误工作.
示例:

import std;
void main()
{
    assert(isNaN(double.nan));
}

--ffast-math -O选项结合ldc编译.
isnan实现:

bool isNaN(X)(X x) @nogc @trusted pure nothrow
if (isFloatingPoint!(X))
{
    version (all)
    {
        return x != x;
    }
    else
    {
        /*
         历史背景保存的代码.至少在英特尔,简单的测试`x!=x`使用一条在一条指令中运行循环的`(ucomiss/ucomisd)`专用指令.`80`位和`128`位的代码更大,但仍小于下面基于整数的方法
        */
     // 略...
   }
}

这不仅与Walter的理解相悖,而且与IEEE754标准相悖.这是一篇更详细文章:小心快速数学
具有快速数学的LLVM假定所有浮点操作数都是有限的,即可在编译时优化x!=xfalse.足够聪明优化器,如果识别出NaN的位模式,原则上可优化检查位模式.

UDA等的好处之一是,可用它们来选择LLVM可执行的特定优化,而无需选择明显危险的优化.
1,2,3
不要滥用异常
0<=NaN.确实,有时0是相等的.但它*不可能*更好.
顺便,十六进制数据没有NaN值.但经常初化它为:0xDEADBEEF
这在野外不太可能.因此,当转储十六进制数据且有DEADBEEF时,表明有未初化数据.
我既用它在返回给调用者前,初化malloc的数据,并为其设置释放后数据.它在清理未初化分配数据释放后使用错误方面非常有效.使用0x00远没有它有效.

posted @   zjh6  阅读(17)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示