ValueError: Math domain error (for a 2nd grade equ

2020-04-28 09:01发布

问题:

I've tried to solve the problem myself but i cant. Its a function in order to solve 2nd grade equations when y=0 like 'ax2+bx+c=0'. when i execute it it says me there is math domain error. if u can help me it will be nice thx.

a=raw_input('put a number for variable a:')    
b=raw_input('put a number for variable b:')    
c=raw_input('put a number for variable c:')

a=float(a)    
b=float(b)    
c=float(c)`

import math


x=(-b+math.sqrt((b**2)-4*a*c))/2*a    
print x`

x=(-b-math.sqrt((b**2)-4*a*c))/2*a`    
print x

PD:im starting with python so im quite a disaster sorry.

回答1:

The issue here is that the standard math library in python cannot handle complex variables. The sqrt you've got up there reflects this.

If you want to handle a function that could have complex variables (such as the one above) I would suggest using the cmath library, which has a replacement cmath.sqrt function.

You could change your above code to the following:

from cmath import sqrt

a = raw_input('put a number for variable a:')    
b = raw_input('put a number for variable b:')    
c = raw_input('put a number for variable c:')

a = float(a)    
b = float(b)    
c = float(c)`

x = (-b + sqrt((b**2) - 4 * a * c)) / 2 * a    
print x`

x = (-b - sqrt((b**2) - 4 * a * c)) / 2 * a`    
print x

and it should fix your problem (I also made some edits to make the code look a little more pythonic (read: pep8 compliant))



回答2:

First, it's worth noting that in "2nd grade math", that equation doesn't have a solution with the values you (presumably) entered.* When you get to high school math and learn about imaginary numbers, you learn that all quadratic equations actually do have solutions, it's just that sometimes the solutions are complex numbers. And then, when you get to university, you learn that whether or not the equations have solutions depends on the domain; the function to real numbers and the function to complex numbers are different functions. So, from either a 2nd-grade perspective or a university perspective, Python is doing the right thing by raising a "math domain error".

* Actually, do you even learn about quadratic equations before middle school? That seems a bit early…


The math docs explain:

These functions cannot be used with complex numbers; use the functions of the same name from the cmath module if you require support for complex numbers. The distinction between functions which support complex numbers and those which don’t is made since most users do not want to learn quite as much mathematics as required to understand complex numbers. Receiving an exception instead of a complex result allows earlier detection of the unexpected complex number used as a parameter, so that the programmer can determine how and why it was generated in the first place.

But there's another reason for this: math was specifically designed to be thin wrappers around the standard C library math functions. It's part of the intended goal that you can take code written for another language that uses C's <math.h>, C++'s <cmath>, or similar functions in Perl, PHP, etc. and have it work the same way with the math module in Python.


So, if you want the complex roots, all you have to do is import cmath and use cmath.sqrt instead of math.sqrt.


As a side note: In general, the operators and other builtins are more "friendly" than the functions from these modules. However, until 3.0, the ** operator breaks this rule, so ** .5 will just raise ValueError: negative number cannot be raised to a fractional power. If you upgrade to 3.x, it will work as desired. (This change is exactly like the one with integer division giving a floating-point result, but there's no __future__ statement to enable it in 2.6-2.7 because it was deemed to be less of a visible and important change.)