ARM Cortex-M4F 处理器有一条指令将立即数加载到浮点寄存器中,如下所示:
VMOV S0,+6.75
但是,常数的值是有限制的,必须等于可以表示为 +/-mx 2 -n的值,其中 m 是 16-31 范围内的整数,n 是 0- 范围内的整数7. 例如,上述指令有效,因为您可以在 m=27 和 n=2 时得到 6.75。
我真的很想找到一种算法来确定是否可以用这种方式表示特定的实数,如果可以,给出 m 和 n 的相应值。
ARM Cortex-M4F 处理器有一条指令将立即数加载到浮点寄存器中,如下所示:
VMOV S0,+6.75
但是,常数的值是有限制的,必须等于可以表示为 +/-mx 2 -n的值,其中 m 是 16-31 范围内的整数,n 是 0- 范围内的整数7. 例如,上述指令有效,因为您可以在 m=27 和 n=2 时得到 6.75。
我真的很想找到一种算法来确定是否可以用这种方式表示特定的实数,如果可以,给出 m 和 n 的相应值。
它只有 8*16*2 = 256 个值,所以一个简单的方法是使用哈希表。在 Python 中:
D = set()
for m in range(16,32):
for n in range(8):
x = m*2.0**-n
D.add(x)
D.add(-x)
def iscortexable(x):
return x in D
给
>>> iscortexable(6.75)
True
>>> iscortexable(8.75)
False
一种更有原则的方法是使用frexp
from math import frexp
def iscortexable(x):
if x == 0:
return False
m, e = frexp(x) # 0.5 <= m < 1
m = m*32 # 16 <= m < 32
n = -(e - 5)
return m.is_integer() and 0 <= n <= 7
如果您愿意,可以通过转换为常规单精度浮点数,然后检查其位来完成此操作。您的公式可以表示的所有数字也可以表示为浮点数,但只有一些浮点数可以通过您的公式表示。
对于您的公式可表示的任何数字,指数保证在 -3 (16*2^-7) 和 +4 (16*2^0) 之间,并且尾数保证在除前四个之外的所有数字都为零小数点后的位。因此,包含在第 23-30 位(含)的字节必须具有介于 124 和 131(含)之间的值,并且第 0-18 位(含)必须为零。要确定 n,请从 131 中减去指数字节;要确定 m,请使用第 19-22 位(含)并加上 16。
请注意,这一切都假设您首先知道该数字可以存储为浮点数。
其实我没有测试它,但它看起来很容易。将数字乘以 1、2、4、8 等,直到 0x80。它会导致 16 到 31 之间的整数/整数吗?在这种情况下 6.75 *4 = 27。所以 m 是 27 n 是 2。2.8750 * 8 = 23 所以 m 是 23,n 是 3。
float vut; //value under test
float f;
unsigned int nn;
int n;
unsigned int m;
for(nn=0x01;nn<=0x80;nn<<=1)
{
f=vut*n;
if(is_an_integer_no_fraction(f))
{
m=f;
if((m>=16)&&(m<=31))
{
n=nn;
n=-n;
//FOUND m and n
break;
}
}
}
if(nn>=0x80)
{
//NOPE doesnt work
}
else
{
//YEP found m and n
}
感谢大家的好建议。回想起来,我可能应该提供更多的背景信息。我为大学二年级学生教授汇编语言编程课程,并使用 Cortex-M4F 作为目标平台。我试图找到一种简单的方法让他们知道何时可以立即使用 VMOV。我终于意识到(有些尴尬)m 和 n 的组合太少了,最好的解决方案是以讲义的形式打印出所有的组合。:-)
再次感谢!
丹——</p>