i am new at python and i had this precision problem with python which i did not have before with c++, the code is for python
import math def f(x): return math.sqrt(x) print((38 / (math.sqrt(38) * math.sqrt(38)))) print(38 / (f(38) * f(38))) print(math.acos(38 / (math.sqrt(38) * math.sqrt(38)))) print(math.acos(38 / (f(38) * f(38))))
the result is
Traceback (most recent call last): File "C:UsersdellPycharmProjectspythonProject2main.py", line 10, in <module> print(math.acos(38 / (math.sqrt(38) * math.sqrt(38)))) ValueError: math domain error 1.0000000000000002 1.0000000000000002
for c++
#include <iostream> #include <cmath> using namespace std; double f(double x); int main() { cout <<38/(f(38)*f(38))<<endl; cout <<38/(sqrt(38)*sqrt(38))<<endl; cout <<acos(38/(f(38)*f(38)))<<endl; cout <<acos(38/(sqrt(38)*sqrt(38)))<<endl; return 0; } double f(double x) { return sqrt(x); }
the result is
1 1 nan 0
this can make crashes
Advertisement
Answer
Different programming languages may behave differently when it comes to float arithmetics. It may come to optimisations, internal implementations of functions like acos
etc.
First, notice that in C++, acos
returns the special value nan
for values out of range, while in Python it throws the ValueError
exception. You can, however, easily get the C++ behavior like this:
import math def my_acos(x): try: return math.acos(x) except ValueError: return float("nan")
Furthermore, you can add rounding to accept values slightly out of range. Your number has 15 zeroes after the decimal point, so let’s round to 15 places (for the sake of demonstration):
import math def my_acos(x): try: return math.acos(round(x, 15)) except ValueError: return float("nan")
With this modification, your code will produce the results you expect.