问题标签 [long-double]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
33632 浏览

gcc - long double(GCC 特定)和 __float128

我正在寻找有关GCC/x86 的详细信息(更多的是出于好奇而不是因为实际问题)long double__float128

可能很少有人会需要这些(我只是,有史以来第一次,真正需要 a double),但我想知道你的工具箱里有什么以及它是关于什么的仍然是值得的(而且很有趣)。

鉴于此,请原谅我有些开放的问题:

  1. 有人可以解释这些类型的实现原理和预期用途,也可以相互比较吗?例如,它们是否因为标准允许类型而“令人尴尬的实现”,如果它们只是与 相同的精度double,或者它们打算作为一流类型,有人可能会抱怨?
  2. 或者,有人可以分享一个好的、可用的网络参考吗?谷歌搜索"long double" site:gcc.gnu.org/onlinedocs并没有给我太多真正有用的东西。
  3. 假设常见的口头禅“如果你认为你需要双精度,你可能不了解浮点数”不适用,即你真的需要比精度更高的精度float,而且不关心是 8 字节还是 16 字节的内存烧毁...是否可以合理地期望一个人也可以直接跳到long double或者__float128没有double显着的性能影响?
  4. 历史上,当值在内存和寄存器之间移动时,英特尔 CPU 的“扩展精度”特性一直是令人讨厌的意外之源。如果实际存储了 96 位,则该long double类型应消除此问题。另一方面,我知道该long double类型与 是互斥的-mfpmath=sse,因为 SSE 中没有“扩展精度”之类的东西。__float128,另一方面,在 SSE 数学上应该可以很好地工作(尽管在没有四精度指令的情况下肯定不是在 1:1 指令库上)。我的这些假设是对的吗?

(3. 和 4. 可能可以通过在分析和反汇编上花费一些工作来弄清楚,但也许其他人之前也有同样的想法并且已经完成了这项工作。)

背景(这是 TL;DR 部分):
我最初偶然发现long double是因为我正在查找DBL_MAX<float.h>顺便说LDBL_MAX一下在下一行。“哦,看,GCC 实际上有 128 位双打,不是我需要它们,但是……很酷”是我的第一个想法。惊喜,惊喜:sizeof(long double)返回 12……等等,你是说 16?

毫不奇怪,C 和 C++ 标准没有给出非常具体的类型定义。C99 (6.2.5 10) 表示的数字是C++03 状态 (3.9.1 8)double的子集,其精度至少与(这是同一件事,只是措辞不同)。基本上,标准将所有内容留给实现,与、和.long doublelong doubledoublelongintshort

维基百科说 GCC 使用“x86 处理器上的 80 位扩展精度,而不管使用的物理存储如何”

GCC 文档在同一页面上声明,由于 i386 ABI,类型的大小为 96 位,但任何选项(嗯?什么?)启用的精度不超过 80 位,还有 Pentium 和更新版本处理器希望它们对齐为 128 位数字。这是 64 位下的默认设置,可以在 32 位下手动启用,从而产生 32 位的零填充。

运行测试的时间:

使用 时long double,输出看起来有点像这样,标记的数字是恒定的,而所有其他数字最终都会随着数字越来越大而变化:

这表明它不是80 位数字。一个 80 位数字有 18 个十六进制数字。我看到 22 个十六进制数字发生了变化,这看起来更像是一个 96 位数字(24 个十六进制数字)。它也不是一个 128 位的数字,因为没有被触及,这与返回 120xdeadbeef是一致的。sizeof

的输出__int128看起来真的只是一个 128 位的数字。所有位最终都会翻转。

如文档所示,使用 32 位零填充与 128 位不-m128bit-long-double对齐。它也不使用,但确实似乎与 128 位对齐,并用值(?!) 填充。long double__int1280x7ffdd000

此外,LDBL_MAX, 似乎对+inf和 都long double有效__float128。在相同的位模式中添加或减去类似1.0E1001.0E2000到/从的数字。 到现在为止,我相信常量将包含最大的可表示数字,但事实并非如此(显然情况并非如此?)。我也不太确定一个 80 位数字如何可以想象128 位值......也许我在一天结束时太累了并且做错了什么。LDBL_MAX
foo_MAX +inf+inf

0 投票
3 回答
106350 浏览

c++ - C和C++中long double和double的区别

可能重复:
long double vs double

我是编程新手,我无法理解 C 和 C++ 中 long double 和 double 之间的区别。我试图谷歌它,但无法理解它并感到困惑。有人可以帮忙吗?

0 投票
2 回答
286 浏览

python - 两个“np.longdouble”的总和会产生很大的数值误差

早上好,

我正在从 FITS 文件中读取两个数字(表示单个数字的整数和浮点部分),将它们转换为长双精度数(在我的机器中为 128 位),然后将它们相加。

结果并不像使用 128 位浮点数所期望的那样精确。这是代码:

这是我得到的答案:

结果与我所期望的(55197.0007660185200000000195833)相差11个十进制数字(总共16个有效数字)。我希望 128 位浮点数的精度更高。我究竟做错了什么?

此结果在 Mac 机器和 Linux 32 位机器上重现(在这种情况下,dtype 为 float96,但值完全相同)

在此先感谢您的帮助!

马泰奥

0 投票
4 回答
172 浏览

c++ - 长双打的加权概率

我正在使用 C++ 中大约 2000 个元素的数组。

