c++ - 是否有 C/C++ 函数可以安全地处理被零除?

标签 c++ c math floating-point divide-by-zero

我们有一种情况想要对两个值 w1w2 进行加权平均,基于另外两个值 v1 & v2 远离零...例如:

  • 如果 v1 为零,则根本不会加权,因此我们返回 w2
  • 如果 v2 为零,则根本不会对其进行加权,因此我们返回 w1
  • 如果两个值都离零同样远,我们做平均并返回 (w1 + w2 )/2

我继承了如下代码:

float calcWeightedAverage(v1,v2,w1,w2)
{
  v1=fabs(v1);
  v2=fabs(v2);
  return (v1/(v1+v2))*w1 + (v2/(v1+v2)*w2);
}

作为背景知识,v1 和 v2 代表两个不同的旋钮转动的程度,它们各自产生的效果的权重只取决于它们转动的多少,而不是朝哪个方向.

显然,当 v1==v2==0 时,这会出现问题,因为我们最终得到 return (0/0)*w1 + (0/0)*w2 而你不能 0/0。对 v1==v2==0 进行特殊测试在数学上听起来很糟糕,即使这对 float 来说不是坏习惯。

所以我想知道

  • 有一个标准的库函数来处理这个问题
  • 有更简洁的数学表示

最佳答案

您正在尝试实现此数学函数:

F(x, y) = (W1 * |x| + W2 * |y|) / (|x| + |y|)

此函数在 x = 0, y = 0 点不连续。不幸的是,正如 R. 在评论中所述,不连续性是不可移除的 - 此时没有可使用的合理值。

这是因为“合理值”会根据您到达 x = 0, y = 0 所采用的路径而变化。例如,考虑沿着路径 F(0, r)r = R1r = 0(这相当于让 X旋钮为零,并平稳地将 Y 旋钮从 R1 向下调整到 0)。 F(x, y) 的值将保持在 W2,直到您到达不连续点。

现在考虑遵循 F(r, 0)(将 Y 旋钮保持在零并将 X 旋钮平稳向下调整至零)- 输出将恒定在 W1 直到到达不连续点。

现在考虑遵循 F(r, r)(将两个旋钮保持在相同的值,并将它们同时向下调整为零)。此处的输出将一直保持在 W1 + W2/2,直到您到达不连续点。

这意味着 W1W2 之间的任何值与 x = 0, y = 0 处的输出同样有效。没有明智的方法可以在它们之间进行选择。 (此外,总是选择 0 因为输出是完全错误的——否则输出将被限制在区间 W1..W2 上(即,对于任何你接近不连续性的路径,限制F() 总是在那个区间内),而 0 甚至可能不在这个区间内!)


您可以通过稍微调整函数来“解决”这个问题 - 在之后向 v1v2 添加一个常量(例如 1.0) fabs()。这将使每个旋钮的最小贡献不能为零 - 只是“接近零”(常数定义接近程度)。

将此常量定义为“非常小的数字”可能很诱人,但这只会导致输出在旋钮接近零点时发生剧烈变化,这可能是不可取的。

关于c++ - 是否有 C/C++ 函数可以安全地处理被零除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3739458/

相关文章:

c++ - 如何处理 clang 中的全局构造函数警告?

C++ 如何在两个不同项目中的静态变量之间发生链接

c++ - libcurl 示例 httpcustomheader.c 是否存在错误(显示不良做法)或者我是否遗漏了什么?

c++ - Qt-Creator 是否支持单元测试?

.net - 乘以逆是好是坏?

java - Thymeleaf 操作执行连接而不是乘法

c++ - 构建TensorFlow r1.14 C++文件时缺少文件 “tensorflow/core/framework/types.pb.h”

c - 一次反转数组中的两位

c - 将文件中的值读取到不对应的数组中

python - DSA 验证计算