我正在寻找一个例程,它可以帮助我在浮点数上做任何运算(它可以是加法),但不使用浮点单元(FPU)。
我必须做一个程序,比较在没有FPU和有FPU的情况下操作的时间。第二部分,使用FPU已经完成,但我找不到任何好的例程。
发布于 2014-02-11 21:11:20
不知道为什么人们都对它的复杂性感到震惊。加法、减法和乘法都不是很难。您将需要将数字拆分为符号、尾数和指数,然后使用整数数学来计算结果,最后将其放回浮点数。我碰巧有浮点乘法(64位GAS语法)的示例代码:
.globl main
main:
subq $8, %rsp
leaq format1(%rip), %rdi
leaq (%rsp), %rsi
leaq 4(%rsp), %rdx
xor %eax, %eax
call scanf
movl (%rsp), %eax # x
movl 4(%rsp), %ecx # y
movl %eax, %edx # edx = x
xorl %ecx, %eax # sgn(x*y) = sgn(x) ^ sgn(y)
andl $0x80000000, %eax # eax has correct sign bit now
movl %ecx, %esi # esi = y
shrl $23, %esi
andl $0xff, %esi # esi = exp(y)
movl %edx, %edi # edi = x
shrl $23, %edi
andl $0xff, %edi # edi = exp(x)
addl %esi, %edi # exp(x*y) = exp(x) + exp(y)
subl $0x7f+23, %edi # subtract bias and mantissa bits
andl $0x007fffff, %edx # edx = man(x)
andl $0x007fffff, %ecx # ecx = man(y)
orl $0x00800000, %ecx # put implicit leading 1 bit
orl $0x00800000, %edx # to both mantissas
imulq %rcx, %rdx # man(x*y) = man(x) * man(y)
bsrq %rdx, %rcx # find first set bit
subl $23, %ecx # leave 23 bits
shrq %cl, %rdx # shift the rest out
andl $0x007fffff, %edx # chop off implicit leading 1 bit
addl %ecx, %edi # adjust the exponent by the bits shifted out
shll $23, %edi # shift exponent into position
orl %edi, %eax # put exponent into result
orl %edx, %eax # put mantissa into result
movss (%rsp), %xmm0
movss 4(%rsp), %xmm1
movd %eax, %xmm2
cvtss2sd %xmm0, %xmm0
cvtss2sd %xmm1, %xmm1
cvtss2sd %xmm2, %xmm2
movl $3, %eax
leaq format2(%rip), %rdi
call printf
addq $8, %rsp
ret
.data
format1: .asciz "%f %f"
format2: .asciz "%f * %f = %f\n"对于zero、nan、inf、overflow之类的特殊情况,留给读者作为练习:)
https://stackoverflow.com/questions/21687312
复制相似问题