定点数基础
众所周知,计算机中所有的信息都是用二进制0和1来表示的,数当然也不例外。用一连串的0和1最方便表达的就是自然数,比如8位的二进制数很容易表示0~255这256个自然数。负数也好办,用补码即可。最高位是符号位,0代表正数,1代表负数。0000 0000 ~ 0111 1111用来表示0~127;1000 0000 ~ 1111 1111用来表示-128 ~ -1。
那么,小数是怎么表示的呢?
一种简单的办法是,用定点数来表示小数。假定还是8位二进制,最高位是符号数。
- 如果用最低1位来表示小数位,则0111 1111代表的是+63.5。
- 如果用最低2位来表示小数位,则0111 1111代表的是+31.75。
- 如果用最低3位来表示小数位,则0111 1111代表的是+15.875。
- 如果用最低4位来表示小数位,则0111 1111代表的是+7.9375。
负数也是类似的:
- 如果用最低1位来表示小数位,则1111 1111代表的是-0.5。
- 如果用最低2位来表示小数位,则1111 1111代表的是-0.25。
- 如果用最低3位来表示小数位,则1111 1111代表的是-0.125。
- 如果用最低4位来表示小数位,则1111 1111代表的是-0.0625。
simulink中的定点数表示方法1:指定小数点位置
打开Data Type Conversion模块的参数配置对话框。
其中有3类用fixdt表示的定点数类型。
其中fixdt(1,16,0)中的“1”表示“有符号数”,“16”表示16位二进制,“0”表示0位小数(即整数)。fixdt(1,16,0)等效于int16。fixdt(1,16,0)中的最后一个0可以省略,即为fixdt(1,16)。
当表示n位小数位时,n可以为正数,也可以为负数。比如n=1时,所表示的小数的最小精度为0.5;当n=-1时,所表示的“小数”的最小精度为2.
可以打开Data Type Assistant来配置:是否有符号、字长、小数部分的长度:
实例1
用这种配置方法来验证一下。搭建如下模型:
其中,常数模块的值为255,输出数据类型为uint8。Display1的格式为“存储的二进制数”。
可以看到,255的存储二进制数为1111 1111.
把Data Type Conversion的输出数据类型配置为fixdt(1,8,1),同时把“输入输出等值模式”由“真实世界的值”改为“存储的整数”。
仿真后结果为,Display2显示的值为-0.5.
如果把Data Type Conversion的输出数据类型改为fixdt(1,8,4),则Display2显示-0.0625
simulink中的定点数表示方法2:指定斜率和偏置
比如,要想用无符号数来表示温度,温度的精度为0.1,要表示的温度范围为-40~120.
则可以用16位无符号数中的0~1600来表示。0代表-40度,1代表-39.9度,100代表-30度,400代表0度,1000代表60度,1600代表120度。
此时的定点数类型应该为:fixdt(0,16,0.1,-40)。
实例2
验证结果:
当CODE为1000时,Temp.为60度:
当CODE为1234时,Temp.为83.4度:
实例3
反过来,也可以看看小数是用什么二进制数来表示的。
当constant的输出数据类型为fixdt(1,8,1)时,二进制数为0000 0111。即 3.5 = 0.5 * 7
当constant的输出数据类型为fixdt(1,8,2)时,二进制数为0000 1110。即3.5 = 0.25 * 14
这种情况下,并不是所有的小数都能精确的表示。比如在fixdt(1,8,1)模式下,0.1和0.2都是0000 0000;0.3~0.7都是0000 0001.
参考资料
Data Type Conversion
将输入信号转换为指定的数据类型
https://ww2.mathworks.cn/help/simulink/slref/datatypeconversion.html
使用 Data Type Assistant 指定数据类型
https://ww2.mathworks.cn/help/simulink/ug/specify-data-types-using-data-type-assistant.html