什么是x86-64长两倍?

有人告诉我说:

在x86-64下,FPalgorithm是用SSE完成的,因此long double是64位。

但是在x86-64 ABI中它说:

C type | sizeof | alignment | AMD64 Architecture long double | 16 | 16 | 80-bit extended (IEEE-754) 

请参阅: amd64-abi.pdf

和gcc说sizeof(long double)是16,并给FLT_DBL = 1.79769e+308FLT_LDBL = 1.18973e+4932

所以我很困惑, long double 64比特怎么样? 我认为这是一个80位的代表。

Solutions Collecting From Web of "什么是x86-64长两倍?"

在x86-64下,FP算法是用SSE完成的,因此long double是64位。

通常发生在x86-64(保证SSE指令的存在)的情况下,但是程序仍然可以使用x87,编译器在使用long double时可以使用x87。

你可以通过在Linux上用g++编译这样的程序来确认:

 #include <iostream> #include <cstdlib> #include <ctime> int main() { std::srand(std::time(NULL)); float f1=rand(), f2=rand(); double d1=rand(), d2=rand(); long double l1=rand(), l2=rand(); std::cout<<f1*f2<<" "<<d1*d2<<" "<<l1*l2<<std::endl; return 0; } 

在汇编输出中,我发现mulsd xmm1, xmm0double产品, mulss xmm0, xmm2float产品(两个SSE指令),但是fmulp st(1), st (x87指令)是long double产品。

所以,经过确认,编译器可以使用SSE,但仍然允许通过旧的x87指令集进行80位精度计算。


请注意,这是编译器特定的 – 一些编译器(例如VC ++)总是忽略80位精度类型,并将long double作为long double的同义词。

另一方面,由于x86-64 System V ABI(在Linux上采用)要求long double是80位,因此编译器使用所有可用的精度类型执行计算的唯一方法是使用x87指令。

AMD ABI实际上不能强制C型long double类型,因为它没有管辖权/权力这样做。 每个C实现都可以根据C标准(如果C实现符合标准)自行规定类型是什么类型,并且每个C实现可以选择是否符合AMD ABI。

这意味着你不能简单地问“什么是x86-64上的long double ?”你必须问在特定的C实现中什么是long double 。 这意味着指定一个特定的C编译器,版本和用于编译的开关。 (编译器可能有一个开关,其中一个设置使64位二进制IEEE 754浮点对象long double ,另一个设置使80位Intel浮点对象long double从技术上讲,编译器,版本和交换机是一个独特的C实现。)

实现long double精度的编译器作为64位二进制IEEE-754浮点对象只是简单地将它们传递给AMD ABI调用的double精度; 它从来没有像ABI所说的那样通过它们long double 。 在这样做的时候,编译器的这个方面只能和其他类似的处理long double软件兼容。

SSE计算是双精度的,中间表示是64位。

正如你所指出的那样,这还不算long double 。 计算后,64位的值只写入长整数。