[英]Fixed point arithmetic long long int representation issue in C
我正在努力实现在其 integer 部分中设置值 1 的有符号 long long int 变量。 查看带有有符号 long int 变量的 16.16 实现,它的工作原理如下:
static signed long int varInit = 1 << 16; /* alternatively: 65536 */
unsigned short int integer_part,fractional_part;
fractional_part = ((unsigned short int *) &varInit)[0];
integer_part = ((unsigned short int *) &varInit)[1];
这导致以下表示: 0001.0000
不幸的是,我无法让它在 32.32 表示中工作:
static signed long long int varInit = 1 << 32;
unsigned long int integer_part,fractional_part;
fractional_part = ((unsigned long int *) &varInit)[0];
integer_part = ((unsigned long int *) &varInit)[1];
我收到以下 gcc 警告: warning: left shift count >= width of type
我怎么了?
我正在尝试获得以下表示: 00000001.00000000
这个表达
1 << 32
具有未定义的行为,因为操作数的类型为int
并且结果的类型也为int
。
来自 C 标准(6.5.7 位移位运算符)
3 对每个操作数执行 integer 提升。 结果的类型是提升的左操作数的类型。 如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义
至少使用表达式
1LL << 32
我试图得到以下表示:00000001.00000000(十六进制)。
不要使用int, long, long long
,因为它们的宽度因平台而异。 使用(u)int32_t, (u)int64_t
以保持一致性。
1 << 32
是int
数学 - 通常太窄而无法移动 32 位。 要形成二进制值 1_00000000_00000000_00000000_00000000,请使用(u)int64_t
数学。
不要假设宽 integer 类型的字节布局具有像fractional_part = ((unsigned short int *) &varInit)[0];
. 使用数学并让编译器发出最佳代码。
#include <stdint.h>
static int64_t varInit = ((int64_t)1) << 32;
// or
static int64_t varInit = INT64_C(1) << 32;
int32_t integer_part = varInit >> 32;
uint32_t fractional_part = varInit & 0xFFFFFFFFu;
// or
int32_t integer_part = varInit / 0x100000000;
uint32_t fractional_part = varInit % 0x100000000u;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.