Skip to content
Advertisement

sqrt() c++ and math.sqrt() python

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.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement