[英]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.