以下函数移位 - 左double
操作数:
double shl(double x,unsigned long long n)
{
unsigned long long* p = (unsigned long long*)&x;
*p += n << 52;
return x;
}
此功能是否保证在所有平台上都能正常工作?
您可以假设x
和n
的有效组合(即x*2^n
不会溢出)。
换句话说,我问的是语言标准是否规定了以下内容:
double
类型的指数位为52,53,54,55,56,57,58,59,60,61,62
double
的位大小等于unsigned long long
的位大小等于64
double
和unsigned long long
的严格别名规则未被破坏
如果C和C ++的答案不同,那么我想知道它们中的每一个。
答案 0 :(得分:8)
不,C和C ++都没有规定语言标准中浮点类型的表示,尽管建议使用IEEE格式,并且应该可以使用宏(__STDC_IEC_559__
)来检测它是否在使用中
除了不同的表示外,您的解决方案还存在多个问题。您已经发现了严格的别名违规...优化器可能会将您的整个函数转换为无操作,因为在函数的开头和返回值之间没有修改double
,它可以假设为{{1}没有改变。你可能还有一个溢出问题 - 你需要某种形式的饱和算法,它不允许结果进入符号位。
但是,您不需要弄乱其中任何一个,因为标准库已经包含您尝试编写的功能。
它的名称为x
(ldexp
为ldexpf
。
答案 1 :(得分:2)
对于C ++:
没有。 C ++不需要IEEE浮点。它甚至不需要二进制指数。
绝对不是。无符号长long可能超过64位。 Double不必是64位。
那种类型的惩罚是不安全的。
答案 2 :(得分:1)
此代码绝对不会将双操作数向左移位。它做了某种位操作,可能希望改变双数的指数。
实际上,代码调用未定义的行为,因为使用long long类型写入左值,然后使用double类型读取。结果,任何事情都可能发生。这是你可以获得的最不可移植的代码。