我有一个非常简单的代码:
#include <stdio.h>
#include <math.h>
int main()
{
long v = 35;
double app = (double)v;
app /= 100;
app = log10(app);
printf("Calculated log10 %lf\n", app);
return 0;
}
这段代码在x86上工作得很好,但在arm上不工作,arm的结果是0.00000。一些想法?
ARM Linux发行版上的浮点支持并非微不足道。因此,您应该使用与您的系统相匹配的工具链,即操作系统和硬件,并使用正确的编译开关。
首先,您需要理解ARM的调用约定,它是关于“调用函数时参数是如何传递的?”。ARM是一个RISC架构,只能在寄存器上工作。没有直接操作内存的指令。如果您需要更改内存中的一个值,首先需要将其加载到寄存器中,修改它,然后将其存储回内存中。
当您调用一个函数时,您可能需要向它传递参数,您可以将参数放在堆栈(内存)上,但是由于ARM只能使用寄存器,您的函数可能首先要做的是将它们加载回寄存器。为了避免这种浪费,ARM调用约定使用寄存器传递参数。然而,由于ARM的寄存器数量有限,调用约定还要求您只对前四个参数使用前四个(r0-r3)寄存器,其余的仍然必须使用堆栈才能传递。
float pi2(float a) {
return a * 3.14f;
}
00000000 <pi2>:
0: f24f 51c3 movw r1, #62915 ; 0xf5c3
4: b508 push {r3, lr}
6: f2c4 0148 movt r1, #16456 ; 0x4048
a: f7ff fffe bl 0 <__aeabi_fmul>
e: bd08 pop {r3, pc}
当浮动硬件支持添加到ARM时(同样是因为体系结构风格),它附带了自己的一组寄存器(s0、s1、...)。
如果我们用-c-o3-mfloat-abi=softfp
编译相同代码段并转储,我们将得到
00000000 <pi2>:
0: eddf 7a04 vldr s15, [pc, #16] ; 14 <pi2+0x14>
4: ee07 0a10 vmov s14, r0
8: ee27 7a27 vmul.f32 s14, s14, s15
c: ee17 0a10 vmov r0, s14
10: 4770 bx lr
12: bf00 nop
14: 4048f5c3 .word 0x4048f5c3
正如您现在所看到的,编译器没有创建对__AEABI_FMUL
的调用,而是在将位于R0
中的参数移动到S14
并在S15
上填充3.14
之后创建一个vmul.f32
指令。在乘法指令之后,它将S14
中可用的结果移回R0
,因为这个函数的任何调用者都希望得到它,因为调用约定。
然而,在保持简洁性的同时,这种方法引入了在ARM寄存器和FP寄存器之间移动值的开销。这显然会影响性能,并由一个新的调用约定解决,该约定由gcc
称为hard
。这个新约定声明,如果函数中有浮点参数,则可以使用与普通寄存器交织的浮点寄存器,并且可以返回浮点寄存器S0
中的浮点值。
同样,如果我们用-c-o3-mfloat-abi=hard
和dump编译代码段,我们将得到
00000000 <pi2>:
0: eddf 7a02 vldr s15, [pc, #8] ; c <pi2+0xc>
4: ee20 0a27 vmul.f32 s0, s0, s15
8: 4770 bx lr
a: bf00 nop
c: 4048f5c3 .word 0x4048f5c3
您可以看到没有登记簿被移动。pi2
的参数在s0
中传递,编译器在S15
中创建用于填充3.14
的代码,并使用vmul.f32 s0、s0、S15
在s0
中获得所需的结果。
有关调用约定的更多信息,您应该查看ARM的网站。
Python3 数字 描述 log10() 方法返回以10为基数的x对数,x>0。 语法 以下是 log10() 方法的语法: import math math.log10( x ) 注意:log10()是不能直接访问的,需要导入 math 模块,通过静态对象调用该方法。 参数 x -- 数值表达式。 返回值返回以10为基数的x对数,x>0。 实例 以下展示了使用 log10() 方法的实例
问题内容: 我正在尝试从CSV文件中的一组数字中找到最大值和最小值。我的代码在某些行中始终为Max函数返回错误的数字。这是我的代码: 我的输出示例: 我不确定我做错了什么。一些建议,将不胜感激。 问题答案: 您的列表元素是字符串。您需要对其进行转换,以避免按字典顺序进行比较(按字母顺序,一次只比较一个字符,这是因为) 除非您实际上想要字符串,否则不要创建新列表,而只需传递给您的函数即可:
本文向大家介绍SQL中的数学函数,包括了SQL中的数学函数的使用技巧和注意事项,需要的朋友参考一下 数学函数在SQL中对于在查询中实现不同的数学概念非常重要。 SQL中的一些主要数学函数如下- ABS(X) 此函数返回X的绝对值。例如- 返回6。 MOD(X,Y) 变量X除以Y,然后返回它们的余数。例如- 返回4。 签名(X) 如果X为正,则此方法返回1;如果为负,则返回-1;如果X的值为0,则返
问题内容: 为什么Python的数学错误? 问题答案: 你已达到计算机科学的新水平,并且你正在走向成熟。 因此,你现在可以进行下一步了。BDFL 本人已授权我向你透露以下超级机密文件。古人先理解它,再解密它,现在,你也将如此! http://floating-point-gui.de/basic/ 请谨慎对待本文件!只与你认识的人分享同样令人困惑的结论!
本文向大家介绍MySQL数学函数简明总结,包括了MySQL数学函数简明总结的使用技巧和注意事项,需要的朋友参考一下 1. ABS(x): 返回x的绝对值 2. PI(): 返回圆周率 3. SQRT(x): 返回x的平方根,要求(x为非负数,返回NULL) 4. MOD(x,y): 求余函数,返回x被y除后的余数;对于带有小数部分的数据值也起作用,它返回除法运算后的精确余数。 5. CEIL(X)
本文向大家介绍Oracle数学相关函数小结,包括了Oracle数学相关函数小结的使用技巧和注意事项,需要的朋友参考一下 本文总结了Oracle数学相关函数。分享给大家供大家参考,具体如下: 1.绝对值:abs() 2.取整函数(大):ceil() 3.取整函数(小):floor() 4.取整函数(截取):trunc() 5.四舍五入:round() 6.取平方:Power(m,n) 7.取平方根: