卓航论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 137|回复: 2
打印 上一主题 下一主题

Vdsp(bf561)中的浮点运算(5):float类型表示总结

[复制链接]
[至尊红钻5级]发帖数量≥8000篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [至尊紫钻4级]金币≥20000个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 论坛元老
 UID:  7   [未点亮普号显示]钻石不足3个
 阁 分: 36567
 阁 望: 0
 阁 献: 0
 活 跃: 0
 发 贴: 12405 (0)
 阁 币: 24162  
性 别: I'm 火星人!
阅读权限: 90
在线时长: 0 小时
注册时间: 2016-10-16
最后登录: 2016-10-18
go
楼主
发表于 2016-10-17 16:27:35 |只看该作者 |倒序浏览
本帖发表于 2016-10-17 16:27:35...阅读 138 人...加油,亲爱的楼主:[db:作者]
1.1 float的疑问
写一行很简单的C代码:
float a = 1234.56;
用vdsp编译后的汇编代码为:
R0 = 20972 ( X ) ;
R0.H = 17562 ;
[ FP + 0x10 ] = R0 ;
有点看不懂,呵呵,R0的值转换为十六进制就是0x449A51EC。根据vdsp文档的说法,其单精度浮点数格式为:

浮点数计算公式:

将0x449A51EC转换为二进制:
0100 0100 1001 1010 0101 0001 1110 1100
可得:
Sign = 0
Mantissa = 001 1010 0101 0001 1110 1100
Exponent = 1000 1001
按照公式

将Exponent转换为十进制,其值为137。
将Mantissa转换为十进制,其值为:
2-3 + 2-4 + 2-6 + 2-9 + 2 -11 + 2-15 + 2-16 + 2-17 + 2-18 + 2-20 + 2-21 =
0.125 + 0.0625 + 0.015625 + 0.001953125 + 0.00048828125 + 0.000030517578125 + 0.0000152587890625 + 0.00000762939453125 + 0.000003814697265625 + 0.00000095367431640625 + 0.000000476837158203125 = 0.205625057220458984375
代入浮点数计算公式:
(-1)0 + 1. 205625057220458984375 * 2 (137-127)
= 1234.56005859375
               
那么编译器又是如何将1234.56转换为0x449A51EC的呢?
首先转换整数部分,用2除,取余数,其结果为:
1234 / 2 = 617 ….. 0
617 / 2 = 308 …….1
308 / 2 = 154 …….0
154 / 2 = 77 ……...0
77 / 2 = 38 ……….1
38 / 2 = 19 ……….0
19/ 2 = 9 ………….1
9 / 2 = 4………… .1
4/ 2 = 2 …………..0
2/2 = 1……………0
1/2 = 0……………1
即100 1101 0010,用16进制表示则为:0x4d2。
再转换小数部分,用2乘,取整数位:
0.56 * 2 = 1.12取1
0.12 * 2 = 0.24取0
0.24 * 2 = 0.48取0
0.48 * 2 = 0.96取0
0.96 * 2 = 1.92取1
0.92 * 2 = 1.84取1
0.84 * 2 = 1.68取1
0.68 * 2 = 1.36取1
0.36 * 2 = 0.72取0
0.72 * 2 = 1.44取1
0.44 * 2 = 0.88取0
0.88 * 2 = 1.76取1
0.76 * 2 = 1.52取1
               
小数部分的值为0.1000 1111 0101 11
所以1234.56表示成二进制数就是
100 1101 0010. 1000 1111 0101 11
由于浮点数表示法的尾数部分以1开头,所以上面的这个数可以表示为:
1.00 1101 0010 1000 1111 0101 11 * 210
从浮点数的表示公式即可算出
Exponent = 127 + 10 = 137
而尾数部分则为
00 1101 0010 1000 1111 0101 11
因此整个数就是:
0      1000 1001   00 1101 0010 1000 1111 0101 11
符号位    指数          尾数
从整数的角度来看就是:
0100 0100 1001 1010 0101 0001 1110 1011
十六进制表示为:
4    4    9    A   5    1   E    B
奇怪得很,最后居然有偏差。莫非VDSP还有什么机关不成?
1.2 FLT_MIN
FLT_MIN是在float.h中定义的一个常量,用以表示单精度浮点数的最小值。
#define FLT_MIN  1.1754943508222875E-38F
那么这个值从何而来?
从浮点数的表示可以知道,尾数必然是大于等于1的,要取最小值,只能将指数设置为最小值,由于浮点数规定将指数为0的情况表示特殊的浮点数,因此指数只能取1,即
0      00000001   00000000000000000000000
符号位    指数     尾数
从16进制整数看它的值就是 0x00 80 00 00。
根据浮点数的计算公式可知这个值为:
1.0 * 2-126
= 1.1754943508222875079687365372222e-38
这个是计算器的计算结果。
1.3 FLT_MAX
               
