C++ 左移a';双倍';操作数

C++ 左移a';双倍';操作数,c++,c,double,bit-shift,C++,C,Double,Bit Shift,以下函数左移双操作数: double shl(double x,unsigned long long n) { unsigned long long* p = (unsigned long long*)&x; *p += n << 52; return x; } double shl(双x,无符号长n) { 无符号长*p=(无符号长*)&x; * P++NNO,无论是C还是C++都不确定语言标准中浮点类型的表示,尽管推荐IEEE格式,并且宏(StdC

以下函数左移
操作数:

double shl(double x,unsigned long long n)
{
    unsigned long long* p = (unsigned long long*)&x;
    *p += n << 52;
    return x;
}
double shl(双x,无符号长n)
{
无符号长*p=(无符号长*)&x;

* P++N

NO,无论是C还是C++都不确定语言标准中浮点类型的表示,尽管推荐IEEE格式,并且宏(StdCdCiCIEC599O< <代码> >)可以被用来检测它是否在使用。 除了不同的表示法外,您的解决方案还存在多个问题。您已经发现了严格的别名冲突…优化器可能会将整个函数变为无操作,因为在函数开头和返回值之间没有修改任何

double
,它可以假定
x
没有更改。您可以另外还有一个溢出问题——您需要某种形式的饱和算法,它不允许将结果带入符号位

但是,您不需要处理这些问题,因为标准库已经包含了您试图编写的函数


它被命名为
ldexp
(和
ldexpf
,用于
float
)。

此代码肯定不会将双操作数向左移动。它执行某种位操作,可能是希望更改双精度数的指数

事实上,代码调用未定义的行为,因为左值是使用long-long类型编写的,然后使用double类型读取。因此,任何事情都可能发生。这是您可以获得的最不可移植的代码。

对于C++:

< C++ >不需要IEEE浮点,它甚至不需要二进制指数。

  • 绝对不是。无符号long-long可能超过64位。Double不必是64位

  • 那种双关语是不安全的


  • 我不认为标准承诺了您列出的3项中的任何一项。例如,Crossworks C可以有32bdoubles@Leeor:32位
    double
    类型不符合C标准的要求。听起来Crossworks C是一个不符合要求的实现。C中的严格别名规则与C++@KeithThompson中的不同,有趣的是,它们声称是,但您提出了一个关于以下最小大小的有效点。谢谢,我的意思是左移的等效值。您对严格别名的解释不太正确。在动态分配内存中,对象的有效类型是最后存储在其中的内容;但对于命名变量,有效类型是声明的类型;例如,yOU不能声明<代码>未签名的长long < /代码>,然后再写一个浮点,并再次读取浮点(即使对齐正确)。(这是C;C++是稍微不同的)好,我确实说过“假设代码> x* 2 ^ n < /代码>不溢出……但是除此之外,它回答我的问题到满(双)精度。谢谢。
    double
    不能小于64位,因为
    float.h
    @BenVoigt中的值有要求。如果我没记错的话,
    double
    必须大于32位,但我不认为它需要是64位。我不记得确切的细节。另外,
    x
    可能没有正确对齐
    un有符号长-长
    @KeithThompson:啊,对了。最小10位十进制数字排除了32位双精度,但最小(十进制)指数范围为+/-37,与
    浮点
    相同,因此它的总位数不必像IEEE754双精度那样多。