[英]Converting 32-bit integer value to unsigned 16-bit integer
C標准怎么說:
uint32_t a = 0x11223344;
uint16_t b = a;
打印時,我得到0x3344,這是有道理的。 所以這必須是合法且正確的行為嗎?
什么C標准說向下癤這樣的事實: 0x11223344
轉換為uint16_t
通過計算值模2 16,這是0x3344
。
但是,它到達那里的過程有幾個步驟:
uint16_t b = a;
是帶有初始化的聲明,將在C 2018 6.7.9 11中進行討論:
標量的初始化程序應為單個表達式,可以選擇用大括號括起來。 對象的初始值是表達式的初始值(轉換后); 采用與簡單賦值相同的類型約束和轉換,將標量的類型作為其聲明類型的非限定版本。
因此,適用於簡單分配的規則。 這些在6.5.16.1 2中進行了討論:
在簡單賦值 ( = )中,將右操作數的值轉換為賦值表達式的類型,並替換存儲在由左操作數指定的對象中的值。
“賦值表達式的類型”是左操作數的類型,按6.5.16 3:
賦值表達式的類型是左值轉換后左操作數將具有的類型。
(在這種情況下,左值轉換沒有什么特別的;對象uint16_t b
會簡單地成為uint16_t
值,因此類型為uint16_t
。)
根據7.20.1.1 1, uint16_t
的類型當然是一個無符號的16位整數:
_t designates an unsigned integer type with width N and no padding bits. 類型定義名稱uint _t指定寬度為N並且沒有填充位的無符號整數類型。
請注意,作為一個無符號的16位整數,其最大值為65535,比最大值65655(2 16 )大一。 這與最后一步有關,即從右操作數到uint16_t
的轉換,這在6.3.1.3 1和2中進行了討論:
將具有整數類型的值轉換為_Bool以外的其他整數類型時,如果該值可以用新類型表示,則該值不變。
否則,如果新類型是無符號的,則通過重復添加或減去比新類型中可以表示的最大值多一個值來轉換該值,直到該值在新類型的范圍內為止。
當我們從0x11223344
0x1122
減去65536( 0x10000
)時,結果是0x3344
,可以用uint16_t
表示,這就是轉換的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.