使用gcc进行编译时,PowerPC上的长双精度出错

时间:2018-01-31 23:28:25

标签: c++ gcc floating-point powerpc long-double

当我为long double变量类型赋值时,我遇到了一个奇怪的错误。 (PowerPC体系结构,gcc v4.9.2)

具体做法是:

const constexpr long double DEGREE_TO_RAD = 0.0174532925199432954743716805978693;
const constexpr long double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;

似乎导致以下编译器错误:

error: ‘(1.0e+0l / 1.74532925199432954743716805978693e-2l)’ is not a constant expression
 const constexpr long double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;

我不是C ++专家;这是我试图专门为我的开发机器环境构建的软件。但是,我的研究让我想到了以下几点:

  

在某些PowerPC和SPARCv9机器上,long double实现为双倍算术,其中long double值被视为两个双精度值的精确总和,至少给出106位精度;对于这种格式,long double类型不符合IEEE浮点标准。否则,long double只是double的同义词(双精度)。 [wiki]

这让我相信构建失败是由于我的架构与标准x86有不同的解释。在源中将long double更改为double可以使编译成功。这是巧合吗?为什么g ++会在这个实例中抛出它?

1 个答案:

答案 0 :(得分:0)

这是一个错误(或多个错误)。可以从GCC的错误消息中看到第一个问题

               ↓                                        ↓
error: ‘(1.0e+0l / 1.74532925199432954743716805978693e-2l)’ is not a constant expression
const constexpr long double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;

源文件中没有L后缀,但是以某种方式出现在错误输出中。如果我通过添加后缀来更正代码,则由于相同的原因它仍然会失败。我没有用于PowerPC的GCC的较新版本,所以我无法验证这一点,但是错误发生在GCC 4.8.5 and 6.3.0 and even AT12.0 (which was based on GCC) on Compiler Explorer

Indeed PowerPC默认将double-double arithmetic用于long double,但是浮点格式只是对用户透明的内部实现细节。它应该影响正确代码的编译。大多数嵌入式系统没有浮点支持,并且大多数当前平台都没有用于128位long double的硬件。他们都使用软件进行这些操作,但是浮点代码仍然可以很好地进行编译。因此,无论采用哪种格式,都应编译有效的代码,然后Clang for PowerPC does compile your snippet

如果我specify -mabi=ieeelongdouble,它们确实可以工作。在这里,您还可以清楚地看到使用和不使用后缀L的区别,因为如果没有后缀,则文字是double,在转换为{{1之前,将被截断为double精度。 }},这意味着您将失去双精度以外的所有数字。请记住,如果您不使用long double

,请始终在浮点类型中使用正确的后缀
double

使用other platformsIEEE-754 quadruple-precision floating-point format常量是相同的