tag 标签: 浮点数

相关帖子
相关博文
  • 热度 18
    2016-1-26 14:02
    1836 次阅读|
    0 个评论
    随着FPGA的发展,其中包含的DSP资源原来越丰富,并且伴随着其结构的优化,在FPGA中实现各种复杂的数字信号处理算法显得游刃有余,很多系统设计从之前的CPU+DSP+FPGA架构慢慢地向单片FPGA转变,并且已经有了实际应用,如Xilinx的Zynq、Altera的Soc FPGA。趁着这次【博客大赛】,决定系统全面地整理、学习一下FPGA中的DSP,从这篇博文开始这个【DSP in FPGA】专题。         专题一:数字表示         自从计算机发明以来,数学运算进入了二进制的世界,简单的0、1变化能组成几乎所有的运算:加法、减法、乘法、除法,甚至三角函数、对数、开方等。对于电子工程师而言,数字电路占据了一半江山,由数字门电路组成的FPGA应该属于二进制世界范畴。         在FPGA中的数字表示基本分为两类:定点数和浮点数,其实不止FPGA,其它算术处理器也是按照此分类。定点数处理具有速度快和成本低的特点,而浮点数处理其动态范围高并且运算无需转换,在FPGA设计前期,需要确定采用定点数还是浮点数实现。         1.  定点数         FPGA设计中常用的定点数有无符号整数、有符号整数和二进制补码。         有N位二进制数x N-1 x N-2 …x 0         无符号整数 (unsigned):x N-1 是最高有效位MSB,x 0 是最低有效位LSB,其取值范围是         有符号整数 (signed):x N-1 是符号位,其它N-1位代表数值,其取值范围是         二进制补码 (two’s complement):其取值范围是 ,二进制补码表示法是数字信号处理领域最为流行的有符号数字表示法;它累加多个有符号数时,中间过程如果出现溢出但是最终结果是在有效范围之内,溢出可以忽略,如3位有符号数运算3+2-3=2,3+2=(011+010) 2 =101 2 ,101用二进制补码表示为-3,溢出了,但是(101-011) 2 =(101+101) 2 =010 2 =2 10 ,结果是正确的。 在 FPGA 中的有符号型数默认由二进制补码表示 。         如下表所示以3位二进制数为例,编码的到的三种定点数的表示   无符号整数 有符号整数 二进制补码 000 0 0 0 001 1 1 1 010 2 2 2 011 3 3 3 100 4 -0 -4 101 5 -1 -3 110 6 -2 -2 111 7 -3 -1              HDL语言中的定点数表示也很多样,以下分别按Verilog HDL和VHDL作说明:           Verilog HDL :在Verilog-2001中,申明reg和wire时,可加入signed、unsigned关键字申明reg和wire是有符号型还是无符号型,如reg signed cnt表示申明一个8位有符号型reg,不加申明默认为unsigned。并且在HDL程序中变量可以在有符号型和无符号型间转换,$signed(x)表示将变量x转换为有符号型表示,$unsigned(x)则表示将变量x转换为无符号型表示,其中转换过程并不会导致变量中具体位0、1间变化,只是表示方式的变化,在参与运算时结果将会发生变化。           VHDL :在VHDL中没有申明变量是有符号数或者无符号数的关键字,只有在开头加入库文件中指定运算操作为有符号型还是无符号型:ieee.std_logic_unsigned.all和ieee.std_logic_signed.all,分别对应std_logic_signed.vhd文件和std_logic_unsigned.vhd文件,如图1所示为两个文件的部分对比,其中左边部分为signed,右边部分为unsigned。红色部分为两文件差别,从第一个红色处,可以很清楚的看到std_logic_signed库定义的加法首先将变量转化为有符号型,而std_logic_unsigned库定义的加法首先将变量转化为无符号型。其中VHDL中也定义了有符号型、无符号型间转换的函数:CONV_SIGNED(x)和CONV_UNSIGNED(x) 图1          为了说明有符号型数和无符号型数的运算区别,编写了一个累加器的小程序(Verilog),如下: module test_2c(     input clk,     input rst,     input a,     output reg sum_unsigned,           output reg signed  sum_signed     );   always@(posedge clk)          if(rst)          begin                    sum_unsigned=3'd0;                    sum_signed=3'd0;          end          else          begin                    sum_unsigned=sum_unsigned + a;                    sum_signed=sum_signed + $signed(a);          end   endmodule          其中sum_unsigned和sum_signed分别为无符号数和有符号数的累加值,并且不考虑溢出情况,如图2所示为仿真图,实现了(011+011+100) 2 的运算,用无符号型表示的sum_unsigned因(110+100) 2 发生了溢出,最终结果是错误的;而用有符号型表示的sum_signed虽然中间过程(011+011) 2 发生溢出,但是因二进制补码的特性,此溢出可以忽略,最终得到正确的结果。 图2          另外在定点数运算中,比如两个数累加或相乘之后都需要位扩展,对于中间过程这种位扩展是为了精度需要,但是作为结果输出时往往需要对扩展位进行截断(truncate)或者舍入(round)处理,截断则是直接丢掉扩展位,不做任何舍入处理;舍入则是为了减小误差加入的 四舍五入 操作:定义舍入之前全精度数为M位,舍入后的数为N位,其中N,当全精度数为无符号数或者数为正的有符号数时,如果舍入相邻位(多余位数中的最高位)中最高位为1,则舍入时必须进1,反之不进位;当全精度数为负的有符号数时,舍入相邻位为1且舍入相邻位后面还有一位为1,则舍入时需进1,反之不进位。分别用verilog //Verilog wire dout; wire din; wire c; assign c=(din ==1’b1) ? ( din (|din ) ) : din ; assign dout=din + {3’b000,c};   --VHDL signal dout:std_logic_vector(3 downto 0); signal din:std_logic_vector(7 downto 0); signal c:std_logic; begin          c= din(3) and (din(2) or din(1) or din(0)) when din(7)=’1’ else din(3);          dout=din(7 downto 4) + (“000” c); end             2.  浮点数          浮点数具有比定点数更高的精度和更大的动态范围,标准的浮点数由一个符号位s(sign)、指数e(exponent)和无符号的规格化尾数f(fraction)构成,格式如下: 符号位s 指数e 尾数f            表达式如下:                                                                       其中bias=2 E-1 -1,E位指数的位数。          举一个例子说明定点数和浮点数之间的转换吧!           定点数 — 浮点数 :十进制数16.5用12位(1,6,5)浮点数格式表示:          16.5 10 =(10000.1) 2 =(-1) 0 ×1.00001×2 4 ,          可以得到s=0,bias=2 6-1 -1=31,e=4+bias=35 10 =100011 2 ,f=00001,因此16.75的12位浮点数表示为0 100011 00001          如果用上述的12位(1,6,5)浮点数格式表示数,绝对值最大可取到±1.11111×2 31 ≈±4.228×10 9 ——决定了取值范围,绝对值最小可取到±1.00000×2 -30 ≈±9.31×10 -10 ——决定了精度;而12位定点数如二进制补码的取值范围为 ,因此同样位数浮点数的动态范围和精度都远远优于定点数。          IEEE754-1985中定义了两种浮点数标准:单精度标准和双精度标准。具体的定义如下:   单精度 双精度 字长 32 64 尾数 23 52 指数 8 11 偏移 127 1023 范围 2 128 ≈3.8×10 38 2 1024 ≈1.8×10 308          在IEEE754-1985标准中,舍入处理提供了四种可选方法:    就近舍入 :其实质就是四舍五入,例如尾数超出规定的23位的多余位数字是10010,多余位的值超过规定的最低有效位值的一半,故最低有效位应增 1。若多余的5位是01111,则简单的截尾即可。对多余的5位10000这种特殊情况:若最低有效位现为0,则截尾;若最低有效位现为1;则向上进 一位使其变为 0。    朝 0 舍入 :即朝数轴原点方向舍入,就是简单的截尾。无论尾数是正数还是负数,截尾都使取值的绝对值比原值的绝对值小。这种方法容易导致误差积累。    朝 +∞ 舍入 :对正数来说,只要多余位不全为0则向最低有效位进1;对负数来说则是简单的截尾。         朝-∞ 舍入 :处理方法正好与 朝+∞舍入情况相反。对正数来说,只要多余位不全为0则简单截尾;对负数来说,向最低有效位进1。         在FPGA实现中,通常不严格采用IEEE754-1985标准的浮点数,而是根据实际动态范围和精度的需要来选择浮点数格式。关于浮点数的运算在【DSP in FPGA】专题后续章节中会详细介绍。
  • 热度 16
    2015-10-8 09:20
    4882 次阅读|
    3 个评论
    Verilog 中的浮点数的表示以及浮点数除法 IP 核的用法          初学 FPGA ,最近用到除法,刚开始想要自己写一段除法的代码来解决,和好多菜鸟一样先去网上输入“ verilog 除法器”去搜索,搜到了一些代码,但是这些代码都是:分子除以分母得到的结果是商和余数。例如 10 除以 5 商 2 余 0 ,这个还好,因为可以整除。如果是 11 除以 5 商 2 余 1 ,可是我想得到的结果是 2.2 。继续在网上找,还是没有找到。后来听从大神指点试试 Verilog 自带的除法 IP 核,于是就去找 IP 核。马上就要切入正题了,在此先介绍一下本人的背景,主要是增强大家学习 FPGA 的信心。 本人本科学的是物理学,硕士学的是光学,大学期间对电脑的认识就是计算机二级的水平,本科毕业论文用了一点 MATLAB ,可以说对于编程完全空白,对于数电中的二极管,三极管,触发器都只停留在知道名字上。对于二进制,十六进制,浮点,整型都没有概念。硕士也就用过 LabVIEW 。就是这样的基础来学 FPGA 的,介绍这么一堆,是因为以前看帖子时经常会看到发帖的人会默认读者懂数电,懂模电,懂进制,懂单片机,懂各种协议,懂一切工科的基础知识。但是问题来了,对于我这种理科生,啥也不懂,怎么办,回答问题的人当然会说:不懂就自己去看呗,谁能把所有的东西都告诉你。事实确实是这样的,什么问题都要自己去解决,但是我想说如果解答者能站在提问者的角度去回答,那么双方都会获益匪浅的,能知道提问者问的是什么并站在提问者的角度去回答对于解答者是一个很高的要求。当然提问者也要懂得独立思考,不要什么都去问,先自己查做好准备再提问,这样才能够提出准确,高效的问题。解答者也乐意解答。 下面我们切入正题: 首先我们把要处理的数据分成两类:整型和浮点型,通俗的说就是整数和小数。我们用这两种数做除法得到的结果无非两种,整除和不能整除,对应的商就是整数和小数。在此我对除法的编程代码原理不做介绍,只介绍如何调用 IP 核,对于除法结果为商和余数的代码在网上可以找到,大家可以自己看。至于结果为小数(也就是没有余数)的我还没有找到。大家可以找找。我们在此调用 quartus 自带的除法 IP 核,首先调用除法 IP 核的方法是: 打开 quartus 菜单中的 tools 选择 MegaWizard Plug-In Manager ,就会跳出窗口: {C}{C} 点击 next 。 {C}{C} 在这个页面中先看左边的窗口,点开第一个文件夹( Arithmetic )图标,其中有两个除法 IP 核,第一个就是图中所示的 ALTFP_DIV ,这个 IP 核得到的结果只有商,而且是浮点数的。另外一个需要往下拖才能看到是 LPM_DIVIDE ,这个我们稍后再说,先看 ALTFP_DIV 。右上角可以选定使用的芯片系列,稍微往下选择输出的编程语言,我用的是 Verilog ,再往下就是输入创建的文件名,我取的是 division 。剩下的不用管,点击 next 就可以了。 {C}{C} 到了这个页面先提醒大家一下,如果大家想详细了解这个 IP 核的信息可以点击右上角的 Documentation ,打开浏览器观看。 页面的信息大家可以自己看看,根据自己的要求选择,在此选择单精度,至于中间靠右下的地方在说明数据的组成,这个放到下面说,至于有个 14 的参数,我还不是很理解,目前理解是计算这个除法需要消耗 14 个时钟,知道的帮我更正一下,点击 next 。 这个页面也不做解释,内容大家自己看,点击 next 。 这个页面根据需要选择,点击 next 。 直接点击 next 。 这是最后一个页面,可以根据自己需要选择要生成的文件。我一般选择把所有的复选框对勾都去掉,因为 division.v (第一个文件)已经默认生成了,之所以做这种选择是因为我是个菜鸟,不知道其他文件有什么用途,所以大家可以给我海量的补充啊! 下面我们要做的就是仿真了,但是在仿真之前我们需要对输入和输出的数据做一个了解,这儿要花费很大的篇幅,大家要做好心理准备。 输入的 dataa 是分子, datab 是分母, result 是商。三者都是单精度 32 位的数据。输入的时钟不在讨论之内。因为这个 IP 核处理的是浮点除法,所以输入输出都是浮点型。下面就来解释整数和小数是如何表示成浮点型的二进制,因为计算机不认识小数点。 根据 IEEE-745 标准规定:单精度 32 位的数据组成是这样的,最高位是符号位(【 32 】),表示正负,往下数八位(【 31 】 - 【 24 】)是阶位,剩下的 23 位是尾数位。如下图所示: 符号位为 0 表示正数, 1 表示负数。用字母 S 表示 阶位用字母 P (十进制)表示,变化范围是 0-256 。 尾数用 M 表示。 这样的一个 32 位表示的十进制数为 ((-1)^S)*(2^(P-127))*1.M , 那么如何将十进制的整数和小数表示成这样的一个 32 位浮点数呢? 举个例子吧: {C} 1、   整数 比如 21 , 21 的二进制是 10101 ,表示成小数形式就是 10101.0 ,将其变为科学计数法形式可以写成 1.01010* ( 2^4 ),括号中 2 的指数( 4 )用来确定阶位,方法是 P-127=4 ,现在我们就能写出 21 的 32 位二进制表示结果了,首先符号位是 0 ,阶位 P = 127+4 ,也就是 131 ,表示为 8 位的二进制是 10000011 ,这就是阶位,尾数如何表示呢?我们从刚刚得到的 1.01010* ( 2^4 )中找答案:尾数取 1.01010 的小数部分,即 01010 ,将 01010 按照顺序从尾数的高位排起,剩余的补零,得到的结果就是 01010000000000000000000 。然后将得到符号位,阶位,尾数位连接起来,为了看清楚,用空格分开,结果就是: 0  10000011   01010000000000000000000 。这就是 21 的 32 位二进制浮点数表示。 {C} 2、   纯小数(不带整数部分的小数) 以 0.25 为例,先做这样的操作, 0.25*2=0.5 , 0.5*2=1 。所以 0.25=1* ( 2^-2 )。 同样可以写成 1.0* ( 2^-2 )。此时就可以写了,符号位是 0 ,阶位 P=(-2)+127 ,即 125 ,表示成 8 位的二进制是 01111101 ,尾数是 1.0 的小数部分,即 0 ,所以尾数是 23 个 0 。所以 0.25 的 32 位二进制浮点数是: 0   01111101   00000000000000000000000 。 至此纯小数的讨论还没有结束,因为 0.25 只代表乘 2 之后,无论乘多少次都能得到整数的小数。还有一部分是无论乘多少次 2 都得不到的整数的小数。比如 0.3 , 0.6 , 0.7 等,其实只要小数的最后一位不是 5 就属于这种小数。我们以 0.3 为例来说明。 方法是这样的:首先符号位是 0 ,要得到阶位和尾数要进行以下操作, 0.3*2=0.6 ,我们取 0.6 的整数部分 0 记在尾数的最高位(【 23 】位), 0.6*2=1.2 ,我们取 1.2 的整数部分 1 记在尾数的次高位(【 22 】),取完后 1.2 就变为 0.2 了。下次运算就要用 0.2 了。 0.2*2=0.4 ,我们取 0.4 的整数部分 0 记在尾数的次次高位(【 21 】)。 依次推下去直到填满尾数的 23 个位。 在此可以告诉大家一个规律,其实只要稍微观察就可以发现: 0.3*2=0.6  取 0 0.6*2=1.2  取 1 0.2*2=0.4  取 0 0.4*2=0.8  取 0 0.8*2=1.6  取 1 0.6*2=1.2  取 1 0.2*2=0.4  取 0 0.4*2=0.8  取 0 0.8*2=1.6  取 1 第一位是 0 ,从第二位开始会以 1001 的形式重复,这是因为被乘数在以 0.6 , 0.2 , 0.4 , 0.8 为周期重复。所以可以很轻易写出 23 位(此处我们写 26 位,因为稍后小数点需要右移两位,还要近似)的结果: 01001100110011001100110011 。得到尾数后就要讨论阶数了,因为尾数是小数部分所以要写成 0.0100110011001100110011001 ,将其写成二进制的科学计数形式: 0.0100110011001100110011001= 1.00110011001100110011001*(2^-2) ,所以阶数就是 P= ( -2 ) +127 ,即 125 ,将其写成 8 位二进制是 01111101 ,至此, 0.3 的符号,阶数,尾数都有了, 0.3 的二进制 32 位单精度浮点数就是: 0  01111101   00110011001100110011001 但是仿真结果却是: 0  01111101   00110011001100110011010 {C}{C} 与我们结果不同的是尾数的后两位,我们是 01 ,仿真结果是 10 ,这是因为尾数的第 24 位是 1 ,根据四舍五入的原则, 24 位会向上进一位,所以 01+1 变为 10 。即 0.3 真正的结果是: 0  01111101   00110011001100110011010 。   {C} 3、   带整数的小数 为了简单,我就偷个懒,以 5.3 为例,说明方法就好,学会了纯小数的表示,这个就很简单了。首先将整数和小数部分分开写成 5 和 0.3 ,分别出其二进制表达, 5 的二进制是 101 , 0.3 的二进制就是我们上面导出的 01001100110011001100110011 将 101 作为整数位, 01001100110011001100110011 作为小数位,写成 101. 01001100110011001100110011 ,将其写成二进制的科学计数法形式, 101. 01001100110011001100110011 = 1. 0101001100110011001100110011* ( 2^2 ),则阶位是 P = 2+127 = 129 ,写成八位二进制是 10000001 , 尾数是 1. 0101001100110011001100110011 的小数部分,遗憾的是尾数只有 23 位,所以只能取小数部分的前 23 位,即 01010011001100110011010 ,则 5.3 的二进制 32 位单精度浮点数就是: 0  10000001  01010011001100110011010 。 长篇大论说了这么多,相信大家都看烦了,但是还没有结束,为什么呢?因为我们现在只是把我们熟悉的十进制的整数和小数表示成了二进制 32 位单精度浮点数,那么这个二进制 32 位单精度浮点数是不是能够准确的表示十进制数呢?在此我们还要说明二进制 32 位单精度浮点数的精度问题,大家再受累看会吧!我们就采用前面得到的四个浮点数来举例做一个逆过程,同时说明一下这个公式 ((-1)^S)*(2^(P-127))*1.M 的用法: 21  其二进制单精度浮点数为 0  10000011   01010000000000000000000 0.25 其二进制单精度浮点数为 0  01111101   00000000000000000000000 0.30 其二进制单精度浮点数为 0  01111101   00110011001100110011010 5.3   其二进制单精度浮点数为 0  10000001   01010011001100110011010 先验证 21 ,用 0  10000011   01010000000000000000000 来得到 21 ,第一位是 0 说明是正数,接下来 8 位是阶位转为十进制是 131 ,即 P = 131 , 1.M = 1.0101 ,注意 1.0101 是二进制的,要将其转成十进制的小数。转换方法是: 整数位乘 2^(0) ,每一个尾数位分别乘以对应的阶,对应的阶已在上图标出,然后相加。 1.0101 可以表示为: 1.0101 = 1*2^(0) + 0*2^(-1) + 1*2^(-2) + 0*2^(-3) + 1*2^(-4) = 1.3125 。 利用公式 ((-1)^S)*(2^(P-127))*1.M 得到 ((-1)^0)*(2^(131-127))*1.3125 = 21 。可见 21 被准确的表示了。   0.25 大家可以自己去验证,因为 0.25 也可以被准确的表示。最终的公式是: ((-1)^0)*(2^(125-127))*1.0 = 0.25 。   接下来验证 0.3 ,用 0  01111101   00110011001100110011010 表示,符号位是 0 ,阶位转成十进制是 125 ,即 P = 125 , 1.M = 1. 00110011001100110011010 ,将其转换成十进制的小数,位数比较多,只将 1 乘的阶位写出, 1. 00110011001100110011010 =1*2^(0) + 1*2^(-3) + 1*2^(-4) + 1*2^(-7) + 1*2^(-8) + 1*2^(-11) + 1*2^(-12) + 1*2^(-15) + 1*2^(-16) + 1*2^(-19) + 1*2^(-20) + 1*2^(-22) = 1.20000004768371582 ,利用公式 ((-1)^S)*(2^(P-127))*1.M 得到 2^(125-127)* 1.20000004768371582 = 0.300000011920928955 ,由此可见精度还是相当高的。之所以大于 0.3 是因为当时我们在处理尾数最后一位时选择从后一位进位了,不知大家还记得否?建议取前八位验证,这样工作量会小好多,如果我取到第六位 1*2^(0) + 1*2^(-3) + 1*2^(-4) + 1*2^(-7) + 1*2^(-8) = 1.19921875 , 1.19921875*0.25 = 0.2998046875 这个精度还凑合吧!所以说二进制 32 位单精度浮点数在大多数时候并不能完全准确的表示十进制的小数。   我想说了这么多,大家应该都明白了吧,剩下的 5.3 大家就自己验证吧,我们还是回到除法吧。一开始我们就利用浮点除法的 IP 核创建了浮点数除法的代码文件 division.v 。接下来写个简单的测试程序。 这个例子是用 1 除以 5 ,结果应该是 0.2 。仿真结果是: 从图中看出经过 14 个时钟周期得到了结果,这个好像是对应了前面创建文件时设置的参数。结果为: 0  01111100  10011001100110011001101 这个结果唯一有疑问的地方就是尾数的最后一位,我们先写出 0.2 的浮点数表示:符号 0 ,写出二进制小数是 0.2*2=0.4  取 0 0.4*2=0.8  取 0 0.8*2=1.6  取 1 0.6*2=1.2  取 1 0.2*2=0.4  取 0 0.4*2=0.8  取 0 0.8*2=1.6  取 1 0.6*2=1.2  取 1 所以小数部分是以 0011 循环的,即 0.0011001100110011001100110011 ,科学计数表示: 0.0011001100110011001100110011=1.1001100110011001100110011*2^(-3) ,保留小数点后的 23 位 10011001100110011001100 ,可是仿真结果最后一位是 1 ,这个在之前举例 0.3 中已经提到过,最后一位要从下一位进位,小数点后的第二十四位是 1 ,所以应该向前进 1 ,所以尾数的最后一位取 1 。 0.2 的表示为: 0  01111100  10011001100110011001101 。 至此,浮点的除法就介绍完了,很啰嗦,可能跟我的表达能力有关吧,我以后尽量简洁一些。 至于第二个除法模块 LPM_DIVIDE 我建议大家自己去看一下,它的结果是商和余数。网上也有很多代码能实现,大家可以自己去查看。   第一次写,不足的地方请指出,互相学习,邮箱: koukuanxyz@163.com 。
  • 热度 20
    2014-2-18 22:08
    1610 次阅读|
    4 个评论
    Stephen Suen Copyright © 2005 Stephen Suen. All rights reserved.      浮点数(Floating Point Number)计算机系统中用于表达实数或者说小数的一种方式。由于其表达方式的原因,产生了围绕浮点数的许多常见问题。最典型的就是"为什么我的浮点运算的结果和想象的不同",即浮点数精度损失问题。本文将回避关于浮点数枯燥的数值计算理论,基于 Java 平台的浮点数支持(当然,也适用于其它绝大部分编程语言),尽可能深入浅出的介绍浮点数的基本知识,和常见问题产生的原因。    本文的最新版本将发布在程序员咖啡馆网站上(建设中)。同时欢迎订阅我们的邮件组,以获得关于本文的正式发布及更新信息。    全文在保证完整性,且保留全部版权声明(包括上述链接)的前提下可以在任意媒体转载——须保留此标注。        --------------------------------------------------------------------------------   目录  1. 什么是浮点数  2. IEEE 浮点数  3. 实数和浮点数之间的变换  4. 特殊值  4.1. NaN  4.2. 无穷  4.3. 有符号的零  4.4. 非规范化数 5. 参考资料 1. 什么是浮点数 在计算机系统的发展过程中,曾经提出过多种方法表达实数。典型的比如相对于浮点数的定点数(Fixed Point Number)。在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置。货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision),小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。SQL 中的 NUMBER 数据类型就是利用定点数来定义的。还有一种提议的表达方式为有理数表达方式,即用两个整数的比值来表达实数。    定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。最终,绝大多数现代的计算机系统采纳了所谓的浮点数表达方式。这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。比如 123.45 用十进制科学计数法可以表达为 1.2345 × 102 ,其中 1.2345 为尾数,10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。    提示: 尾数有时也称为有效数字(Significand)。尾数实际上是有效数字的非正式说法。   同样的数值可以有多种浮点数表达方式,比如上面例子中的 123.45 可以表达为 12.345 × 101,0.12345 × 103 或者 1.2345 × 102。因为这种多样性,有必要对其加以规范化以达到统一表达的目标。规范的(Normalized)浮点数表达方式具有如下形式:    ±d.dd...d × β e , (0 ≤ d i β)   其中 d.dd...d 即尾数,β 为基数,e 为指数。尾数中数字的个数称为精度,在本文中用 p 来表示。每个数字 d 介于 0 和基数之间,包括 0。小数点左侧的数字不为 0。    基于规范表达的浮点数对应的具体值可由下面的表达式计算而得:    ±(d 0 + d 1β-1 + ... + d p-1β-(p-1))β e , (0 ≤ d i β)   对于十进制的浮点数,即基数 β 等于 10 的浮点数而言,上面的表达式非常容易理解,也很直白。计算机内部的数值表达是基于二进制的。从上面的表达式,我们可以知道,二进制数同样可以有小数点,也同样具有类似于十进制的表达方式。只是此时 β 等于 2,而每个数字 d 只能在 0 和 1 之间取值。比如二进制数 1001.101 相当于 1 × 2 3 + 0 × 22 + 0 × 21 + 1 × 20 + 1 × 2-1 + 0 × 2-2 + 1 × 2-3,对应于十进制的 9.625。其规范浮点数表达为 1.001101 × 23。     2. IEEE 浮点数 计算机中是用有限的连续字节保存浮点数的。保存这些浮点数当然必须有特定的格式,Java 平台上的浮点数类型 float 和 double 采纳了 IEEE 754 标准中所定义的单精度 32 位浮点数和双精度 64 位浮点数的格式。    注意: Java 平台还支持该标准定义的两种扩展格式,即 float-extended-exponent 和 double-extended-exponent 扩展格式。这里将不作介绍,有兴趣的读者可以参考相应的参考资料。   在 IEEE 标准中,浮点数是将特定长度的连续字节的所有二进制位分割为特定宽度的符号域,指数域和尾数域三个域,其中保存的值分别用于表示给定二进制浮点数中的符号,指数和尾数。这样,通过尾数和可以调节的指数(所以称为"浮点")就可以表达给定的数值了。具体的格式参见下面的图例:    在上面的图例中,第一个域为符号域。其中 0 表示数值为正数,而 1 则表示负数。    第二个域为指数域,对应于我们之前介绍的二进制科学计数法中的指数部分。其中单精度数为 8 位,双精度数为 11 位。以单精度数为例,8 位的指数为可以表达 0 到 255 之间的 255 个指数值。但是,指数可以为正数,也可以为负数。为了处理负指数的情况,实际的指数值按要求需要加上一个偏差(Bias)值作为保存在指数域中的值,单精度数的偏差值为 127,而双精度数的偏差值为 1023。比如,单精度的实际指数值 0 在指数域中将保存为 127;而保存在指数域中的 64 则表示实际的指数值 -63。 偏差的引入使得对于单精度数,实际可以表达的指数值的范围就变成 -127 到 128 之间(包含两端)。我们不久还将看到,实际的指数值 -127(保存为 全 0)以及 +128(保存为全 1)保留用作特殊值的处理。这样,实际可以表达的有效指数范围就在 -127 和 127 之间。在本文中,最小指数和最大指数分别用 emin 和 emax 来表达。    图例中的第三个域为尾数域,其中单精度数为 23 位长,双精度数为 52 位长。除了我们将要讲到的某些特殊值外,IEEE 标准要求浮点数必须是规范的。这意味着尾数的小数点左侧必须为 1,因此我们在保存尾数的时候,可以省略小数点前面这个 1,从而腾出一个二进制位来保存更多的尾数。这样我们实际上用 23 位长的尾数域表达了 24 位的尾数。比如对于单精度数而言,二进制的 1001.101(对应于十进制的 9.625)可以表达为 1.001101 × 23,所以实际保存在尾数域中的值为 00110100000000000000000,即去掉小数点左侧的 1,并用 0 在右侧补齐。    值得注意的是,对于单精度数,由于我们只有 24 位的指数(其中一位隐藏),所以可以表达的最大指数为 224 - 1 = 16,777,215。特别的,16,777,216 是偶数,所以我们可以通过将它除以 2 并相应地调整指数来保存这个数,这样 16,777,216 同样可以被精确的保存。相反,数值 16,777,217 则无法被精确的保存。由此,我们可以看到单精度的浮点数可以表达的十进制数值中,真正有效的数字不高于 8 位。事实上,对相对误差的数值分析结果显示有效的精度大约为 7.22 位。参考下面的示例:    true value stored value -------------------------------------- 16,777,215 1.6777215E7 16,777,216 1.6777216E7 16,777,217 1.6777216E7 16,777,218 1.6777218E7 16,777,219 1.677722E7 16,777,220 1.677722E7 16,777,221 1.677722E7 16,777,222 1.6777222E7 16,777,223 1.6777224E7 16,777,224 1.6777224E7 16,777,225 1.6777224E7 --------------------------------------根据标准要求,无法精确保存的值必须向最接近的可保存的值进行舍入。这有点像我们熟悉的十进制的四舍五入,即不足一半则舍,一半以上(包括一半)则进。不过对于二进制浮点数而言,还多一条规矩,就是当需要舍入的值刚好是一半时,不是简单地进,而是在前后两个等距接近的可保存的值中,取其中最后一位有效数字为零者。从上面的示例中可以看出,奇数都被舍入为偶数,且有舍有进。我们可以将这种舍入误差理解为"半位"的误差。所以,为了避免 7.22 对很多人造成的困惑,有些文章经常以 7.5 位来说明单精度浮点数的精度问题。    提示: 这里采用的浮点数舍入规则有时被称为舍入到偶数(Round to Even)。相比简单地逢一半则进的舍入规则,舍入到偶数有助于从某些角度减小计算中产生的舍入误差累积问题。因此为 IEEE 标准所采用。   3. 实数和浮点数之间的变换 现在我们已经明白了浮点数的 IEEE 表达方式。我们来做些实数和浮点数之间的变换练习以加深理解。在这些练习中,你还会发现一些围绕浮点数运算的令人吃惊的事实。    首先我们来看看事情简单的一面,从浮点数变换到实数。理解了浮点数的格式,做这个练习并不难。假定我们有一个 32 位的数据,用十六进制表示为 0xC0B40000,并且我们知道它实际上是一个单精度的浮点数。为了得到该浮点数实际表达的实数,我们首先将它变换为二进制形式:    C 0 B 4 0 0 0 0 1100 0000 1011 0100 0000 0000 0000 0000接着按照浮点数的格式切分为相应的域:    1 10000001 01101000000000000000000符号域 1 意味着负数;指数域为 129 意味着实际的指数为 2 (减去偏差值 127);尾数域为 01101 意味着实际的二进制尾数为 1.01101 (加上隐含的小数点前面的 1)。所以,实际的实数为:    -1.01101 × 22 -(20 + 2-2 + 2-3 2-5) × 22 -5.625从实数向浮点数变换稍微麻烦一点。假定我们需要将实数 -9.625 表达为单精度的浮点数格式。方法是首先将它用二进制浮点数表达,然后变换为相应的浮点数格式。    首先,将小数点左侧的整数部分变换为其二进制形式,9 的二进制性形式为 1001。处理小数部分的算法是将我们的小数部分乘以基数 2,记录乘积结果的整数部分,接着将结果的小数部分继续乘以 2,并不断继续该过程:    0.625 × 2 = 1.25 1 0.25 × 2 = 0.5 0 0.5 × 2 = 1 1 0当最后的结果为零时,结束这个过程。这时右侧的一列数字就是我们所需的二进制小数部分,即 0.101。这样,我们就得到了完整的二进制形式 1001.101。用规范浮点数表达为 1.001101 × 23。    因为是负数,所以符号域为 1。指数为 3,所以指数域为 3 + 127 = 130,即二进制的 10000010。尾数省略掉小数点左侧的 1 之后为 001101,右侧用零补齐。最终结果为:    1 10000010 00110100000000000000000最后可以将浮点数形式表示为十六进制的数据如下:    1100 0001 0001 1010 0000 0000 0000 0000 C 1 1 A 0 0 0 0最终结果为 0xC11A0000。    很简单?等等!你可能已经注意到了,在上面这个我们有意选择的示例中,不断的将产生的小数部分乘以 2 的过程掩盖了一个事实。该过程结束的标志是小数部分乘以 2 的结果为 1,不难想象,很多小数根本不能经过有限次这样的过程而得到结果(比如最简单的 0.1)。我们已经知道浮点数尾数域的位数是有限的,为此,浮点数的处理办法是持续该过程直到由此得到的尾数足以填满尾数域,之后对多余的位进行舍入。换句话说,除了我们之前讲到的精度问题之外,十进制到二进制的变换也并不能保证总是精确的,而只能是近似值。事实上,只有很少一部分十进制小数具有精确的二进制浮点数表达。再加上浮点数运算过程中的误差累积,结果是很多我们看来非常简单的十进制运算在计算机上却往往出人意料。这就是最常见的浮点运算的"不准确"问题。参见下面的 Java 示例:    System.out.print("34.6-34.0=" + (34.6f-34.0f));这段代码的输出结果如下:    34.6-34.0=0.5999985产生这个误差的原因是 34.6 无法精确的表达为相应的浮点数,而只能保存为经过舍入的近似值。这个近似值与 34.0 之间的运算自然无法产生精确的结果。     4. 特殊值 通过前面的介绍,你应该已经了解的浮点数的基本知识,这些知识对于一个不接触浮点数应用的人应该足够了。不过,如果你兴趣正浓,或者面对着一个棘手的浮点数应用,可以通过本节了解到关于浮点数的一些值得注意的特殊之处。    我们已经知道,指数域实际可以表达的指数值的范围为 -127 到 128 之间(包含两端)。其中,值 -127(保存为 全 0)以及 +128(保存为全 1)保留用作特殊值的处理。本节将详细 IEEE 标准中所定义的这些特殊值。    浮点数中的特殊值主要用于特殊情况或者错误的处理。比如在程序对一个负数进行开平方时,一个特殊的返回值将用于标记这种错误,该值为 NaN(Not a Number)。没有这样的特殊值,对于此类错误只能粗暴地终止计算。除了 NaN 之外,IEEE 标准还定义了 ±0,±∞ 以及非规范化数(Denormalized Number)。    对于单精度浮点数,所有这些特殊值都由保留的特殊指数值 -127 和 128 来编码。如果我们分别用 emin 和 emax 来表达其它常规指数值范围的边界,即 -126 和 127,则保留的特殊指数值可以分别表达为 emin - 1 和 emax + 1; 。基于这个表达方式,IEEE 标准的特殊值如下所示:      其中 f 表示尾数中的小数点右侧的(Fraction)部分。第一行即我们之前介绍的普通的规范化浮点数。随后我们将分别对余下的特殊值加以介绍。    4.1. NaN NaN 用于处理计算中出现的错误情况,比如 0.0 除以 0.0 或者求负数的平方根。由上面的表中可以看出,对于单精度浮点数,NaN 表示为指数为 emax + 1 = 128(指数域全为 1),且尾数域不等于零的浮点数。IEEE 标准没有要求具体的尾数域,所以 NaN 实际上不是一个,而是一族。不同的实现可以自由选择尾数域的值来表达 NaN,比如 Java 中的常量 Float.NaN 的浮点数可能表达为 01111111110000000000000000000000,其中尾数域的第一位为 1,其余均为 0(不计隐藏的一位),但这取决系统的硬件架构。Java 中甚至允许程序员自己构造具有特定位模式的 NaN 值(通过 Float.intBitsToFloat() 方法)。比如,程序员可以利用这种定制的 NaN 值中的特定位模式来表达某些诊断信息。    定制的 NaN 值,可以通过 Float.isNaN() 方法判定其为 NaN,但是它和 Float.NaN 常量却不相等。实际上,所有的 NaN 值都是无序的。数值比较操作符 ,=, 和 = 在任一操作数为 NaN 时均返回 false。等于操作符 == 在任一操作数为 NaN 时均返回 false,即使是两个具有相同位模式的 NaN 也一样。而操作符 != 则当任一操作数为 NaN 时返回 true。这个规则的一个有趣的结果是 x!=x 当 x 为 NaN 时竟然为真。    可以产生 NaN 的操作如下所示:      此外,任何有 NaN 作为操作数的操作也将产生 NaN。用特殊的 NaN 来表达上述运算错误的意义在于避免了因这些错误而导致运算的不必要的终止。比如,如果一个被循环调用的浮点运算方法,可能由于输入的参数问题而导致发生这些错误,NaN 使得 即使某次循环发生了这样的错误,也可以简单地继续执行循环以进行那些没有错误的运算。你可能想到,既然 Java 有异常处理机制,也许可以通过捕获并忽略异常达到相同的效果。但是,要知道,IEEE 标准不是仅仅为 Java 而制定的,各种语言处理异常的机制不尽相同,这将使得代码的迁移变得更加困难。何况,不是所有语言都有类似的异常或者信号(Signal)处理机制。    注意: Java 中,不同于浮点数的处理,整数的 0 除以 0 将抛出 java.lang.ArithmeticException 异常。   4.2. 无穷 和 NaN 一样,特殊值无穷(Infinity)的指数部分同样为 emax + 1 = 128,不过无穷的尾数域必须为零。无穷用于表达计算中产生的上溢(Overflow)问题。比如两个极大的数相乘时,尽管两个操作数本身可以用保存为浮点数,但其结果可能大到无法保存为浮点数,而必须进行舍入。根据 IEEE 标准,此时不是将结果舍入为可以保存的最大的浮点数(因为这个数可能离实际的结果相差太远而毫无意义),而是将其舍入为无穷。对于负数结果也是如此,只不过此时舍入为负无穷,也就是说符号域为 1 的无穷。有了 NaN 的经验我们不难理解,特殊值无穷使得计算中发生的上溢错误不必以终止运算为结果。    无穷和除 NaN 以外的其它浮点数一样是有序的,从小到大依次为负无穷,负的有穷非零值,正负零(随后介绍),正的有穷非零值以及正无穷。除 NaN 以外的任何非零值除以零,结果都将是无穷,而符号则由作为除数的零的符号决定。    回顾我们对 NaN 的介绍,当零除以零时得到的结果不是无穷而是 NaN 。原因不难理解,当除数和被除数都逼近于零时,其商可能为任何值,所以 IEEE 标准决定此时用 NaN 作为商比较合适。   4.3. 有符号的零 因为 IEEE 标准的浮点数格式中,小数点左侧的 1 是隐藏的,而零显然需要尾数必须是零。所以,零也就无法直接用这种格式表达而只能特殊处理。    实际上,零保存为尾数域为全为 0,指数域为 emin - 1 = -127,也就是说指数域也全为 0。考虑到符号域的作用,所以存在着两个零,即 +0 和 -0。不同于正负无穷之间是有序的,IEEE 标准规定正负零是相等的。    零有正负之分,的确非常容易让人困惑。这一点是基于数值分析的多种考虑,经利弊权衡后形成的结果。有符号的零可以避免运算中,特别是涉及无穷的运算中,符号信息的丢失。举例而言,如果零无符号,则等式 1/(1/x) = x 当x = ±∞ 时不再成立。原因是如果零无符号,1 和正负无穷的比值为同一个零,然后 1 与 0 的比值为正无穷,符号没有了。解决这个问题,除非无穷也没有符号。但是无穷的符号表达了上溢发生在数轴的哪一侧,这个信息显然是不能不要的。零有符号也造成了其它问题,比如当 x=y 时,等式1/x = 1/y 在 x 和 y 分别为 +0 和 -0 时,两端分别为正无穷和负无穷而不再成立。当然,解决这个问题的另一个思路是和无穷一样,规定零也是有序的。但是,如果零是有序的,则即使 if (x==0) 这样简单的判断也由于 x 可能是 ±0 而变得不确定了。两害取其轻者,零还是无序的好。   4.4. 非规范化数 我们来考察浮点数的一个特殊情况。选择两个绝对值极小的浮点数,以单精度的二进制浮点数为例,比如 1.001 × 2-125 和 1.0001 × 2-125 这两个数(分别对应于十进制的 2.6448623 × 10-38 和 2.4979255 × 10-38)。显然,他们都是普通的浮点数(指数为 -125,大于允许的最小值 -126;尾数更没问题),按照 IEEE 754 可以分别保存为 00000001000100000000000000000000(0x1100000)和 00000001000010000000000000000000(0x1080000)。    现在我们看看这两个浮点数的差值。不难得出,该差值为 0.0001 × 2-125,表达为规范浮点数则为 1.0 × 2-129。问题在于其指数大于允许的最小指数值,所以无法保存为规范浮点数。最终,只能近似为零(Flush to Zero)。这中特殊情况意味着下面本来十分可靠的代码也可能出现问题:    if (x != y) { z = 1 / (x -y); }正如我们精心选择的两个浮点数展现的问题一样,即使 x 不等于 y,x 和 y 的差值仍然可能绝对值过小,而近似为零,导致除以 0 的情况发生。    为了解决此类问题,IEEE 标准中引入了非规范(Denormalized)浮点数。规定当浮点数的指数为允许的最小指数值,即 emin 时,尾数不必是规范化的。比如上面例子中的差值可以表达为非规范的浮点数 0.001 × 2-126,其中指数 -126 等于 emin。注意,这里规定的是"不必",这也就意味着"可以"。当浮点数实际的指数为 emin,且指数域也为 emin 时,该浮点数仍是规范的,也就是说,保存时隐含着一个隐藏的尾数位。为了保存非规范浮点数,IEEE 标准采用了类似处理特殊值零时所采用的办法,即用特殊的指数域值 emin - 1 加以标记,当然,此时的尾数域不能为零。这样,例子中的差值可以保存为 00000000000100000000000000000000(0x100000),没有隐含的尾数位。    有了非规范浮点数,去掉了隐含的尾数位的制约,可以保存绝对值更小的浮点数。而且,也由于不再受到隐含尾数域的制约,上述关于极小差值的问题也不存在了,因为所有可以保存的浮点数之间的差值同样可以保存。     5. 参考资料   Java Language Specification, Third Edition    David Goldberg, What Every Scientist Should Know About Floating-Point Arithmetic    Brian Goetz, Java theory and practice: Where's your point?   
  • 热度 15
    2014-2-18 21:53
    1539 次阅读|
    0 个评论
    摘 要重点说明浮点数的格式,十进制数与浮点之间的相互转换以及程序设计。   在我们设计的仪表中采用PIC系列单片机,碰到了浮点数的运算问题,查阅其有关资料发现,其浮点数的格式及其与十进制数之间的转换,与我们常用的MCS-51单片机所提供的三字节、四字节浮点数完全不同,本文将说明其浮点数的格式及其与十进制数之间的转换和程序设计步骤。   1 浮点数的格式   Microchip公司单片机所采用的浮点数格式是IEEE-754标准的变异型。32位浮点数格式为:     其中:×表示一位二进制数0或1;eb 为指数的偏差;S为浮点数的符号位,S=0为正数,S=1为负数;小数点“·”在符号位S的右边;BY0 BY1 BY2为尾数的小数部分。   应特别注意:   ⑴ 浮点数隐含其整数部分为1。 ⑵ 十进制数0 的浮点数表示为00H,00H, 00H, 00H。   2 浮点数与十进制数之间的相互转换   2.1 十进制数转换成浮点数   设:十进数为A,则2Z=A,Z= lnA/ln2,指数P=int(z);尾数部分X: X=A/2P, 其整数部分隐含为1(零除外),将其小数部分按原码格式化为二进制数,即为尾数的小数部分BY0 BY1 BY2。而指数偏差eb=P+7FH(其中的7FH 为指数的偏移量)。符号位S,视十进制数的正负而确定。   例如十进制数50.265化为32位规格化浮点数:A=50.265,则Z=ln50.265/ln2,P=int(Z),故P=5; X=A/2P=50.265/25=1.57078125,将0.57078125化为23位二进制小数,即是BY0 BY1 BY2,在最高位添上十进制数的符号位S(因十进制数为正数,故S=0);而eb=P+7FH,所以,十进制数50.265的32位规格化浮点数即为84H,49H,0FH,5CH。   2.2 浮点数转换为十进制数   设浮点数为 eb S.BY0 BY1 BY2。由于浮点数隐含尾数的整数为1,故尾数X的实际值为:   BY0 BY1 BY2;指数P=eb-7FH;故:十进制数   A=(-1)S×2P×X   例:32位规格化浮点数84H,49H,0FH,5CH转换为十进制数。   符号位S=0;指数P=84H-7FH,故P=5; 尾数的小数部分为49H,0FH,5CH左移一位,而尾数的整数部分隐含为1,故尾数X的实际值为:1.57078123;十进制数A=(-1)0×25×1.57078123,即A=50.265。   3 浮点数与十进制数相互转换的程序设计   3.1 浮点数转换为十进制数的程序设计   (1)检测浮点数是否为零;若为零,则十进制数整数部分和小数部分均为零。   (2)保存浮点数的符号位,将浮点数隐含的1置于浮点数的符号位,指数偏差eb加1,小数点移到原浮点数的符号位之前。   (3)判断指数偏差大于7FH否?若小于等于7FH,则该进制数整数部分为零,浮点数尾数部分右移n次(注:n=7FH-指数偏差eb), 即求得二进制小数部分。若大于7FH,则将小数点右移n’次(注:n’=指数偏差eb-7FH),即求得二进制整数部分和小数部分。   (4)将二进制整数部分转换为十进制整数;将二进制小数部分转换为十进制小数。至此,完成了浮点数到十进制数的转换。   3.2 十进制数转换为浮点数的程序设计   (1)检测十进制数是否为零,若为零,则浮点数置成00H,00H,00H,00H。   (2)保存十进制数的符号位,将十进制数的整数部分转换为二进制整数,将十进制数的小数部分转换为二进制小数(设二进制整数为三个字节,二进制小数为两个字节)。   (3)将浮点数的指数偏差eb置为7FH+23,检测二进制整数的最高位是否为1,不是,则将二进制整数和二进制小数联合左移,左移一次,指数偏差减1,直至二进制整数的最高位为1;隐含尾数整数的1,将二进制整数的最高位改为数的符号位。至此,指数偏差eb单元及原二进制整数的三个单元中的内容,即构成四字节浮点数。   最后应该指出,本文所述32位浮点数,精度相当于7位十进制数;32位浮点数运算程序在Microchip 公司提供的有关资料中均有,但是,在调试其浮点子程序时,发现0减0的结果为00H,80H, 00H,00H,而不是00H,00H,00H,00H,编程时应注意。   4 结语   本文中的十进制数与浮点数之间相互转换的程序设计,在智能化仪表的键盘置数及数据显示中,具有实用价值。这里提出了一种设计思路,没有复杂的算法,程序设计亦较简单,工作量较少,可利用Microchip公司提供的现成子程序实现十进制整数与二进制整数的相互转换,十进制小数与二进制小数的相互转换。   参考文献   1 Microchip公司CD-ROM盘中的应用笔记,1997(2) 2 单片机软件设计技术. 科学技术文献出社,1988.7 
  • 热度 9
    2010-2-25 10:33
    1067 次阅读|
    0 个评论
          在计算机中,使用float或者double来存储小数是不能得到精确值的。如果你希望得到精确计算结果,最好是用分数形式来表示小数。有限小数或者无限循环小数都可以转化为分数。比如:       0.9 = 9/10       0.333(3)= 1/3(括号中的数字表示是循环节)       当然一个小数可以用好几种分数形式来表示。如:       0.333(3)= 1/3 = 3/9       给定一个有限小数或者无限循环小数,你能否以分母最小的分数形式来返回这个小数呢?如果输入为循环小数,循环节用括号标记出来。下面是一些可能的输入数据,如0.3、0.30、0.3(000)、0.3333(3333)、……