FLT_MAX是在float.h中定义的一个常量,用以表示单精度浮点数的最大值。
#define FLT_MAX 3.4028234663852886E+38F
那么这个值从何而来?
从浮点数的表示可以知道,要取最大值,可以将指数和尾数都设置为最大值,由于标准规定将指数全为1留做特殊表示,故指数最大值为255,这个数即
0      11111110   11111111111111111111111
符号位    指数     尾数
从16进制整数看它的值就是 0x7f 7f ff ff。
根据浮点数的计算公式可知这个值为:
1. 9999997615814208984375 * 2(254-127)
= 3.4028234663852886E+38
这个是计算器的计算结果。
1.4 FLT_EPSILON
FLT_EPSILON是在float.h中定义的一个常量,用以表示一个单精度浮点数的最小分辨率,文档对此值的描述是:
A constant that represents the smallest value that may added to 1.0 and still result in a change of value (for example, FLT_EPSILON)
也就是加1后要能看得出变化!
FLT_EPSILON定义为:
#define FLT_EPSILON  1.1920928955078125E-07F
那么这个值从何而来?
先看1.0的浮点表示:
0      01111111   00000000000000000000000
符号位    指数     尾数
从十六进制的角度看就是0x3f80 0000
要想把这个值加上一个足够小的值但仍然能看出变化,当然就是把尾数直接加1,这个数即2-23,转换成十进制就是FLT_EPSILON的值。
下面是一个很有意思的问题:
float a = FLT_EPSILON;
这个时候a的值会是什么?
在VDSP下试了一下,a的值看成整数是:0x3400 0000,也就是:
0      01101000   00000000000000000000000
符号位    指数     尾数
即1.0 x 2(104-127) = 1.0 x 2-23
               
1.5 INF和NAN
IEEE754规定了单精度浮点数的类型:
TypeExponentFractionValue
NAN255NonzeroUndefined
Infinity2550(–1)s Infinity
Normal1

INF的表示要求指数为255,尾数为0,即:
0        11111111   00000000000000000000000
符号位    指数     尾数
也就是0x7f80 0000。
在VDSP下可以用:
float a = 1.0 / 0.0;
来生成一个INF的数。
当然,符号位也可以取负数,即:
1      11111111   00000000000000000000000
符号位    指数     尾数
也就是0xff80 0000。
在VDSP下可以用:
float a = -1.0 / 0.0;
来生成一个-INF的数。
上述两个INF都可以用isinf函数来检测它。
NAN的表示要求指数为255,尾数不为0,即:
0      11111111   00000000000000000000001
符号位    指数     尾数(可取任意不为0的值)
也就是0x7f80 0001这样的数。
在VDSP下可以用:
float a = 0.0 / 0.0;
来生成一个NAN的数,不过这个时候它的值为0xffff ffff。
可以使用isnan函数来检测它。
分享到: QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏0 支持支持0 反对反对0

使用道具 举报

[至尊红钻2级]发帖数量≥100篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [未点亮至尊绿钻]贡献度不足10点 [未点亮至尊紫钻]金币不足100个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 注册会员
 UID:  13   [未点亮普号显示]钻石不足3个
 阁 分: 168
 阁 望: 8
 阁 献: 3
 活 跃: 0
 发 贴: 142 (0)
 阁 币: 7  
性 别: I'm Boy
阅读权限: 20
在线时长: 5 小时
注册时间: 2011-1-6
最后登录: 2016-10-21
沙发
发表于 2016-10-18 19:37:51 |只看该作者
本回复帖发表于 2016-10-18 19:37:51,感谢php_z对本帖的认真回复,你的回复是对楼主莫大的鼓舞
帮帮顶顶!!

使用道具 举报

[至尊红钻2级]发帖数量≥100篇 [未点亮至尊黄钻]威望不足10点 [未点亮至尊蓝钻]在线时间不足10小时 [至尊绿钻1级]贡献度≥10点 [未点亮至尊紫钻]金币不足100个 [未点亮至尊粉钻]精华贴数不足10贴 [未点亮至尊黑钻]活跃不足8个
 等级: 
 级别: 中级会员
 UID:  169   [未点亮普号显示]钻石不足3个
 阁 分: 270
 阁 望: 4
 阁 献: 10
 活 跃: 0
 发 贴: 243 (0)
 阁 币: 9  
性 别: I'm 火星人!
阅读权限: 30
在线时长: 2 小时
注册时间: 2011-1-5
最后登录: 2016-10-21
板凳
发表于 2016-10-20 10:00:56 |只看该作者
本回复帖发表于 2016-10-20 10:00:56,感谢jinxun对本帖的认真回复,你的回复是对楼主莫大的鼓舞
好好 学习了 确实不错

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1、请认真发帖,禁止回复纯表情,纯数字等无意义的内容!帖子内容不要太简单!
2、提倡文明上网,净化网络环境!抵制低俗不良违法有害信息。
3、每个贴内连续回复请勿多余3贴,每个版面回复请勿多余10贴!
4、如果你对主帖作者的帖子不屑一顾的话,请勿回帖。谢谢合作!

手机版| 百度搜索:vkee.pw

2012-2015 卓航旗下 GMT+8, 2024-6-16 20:16 , Processed in 0.729096 second(s), 30 queries . Powered by Discuz! X3.2  

禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.如遇版权问题,请及时联系站长(QQ:5213513)

今天是: | 本站已经安全运行: //这个地方可以改颜色

快速回复 返回顶部 返回列表