Я работаю над программой, которая находит корни квадратного уравнения. Мне удалось получить первый рут в подпрограмме root1. Однако, когда я пытаюсь найти второй корень в root2, часть /2a квадратичной формулы продолжает давать NaN.
Вот код:
INCLUDE Irvine32.inc
INCLUDE macros.inc
.data
a real8 ?
b real8 ?
cc real8 ?
a2 real8 ?
b2 real8 ?
cc2 real8 ?
two real8 2.0
four real8 4.0
two2 real8 2.0
four2 real8 4.0
ten real8 1000.0
num real8 10.0
.code
main PROC
finit
mWrite "Enter coefficient (a): "
call ReadFloat
fst a
fstp a2
mWrite "Enter coefficient (b): "
call ReadFloat
fst b
fstp b2
mWrite "Enter coefficient (c): "
call ReadFloat
fst cc
fstp cc2
mWrite "Roots: "
call root1
call Crlf
call root2
;call showfpustack
exit
main ENDP
root1 PROC
; b^2
fld b
fmul b
fchs ; flip sign
fst b
; 4 * a * c
fld four
fmul a
fmul cc
fchs
fsub b
fsqrt
fst four
fld b
fchs
fsqrt
fchs
fadd four
fst b
fld two
fmul a
fst two
fld b
fdiv two
call WriteFloat
call showfpustack
ret
root1 endp
root2 PROC
fld b2
fmul b2
fchs
fst b2
fld four2
fmul a2
fmul cc2
fchs
fsub b2
fsqrt
fst four2
fld b2
fchs
fsqrt
fchs
fsub four2
fst b2
call Crlf
call WriteFloat
fld two2
fmul a2
fst two2
fld b2
fdiv two2
call showfpustack
ret
root2 endp
end main
Мне удалось проверить результаты предыдущих расчетов. Вот только с этой частью у меня проблемы.
fmul
на 2 вы можете простоfadd st0
удвоить текущее значение вершины стека. Но в любом случае, когда вы делаете один шаг в отладчике, где появляется NaN? Вы берете sqrt отрицательного числа? Или вы переполняете стек всеми этимиfld
нажатиями стека и не выталкиваете? Кроме того, зачем вам перезаписывать константу4.0
результатом fsqrt? Это странно и означает, что вы не можете снова вызвать свою функцию. - person Peter Cordes   schedule 19.11.2020WriteFloat
? Изменяет лиWriteFloat
регистры FP? Используйте отладчик, чтобы выяснить это, вместо того, чтобы тратить время только на вызов функций печати. Или вы имеете в виду root2, который использует толькоshowfpustack
? - person Peter Cordes   schedule 19.11.2020fmul a2
? Это не просто загружается, этоst0 *= a2
. Но в любом случае, каковы были старые значенияst0
иa2
на тот момент? Вы уверены, что он не попал в NaN вfld two2
? Этого можно было бы ожидать, если бы все восемьst0
..st7
регистров стека x87 уже использовались до загрузки; как я уже сказал, потому что ты никогда ничего не хлопаешь. - person Peter Cordes   schedule 19.11.2020fdivr b2
для выполненияst0 = b2 / st0
вместо этого store/load/fdiv. Или вы могли быfld b2
/fxchg
/fdivp
или что-то в этом роде, но это явно хуже. Как я уже сказал, вам не нужно перезаписывать свои константы, это просто сбивает с толку любого, кто читает ваш код. - person Peter Cordes   schedule 19.11.2020