问题
I am attempting to create a simple quadratic formula program for my TI-Nspire CX CAS. I seem to have everything correct, and it works on the computer:
However, it doesn't work on the calculator. I get the second one correct, but the 1st is -4.44089...e-16. (doesn't say ..., just using it because I don't want to type out the whole thing)
The (simplified) code is as follows:
function quadraticA(f,s,t)
return ((-1*s)+math.sqrt(s^2-4*f*t))/(2*f)
end
function quadraticB(f,s,t)
return ((-1*s)-math.sqrt(s^2-4*f*t))/(2*f)
end
function on.paint(gc)
formula:setExpression("0s: "..quadraticA(tonumber(a),tonumber(b),tonumber(c)))
formulaB:setExpression(quadraticB(tonumber(a),tonumber(b),tonumber(c)))
end
Why do I get a different answer on the calculator then on the computer? How can I fix the issue?
Thanks in advance!
回答1:
What Egor is trying to say is that computers do not calculate exact answers most of the time.
Texas Instruments deals primarily in the micro-controllers so I wouldn't expect the usual x86-64 processor inside that device of yours. That means TI can do a whole lot of things in their own way. They may make own decisions on how to handle small values, rounding, how to handle complex mathematical operations etc...
Computers use at least 32 bit floating point numbers these days. This page gives precision (number of bits before e^-16
that are correct in the machine representation). For 32 bits that value is 24
. I couldn't find much info on the calculator, except the wiki page, which says its precision is 14
. More than half-float less than float, not defined in that IEEE standard.
That sqrt
over there is a nasty function. Computing its value requires quite a lot of computations. Lots of steps means lots of arithmetic errors, the lower precision the further from true value it gets. This also depends on the exact algorithm chosen in the sqrt
function. You could check whether the math.sqrt(4^2)
returns what it should return and whether math.sqrt(4^2))/(2*4)
return exactly half of that.
Battling with numerical errors in computations is an entire discipline on its own and recipes differ depending on what equation you are tackling. There's this post considering the quadratic equations.
Or maybe in your case you'll be happier with just discarding all but few numbers after the decimal point in the final answer.
回答2:
As Dimitry pointed out, I must write, essentially, a CAS engine. Here is a square root simplification in lua:
function factors(a)
factorsOfA={}
counter = 0
for i = 1, a do
counter = counter + 1
if modulo(a,i) == 0 then
factorsOfA[counter]=i
end
end
return factorsOfA
end
function simplifySqrt(radicand)
radicandFactors = factors(radicand)
outsideRadicand = 1
for m,i in pairs(radicandFactors) do
if math.floor(math.sqrt(i))^2 == i then
outsideRadicand = outsideRadicand * math.floor(math.sqrt(i))
end
end
insideRadicand = radicand/outsideRadicand^2
return outsideRadicand.."sqrt("..insideRadicand..")"
end
I hope this helps!
来源:https://stackoverflow.com/questions/50310056/inspired-lua-program-is-different-on-computer-and-calculator