簡體   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