长双精度(GCC特定)和浮点数128
我正在GCC/x86中查找有关长双精度(GCC特定)和浮点数128,gcc,long-double,Gcc,Long Double,我正在GCC/x86中查找有关长双精度和浮点128的详细信息(更多是出于好奇,而不是因为实际问题) 可能很少有人会需要这些(我只是第一次真正需要一个双倍的),但我想知道你的工具箱里有什么以及它是关于什么的仍然是值得的(而且很有趣) 有鉴于此,请原谅我有些开放性的问题: 有人能解释一下这些类型的实现原理和预期用途吗?例如,它们是“尴尬的实现”,因为标准允许使用该类型,如果它们的精度与double相同,有人可能会抱怨,还是打算作为一级类型 或者,是否有人有一个好的、可用的web引用可以共享?谷歌搜索
长双精度
和浮点128
的详细信息(更多是出于好奇,而不是因为实际问题)
可能很少有人会需要这些(我只是第一次真正需要一个双倍的),但我想知道你的工具箱里有什么以及它是关于什么的仍然是值得的(而且很有趣)
有鉴于此,请原谅我有些开放性的问题:
有人能解释一下这些类型的实现原理和预期用途吗?例如,它们是“尴尬的实现”,因为标准允许使用该类型,如果它们的精度与double
相同,有人可能会抱怨,还是打算作为一级类型李>
或者,是否有人有一个好的、可用的web引用可以共享?谷歌搜索“长双”网站:gcc.gnu.org/onlinedocs
并没有给我多少真正有用的信息
假设常见的咒语“如果你认为你需要双精度,你可能不理解浮点”不适用,也就是说,你真的需要更多的精度而不仅仅是float
,你也不在乎8字节还是16字节的内存被烧掉。。。我们是否有理由期望在没有显著性能影响的情况下跳转到长双精度
或\uuuu128
而不是双精度
当值在内存和寄存器之间移动时,Intel CPU的“扩展精度”功能历来是令人不快的意外之源。如果实际存储了96位,则长双精度
类型应该可以消除此问题。另一方面,我了解到长双精度
类型与-mfpmath=sse
是相互排斥的,因为在sse中没有“扩展精度”这样的东西<另一方面,code>\uuu float128应该可以很好地与SSE math配合使用(尽管在没有四精度指令的情况下,肯定不会以1:1指令为基础)。我的这些假设正确吗
(3.和4.可能可以通过一些分析和分解工作来解决,但可能其他人以前也有同样的想法,并且已经完成了这项工作。)
太长了,读不下去了(背景是TL,DR部分):>BR>
起初,我无意中发现了长双精度,因为我在
中查找DBL\u MAX
,顺便说一下LDBL\u MAX
在下一行。“哦,看,GCC实际上有128位的双倍,不是我需要它们,而是…酷”是我的第一个想法。惊喜,惊喜:sizeof(长双精度)
返回12。。。等等,你是说16岁
<> P. C和C++标准并不意外地给出了一个非常具体的定义。C99(6.2.5 10)说double
的数字是long double
的一个子集,而C++03(3.9.1 8)说long double
至少具有与double
相同的精度(这是同样的事情,只是措辞不同)。基本上,这些标准将一切都留给实现,方式与long
、int
和short
相同
维基百科说,GCC“在x86处理器上使用80位扩展精度,而不管使用的是什么物理存储”
GCC文档在同一页上声明,由于i386 ABI,类型的大小为96位,但任何选项都不能启用超过80位的精度(嗯?什么?),奔腾和更新的处理器也希望将其对齐为128位数字。这是64位下的默认值,可以在32位下手动启用,从而产生32位的零填充
运行测试的时间:
#include <stdio.h>
#include <cfloat>
int main()
{
#ifdef USE_FLOAT128
typedef __float128 long_double_t;
#else
typedef long double long_double_t;
#endif
long_double_t ld;
int* i = (int*) &ld;
i[0] = i[1] = i[2] = i[3] = 0xdeadbeef;
for(ld = 0.0000000000000001; ld < LDBL_MAX; ld *= 1.0000001)
printf("%08x-%08x-%08x-%08x\r", i[0], i[1], i[2], i[3]);
return 0;
}
这表明它不是一个80位的数字。80位数字有18个十六进制数字。我看到22个十六进制数字在变化,看起来更像96位数字(24个十六进制数字)。它也不是128位数字,因为未触及0xdeadbeef
,这与sizeof
返回12一致
\uuu int128
的输出看起来实际上只是一个128位的数字。所有的比特最终都会翻转
如文档所示,使用-m128位长双精度
编译时,不会将长双精度
与32位零填充对齐到128位。它也不使用\uuu int128
,但实际上似乎与128位对齐,用值0x7ffdd000
(?!)填充
此外,LDBL\u MAX
似乎可以作为+inf
用于长双精度
和\u浮点128
。将像1.0E100
或1.0E2000
这样的数字与LDBL_MAX
相加或相减会产生相同的位模式。到目前为止,我认为
foo_MAX
常量包含的最大可表示数字不是+inf
(显然不是这样的?)。我也不太清楚,对于128位的值,80位的数字如何可以想象为+inf
。。。也许一天结束时我太累了,做了些错事。广告1
这些类型设计用于处理具有巨大动态范围的数字。长双精度在x87 FPU中以本机方式实现。我怀疑在现代x86上,128b double将以软件模式实现,因为没有硬件在硬件中进行计算
有趣的是,在一行中执行许多浮点运算是很常见的,中间结果实际上并不存储在声明的变量中,而是存储在FPU寄存器中,充分利用了全精度。这就是为什么比较:
double x = sin(0); if (x == sin(0)) printf("Equal!");
不安全,无法保证工作(无额外开关)
公元3年
速度会受到影响,具体取决于您使用的精度。Y
double x = sin(0); if (x == sin(0)) printf("Equal!");
void
set_fpu (unsigned int mode)
{
asm ("fldcw %0" : : "m" (*&mode));
}