【问题标题】:sqrt() c++ and math.sqrt() pythonsqrt() c++ 和 math.sqrt() python
【发布时间】:2021-12-25 00:59:45
【问题描述】:

我是 python 的新手,我遇到了 python 的精度问题,这是我以前用 c++ 没有的,代码是 对于蟒蛇

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))))

结果是

Traceback (most recent call last):
  File "C:\Users\dell\PycharmProjects\pythonProject2\main.py", line 10, in <module>
    print(math.acos(38 / (math.sqrt(38) * math.sqrt(38))))
ValueError: math domain error
1.0000000000000002
1.0000000000000002

对于 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);
}

结果是

1
1
nan
0

这会导致崩溃

【问题讨论】:

  • 那么你的问题是什么?
  • 浮点是一个近似值。舍入错误可能会累积,结果可能不完全是 1
  • 除非您要求更多,否则 C++ 会礼貌地将这些数字四舍五入到小数点后六位。
  • 有几件事:当使用 >> 运算符作为 cout 或作为 acos() 函数的参数时,sqrt()*sqrt() 在 c++ 中为您提供确切的值,但是当您使用 sqrt( ) 作为函数的返回值(代码 i 中的 f()),你会有所不同,cout 的 >> 运算符仍然给出准确的值(可能是 rnded 的值)但使用 f() 作为 acos 的参数() 给出一个“nan”,这是一个超出范围的错误。使用 python 使用 math.sqrt() 或 math.sqrt() 作为函数的重新调整值,你总是会得到一个超出范围的错误。所以 c++ 中 acos() sqrt()*sqrt() 的参数与 math.sqrt()*math.sqrt() 不同

标签: python c++


【解决方案1】:

在浮点运算方面,不同的编程语言可能会有不同的表现。它可能会涉及到优化、acos 等函数的内部实现。

首先,请注意,在 C++ 中,acos 为超出范围的值返回特殊值 nan,而在 Python 中则抛出 ValueError 异常。但是,您可以像这样轻松获得 C++ 行为:

import math

def my_acos(x):
    try:
        return math.acos(x)
    except ValueError:
        return float("nan")

此外,您可以添加舍入以接受稍微超出范围的值。您的数字在小数点后有 15 个零,所以让我们四舍五入到 15 位(为了演示):

import math

def my_acos(x):
    try:
        return math.acos(round(x, 15))
    except ValueError:
        return float("nan")

通过此修改,您的代码将产生您期望的结果。

【讨论】:

  • tnx,我会根据要求修改代码,这实际上是两个几何向量之间的角度问题,如果它等于或接近 Pi 或 0,特别是对于具有陡峭时间梯度的移动物体,有可能发生这种情况。同样 sqrt() 作为函数的返回值和在 python 中直接使用是一样的,而 c++ 则不是这样。
猜你喜欢
  • 2011-06-23
  • 2015-12-09
  • 2011-12-25
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多