繁体   English   中英

C 中的定点算术 long long int 表示问题

[英]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 << 32int数学 - 通常太窄而无法移动 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM