相关疑难解决方法(0)

计算正确舍入/几乎正确舍入的浮点立方根

假设可以使用正确舍入的标准库函数,例如CRlibm中的函数.那么如何计算双精度输入的正确圆角立方根?

引用FAQ时,这个问题不是"[我]面临的实际问题".这有点像家庭作业.但立方根是经常发现的操作,可以想象这个问题是某人面临的实际问题.

由于"最好的Stack Overflow问题中有一些源代码",这里有一些源代码:

  y = pow(x, 1. / 3.);
Run Code Online (Sandbox Code Playgroud)

上面没有计算正确的圆形立方根,因为1/3不能完全表示为a double.


补充说明:

文章介绍如何计算浮点立方根,但推荐牛顿迭代算法的最后一次迭代(S)将不得不做更高精度的算法来计算正确舍入的双精度立方根.这可能是计算它的最佳方式,但我仍在寻找一种利用现有正确舍入标准化功能的快捷方式.

C99包含一个cbrt()函数,但不能指望所有编译器都能正确舍入甚至忠实.CRlibm的设计者本可以选择包含cbrt()在提供的功能列表中,但他们没有.可以参考其他正确舍入的数学函数库中可用的实现.

algorithm floating-point ieee-754

9
推荐指数
3
解决办法
721
查看次数

为什么我为std :: exp获得特定于平台的结果?

我有一个程序在Android和Windows下给出了截然不同的结果.当我根据二进制文件验证输出数据包含预期结果时,差异即使非常小(舍入问题)也很烦人,我必须找到解决方法.

这是一个示例程序:

#include <iostream>
#include <iomanip>
#include <bitset>

int main( int argc, char* argv[] )
{
    // this value was identified as producing different result when used as parameter to std::exp function
    unsigned char val[] = {158, 141, 250, 206, 70, 125, 31, 192};

    double var = *((double*)val);

    std::cout << std::setprecision(30);

    std::cout << "var is " << var << std::endl;
    double exp_var = std::exp(var);
    std::cout << "std::exp(var) is " << exp_var << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

在Windows下,使用Visual 2015编译,我得到输出:

var is -7.87234042553191493141184764681
std::exp(var) …
Run Code Online (Sandbox Code Playgroud)

c++ rounding-error exp

6
推荐指数
1
解决办法
247
查看次数

不同语言的浮点精度

我目前正在进行坐标之间的距离计算,并且根据所使用的语言得出的结果略有不同。

计算的一部分是计算cosine给定值的radian。我得到以下结果

// cos(0.8941658257446736)

// 0.6261694290123146 node
// 0.6261694290123146 rust
// 0.6261694290123148 go
// 0.6261694290123148 python
// 0.6261694290123148 swift
// 0.6261694290123146 c++
// 0.6261694290123146 java
// 0.6261694290123147 c
Run Code Online (Sandbox Code Playgroud)

我想尝试并了解原因。如果16dp c四舍五入,过去是唯一的“正确”答案。我感到惊讶的是python,结果有所不同。

目前,这种微小的差异正在被放大,并且超过000个位置增加了不小的距离。

不太确定这是如何重复的。另外,我要求的是整体答案,而不是具体的语言。我没有计算机科学学位。

更新 我接受这可能是一个太宽泛的问题,我想我很好奇为什么我的背景不是CS。我感谢评论中发布的博客链接。

更新2

这个问题源于将服务从移植nodejsgoGo甚至更奇怪,因为距离的总和随多个值而变化,所以我现在无法运行测试。

给定一个坐标列表并计算距离并将它们加在一起,我得到不同的结果。我没有问一个问题,但似乎go会产生不同的结果。

9605.795975874069
9605.795975874067
9605.79597587407
Run Code Online (Sandbox Code Playgroud)

为了完整起见,这里是我正在使用的距离计算:

// cos(0.8941658257446736)

// 0.6261694290123146 node
// 0.6261694290123146 rust
// 0.6261694290123148 go
// 0.6261694290123148 python
// 0.6261694290123148 swift
// 0.6261694290123146 c++
// 0.6261694290123146 java …
Run Code Online (Sandbox Code Playgroud)

c c++ java go rust

6
推荐指数
1
解决办法
250
查看次数

Clang 和 Visual C++ 之间的 acos 精度略有差异

我正在使用一些跨平台代码。在 Mac 上它是用 Clang 编译的,在 Windows 上它是用 Visual C++ 编译的。

有一个计算可能很敏感,并且触发断言的 Mac 和 Windows 之间存在差异。最终 acos 结果之间存在差异,但我不清楚为什么。

在这两个平台上,acos 的输入恰好是 -1.0f。在 Visual C++ 中,acos(-1.0f)为 3.14159274。这就是 pi 作为浮点数的值,这正是我所期望的。

但在 macOS 上:

float value = acos(-1.0f);

...计算结果为 3.1415925。这足以引发代码中的问题。acos 是一种对于 float 来说可能不精确的操作 - 我理解这一点。并且不同的编译器可以有不同的acos实现。我只是不清楚为什么 Clang 似乎对如此简单的 acos 结果有问题,而 Visual C++ 却没有。浮点数能够代表 3.14159274,但这不是我得到的结果。

可以使用以下命令从 Xcode 版本的 Clang 中获取准确/Visual C++ 对齐的值:

float value = (float)acos((double)-1.0f);

因此,我可以通过提高精度来解决这个问题,然后将值向下转换回浮点数以保留与 Windows 相同的舍入。我只是在寻找一个理由,说明当 VC++ 编译器似乎不存在精度问题时,为什么需要额外的精度。Clang/Xcode/VC++ 数学库之间也可能存在差异。我只是假设 acos(-1.0) 可能在编译器中更稳定。我在舍入模式中找不到任何差异(即使舍入不是必需的),并且 Xcode 和 Visual Studio 中的新项目也显示出相同的差异。两台机器都是英特尔的。

c++ math

1
推荐指数
1
解决办法
309
查看次数

标签 统计

c++ ×3

algorithm ×1

c ×1

exp ×1

floating-point ×1

go ×1

ieee-754 ×1

java ×1

math ×1

rounding-error ×1

rust ×1