【发布时间】:2016-06-13 05:00:09
【问题描述】:
用于证明三角恒等式:
cos(fi+theta) = cos(theta)cos(fi)-sin(theta).sin(fi)
以下用 NASM 编写的程序应该在验证身份时打印 1,否则打印 0。我总是得到 0 作为输出。在我看来,我认为我的逻辑是正确的。内存加载或堆栈溢出存在问题。
[bits 32]
extern printf
extern _exit
section .data
hello: db "Value = %d ", 10, 0
theta: dd 1.0
fi: dd 2.0
threshold: dd 1e-1
SECTION .text
global main ; "C" main program
main:
start:
; compute cos(theta)cos(fi)-sin(theta).sin(fi)
fld dword [theta]
fcos
fld dword [fi]
fcos
fmul st0,st1
fstp dword [esp]
fld dword [theta]
fsin
fld dword [fi]
fsin
fmul st0,st1
fld dword [esp]
fmul st0,st1
fstp dword [esp]
;compute cos(fi+theta)
fld dword [theta]
fld dword [fi]
fadd st0,st1
fcos
; compare
fld dword [esp]
fsub st0, st1
fld dword [threshold]
fcomi st0, st1
ja .equal
mov eax, 0
jmp .exit
.equal:
mov eax, 1
.exit:
mov dword[ esp ], hello
mov dword [ esp + 4 ], eax
call printf
; Call 'exit': exit( 0 );
mov dword[ esp ], 0
call _exit
【问题讨论】:
-
你知道due to limitations inherent to IEEE-754 floating-point arithmetic,这样的身份很少是真的吗?此外,由于
pi不能以有限精度表示,并且由于制表者的困境,IEEE-754 不需要对sin()和cos()进行正确舍入,所以sin(pi)和cos(pi/2)不一定等同于@987654330 @. -
@IwillnotexistIdonotexist 那么我们如何证明这些身份呢?
-
使用代数和微积分可以做到这一点,因为他们知道使用 IEEE-754 算法的实现永远只是一个近似值。这也是为什么人们永远不会像您那样测试浮点值之间的精确相等性的原因;人们通常对 近似 相等(与真实值相差很小的绝对或相对增量)更感兴趣。
-
另见Bruce Dawson's article on FP comparisons;这可能有助于澄清您对浮点的用途以及您可以使用它做什么和不能做什么有用的理解。另请注意,为单个测试用例值测试假设可能会反驳它,但您只能使用此技术通过测试每个可能的 32 位
float值来证明它。其中只有 2^32 个(包括 NaN),因此实际上不会花费不合理的时间。