将 32 位整数值转换为无符号 16 位整数

标签 c types type-conversion integer unsigned-integer

C 标准说了什么:

uint32_t a = 0x11223344;
uint16_t b = a;

打印时,我得到 0x3344,这是有道理的;所以这一定是合法和正确的行为?

最佳答案

C 标准所说的归结为 0x11223344 通过计算模 216 的值转换为 uint16_t,即0x3344

但是,它到达那里的过程有几个步骤:

uint16_t b = a;是带有初始化的声明,在C 2018 6.7.9 11中讨论:

The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.

因此适用简单赋值规则。这些在 6.5.16.1 2 中讨论:

In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.

“赋值表达式的类型”是左操作数的类型,根据 6.5.16 3:

The type of an assignment expression is the type the left operand would have after lvalue conversion.

(在这种情况下,左值转换没有什么特别之处;对象 uint16_t b 只会变成一个 uint16_t 值,所以类型是 uint16_t.)

根据 7.20.1.1 1,uint16_t 的类型当然是一个无符号的 16 位整数:

The typedef name uintN_t designates an unsigned integer type with width N and no padding bits.

请注意,作为一个无符号的 16 位整数,其最大值为 65535,再多一则为 65536(216)。这与最后一步有关,即从右操作数到 uint16_t 的转换,这在 6.3.1.3 1 和 2 中讨论:

When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

当我们将0x112233440x1122次减去65536(0x10000),结果为0x3344,可以由 uint16_t 表示,因此这是转换的结果。

关于将 32 位整数值转换为无符号 16 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54029050/

相关文章:

c - 64位架构下的C问题: pthread_kill()

c++ - 如果 : char x = short y in c++ 会发生什么

go - 列出给定导入路径的所有导入类型

ios - 从 NSDictionary Swift 设置枚举

c - 数字后的后缀 L 是否总是与在数字前放置带有 "long"的括号具有相同的效果?

java - 在 Android 中将 List<List<String>> 转换为 ArrayList<String>

mysql - 在 MySQL 中将存储的 md5 字符串转换为十进制值

c - 我应该明确定义我的枚举常量的值吗

c - 在 C 中创建 double 并将它们插入排序数组的循环

c - 处理 C 中的指针参数