- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
学习LabVIEW(十)——关于Matlab的eps函数(十三)
录入:edatop.com 点击:
- 在《关于Matlab的eps函数》中,我们讨论了eps的本质,并使用Matlab的typecast函数(用来实现reinterpret cast)实现了eps的计算;
- 在《关于Matlab的eps函数(续)》,《关于Matlab的eps函数(又续)》,《关于Matlab的eps函数(六)》和《关于Matlab的eps函数(七)——“又续”的续》中,我们利用位段结构体实现了eps计算,这种版本的可读性比最初用typecast实现的版本要好多了;
- 在《关于Matlab的eps函数(再续)》中,我们根据mathworks上的一个帖子,讨论了利用纯粹的数学运算而不是位运算实现eps的方法;
- 在《关于Matlab的eps函数(五)》和《Article 4 in 1: 关于Matlab的eps函数(八) &读Matlab7.7的rank函数 &读Matlab7.7的orth》中,讨论了eps函数的几个实际应用;
- 在《关于Matlab的eps函数(九)——Java也有"eps"函数》中,我们展示了Java中,与eps功能类似的方法ulp的用法,并讨论了ulp和eps的不同;
- 在《关于Matlab的eps函数(十)——MATLAB Coder生成的C代码》中,我们通过MATLAB Coder窥见了官方的eps实现方法;
- 在《GPU Powered Matlab(三)——关于Matlab的eps函数(十一)》和《GPU Powered Matlab(三点一)——关于Matlab的eps函数(十二)》中,我们试着将eps搬到CUDA GPU上执行。
上图中数值显示控件“数值3”输出的数值为0,说明LabVIEW节点“计算机 ”和Matlab的eps(1)相等。实际上,由于MATLAB的函数支持可变个数的参数,且函数调用的时候可以省去括号,因此eps(1)也可以写成eps这种形式,这就是导致很多人认为Matlab中的eps是一个常数而非函数的原因。如果勤快的话,在Matlab的Command Window中敲上一行“doc eps”就能看到关于eps的更多信息。
eps(1) * 2 ^ E
得到了eps(R)的值。这里我们也可以使用这种手法。
*(type *) &R
的变换,正是我们所需要的。
>> format hex
取一个双精度浮点数15,转换成字节数组:
>> bytes = typecast(15, uint8)
bytes =
我们知道,浮点数是由符号,指数,尾数三个部分组成的。这里试着将字节数组最后一个字节的最高位改成1,对应的浮点数就是符号位变成1,会变成负数:
>> bytes(end) = hex2dec(c0);
>> format; dbl = typecast(bytes, double)
dbl =
再试试对浮点数的指数部分进行操作。双精度浮点数有8个字节,64位。其中符号位1位,指数位11位,尾数位52位,如果想把指数加上1(等效于浮点数乘以2),只需要执行下面的操作:
>> typecast(typecast(15, uint64) bitshift(uint64(1), 52), double)
ans =
首先将双精度浮点数15 reinterpret成unsigned int64,然后加上1左移52位,再reinterpret成double。就是这么简单。 [p]
非常重要的一点,上面这些蓝色的数值常量,需要手工指定其具体的整数类型。在常量的蓝色方框内点击右键,在弹出的菜单中选择“表示法->UINT64”显式指定数据的具体整数类型,否则运算会出错,无法得到期望的结果。
这正是我们需要的数值。15位于8和16的中间,8是2的3次方,16是2的4次方,所以15的指数部分是3。现在将“计算机 ”乘以2的三次方(利用“按2的幂缩放”节点),就得到了eps(15)的值:
我们将计算得到的数值与Matlab的eps(15)进行了比较。“数值5”控件显示计算的结果为1.77636E-15;“数值6”控件显示LabVIEW计算的结果与Matlab计算的结果的差,输出为0,说明和Matlab是一致的。利用这么简单的G语言框图,我们就实现了eps的计算。