gpt4 book ai didi

c++ - 右移开头为零

转载 作者:可可西里 更新时间:2023-11-01 18:04:04 27 4
gpt4 key购买 nike

我正在尝试进行一种左移,在开头添加零而不是一。例如,如果我左移 0xff,我会得到:

0xff << 3 = 11111000

但是,如果我右移它,我会得到:

0xff >> 3 = 11111111

是否有任何操作可以用来获得相当于左移的操作?即我想得到这个:

00011111

有什么建议吗?

编辑

为了回答评论,这里是我使用的代码:

int number = ~0;
number = number << 4;
std::cout << std::hex << number << std::endl;

number = ~0;
number = number >> 4;
std::cout << std::hex << number << std::endl;

输出:

fffffff0
ffffffff

因为它似乎在一般情况下应该有效,所以我很想知道为什么这个特定代码不起作用。有什么想法吗?

最佳答案

这就是 C 和二进制算法的工作原理:

如果你左移 0xff << 3 ,你得到二进制:00000000 11111111 << 3 = 00000111 11111000

如果你右移 0xff >> 3 ,你得到二进制:00000000 11111111 >> 3 = 00000000 00011111

0xff是一个(带符号的)整数,其值为正值 255 .因为它是正数,所以转换它的结果在 C 和 C++ 中都是明确定义的行为。它不会进行任何算术移位,也不会进行任何种类或定义不明确的行为。

#include <stdio.h>

int main()
{

printf("%.4X %d\n", 0xff << 3, 0xff << 3);
printf("%.4X %d\n", 0xff >> 3, 0xff >> 3);

}

输出:

07F8 2040
001F 31

所以您在程序中做了一些奇怪的事情,因为它没有按预期工作。也许您正在使用 char 变量或 C++ 字 rune 字。


来源:ISO 9899:2011 6.5.7。


问题更新后编辑

int number = ~0;给你一个等于 -1 的负数,假设是二进制补码。

number = number << 4;调用未定义的行为,因为您左移了一个负数。该程序正确地实现了未定义的行为,因为它要么做某事,要么什么都不做。它可能会打印出 fffffff0 或者它可能会打印出粉红色的大象,或者它可能会格式化硬盘。

number = number >> 4;调用实现定义的行为。在您的情况下,您的编译器会保留符号位。这被称为 arithmetic shift ,算术右移的工作方式是 MSB 填充移位前的任何位值。因此,如果您有一个负数,您将体验到该程序正在“移入一个”。

在 99% 的现实世界案例中,对有符号数使用按位运算符是没有意义的。因此,始终确保您使用的是无符号数,并且 C/C++ 中没有任何危险的隐式转换规则将它们转换为有符号数(有关危险转换的更多信息,请参阅“整数提升规则”和“通常的算术转换” ",很多关于 SO 的好信息)。

EDIT 2,C99 标准的基本原理文档 V5.10 中的一些信息:

6.5.7 Bitwise shift operators

The description of shift operators in K&R suggests that shifting by a long count should force the left operand to be widened to long before being shifted. A more intuitive practice, endorsed by the C89 Committee, is that the type of the shift count has no bearing on the type of the result.

QUIET CHANGE IN C89

Shifting by a long count no longer coerces the shifted operand to long. The C89 Committee affirmed the freedom in implementation granted by K&R in not requiring the signed right shift operation to sign extend, since such a requirement might slow down fast code and since the usefulness of sign extended shifts is marginal. (Shifting a negative two’s complement integer arithmetically right one place is not the same as dividing by two!)

关于c++ - 右移开头为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14396858/

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