循环意外的无限字节

时间:2010-10-20 08:03:11

标签: java types for-loop byte infinite-loop

我有以下循环:

for (byte i = 0 ; i < 128; i++) {
    System.out.println(i + 1 + " " + name);
}

当我执行我的程序时,它会在无限循环中打印-128到127之间的所有数字。为什么会这样?

8 个答案:

答案 0 :(得分:79)

字节是1字节类型,因此可以在-128 ... 127之间变化,因此条件i&lt; 128总是如此。当你添加1到127时,它会溢出并变为-128,依此类推(无限)循环......

答案 1 :(得分:20)

在127之后,当它递增时,它将变为-128,因此您的条件将不匹配。

  

byte byte数据类型是一个8位带符号的二进制补码整数。它的最小值为-128,最大值为127(含)。 byte数据类型可用于在大型阵列中保存内存,其中内存节省实际上很重要。它们也可用于代替int,其限制有助于澄清您的代码;变量范围有限的事实可以作为一种文档形式。


它会像这样工作:

0, 1, 2, ..., 126, 127, -128, -127, ...

因为8位可以表示最多127的有符号数。

有关原始数据类型,请参阅here


图片说的不仅仅是文字 alt text

答案 2 :(得分:11)

因为字节是用Java签名的,所以它们总是小于128。

为什么Java选择带符号的字节从时间的深处是一个谜。我从来没有理解为什么他们破坏了一个非常好的无符号数据类型: - )

请改为尝试:

for (byte i = 0 ; i >= 0; ++i ) {

或者,更好的是:

for (int i = 0 ; i < 128; ++i ) {

答案 3 :(得分:7)

因为当i == 127并且你执行i ++时它会溢出到-128。

答案 4 :(得分:6)

类型字节的范围是-128..127。所以i总是小于128。

答案 5 :(得分:3)

好吧,所以背后的原因已经得到了解答,但如果您对某些背景感兴趣:

bit是计算机可以识别的最小存储单位(n.b。不是最小的数字)。一点是01

byte是8位数据类型,这意味着它由8位字符串组成,例如101010100001110。使用简单的组合,我们知道有2^8 = 256种可能的字节组合。

如果我们只想表示正数,我们可以从基数2到基数10进行直接转换。工作方式是,对于位字符串b7b6b5b4b3b2b1b0,十进制数是dec = sum from n=0 to 7 of (bn * 2^n)

仅表示正数(unsigned byte),我们可以在0255范围内表示256个可能的数字。

当我们想要表示签名数据时会出现问题。一个天真的方法(n.b.这是用于背景,而不是java的方式)是取最左边的位并使其为1为负且0为正的符号位。例如,000101102110010110-21

这种系统存在两个主要问题。第一个是00000000010000000-0,但众所周知,没有-0与{{1}有所不同但是,这样的系统允许数字和0。第二个问题是,由于代表两个零,系统只允许表示从0 ≠ -0-127的数字,范围仅为127254比以前少)。

一个更好的系统(以及大多数系统使用的系统)称为Two's Compliment。在Two's Compliment中,正数用正常位串表示,其中最左边的位为0.负数用最左边的位表示为1然后计算两个对该数字的称赞(从系统得到它的名称) )

虽然在数学上这是一个稍微复杂一点的过程,因为我们处理数字2有一些捷径。从本质上讲,你可以采用正面版本(从右到左)取全部零,直到你达到1.复制那些零和一个,然后取其余位的2。例如,要获得NOT,正-2121,我们会使用00010110而不是其余来获得10,这两个人的赞美代表{ {1}}。

Two's Compliment是一个难以理解的系统,但它避免了前面提到的问题,并且n位数可以表示从11101010-21的所有数字,对于我们的字节意味着-2^(n-1)2^(n-1)-1(因此问题中的问题)

一些注意事项:
  - 这仅用于整数表示。实数表示完全是另一个系统(如果有请求,我相信我们可以做一个数字表示CW帖子)
  - 如果您有兴趣,Wikipedia会有更多数字代表系统。

答案 6 :(得分:2)

如果你这样做是最好的

for (byte i = 0 ; i < Byte.MAX_VALUE; i++ ) {
  System.out.println( i + 1 + " " + name );
}

答案 7 :(得分:1)

这应该有效

        for (byte i = 0 ; i<128; ++i ) {
        if(i==-128)
            break;
        System.out.println( i + 1 + " " + "name" );
    }