将32位整数值转换为无符号16位整数 [英] Converting 32-bit integer value to unsigned 16-bit integer

查看:534
本文介绍了将32位整数值转换为无符号16位整数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C标准怎么说?

uint32_t a = 0x11223344;
uint16_t b = a;

打印时,我得到0x3344,这很有意义;所以这必须是合法且正确的行为吗?

When printed, I am getting 0x3344, which makes sense; so this must be legal and correct behaviour?

推荐答案

C标准所说的内容归结为以下事实:通过计算值取模2 16 ,即 0x3344 .

What the C standard says boils down to the fact that 0x11223344 is converted to uint16_t by calculating the value modulo 216, which is 0x3344.

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

However, the process by which it gets there has several steps:

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

uint16_t b = a; is a declaration with an initialization, which is discussed in 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中讨论:

So the rules for simple assignment apply. These are discussed in 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 the assignment expression" is the type of the left operand, per 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 .)

(In this case, there is nothing remarkable about lvalue conversion; the object uint16_t b would simply become a uint16_t value, so the type is uint16_t.)

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

The type of uint16_t is, of course, an unsigned 16-bit integer, per 7.20.1.1 1:

typedef名称 uint N _t 表示宽度为 N 且没有填充位的无符号整数类型.

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

请注意,它是一个无符号的16位整数,最大值为65535,而最大值为65536(2 16 ).这与最后一步有关,即从右操作数到 uint16_t 的转换,这在6.3.1.3 1和2中进行了讨论:

Note that, as an unsigned 16-bit integer, its maximum value is 65535, and one more than that is 65536 (216). This is relevant for the final step, the conversion from the right operand to uint16_t, which is discussed in 6.3.1.3 1 and 2:

将整数类型的值转换为 _Bool 以外的其他整数类型时,如果该值可以用新类型表示,则该值不变.

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.

当我们从 0x11223344 0x1122 次数中减去65536( 0x10000 )时,结果为 0x3344 ,这可以用 uint16_t 表示,这就是转换的结果.

When we subtract 65536 (0x10000) from 0x11223344 0x1122 times, the result is 0x3344, which can be represented by a uint16_t, so that is the result of the conversion.

这篇关于将32位整数值转换为无符号16位整数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