HP Forums

Full Version: Solve() gives wrong answer (r10077)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

this is probably a stupid question but why does not the following equation give me an answer?

Solve(0.04*x^2-2.4*x+36=0)
Prime answers [[]]

Solving it on paper gives x=30
Wolfram Alpha solves this just fine

Thanks Smile
(04-27-2016 09:47 AM)drkosse Wrote: [ -> ]Hi,

this is probably a stupid question but why does not the following equation give me an answer?

Solve(0.04*x^2-2.4*x+36=0)
Prime answers [[]]

Solving it on paper gives x=30
Wolfram Alpha solves this just fine

Thanks Smile

It's a rounding problem. The exact equation has two equal real roots which the CAS finds perfectly well with 4/100 and 24/10 in place of 0.04 and 2.4. With the approximate numbers in place I'm assuming that b^2-4*a*c is - just! - negative and so no real root exists.

Keeping the approximate numbers and changing 36 to 35.99999999 also works, as does using csolve instead of solve.

What is more annoying is that taking the equation 0.04*x^2-2.4*x+30=0 (which has two real roots that solve finds without difficulty) and multiplying each term by 1e-16 produces an equation that solve (or fsolve or csolve) won't solve. The CAS has a particular aversion to small approximate numbers which other systems do not share. As a physicist I find this frustrating, although once aware of the problem there are work-arounds.

Nigel (UK)
The CAS uses base-2 representation for numbers for speed. However, this also means that floating point calculations are seemingly inaccurate for many cases (what you see is not what you get) because there are certain decimal values that cannot be represented exactly using the base-2 representation (as an example: 0.2). I believe this is not an issue with BCD representations. What you see is in fact what you get.

http://www-fourier.ujf-grenoble.fr/~pari...n/#htoc558
https://users.cs.duke.edu/~raw/cps104/TW...ating.html

Converting all non-integer values to their rational form, however, will fix this issue if you insist on using the solve() command. The solve() command attempts to solve equations exactly and will return an empty list if it cannot. Using fsolve() in the case of "approximate" expressions should, however, give the correct (approximate) solution.
The majority of my regressions tests are with exact data, this explains these kinds of quirks. I believe I can fix
Code:
fsolve(0.04e-16*x^2-2.4e-16*x+30e-16);

For the other example, it's intrinsically not possible to solve it, as explained by Han. Binary floats can only represent exactly rationals with a denominator dividing a power of 2, that's not the case for 0.04=1/25, therefore rounding errors might transform a 0 discriminant to something negative. csolve will return complex roots in this situation.
(04-27-2016 01:16 PM)Nigel (UK) Wrote: [ -> ]
(04-27-2016 09:47 AM)drkosse Wrote: [ -> ]Hi,

this is probably a stupid question but why does not the following equation give me an answer?

Solve(0.04*x^2-2.4*x+36=0)
Prime answers [[]]

Solving it on paper gives x=30
Wolfram Alpha solves this just fine

Thanks Smile

It's a rounding problem. The exact equation has two equal real roots which the CAS finds perfectly well with 4/100 and 24/10 in place of 0.04 and 2.4. With the approximate numbers in place I'm assuming that b^2-4*a*c is - just! - negative and so no real root exists.

Keeping the approximate numbers and changing 36 to 35.99999999 also works, as does using csolve instead of solve.

What is more annoying is that taking the equation 0.04*x^2-2.4*x+30=0 (which has two real roots that solve finds without difficulty) and multiplying each term by 1e-16 produces an equation that solve (or fsolve or csolve) won't solve. The CAS has a particular aversion to small approximate numbers which other systems do not share. As a physicist I find this frustrating, although once aware of the problem there are work-arounds.

Nigel (UK)

csolve gets {30-5.96046447754E-6*i,30+5.96046447754E-6*i}

Tom L[/b]
solve(4/100*x^2-24/10*x+36=0,x) returns {30}
Ok, so I will simply convert the decimals to ratios (manually or with function exact()) and then use solve(), like:

solve(1/25*x^2-12/5*x+36=0) which gives {30}

Thank you all for the explanations Smile
(04-27-2016 01:16 PM)Nigel (UK) Wrote: [ -> ]...I find this frustrating, although once aware of the problem there are work-arounds.

Nigel (UK)

I totally agree with you Confused
Please add a note about this problem to the calculators help file, Thank You.
Same problem with proot([0.04,-2.4,36])
the answer is [30-2.107e6i 30+2.107e-6i]

so we have an error in the order of 1e-6 with thew first coefficient in the order of 1e-2.

I find this error very big, also considering binary approximation.
(04-28-2016 06:54 AM)retoa Wrote: [ -> ]Same problem with proot([0.04,-2.4,36])
the answer is [30-2.107e6i 30+2.107e-6i]

so we have an error in the order of 1e-6 with thew first coefficient in the order of 1e-2.

I find this error very big, also considering binary approximation.

Actually, this error is about the correct size. It comes from \( b^2-4ac \) being very slightly negative instead of zero. If \( b^2-4ac=-\epsilon \) then the imaginary part of the roots is \( \pm{\rm i}\sqrt\epsilon/2a \) and an error of \( \sim10^{-6} \) is understandable if \( \epsilon\sim10^{-12} \).

Nigel (UK)
Hi!:
This equation, is very easy, for Solve.

1) Press App.
2) Select Solve.
3) Write, the equation, in E1.
4) Press, Num and Solve.
5) You can see, the result.

Note: See, the images and comparison, with Wolfram Alpha.
Kind Regards.
informach.
(04-28-2016 12:34 PM)informach Wrote: [ -> ]Hi!:
This equation, is very easy, for Solve.

1) Press App.
2) Select Solve.
3) Write, the equation, in E1.
4) Press, Num and Solve.
5) You can see, the result.

Note: See, the images and comparison, with Wolfram Alpha.
Kind Regards.
informach.

The problem is not with the Solve App, it's with the solve command in CAS
Hi!, retoa:

Don't worry !. Be Happy !.

Kind Regards.
informach.
(04-28-2016 01:11 PM)informach Wrote: [ -> ]Hi!, retoa:

Don't worry !. Be Happy !.

Kind Regards.
informach.

Hi informarch,

this is not new, it was already proposed yesterday by drkosse and it obviously works as you don't have any binary approximation.
The problem comes only if you use solve() or proot() with approximated values. Please read the whole thread.
No problem with integers, nor with fractions.
For the [CAS] solve(0.04*x^2-2.4*x+36 = 0) test case:

When only the first coefficient is exact: solve(1/25*x^2-2.4*x+36 = 0,x) ==> {30}

When only the second coefficient is exact: solve(0.04*x^2-12/5*x+36 = 0,x) ==> {30,30}

-Dale-
Reference URL's