在 Windows 上使用长双打

Posted

技术标签:

【中文标题】在 Windows 上使用长双打【英文标题】:Using long doubles on windows 【发布时间】:2014-11-29 23:28:21 【问题描述】:

我有一个应用程序,由于在进行双精度数学运算时出现灾难性截断错误,我绝对必须使用 long double 数据类型。我的测试程序快疯了,因为在 Windows 上使用 Visual Studio 的 long double 只是 double 的别名,而在 linux 和 OSX 上,long double 是真正的 long double,名义上的精度为 1e-19。

在 mingw(GCC 的 windows 端口)上是我感到困惑的地方。 Mingw 声称 LDBL_EPSILON 的精度为 1e-19,但 googleing 表明 mingw 使用的 c 运行时实际上只是 microsoft c 运行时,它不支持真正的长双精度。任何人都可以在这里解释一下吗?

编辑:问题的症结在于:在mingw上,如果我调用数学函数log(long double x),这只是log(double x)的别名吗?在这两种情况下,我如何编写自己的脚本来测试这种行为和/或测试它?

【问题讨论】:

基本算术通常是语言的一部分,而不是C runtime 的一部分,C runtime 主要是指 C 标准库的实现以及信号处理、内存分配等运行时设施。 但是数学函数不是 c 运行时的一部分吗?例如日志(长双)?如果我弄错了,请原谅我的无知 一个常见的新手错误是减去两个大致相等的数字。无论如何,先看看算法是个好主意。 是的,我不是新手,算法已经过大量优化以避免截断等。 ergo -> 我真的需要 long double 【参考方案1】:

以下代码

#include <iostream>
#include <cmath>

int main(void)

    long double y = 2.0L;

    std::cout << sizeof(y) << std::endl;

    long double q = sqrt(y);

    std::cout << q << std::endl;

    return 0;

产生的输出 16 1.41421,到目前为止一切顺利

运行它抛出预处理器(-E 选项)并发现调用了内部但不同于双 sqrt() 函数

using ::sqrt;

inline constexpr float sqrt(float __x)
 return __builtin_sqrtf(__x); 

inline constexpr long double sqrt(long double __x)
 return __builtin_sqrtl(__x); 

log()、sin() 也一样,随便你说吧

因此,我相信 MinGW 在算术和 math.functions 中支持 long double 格式,并且这种支持是内置的,而不是基于 libquadmath

【讨论】:

【参考方案2】:

刚刚尝试使用 MinGW(来自 nuwen 的 MinGW 发行版,gcc/g++ 4.9.1,64 位)

以下节目

#include <iostream>

int main(void)

    double x = 1.0;
    long double y = 2.0L;

    std::cout << sizeof(x) << std::endl;
    std::cout << sizeof(y) << std::endl;

生产 8 16

我猜,支持 long double 并且不同于标准 double,因此 您的计算可能会产生预期的结果

我听说由于使用 MS 旧运行时,在 Windows 上打印长双打存在问题。 您可能必须使用强制转换或滚动您自己的输出例程

【讨论】:

在 mingw 中修复了 long doubles 的打印,您只需要执行 %Lg 而不是 %g 即可进行一般浮点输出。这是个好消息,非常感谢。 如果在 Windows 上,GCC 将“long double”映射到 libquadmath 中的 __float128 类型,我不会感到惊讶。我建议检查 libquadmath 文档,该库具有所有数学函数和与字符串的转换。 刚刚检查了上面提到的 MinGW 4.9.1 发行版,它确实安装了 libquadmath.a 四边形数学非常慢,而且由于性能也很重要,我需要长双精度,而不是四边形 如果我没记错的话,quad math 是软件模拟的,而 long doubles 可以在某些 SSE 库中使用

以上是关于在 Windows 上使用长双打的主要内容,如果未能解决你的问题,请参考以下文章

如何在Windows和Linux上确保相同的浮点行为?

如何将长双打与 qsort 以及关于 NaN 进行比较?

在Windows上使用 Python 安装+ win10启用长路径

无法使用 Python 在 Windows 上找到具有长名称的文件

OpenCL:处理双打错误

不能在双打上使用模数?