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.checkedint
的Checked!(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
类型,而不是模块
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现