从这个问题Replacing __aeabi_dsub to save space (-flto issues)中提取双减法代码并稍微调整它(对于double和float值):
extern "C" double __aeabi_dsub(double a, double b) {
// flip top bit of 64 bit number (the sign bit)
reinterpret_cast<unsigned char *>(&b)[7] ^= 0x80; // assume little endian
return a + b;
}
extern "C" float __aeabi_fsub(float a, float b) {
// flip top bit of 32 bit number (the sign bit)
reinterpret_cast<unsigned char *>(&b)[3] ^= 0x80; // assume little endian
return a + b;
}
字符串
**这些a - b
的实现(对于double
/float
)是否违反了任何浮点代码/ IEEE规范?**假设ARM Cortex-M0架构不支持浮点,由GCC编译。
2条答案
按热度按时间flseospp1#
假设IEEE 754浮点,这不应该破坏任何代码,这很容易通过查看编译代码来看到。
字符串
编译为
型
(https://godbolt.org/z/rY4h5YTqb)
正如您所看到的,即使在不允许不兼容的FP转换的低优化级别上,这些也是等效的。
whhtz7ly2#
这应该是很好的,至少在概念层面上。但是,你需要在这里小心一点。
减法例程与加法例程大小相同的事实可能意味着(至少)两件事:
我之所以这样说是因为我过去写过多精度整数库,除了一些委托,加法和减法例程可以假设某些属性以简化代码。因此,例如,(伪)代码将类似于(在注解中,
+x
意味着x >= 0
,-x means
x < 0`):字符串
右边的注解显示了使
if
条件为真的保证条件。并不是所有这些都被显式检查,因为如果没有它们,早期的if
语句将为true,并且w函数将已经返回。“简化代码”区可以集中精力做好自己的工作,知道它拥有的数字是“安全的”。举例来说:
所以,如果你的加法和减法例程基本上是重复的(即库编写者做得很差),没有相互引用(即使是间接地通过其他调用),你可能会通过使用你的方法保存一些空间。
然而,如果库的编写者比这聪明一点,他们很可能已经完成了类似于我上面描述的委托工作。这意味着用你所提议的东西来替换
sub
是一个相当糟糕的主意:型
这是因为
add(5, -1)
几乎会将该调用委托给sub(5, 1)
。当然,这会将它发送回add(5, -1)
,依此类推,直到堆栈溢出:-)所以,在你认为你的方法有效之前,要确保这些委托不会发生。因为这是一个库编写者 * 应该 * 在他们的代码中放入的东西(但请参阅上面的“做得很差”文本)。