浮点数

简介

种类——-符号位————-指数位—————-尾数位—-
float—第31位(占1bit)—第30-23位(占8bit)—-第22-0位(占23bit)
double–第63位(占1bit)—第62-52位(占11bit)—第51-0位(占52bit)

单精度浮点数的有效位是7位,因为尾数位23位最大值为2^24 - 1=16777215,对应十进制最大为10^7

float a = 10.12345678;
printf("a=%f\n", a);

结果是10.123457,有效数字是7位

float a = 0.12345678;
printf("a=%f\n", a);

结果是0.123457,有效数字是6位,好奇怪不是7位。


arm中浮点数计算

arm中浮点数计算目前可以通过VFP或者NEON
VFP: Vector Float Point,向量浮点计算单元,
NEON: SIMD(Single Instruction Multiple Data)

编译选项
-mfpu=name (vfpvx or neon) 指定FPU单元
-mfloat-abi=name (soft, hard, softfp) 指定软件浮点,硬件浮点或者兼容软浮点调用接口
soft, 不使用硬件浮点单元,gcc使用软件浮点库来完成浮点运算
softfp, 使用硬件浮点单元,生成硬件浮点指令,生成何种类型的硬件浮点指令由-mfpu选项指定,调用接口的规则和soft选项一致
hard, 使用硬件浮点单元,生成硬件浮点指令,与softfp的区别在于调用接口的规则不同。

如果只指定-mfpu,那么默认编译不会选择硬件浮点指令集
如果只指定-mfloat-abi = hard或者softfp,那么编译会使用硬件浮点指令集

    int main(void)  
    {  
        float f1, f2, f3;  
        f1 = 1.2;  
        f2 = 1.3;  
        f3 = f1 / f2;  
        return 0;  
    }  

-mfpu=neon

arm-eabi-gcc -S hello.c -mfpu=neon

    .arch armv5te
    .fpu softvfp
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 6
    .eabi_attribute 18, 4
    .file   "hello.c"
    .global __aeabi_fdiv
    .text
    .align  2
    .global main
    .type   main, %function
main:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 16
    @ frame_needed = 1, uses_anonymous_args = 0
    stmfd   sp!, {fp, lr}
    .save {fp, lr}
.LCFI0:
    .setfp fp, sp, #4
    add fp, sp, #4
.LCFI1:
    .pad #16
    sub sp, sp, #16