相关资源
  • 所需E币: 1
    时间: 2022-4-2 22:09
    大小: 10.16KB
    上传者: Argent
    PLC技术在工业控制领域应用广泛,分享一些有关实用的三菱PLC参考程序,希望能够帮助到有需要的网友。
  • 所需E币: 2
    时间: 2021-3-23 23:54
    大小: 5.04MB
    上传者: stanleylo2001
    DSP定点和浮点数格式DSP中数据通常是有定点数与浮点数表示,其中可以对字长进行相关定义,可以选取字长为16位、24位、32位不同字长使用。而格式与字长决定了数据的精度与动态范围,同时也
  • 所需E币: 0
    时间: 2021-3-19 22:55
    大小: 5.04MB
    上传者: samewell
    DSP-定点和浮点数格式
  • 所需E币: 0
    时间: 2020-9-25 23:51
    大小: 4.09MB
    上传者: LGWU1995
    DSP-定点和浮点数格式.rar
  • 所需E币: 0
    时间: 2020-9-26 00:36
    大小: 4.09MB
    上传者: LGWU1995
    DSP定点和浮点数格式
  • 所需E币: 0
    时间: 2020-9-23 01:29
    大小: 5.92MB
    上传者: bwj312
    DSP定点和浮点数格式
  • 所需E币: 3
    时间: 2019-12-25 22:00
    大小: 77.49KB
    上传者: 微风DS
    实验目的(1)练习TMS320C54X汇编程序的编写与调试方法,重点练习C54X程序流程控制的方法。(2)学习并掌握应用TMS320C54X来进行浮点数的各种算术运算的算法实现。(3)练习并掌握TMS320C54X的汇编语言的汇编指令系统的使用方法,重点练习具有C54X特点的一些在功能上有所扩展的特殊指令,并了解这些指令在进行算术运算或各种控制时所带来的方便。(4)练习并掌握用CCS调试程序的一些基本操作。……
  • 所需E币: 4
    时间: 2019-12-25 21:05
    大小: 67.43KB
    上传者: quw431979_163.com
    这是本人使用的MSC-513字节和4字节浮点数计算程序,主要用于数据采集及上传,经过IEEE转换,在上位机直接显示,本人还有热电阻和热电偶温度查表计算程序,有需要可EMAIL.……
  • 所需E币: 4
    时间: 2019-12-25 01:50
    大小: 10.2KB
    上传者: 16245458_qq.com
    浮点数运算……