每个元素代表该元素被随机选择的概率。

然后,我将此数组转换为累积数组,目的是使用它来计算掷骰子时选择哪个元素。

示例数组:{1,2,3,4,5}

示例累积数组:{1,3,6,10,15}

当滚动数字 3、4 或 5 时,我希望能够在累积数组中选择 3。

增加的复杂性是我的数组由长双精度数组成。这是几个连续元素的示例:

0.96930161525189592646367317541056252139242133125662803649902343750 0.96941377254127855667142910078837303444743156433105468750000000000 0.96944321382974149711383993199831365927821025252342224121093750000 0.96946143938926617454089618153290075497352518141269683837890625000 0.96950069444055009509463721739663810694764833897352218627929687500 0.96951751803395748961766908990966840065084397792816162109375000000

这可能是用这个数据集做加权概率的一种糟糕的方法,所以我愿意接受任何关于解决这个问题的更好方法的建议。

0 投票
2 回答
376 浏览

c - 为什么“long double”类型的变量会产生荒谬的输出,而“float”和“double”类型的工作正常?

我想要下面的程序做的就是打印所有小于 30 的正数的乘积(以指数和非指数形式)。当变量product声明为 afloat或 a时它工作正常double,但当类型为 时会产生完全荒谬(否定)的结果long double。那么请回答由此引发的这两个问题:

  1. 为什么long double产生完全荒谬(甚至负面)的结果,而float变量 double的类型product产生正确的结果?

    我有这个概念,long double它只不过是 的“高容量”版本double,它本身就是float类型的“高容量”版本!

  2. 现在对于产生正确结果的类型product,即floatdouble,为什么它们以指数形式(%e)产生相同的输出,但对于非指数形式(%f)产生明显不同的输出?


product作为浮点数的输出

product双倍输出

输出product只要双倍

0 投票
4 回答
10633 浏览

c - sizeof long double 和精度不匹配?

考虑以下 C 代码:

gcc 4.8.1用under编译Ubuntu x64 13.04,它打印:

这告诉我 long double 的权重为 16 个字节,但小数点似乎只能到第 20 位。这怎么可能?16 个字节对应一个四边形,一个四边形会给我 33 到 36 个小数。

0 投票
5 回答
40945 浏览

c++ - 为什么要使用 float 而不是 double 或 double 而不是 long double?

我仍然是编程的初学者,而且我的问题总是比我们的书或互联网搜索可以回答的要多(除非我错过了什么)。因此,如果有人回答了这个问题,但我找不到它,我会提前道歉。

我知道 float 的范围比 double 更小,因此精度较低,据我所知, long double 甚至更精确(?)。所以我的问题是你为什么要首先使用一个不太精确的变量?它是否与不同的平台、不同的操作系统版本、不同的编译器有关?或者在编程中是否有特定的时刻在战略上更有利地使用浮点数而不是双/长双精度数?

谢谢大家!

0 投票
1 回答
90 浏览

c++ - 哪些编译器给出最长的 long double

我可能在这里做了一些非常愚蠢的事情,但我已经达到了 double 可以实现的极限,并且在我的编译器上(我在 mac 上使用最新的 xcode)long double 似乎并没有更好。

我在其他地方读到 long double 的长度取决于编译器,如果是这样,你们会建议我使用什么来提供最长的 long double1

0 投票
6 回答
13646 浏览

c - 如何在 C 中轻松计算 unsigned long long 的平方根?

我正在查看另一个问题(此处),有人正在寻找一种方法来获取 x86 程序集中的 64 位整数的平方根。

事实证明这很简单。解决方案是转换为浮点数,计算 sqrt,然后再转换回来。

我需要在 C 中做一些非常相似的事情,但是当我研究等价物时,我有点卡住了。我只能找到一个接受双打的 sqrt 函数。双精度数不具备存储大型 64 位整数而不引入显着舍入误差的精度。

是否有一个我可以使用的具有long doublesqrt 函数的通用数学库?

0 投票
3 回答
1514 浏览

c - 访问长双位表示

TLDR;以下代码是否调用未定义(或未指定)的行为?

在我的 x86-64 机器上,输出取决于传递给编译器的特定优化标志(gcc-4.8.0、-O0 与 -O1)。

使用-O0,我得到

使用-O1时,我得到

请注意倒数第二行中的额外 1。此外,在 memset 之后取消注释打印指令会使 1 消失。这似乎依赖于两个事实:

  1. long double 被填充,即 sizeof(long double) = 16 但只使用了 10 个字节。
  2. 对 memset 的调用可能会被优化掉
  3. long doubles 的填充位可能会在没有通知的情况下发生变化,即 value1 和 value2 上的浮点运算似乎会扰乱填充位。

我正在编译-std=c99 -Wall -Wextra -Wpedantic并且没有收到任何警告,所以我不确定这是一个严格的混叠违规情况(但很可能是)。通过-fno-strict-aliasing并没有改变任何事情。

上下文是在此处描述的 HDF5 库中发现的错误。HDF5 在计算浮点类型的本机位表示方面做了一些调整,但如果填充位不保持为零,它就会感到困惑。

所以:

  1. 这是未定义的行为吗?
  2. 这是一个严格的混叠违规吗?

谢谢。

编辑:这是 printme 的代码。我承认我只是从某个地方剪切和粘贴而没有过多关注它。如果问题出在这儿,我会脱下裤子绕过桌子。