d中nan接下来

可这样:

static assert(float() is float.nan);

这仅适合float.init,但如果操作它并返回nan,那不一定是真的,因为nans有几种位模式.

static assert(float() is real.nan);
static assert(double() is real.nan);
static assert(real() is real.nan);

同小类型比较,会提升.
除了T.nan还有其他类型NaN吗?如何生成它们?
0F/0F is float.nan是真.
大小无关,而是nan们可以不同形式出现.考虑:

void main() {
    float f = 7.0;
    f /= 0;
    import core.stdc.stdio;
    printf("%d\n", *cast(int*)&f);
    if(f is float.init)
        printf("nan\n");
}

该与float.init不一样,

f = 1.0;
f /= 0;
assert(f is f.infinity);
//
float f = 0;
f /= 0;
assert(f is f.nan); //失败了.

这样来零初化:

template ZeroInit(T)
{
    union U
    {
        byte[T.sizeof] a;
        T zeroed;
    }
    enum ZeroInit = U().zeroed;
}

struct S
{
    float f;
    float[2] a;
}

void main()
{
    S s = ZeroInit!S;
    assert(s.f == 0);
    assert(s.a == [0,0]);
}

int.min并不是真正的NaN.
但它应该是!int.min是臭名昭著的虚假值.甚至不能在它上面使用abs():它要么给你不同类型,要么返回垃圾.
我在每个程序中做的第一件事就是精确定义:byte/short/int/long的别名,置T.min+1为实际最小值.
不必自己写;可用std.checkedintChecked!(int,WithNaN),在此

可以这样,用std.typecons.Typefef:

import std;

alias Distance = Typedef!(double, 0.0, "distance");
alias Temperature = Typedef!(double, 0.0, "temperature");

void main()
{
    Temperature t;
    Distance d;
    d += 4.5;
    // t = d; // 不编译
}

但是,可能会在中间结果中丢失类型信息:

t = 0.5 + d;//结果为双精

包含NaN无穷大等值理由:重点是简化错误处理,并允许延迟处理错误.

alias this是隐式转换工具.

个人喜欢D的做法.一旦你知道浮点有个"无"方便初化值,同样原因null指针和类引用的方便初化值.但如果我不知道NaN,这会很烦人.最大弱点是它违背了C,C++C#(等其他语言)做法,很容易让人感到惊讶.
背后重要理念是D总是用"空"值作为初化值(如果有的话).
另一方面,程序员可显式初化变量为float.nan.
我在每个程序中都包含它,且从不使用其他有符号整数(正值用于位操作,而不是计算).checkedint应只是int类型,而不是模块.

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