bash shell位移产生不同的数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18898715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:37:45  来源:igfitidea点击:

shell bit shifting producing different numbers

linuxbashshellembedded

提问by ArmenB

in my local machines bash when I run:

当我运行时,在我的本地机器 bash 中:

echo $((192 << 24))
3221225472

but on my embedded targets busy box SHELL I get something else:

但是在我的嵌入式目标繁忙的盒子 SHELL 上,我得到了别的东西:

echo $((192 << 24))
-1073741824

it works when I left shift by a smaller number though. The embedded device is 64bit, where my local host is 32 bit.

不过,当我左移较小的数字时,它会起作用。嵌入式设备是 64 位,我的本地主机是 32 位。

Just to be clear, on the 32bit machine, the value is positive, on the 64 bit machine it's negative.

需要明确的是,在 32 位机器上,该值是正数,在 64 位机器上它是负数。

EDIT: This is on the embedded device which is 64 bit machine with SHELL. It doesn't happen when left shifting by 23.

编辑:这是在带有 SHELL 的 64 位机器的嵌入式设备上。左移 23 时不会发生这种情况。

echo $((192 << 23))
1610612736
echo $((192 << 24))
-1073741824

On the local host, which is a 32 machine with BASH:

在本地主机上,这是一台带有 BASH32 台机器

echo $((192 << 55))
6917529027641081856
echo $((192 << 56))
-4611686018427387904

采纳答案by loreb

POSIX (here) says "Only signed long integer arithmetic is required", and in C a long is at least 32 bits; that being said, some shells explicitly choose a fixed width, eg mksh uses 32 bits arithmetic, and peeking at the busybox' source (math.h) it seems like they only use 64 bits is ENABLE_SH_MATH_SUPPORT_64 is #define'd, regardless of whether the underlying system is 32/64 bits. If anyone knows better, speak up!

POSIX(此处)表示“只需要有符号长整数算术”,并且在 C 中 long 至少为 32 位;话虽如此,一些 shell 明确选择了一个固定的宽度,例如 mksh 使用 32 位算术,并且查看 busybox 的源代码 (math.h) 似乎他们只使用 64 位是 ENABLE_SH_MATH_SUPPORT_64 是 #define'd,无论是否底层系统是 32/64 位。如果有人知道更好,请说出来!

回答by Dan

The binary representation of 192is 11000000. When you shift it left 24 places, the only two bits which are set are the two most significant bits - the representation is 11000000 00000000 00000000 00000000. When a 32 bit system sees the most significant bit set, it interprets it as a negative number in "two's complement" format. For a 64 bit system, the most significant bit is still zero, so it is interpreted as a positive number.

的二进制表示19211000000。当您将其左移 24 位时,唯一设置的两位是两个最高有效位 - 表示为11000000 00000000 00000000 00000000. 当 32 位系统看到最高有效位集时,它会将其解释为“二进制补码”格式的负数。对于 64 位系统,最高有效位仍然为零,因此它被解释为正数。

This is simply an integer overflow on the 32 bit machine. You could expect the same behavior in C or any other language when using 32 vs 64 bit signed integer types.

这只是 32 位机器上的整数溢出。在使用 32 位与 64 位有符号整数类型时,您可以期望在 C 或任何其他语言中具有相同的行为。

回答by pepeR0ni

Got the same on on my native embedded android shell but after starting busybox shell it works correctly.

在我的本机嵌入式 android shell 上得到相同的结果,但在启动 busybox shell 后它可以正常工作。

# echo $((192 << 23))
1610612736
# echo $((192 << 23))
1610612736
# echo $((192 << 24))
-1073741824

# busybox sh
/ # echo $((192 << 23))
1610612736
/ # echo $((192 << 24))
3221225472
/ # busybox

using BusyBox v1.19.3

使用 BusyBox v1.19.3

回答by konsolebox

Well it simply because of the number of bits the number is represented. 192 (0xc0) when shifted becomes 0xc0000000. On a 32 bit machine, it's already a negative number whereas on a 64bit machine, it's still on the range of a positive number.

好吧,这仅仅是因为数字表示的位数。192 (0xc0) 移位时变为 0xc0000000。在 32 位机器上,它已经是一个负数,而在 64 位机器上,它仍然在正数的范围内。

回答by Digital Trauma

I think you almost answered your own question - the shell in the 32bit machine presumably uses 32bit signed integers for this kind of arithmetic, whereas the shell in the 64bit machine presumably uses 64bit signed integers. With 32bit signed integers, the max possible value is 2^31, so 3221225472 would result in an overflow.

我想你几乎回答了你自己的问题 - 32 位机器中的 shell 大概使用 32 位有符号整数进行这种算术,而 64 位机器中的外壳大概使用 64 位有符号整数。对于 32 位有符号整数,最大可能值为 2^31,因此 3221225472 会导致溢出。

回答by devnull

It's apparent that the result is overflowing on your embedded device. Some calculations based on your findings seem to substantiate the hypothesis:

很明显,结果在您的嵌入式设备上溢出。基于你的发现的一些计算似乎证实了这个假设

$ echo 3221225472 - 1073741824 | bc -l
2147483648

$ echo 2^31 | bc -l
2147483648

If you try with more on your local machine, you'd figure that it'd overflow too!

如果您在本地机器上尝试更多,您会发现它也会溢出!

$ echo $((192 << 56))
-4611686018427387904

EDIT: As you've commentedthat you're Busybox 1.13.2, there's a chance that you're running into thisissue. Upgrading might help!

编辑:正如您所评论的,您是 Busybox 1.13.2,您可能会遇到问题。升级可能会有所帮助!