gpt4 book ai didi

c - 如何在保留原始位模式的同时将 (int) 转换为 (unsigned int)?

转载 作者:太空狗 更新时间:2023-10-29 17:22:39 27 4
gpt4 key购买 nike

假设我们定义:

short x = -1;
unsigned short y = (unsigned short) x;

根据C99标准:

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. (ISO/IEC 9899:1999 6.3.1.3/2)

因此,假设两个字节用于short 和二进制补码表示,这两个整数的位模式是:

x = 1111 1111 1111 1111 (value of -1),
y = 1111 1111 1111 1111 (value of 65535).

由于-1不在unsigned short的取值范围内,而unsigned short可以表示的最大值为65535,所以将65536加到- 1得到65535,在unsigned short范围内。因此,在从 intunsigned 的转换中,位保持不变,尽管表示的值发生了变化。

但是,该标准还规定表示可以是二进制补码、一个补码或符号和大小。 “其中哪些应用是实现定义的,...”(ISO/IEC 9899:1999 6.2.6.2/2)

在使用补码的系统上,x 在转换之前将表示为 1111 1111 1111 1110,在使用符号和幅度表示的系统上,x 将表示为 1000 0000 0000 0001。这两个位模式都表示值 -1,不在 unsigned short 的值范围内,因此在每种情况下都会将 65536 添加到 -1 以将值纳入范围内。转换后,这两个位模式都将是 1111 1111 1111 1111

因此,在从 intunsigned int 的转换中保留位模式取决于实现。

在保留位模式的同时将 int 转换为 unsigned int 的能力似乎是对负数进行移位操作的便捷工具,并且我已经看到它被提倡为一种技术。但这种技术似乎并不能保证按标准工作。

我在这里阅读的标准是否正确,或者我是否误解了从有符号类型到无符号类型的转换细节?二进制补码实现是否足够普遍,以至于从 int 转换为 unsigned 时保留位模式的假设是合理的?如果不是,是否有更好的方法在从 intunsigned int 的转换下保留位模式?

编辑

我最初的目标是找到一种将 int 转换为 unsigned int 的方法,以保留位模式。我在想从 intintN_t 的转换可以帮助实现这一点:

unsigned short y = (unsigned short)(int16_t) x;

但是这个想法当然是错误的!充其量这只会在转换为 unsigned 之前强制执行二进制补码表示,因此最终的位模式将是二进制补码。我很想删除这个问题,但我仍然对从 int 转换为 unsigned int 保留位模式的方法感兴趣,@Leushenko 提供了一个非常简洁的方法使用 union 解决这个问题。但是,我更改了问题的标题以反射(reflect)原意,并编辑了结束问题。

最佳答案

如果您特别想保留位模式高于其他任何东西,这似乎是通过 union 而不是强制转换运算符的绝佳用例:

union S2US { short from; unsigned short to; };

...
short value = ...
unsigned short bits = (union S2US){ .from = value }.to;
...

footnote 95 中所述(根据第 6.5.2.3 节),“如果用于读取 union 对象内容的成员与最后用于在对象中存储值的成员不同,则重新解释该值的对象表示的适当部分作为 6.2.6 中描述的新类型的对象表示。重新解释不涉及以任何方式操作数据,因此根据成员类型,提取的值不能保证与插入的值有任何直接的算术关系,但保证具有完全相同的内存表示。

由于整数类型的有符号和无符号版本的大小相同(6.2.5 p6),并且 union 的所有成员必须在同一位置开始存储(6.7.2.1 p16),因此 union 仅包含宽度相同的有符号和无符号整数必须在任一方向上忠实地从一个位复制到另一个位。

关于c - 如何在保留原始位模式的同时将 (int) 转换为 (unsigned int)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40440468/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com