浮点数 2.014

6/10更新

无版本差异

浮点数字法:
浮点数
浮点数 后缀
整数 虚数后缀
整数 浮点后缀 虚数后缀
整数 实数后缀 虚数后缀

浮点数:
十进制浮点数
十六进制浮点数

十进制浮点数:
多个十进制数字 .
多个十进制数字 .多个十进制数字
多个十进制数字 .多个十进制数字 十进制指数
. 十进制数
. 十进制数 十进制指数
多个十进制数字 十进制指数

十进制指数
e 多个十进制数字
E 多个十进制数字
e+ 多个十进制数字
E+ 多个十进制数字
e- 多个十进制数字
E- 多个十进制数字

十六进制浮点数:
十六进制前缀 多个十六进制数字 .多个十六进制数字 十六进制指数
十六进制前缀 .多个十六进制数字 十六进制指数
十六进制前缀 多个十六进制数字 十六进制指数

十六进制前缀:
0x
0X

十六进制指数:
p 多个十六进制数字
p+ 多个十六进制数字
p- 多个十六进制数字

后缀:
浮点后缀
实数后缀
虚数后缀
浮点后缀 虚数后缀
实数 虚数后缀

浮点后缀:
f
F

实数后缀:
L

虚数后缀:
i



浮点数可以使用十进制或者十六进制格式,如同标准 C 一样。

十六进制浮点数以 0x 开头,阶码以 p 或 P 开头,后面跟着以 2 为底的阶数。

浮点数可以内嵌 '_' 字符,它们会被忽略。嵌入的‘_’用来格式化冗长的文字以提高可读
性,例如可以将它们用作千位分隔符:

123_456.567_8 // 123456.5678
1_2_3_4_5_6_._5_6_7_8 // 123456.5678
1_2_3_4_5_6_._5e-6_ // 123456.5e-6

不带后缀浮点文字类型是 double。浮点数可以跟随有一个 f、F 或 L 后缀。
f 或 F 后缀说明是fload;
L 代表 real。

如果浮点文字后面跟着 i,那么它就是一个 ireal (虚数) 类型。

示例:
0x1.FFFFFFFFFFFFFp1023 // double.max
0x1p-52 // double.epsilon
1.175494351e-38F // float.min
6.3i // idouble 6.3
6.3fi // ifloat 6.3
6.3Li // ireal 6.3

如果该串文字 超出 了该类型的表示 范围,会被视为错误。如果该串文字取整后可以用该类型的 有效位 数字 表示,就不是错误。

复数文字不是 特征符,而是在语义分析时用 实数 和 虚数 表达式构造的:

4.5 + 6.2i // 复数


浮点
23.1 浮点运算中间值
在许多计算机上,使用较高精度的运算并不比使用较低精度的运算耗费的时间长,所以为内
部的临时变量采用机器允许的最高精度对于数值运算是有意义的。这里采用的哲学是不强求
语言为统一而采用各种硬件的最低精度,从而充分利用目标硬件的最佳性能。
对于浮点运算表达式的中间值来说,可能会使用高于表达式类型所要求的精度。操作数的类
型只决定最低精度而不是最高精度。实现注意: 例如,在 Intel x86 机器上,计算的中间步
骤最好(但不是必需)使用硬件提供的全部 80 位精度。
如果临时变量和公共子表达式的使用量很大的话,优化后的代码很可能会得到比未优化代码
更精确的解。
算法应该以计算的最小精度为基础。如果实际的精度更高,它们也不应该退化或者失败。同
扩展类型不同,float 或者 double 类型应该用于:
• 减少大型数组的内存消耗
• 在速度比正确性更为重要时
• 保持跟 C 数据和函数参数的兼容性
23.2 浮点常量合拢(Constant Folding)
不管操作数的类型是什么,在 实数 或更大精度的情况下都会完成浮点常量合拢。遵从的规
则就是 IEEE 754 规则,同时也会使用四舍五入原则。
浮点常量被内在地以实现里至少的 实数 精度进行表示,不管该常量的类型。对于常量合拢
也可以使用额外的精度。结果精度的处理会在编译过程中尽可能晚地进行。例如:
const float f = 0.2f;
writefln(f - 0.2);
会输出 0。非常量静态值在编译时不能被传播,因此:
static float f = 0.2f;
writefln(f - 0.2);
会输出 2.98023e-09。在需要那些不会被舍入影响的特定浮点位模式时,也可以使用十六进
制浮点数常量。查找 0.2f 的十六进制值:
import std.stdio;
void main()
{
writefln("%a", 0.2f);
}
结果就是 0x1.99999ap-3。使用十六进制常量:
const float f = 0x1.99999ap-3f;
writefln(f - 0.2);
205
第 23 章 浮点 — 张雪平
输出 2.98023e-09。
不同的编译器设置、优化设置以及内嵌设置都会影响常量合拢(constant folding)的优化,因此
浮点计算的结果可能会由于这些设置而有所不同。
23.3 负数和虚数类型
在现有的语言中,为了将复数类型添加到现存类型体系中可谓费尽周折:模板、结构、运算
符重载等等,并且最终的结果几乎都是失败。失败的原因可能是由于复数运算的语义很微
妙,是由于编译器不理解程序员想要做什么,因而无法对语义的实现进行优化。
所有这些的目的都只是为了避免加入一个新类型。添加一个新类型意味着编译器可以使所有
的复数语义工作“正常”。然后程序员就可以依靠复数的正确(至少是稳定)的实现。
伴随而来的是对虚数的需求。虚数类型是我们可以避开一些微妙的语义问题,并且由于不用
处理隐含的 0 实部,可以提高运算的性能。
虚数文字量有一个 i 作为后缀:
ireal j = 1.3i;
复数文字量没有自身特殊的语法,只需写成实数类型和虚数类型相加即可:
cdouble cd = 3.6 + 4i;
creal c = 4.5 + 2i;
复数、实数和虚数有两个特性:
.re 实数部分(对于虚数则为 0)
.im 虚数部分(对于实数则为 0)
例如:
cd.re 是 4.5 double
cd.im 是 2 double
c.re 是 4.5 real
c.im 是 2 real
j.im 是 1.3 real
j.re 是 0 real
23.4 取整控制
IEEE 754 浮点数算术包括了设置四种不同的取整模式的能力。这些都可以通过在 std.c.fenv
里的函数访问到。
23.5 异常标志
IEEE 754 浮点数算术可以为计算中发生的事件设立标志:
206
第 23 章 浮点
FE_INVALID
FE_DENORMAL
FE_DIVBYZERO
FE_OVERFLOW
FE_UNDERFLOW
FE_INEXACT
这些标志可以使用在 std.c.fenv 里的函数进行设置/重置。

23.6 浮点数比较
除了常用的 <、<=、>、>=、== 和 != 比较运算符外,D 另外提供了专用于浮点数的运算
符。 它们是 !<>=、<>、<>=、!<=、!<、!>=、!>、!<>,并符合 C 扩展 NCEG 的语义。参看“浮点数比较”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值