1位Matlab定点数的性质
我注意到Matlab FI数字的一个有趣行为。它只发生在1位有符号的数字上(这种数据类型在实践中没有太多意义)。 我知道将一个double乘以一个fi不是一个好的实践,这种行为甚至可能取决于Matlab版本,但我希望这种行为与位数无关。这在2011b、2013a和2013b版本中似乎是一致的,我想了解为什么会这样 示例1:-1可以表示为1位有符号。但是,结果有-2的一小部分,这将只允许数字[-8,-4,0,4]1位Matlab定点数的性质,matlab,fixed-point,Matlab,Fixed Point,我注意到Matlab FI数字的一个有趣行为。它只发生在1位有符号的数字上(这种数据类型在实践中没有太多意义)。 我知道将一个double乘以一个fi不是一个好的实践,这种行为甚至可能取决于Matlab版本,但我希望这种行为与位数无关。这在2011b、2013a和2013b版本中似乎是一致的,我想了解为什么会这样 示例1:-1可以表示为1位有符号。但是,结果有-2的一小部分,这将只允许数字[-8,-4,0,4] >> a = fi(-1,1,1,0) a = -1 s1,
>> a = fi(-1,1,1,0)
a = -1
s1,0
>> 1*a
ans = 0
s2,-2
示例2:1位无符号的行为与预期相同,分数部分保持不变
>> b = fi(1,0,1,0)
b = 1
u1,0
>> 1*b
ans = 1
u2,0
示例3:一个2位带符号的函数按预期运行,分数部分不变,整数部分扩展
>> c = fi(-2,1,2,0)
c = -2
s2,0
>> 1*c
ans = -2
s4,0
示例4:另一个1位,带符号,显示与示例1类似的行为
>> d = fi(-0.5,1,1,1)
d = -0.5000
s1,1
>> 1*d
ans = 0
s2,-1
当matlab以不同的格式乘以数字时,首先要修改格式。如果将
1
转换为与值相同的格式,则此格式中的数字1有时为0
,因此产品为零是有意义的,一切都如预期的那样
示例1
a = fi(-1,1,1,0); a_one = fi(1,1,1,0); disp([a, a_one, a*a_one])
-1 0 0
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 1
FractionLength: 0
示例2
b = fi(1,0,1,0); b_one = fi(1,0,1,0); disp([b, b_one, b*b_one])
1 1 1
DataTypeMode: Fixed-point: binary point scaling
Signedness: Unsigned
WordLength: 1
FractionLength: 0
示例3
c = fi(-2,1,2,0); c_one = fi(1,1,2,0); disp([c, c_one, c*c_one])
-2 1 -2
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 2
FractionLength: 0
示例4
d = fi(-0.5,1,1,1); d_one = fi(1,1,1,1); disp([d, d_one, d*d_one])
-0.500000000000000 0 0
DataTypeMode: Fixed-point: binary point scaling
Signedness: Signed
WordLength: 1
FractionLength: 1
免责声明:以下是来自MathWorks支持部门的(稍加编辑)答案,为完整起见,我添加了该答案。简言之,事实证明,这并不局限于1位数据类型,而是(正如sebas所指出的)双常量被强制转换到另一个操作数并在那里饱和,特别是在没有警告的情况下,但符合规范
结果表明,双常量值(例如,
1
)在进行数学运算(例如,*
)之前,使用另一个操作数的有符号性和字长强制转换为FI类型。但是,新的FI类型使用“最佳精度”分数长度,而不是其他操作数的分数长度
下面是一些具有显式fi()
构造函数的等效MATLAB代码,说明了这一点:
示例1。
>> a = fi(-1,1,1,0)
a =
-1
s1,0
>> fi(1,a.SignednessBool,a.WordLength) * a
ans =
0
s2,-2
>> 1*a
ans =
0
s2,-2
>> b = fi(1,0,1,0)
b =
1
u1,0
>> fi(1,b.SignednessBool,b.WordLength) * b
ans =
1
u2,0
>> 1 * b
ans =
1
u2,0
>> c = fi(-2,1,2,0)
c =
-2
s2,0
>> fi(1,c.SignednessBool,c.WordLength) * c
ans =
-2
s4,0
>> 1 * c
ans =
-2
s4,0
>> d = fi(-0.5,1,1,1)
d =
-0.5000
s1,1
>> fi(1,d.SignednessBool,d.WordLength) * d
ans =
0
s2,-1
>> 1*d
ans =
0
s2,-1
示例2。
>> a = fi(-1,1,1,0)
a =
-1
s1,0
>> fi(1,a.SignednessBool,a.WordLength) * a
ans =
0
s2,-2
>> 1*a
ans =
0
s2,-2
>> b = fi(1,0,1,0)
b =
1
u1,0
>> fi(1,b.SignednessBool,b.WordLength) * b
ans =
1
u2,0
>> 1 * b
ans =
1
u2,0
>> c = fi(-2,1,2,0)
c =
-2
s2,0
>> fi(1,c.SignednessBool,c.WordLength) * c
ans =
-2
s4,0
>> 1 * c
ans =
-2
s4,0
>> d = fi(-0.5,1,1,1)
d =
-0.5000
s1,1
>> fi(1,d.SignednessBool,d.WordLength) * d
ans =
0
s2,-1
>> 1*d
ans =
0
s2,-1
示例3。
>> a = fi(-1,1,1,0)
a =
-1
s1,0
>> fi(1,a.SignednessBool,a.WordLength) * a
ans =
0
s2,-2
>> 1*a
ans =
0
s2,-2
>> b = fi(1,0,1,0)
b =
1
u1,0
>> fi(1,b.SignednessBool,b.WordLength) * b
ans =
1
u2,0
>> 1 * b
ans =
1
u2,0
>> c = fi(-2,1,2,0)
c =
-2
s2,0
>> fi(1,c.SignednessBool,c.WordLength) * c
ans =
-2
s4,0
>> 1 * c
ans =
-2
s4,0
>> d = fi(-0.5,1,1,1)
d =
-0.5000
s1,1
>> fi(1,d.SignednessBool,d.WordLength) * d
ans =
0
s2,-1
>> 1*d
ans =
0
s2,-1
示例4.
>> a = fi(-1,1,1,0)
a =
-1
s1,0
>> fi(1,a.SignednessBool,a.WordLength) * a
ans =
0
s2,-2
>> 1*a
ans =
0
s2,-2
>> b = fi(1,0,1,0)
b =
1
u1,0
>> fi(1,b.SignednessBool,b.WordLength) * b
ans =
1
u2,0
>> 1 * b
ans =
1
u2,0
>> c = fi(-2,1,2,0)
c =
-2
s2,0
>> fi(1,c.SignednessBool,c.WordLength) * c
ans =
-2
s4,0
>> 1 * c
ans =
-2
s4,0
>> d = fi(-0.5,1,1,1)
d =
-0.5000
s1,1
>> fi(1,d.SignednessBool,d.WordLength) * d
ans =
0
s2,-1
>> 1*d
ans =
0
s2,-1
我希望这些示例有助于澄清双常量值的隐式类型转换问题(例如,
1
) 由于那个问题没有引起任何注意,我已经交叉贴到了。如果我在那里得到任何答案,我将在这里更新。通过此操作,我们进入mtimes.m
,在本例中,它调用fimtimes(a,b)
函数。我无法使用此函数检查代码。因此,为了得到答案,我们需要Mathworks的人加入进来。否则,我能给出的最好结果是:这是fimtimes
(和fitimes
)中的一个bug。此外,我还观察到除法中类似的奇怪行为。对于第一个示例中定义的a
,我看到1/a=0
和a/1=-1
,但第二个结果给出了一个被零除的警告!感谢@nguthrie确认此问题!我还将此问题直接发送给Mathworks支持部门。我不确定是否理解发生的情况,但我猜测您的字长不足会导致类似舍入错误的情况?您是对的,这可能取决于double首先转换为的确切类型。我还发现了一些更奇怪的不是1位数字的情况,比如fi(2,0,2,0)*10
返回24
。。。找到一种了解这种中介类型的方法会很有趣——调试器是否可以用于调查这种情况?然而,我不喜欢你的答案是你输出3个不同类型的变量作为一个向量:因为向量总是有一个单一的数据类型,我们的问题是具体的类型,最好打印d
,d_one
和d*d_one
分别为+50,因为将double转换为另一个操作数的类型实际上是关键。谢谢