在 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上使用 Python 安装+ win10启用长路径