shell位移产生不同的数字

时间:2013-09-19 15:21:00

标签: linux bash shell embedded

当我跑步时,在我的本地机器bash中

echo $((192 << 24))
3221225472

但在我的嵌入式目标忙盒SHELL我得到了别的东西:

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

当我离开一个较小的数字时它会起作用。嵌入式设备是64位,我的本地主机是32位。

为了清楚,在32位机器上,值为正,在64位机器上它是负数。

编辑: 这是在 64位机器和SHELL 的嵌入式设备上。当左移23时不会发生。

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

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

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

6 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

POSIX(here)表示“只需要有符号的长整数运算”,而在C中,long至少为32位;话虽这么说,有些shell显式选择固定宽度,例如mksh使用32位算术,并且在busybox'源(math.h)上偷看它们似乎只使用64位,ENABLE_SH_MATH_SUPPORT_64是#define'd,无论是否底层系统是32/64位。 如果有人知道的话,请说出来!

答案 2 :(得分:1)

很明显,结果会在嵌入式设备上溢出。根据您的发现进行的一些计算似乎证实了假设

$ echo 3221225472 - 1073741824 | bc -l
2147483648

$ echo 2^31 | bc -l
2147483648

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

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

编辑:当你commented表示你是Busybox 1.13.2时,你可能会遇到this问题。升级可能会有所帮助!

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

在我的原生嵌入式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

使用BusyBox v1.19.3