您的位置 首页 电路

学习LabVIEW(十)——关于Matlab的eps函数(十三)

关于Matlab的eps函数的实现原理,我以前写过十几篇短文了。其中最接近官方的版本可以参考《关于Matlab的eps函数(十)——MATLABCoder生

关于Matlab的eps函数的完成原理,我曾经写过十几篇短文了。其间最接近官方的版别能够参阅《关于Matlab的eps函数(十)——MATLAB Coder生成的C代码》。那时运用了MATLAB的Coder直接生成了一份eps的C言语版别,应该便是官方的完成办法了。
为什么这么重视eps函数?由于关于数值剖析而言,eps是非常重要的,它展现了依据IEEE754浮点数的一个根本特点:相对浮点精度。但是,虽然eps如此重要,能够说清楚eps运算办法的人屈指可数。现代社会,人人都要会编程,但是假如仅仅接受了一般的编程入门学习,没有像核算机专业科班出身的那群人那样花了很多很多的学时学习数值剖析的话,就会倾向于将核算机中的浮点数与数学中的实数这个概念等价起来。可现实却是:浮点数和数学概念中的实数有着巨大的差异。比方,概念中的实数,是能够接连取值的。而依据754规范的浮点数,则和整数相似,取值是离散的!而eps正是衡量一个浮点数取值到下一个浮点数取值之间的距离的东西。与整数不同的是,浮点数之间的距离不是原封不动,而是跟着浮点数数值的改变而改变的;所以eps不是一个常数而是一个函数。

  • 在《关于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上履行。

今日要做的工作,是在LabVIEW顶用朴实的G言语完成eps运算。其实我现在并不需求在LabVIEW中运用eps,仅仅想经过完成eps来了解LabVIEW究竟有多强的位运算才能。
首要,LabVIEW在“编程->数值”中供给了名为“核算机ɛ”的节点,这个节点是一个常数节点(而非函数),其数值等于MATLAB中的eps(1):

上图中数值显现控件“数值3”输出的数值为0,阐明LabVIEW节点“核算机ɛ”和Matlab的eps(1)持平。实践上,由于MATLAB的函数支撑可变个数的参数,且函数调用的时分能够省去括号,因而eps(1)也能够写成eps这种方法,这便是导致很多人以为Matlab中的eps是一个常数而非函数的原因。假如勤快的话,在Matlab的Command Window中敲上一行“doc eps”就能看到关于eps的更多信息。
已然“核算机ɛ”节点不是函数,咱们就需求自己增加额定的程序来完成eps的功用了。实践上,C++中也供给了eps(1)的数值,而咱们在《关于Matlab的eps函数(六)》中的完成办法,便是用位运算的办法获取给定的浮点数R的指数部分E,然后运用表达式
eps(1) * 2 ^ E
得到了eps(R)的值。这儿咱们也能够运用这种方法。
为了提取浮点数的指数部分,咱们首要测验一下LabVIEW的位运算才能。想要对浮点数进行位操作,就需求言语供给一种reinterpret cast的机制。在Matlab中是typecast,而LabVIEW也供给了typecast,依据文档,LabVIEW的typecast节点能够完成:
*(type *) &R
的改换,正是咱们所需求的。
浮点数实质上和整数没有差异,便是内存中的几个字节的调集,里边的位的取值包含了信息。和整数仅有的不同便是解读这些位的办法。但是没有学过低阶言语的编程者,受到了高阶言语编译器/解说器的照料,浮点数的存储和核算这些细节彻底被言语的机制所掩盖。这是一件功德,由于咱们编程的时分就不必关怀太多的细节。这也是一件坏事,让咱们不必去了解浮点数的底层机制。时刻长了,咱们就形成了过错的形象:已然言语不让我对浮点数做位操作,那浮点数大约便是不能做位操作的吧。我曾经在大学的时分,近邻有一个项目组,由于不知道如安在C言语中将浮点数拆成字节数组以放到串口缓冲区中,差点连硬件电路都改了。
LabVIEW的typecast的用法简直和Matlab的typecast函数相同。咱们先温习一下Matlab的typecast函数。
首要将输出格局调成16进制:
>> format hex
取一个双精度浮点数15,转换成字节数组:
>> bytes = typecast(15, uint8)

bytes =

0000000000002e40

咱们知道,浮点数是由符号,指数,尾数三个部分组成的。这儿试着将字节数组最终一个字节的最高位改成1,对应的浮点数便是符号位变成1,会变成负数:
>> bytes(end) = hex2dec(c0);
>> format; dbl = typecast(bytes, double)

dbl =

-15

再试试对浮点数的指数部分进行操作。双精度浮点数有8个字节,64位。其间符号位1位,指数位11位,尾数位52位,假如想把指数加上1(等效于浮点数乘以2),只需求履行下面的操作:
>> typecast(typecast(15, uint64) bitshift(uint64(1), 52), double)

ans =

30

首要将双精度浮点数15 reinterpret成unsigned int64,然后加上1左移52位,再reinterpret成double。便是这么简略。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/dianlu/211849.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部