可接受的 ARM Cortex-M4F 浮点立即数的算法?
Posted
技术标签:
【中文标题】可接受的 ARM Cortex-M4F 浮点立即数的算法?【英文标题】:Algorithm for acceptable ARM Cortex-M4F floating-point immediates? 【发布时间】:2016-11-03 22:50:54 【问题描述】:ARM Cortex-M4F 处理器有一条指令可以将立即数加载到浮点寄存器中,如下所示:
VMOV S0,+6.75
但是,常量的值是有限制的,必须等于可以表示为 +/-m x 2-n 的值,其中 m 是 16-31 范围内的整数n 是 0-7 范围内的整数。例如,上述指令有效,因为您可以在 m=27 和 n=2 时得到 6.75。
我真的很想找到一种算法来确定一个特定的实数是否可以用这种方式表示,如果可以,给出 m 和 n 的对应值。
【问题讨论】:
FWIW,我不知道答案,但我可以推断必须存在一种直接的方法,因为这正是汇编器在编码这样一个指令放在首位。为了省点麻烦,here's an assembler - 任何巫术似乎都涉及将数字作为常规 IEEE754 浮点数开始,这意味着您可能必须首先弄清楚它是否可以表示为其中之一. 如果你有可用的 C 数学库 frexp 可能是一种开始 【参考方案1】:如果您愿意,可以通过转换为常规单精度浮点数,然后检查其位来实现。您的公式可以表示的所有数字也可以表示为浮点数,但您的公式只能表示一些浮点数。
对于您的公式可表示的任何数字,指数保证在 -3 (16*2^-7) 和 +4 (16*2^0) 之间,尾数保证除小数点后的前四位。因此,包含在第 23-30 位(含)的字节必须具有介于 124 和 131(含)之间的值,并且位 0-18(含)必须为零。要确定 n,请从 131 中减去指数字节;要确定 m,请使用第 19-22 位(含)并加上 16。
请注意,这一切都假定您首先知道该数字可以存储为浮点数。
【讨论】:
【参考方案2】:只有 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】:实际上我没有测试它,但它看起来很容易。将数字乘以 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
【讨论】:
【参考方案4】:感谢大家提出的宝贵建议。回想起来,我可能应该提供更多的背景信息。我为大学二年级学生教授汇编语言编程课程,并使用 Cortex-M4F 作为目标平台。我试图找到一种简单的方法让他们知道何时可以立即使用 VMOV。我终于(有些尴尬)意识到 m 和 n 的组合太少了,最好的解决方案是以讲义的形式打印出所有组合。 :-)
再次感谢!
丹——
【讨论】:
以上是关于可接受的 ARM Cortex-M4F 浮点立即数的算法?的主要内容,如果未能解决你的问题,请参考以下文章