When I try to execute my code I get a error telling me "Value out of range".
program solveQuadratic;
#include( "stdlib.hhf" );
static
a: real32;
b: real32;
c: real32;
discriminant: real32;
root1: real32;
root2: real32;
begin solveQuadratic;
// Prompt and read values for a, b, and c
stdout.put("Gimme a value for a: ");
stdin.get(a);
stdout.put("Gimme a value for b: ");
stdin.get(b);
stdout.put("Gimme a value for c: ");
stdin.get(c);
// Calculate the discriminant
fld(b);
fmul(st0, st1); // b^2
fld(a);
fld(c);
fmul(st0, st1); // a * c
fadd(st0, st1); // 2ac
fsub(); // b^2 - 4ac
fstp(discriminant);
// Compute the roots
fld(discriminant);
fsqrt();
fstp(root1); // store sqrt(discriminant) in root1
// Calculate the positive root
fld(b);
fchs(); // -b
fld(root1);
fadd(); // -b + sqrt(discriminant)
fld(a);
fadd(st0, st0); // 2a
fdiv(); // (-b + sqrt(discriminant)) / (2a)
fstp(root1);
// Calculate the negative root
fld(b);
fchs(); // -b
fld(root1);
fsub(); // -b - sqrt(discriminant)
fld(a);
fadd(st0, st0); // 2a
fdiv(); // (-b - sqrt(discriminant)) / (2a)
fstp(root2);
// Output the roots
stdout.put("x is ", root1:0:5, " and x is also ", root2:0:5, "\n");
end solveQuadratic;
I was expecting this to be outputted
Gimme a value for a: 2.1
Gimme a value for b: 3.1
Gimme a value for c: -5.0
x is -2.44857 and x is also 0.97238
but all I get is a conversion error and I don't know why.
You have stored sqrt(discriminant)
in root1, but in doing so you have made the calculation for the negative root impossible!
fld(b); fmul(st0, st1); // b^2
You can't multiply by ST1 if you didn't load that register! fmul(b)
would be fine.
fld(a); fld(c); fmul(st0, st1); // a * c fadd(st0, st1); // 2ac
This multiplication is ok but the addition really does a * c + a
because ST1 still holds the a value, that you should also remove else the fpu stack will overflow at some point. Also, why do you go for 2ac
when you should be going for 4ac
?
faddp()
, fsubp
, and fdivp
to discard values you no longer need.This is very important since the fpu stack has only 8 registers to play with!
fld(b);
fmul(b); // b^2
fld(a);
fmul(c); // a * c
fadd(st0, st0); // 2ac
fadd(st0, st0); // 4ac
fsubp(); // b^2 - 4ac
// fstp(discriminant);
// fld(discriminant);
fsqrt();
fstp(root2); // store sqrt(discriminant) in root2
// Calculate the positive root
fld(b);
fchs(); // -b
fld(root2);
faddp(); // -b + sqrt(discriminant)
fld(a);
fadd(st0, st0); // 2a
fdivp(); // (-b + sqrt(discriminant)) / (2a)
fstp(root1);
// Calculate the negative root
fld(b);
fchs(); // -b
fld(root2);
fsubp(); // -b - sqrt(discriminant)
fld(a);
fadd(st0, st0); // 2a
fdivp(); // (-b - sqrt(discriminant)) / (2a)
fstp(root2);
You can replace:
fld(root2);
faddp(); // -b + sqrt(discriminant)
by
fadd(root2);
Also, you can replace:
fld(root2);
fsubp(); // -b - sqrt(discriminant)
by
fsub(root2);