.LCFI2:
    ldr r3, .L3 @ float
    str r3, [fp, #-16]  @ float
    ldr r3, .L3+4   @ float
    str r3, [fp, #-12]  @ float
    ldr r0, [fp, #-16]  @ float
    ldr r1, [fp, #-12]  @ float
    bl  __aeabi_fdiv
    mov r3, r0
    str r3, [fp, #-8]   @ float
    mov r3, #0
    mov r0, r3
    sub sp, fp, #4
    ldmfd   sp!, {fp, pc}
.L4:
    .align  2
.L3:
    .word   1067030938
    .word   1067869798
.LFE0:
    .fnend
    .size   main, .-main
    .ident  "GCC: (Sourcery G++ Lite 2009q3-67) 4.4.1"
    .section    .note.GNU-stack,"",%progbits

-mfpu=vfp

arm-eabi-gcc -S hello.c -mfpu=vfp

    .arch armv5te
    .fpu softvfp
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 6
    .eabi_attribute 18, 4
    .file   "hello.c"
    .global __aeabi_fdiv
    .text
    .align  2
    .global main
    .type   main, %function
main:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 16
    @ frame_needed = 1, uses_anonymous_args = 0
    stmfd   sp!, {fp, lr}
    .save {fp, lr}
.LCFI0:
    .setfp fp, sp, #4
    add fp, sp, #4
.LCFI1:
    .pad #16
    sub sp, sp, #16
.LCFI2:
    ldr r3, .L3 @ float
    str r3, [fp, #-16]  @ float
    ldr r3, .L3+4   @ float
    str r3, [fp, #-12]  @ float
    ldr r0, [fp, #-16]  @ float
    ldr r1, [fp, #-12]  @ float
    bl  __aeabi_fdiv
    mov r3, r0
    str r3, [fp, #-8]   @ float
    mov r3, #0
    mov r0, r3
    sub sp, fp, #4
    ldmfd   sp!, {fp, pc}
.L4:
    .align  2
.L3:
    .word   1067030938
    .word   1067869798
.LFE0:
    .fnend
    .size   main, .-main
    .ident  "GCC: (Sourcery G++ Lite 2009q3-67) 4.4.1"
    .section    .note.GNU-stack,"",%progbits

可以看到上面两个例子,使用的是.fpu softvfp


-mfpu=neon -mfloat-abi=hard

arm-eabi-gcc -S hello.c -mfpu=neon -mfloat-abi=hard

    .arch armv5te
    .eabi_attribute 27, 3
    .eabi_attribute 28, 1
    .fpu neon
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 6
    .eabi_attribute 18, 4
    .file   "hello.c"
    .text
    .align  2
    .global main
    .type   main, %function
main:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 16
    @ frame_needed = 1, uses_anonymous_args = 0
    @ link register save eliminated.
    str fp, [sp, #-4]!
    .save {fp}
.LCFI0:
    .setfp fp, sp, #0
    add fp, sp, #0
.LCFI1:
    .pad #20
    sub sp, sp, #20
.LCFI2:
    flds    s15, .L3
    fsts    s15, [fp, #-16]
    flds    s15, .L3+4
    fsts    s15, [fp, #-12]
    flds    s14, [fp, #-16]
    flds    s15, [fp, #-12]
    fdivs   s15, s14, s15
    fsts    s15, [fp, #-8]
    mov r3, #0
    mov r0, r3
    add sp, fp, #0
    ldmfd   sp!, {fp}
    bx  lr
.L4:
    .align  2
.L3:
    .word   1067030938
    .word   1067869798
.LFE0:
    .fnend
    .size   main, .-main
    .ident  "GCC: (Sourcery G++ Lite 2009q3-67) 4.4.1"
    .section    .note.GNU-stack,"",%progbits

-mfpu=neon -mfloat-abi=softfp

arm-eabi-gcc -S hello.c -mfpu=neon -mfloat-abi=softfp

    .arch armv5te
    .eabi_attribute 27, 3
    .fpu neon
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 6
    .eabi_attribute 18, 4
    .file   "hello.c"
    .text
    .align  2
    .global main
    .type   main, %function
main:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 16
    @ frame_needed = 1, uses_anonymous_args = 0
    @ link register save eliminated.
    str fp, [sp, #-4]!
    .save {fp}
.LCFI0:
    .setfp fp, sp, #0
    add fp, sp, #0
.LCFI1:
    .pad #20
    sub sp, sp, #20
.LCFI2:
    flds    s15, .L3
    fsts    s15, [fp, #-16]
    flds    s15, .L3+4
    fsts    s15, [fp, #-12]
    flds    s14, [fp, #-16]
    flds    s15, [fp, #-12]
    fdivs   s15, s14, s15
    fsts    s15, [fp, #-8]
    mov r3, #0
    mov r0, r3
    add sp, fp, #0
    ldmfd   sp!, {fp}
    bx  lr
.L4:
    .align  2
.L3:
    .word   1067030938
    .word   1067869798
.LFE0:
    .fnend
    .size   main, .-main
    .ident  "GCC: (Sourcery G++ Lite 2009q3-67) 4.4.1"
    .section    .note.GNU-stack,"",%progbits

-mfpu=vfpv3 -mfloat-abi=hard

arm-eabi-gcc -S hello.c -mfpu=vfpv3 -mfloat-abi=hard

    .arch armv5te
    .eabi_attribute 27, 3
    .eabi_attribute 28, 1
    .fpu vfpv3
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 6
    .eabi_attribute 18, 4
    .file   "hello.c"
    .text
    .align  2
    .global main
    .type   main, %function
main:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 16
    @ frame_needed = 1, uses_anonymous_args = 0
    @ link register save eliminated.
    str fp, [sp, #-4]!
    .save {fp}
.LCFI0:
    .setfp fp, sp, #0
    add fp, sp, #0
.LCFI1:
    .pad #20
    sub sp, sp, #20
.LCFI2:
    flds    s15, .L3
    fsts    s15, [fp, #-16]
    flds    s15, .L3+4
    fsts    s15, [fp, #-12]
    flds    s14, [fp, #-16]
    flds    s15, [fp, #-12]
    fdivs   s15, s14, s15
    fsts    s15, [fp, #-8]
    mov r3, #0
    mov r0, r3
    add sp, fp, #0
    ldmfd   sp!, {fp}
    bx  lr
.L4:
    .align  2
.L3:
    .word   1067030938
    .word   1067869798
.LFE0:
    .fnend
    .size   main, .-main
    .ident  "GCC: (Sourcery G++ Lite 2009q3-67) 4.4.1"
    .section    .note.GNU-stack,"",%progbits

-mfpu=vfpv3 -mfloat-abi=softfp

arm-eabi-gcc -S hello.c -mfpu=vfpv3 -mfloat-abi=softfp

    .arch armv5te
    .eabi_attribute 27, 3
    .fpu vfpv3
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 6
    .eabi_attribute 18, 4
    .file   "hello.c"
    .text
    .align  2
    .global main
    .type   main, %function
main:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 16
    @ frame_needed = 1, uses_anonymous_args = 0
    @ link register save eliminated.
    str fp, [sp, #-4]!
    .save {fp}
.LCFI0:
    .setfp fp, sp, #0
    add fp, sp, #0
.LCFI1:
    .pad #20
    sub sp, sp, #20
.LCFI2:
    flds    s15, .L3
    fsts    s15, [fp, #-16]
    flds    s15, .L3+4
    fsts    s15, [fp, #-12]
    flds    s14, [fp, #-16]
    flds    s15, [fp, #-12]
    fdivs   s15, s14, s15
    fsts    s15, [fp, #-8]
    mov r3, #0
    mov r0, r3
    add sp, fp, #0
    ldmfd   sp!, {fp}
    bx  lr
.L4:
    .align  2
.L3:
    .word   1067030938
    .word   1067869798
.LFE0:
    .fnend
    .size   main, .-main
    .ident  "GCC: (Sourcery G++ Lite 2009q3-67) 4.4.1"
    .section    .note.GNU-stack,"",%progbits

使用softfp和hard使用的指令集是一样的,都是硬件浮点, neon和vfp的区别,仅仅体现在.fpu vfpv3和.fpu neon。


-mfloat-abi=hard

arm-eabi-gcc -S hello.c -mfloat-abi=hard

    .arch armv5te
    .eabi_attribute 27, 3
    .eabi_attribute 28, 1
    .fpu vfp
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 6
    .eabi_attribute 18, 4
    .file   "hello.c"
    .text
    .align  2
    .global main
    .type   main, %function
main:
    .fnstart
.LFB0:
    @ args = 0, pretend = 0, frame = 16
    @ frame_needed = 1, uses_anonymous_args = 0
    @ link register save eliminated.
    str fp, [sp, #-4]!
    .save {fp}
.LCFI0:
    .setfp fp, sp, #0
    add fp, sp, #0
.LCFI1:
    .pad #20
    sub sp, sp, #20
.LCFI2:
    flds    s15, .L3
    fsts    s15, [fp, #-16]
    flds    s15, .L3+4
    fsts    s15, [fp, #-12]
    flds    s14, [fp, #-16]
    flds    s15, [fp, #-12]
    fdivs   s15, s14, s15
    fsts    s15, [fp, #-8]
    mov r3, #0
    mov r0, r3
    add sp, fp, #0
    ldmfd   sp!, {fp}
    bx  lr
.L4:
    .align  2
.L3:
    .word   1067030938
    .word   1067869798
.LFE0:
    .fnend
    .size   main, .-main
    .ident  "GCC: (Sourcery G++ Lite 2009q3-67) 4.4.1"
    .section    .note.GNU-stack,"",%progbits

当直接使用-mfloat-abi=hard时,会默认使用.fpu vfp硬件浮点。


参考文章

  1. Linux下VFP NEON浮点编译
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckywang1103

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值