And*_*zos 8 c linux floating-point x86-64 ieee-754
有人告诉我:
在x86-64下,FP算法使用SSE完成,因此long double是64位.
但是在x86-64 ABI中它说:
C type | sizeof | alignment | AMD64 Architecture
long double | 16 | 16 | 80-bit extended (IEEE-754)
Run Code Online (Sandbox Code Playgroud)
和gcc说sizeof(long double)是16并给出FLT_DBL= 1.79769e+308和FLT_LDBL = 1.18973e+4932
所以我很困惑,long double64位是怎么回事?我认为这是一个80位的表示.
Mat*_*lia 10
在x86-64下,FP算法使用SSE完成,因此long double是64位.
这通常发生在x86-64(保证存在SSE指令)的情况下,但程序仍然可以自由使用x87,编译器在使用时可以使用x87 long double.
您可以通过g++在Linux上编译这样的程序来确认这一点:
#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;
}
Run Code Online (Sandbox Code Playgroud)
在装配输出,我找到mulsd xmm1, xmm0了double产品和mulss xmm0, xmm2对float产品(包括SSE指令),但fmulp st(1), st(的x87指令)的long double产品.
因此,经过验证,编译器尽可能使用SSE,但仍允许通过旧的x87指令集进行80位精度计算.
请注意,这是特定于编译器的 - 一些编译器(例如VC++)总是忽略80位精度类型,并且只是long double作为它的同义词double.
另一方面,由于x86-64 System V ABI(在Linux上采用)强制要求long double为80位,因此编译器使用该类型的所有可用精度执行计算的唯一方法是使用x87指令.
AMD ABI 实际上无法强制规定 Clong double类型是什么,因为它没有这样做的管辖权/权限。每个 C 实现都可以根据 C 标准(如果 C 实现符合标准)制定自己的类型规范,并且每个 C 实现可以选择是否符合 AMD ABI。
这意味着您不能简单地询问 \xe2\x80\x9c x86-64 上有什么?\xe2\x80\x9d 您必须询问特定 C 实现中的long double内容。long double这意味着指定特定的 C 编译器、版本和用于编译的开关。(编译器可能有一个开关,其中一个设置生成long double64 位二进制 IEEE 754 浮点对象,另一设置生成long double80 位 Intel 浮点对象。从技术上讲,编译器、版本和开关的每种不同组合是一个独特的 C 实现。)
一个编译器实现long double为 64 位二进制 IEEE-754 浮点对象的编译器只是将它们作为 AMD ABI 调用的对象进行传递double;它从来没有像 ABI 所说的那样传递它们long double。这样做时,编译器的这一方面将仅与处理类似的其他软件兼容long double。
| 归档时间: |
|
| 查看次数: |
6171 次 |
| 最近记录: |