从4个字节构建有符号整数?

时间:2017-03-02 20:22:16

标签: java binary

我已经学习了一些关于二进制和内存的知识,我看了如何编写int,从我所理解的它基本上写了4个字节,其中signed的最大数字是4个字节{{1} }:

2139062143

然后我每次向左移动一个字节(8位)。

但我得到的最大数字是2147483647而不是Sub GSFlagged(prg As String) 'prg is the Program Name Dim rng As Range Dim rngA As Range Dim rngx(1 To 8) As Variant Dim rngu As Range Dim r As Long Dim wsMaster As Worksheet Dim wsGenScore As Worksheet Dim wsScore As Worksheet Set wsMaster = Worksheets("Master List") Set wsGenScore = Worksheets("Generate Scorecard") Set wsScore = Worksheets("Scorecard") wsMaster.Activate 'Make sure that the master list is not filtered If wsMaster.AutoFilterMode = True Then wsMaster.AutoFilterMode = False End If 'Select all data in the Masterlist and then remove the headers Set rng = wsMaster.Range("B4:E4", Range("B4:E4").End(xlDown)) Set rng = rng.Offset(1, 0).Resize(rng.Rows.Count - 1) 'Filter by the program name wsMaster.Range("B4").AutoFilter Field:=2, Criteria1:=prg Set rngA = rng.SpecialCells(xlCellTypeVisible) 'Filter by flags with a loop over the variable r and save each set of visible cells as rngx(r) For r = 1 To 8 If wsGenScore.Shapes("Flag" & r).ControlFormat.Value = 1 Then wsMaster.Activate If wsMaster.AutoFilterMode = True Then wsMaster.AutoFilterMode = False End If wsMaster.Range("B4").AutoFilter Field:=r + 6, Criteria1:="<>" Set rngx(r) = rng.SpecialCells(xlCellTypeVisible) End If Next r 'After filtering through all the SKUs we union them using Proper Union a Custom VBA that allows for null values and removes duplicates. Set rngu = ProperUnion(rngx(1), rngx(2), rngx(3), rngx(4), rngx(5), rngx(6), rngx(7), rngx(8)) 'Now that we have rngu which is the union of all flagged SKUs we want to intersect that with the SKUs that are in the chosen program. Set rngi = Intersect(rngA, rngu) End Sub ,为什么会这样?

3 个答案:

答案 0 :(得分:1)

在二进制文件中,每个类型的MAX_VALUE0位开头,并继续所有1位。这意味着,要获得Integer.MAX_VALUE,您需要一个0位,后跟31 1位:

Integer.MAX_VALUE:    01111111111111111111111111111111

然而,你不是那样做的。您正在使用Byte.MAX_VALUE重复四次。这意味着您有一个0位,后跟七个1位,后跟一个0位,后跟七个1位,依此类推:

Byte.MAX_VALUE:       01111111
Byte.MAX_VALUE×4:     01111111011111110111111101111111 (2,139,062,143)

由于-1仅由1位组成,因此您可以使用一个Byte.MAX_VALUE后跟三个-1来获得所需内容:

Byte.MAX_VALUE:       01111111
-1:                   11111111
Byte.MAX_VALUE, -1×3: 01111111111111111111111111111111

当您尝试组合这些时,会出现第二个问题。当Java将负byte转换为int时,它变为负int,这意味着大量的1被添加到二进制文件的左侧。因此,您需要使用& 0xff(或Byte.toUnsignedInt)从每个byte中删除这些添加的位。

最好使用|代替+,因为它更符合正确的含义。

所以,要生成Integer.MAX_VALUE

byte a = Byte.MAX_VALUE;
byte b = -1;
byte c = -1;
byte d = -1;

System.out.println(((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | ((d & 0xff) << 0));

答案 1 :(得分:0)

不,MSB必须为零,所有其他位必须为1.这为0x7FFFFFFF提供了2's complement中带符号32位整数的最大值。

答案 2 :(得分:0)

byte在-128和127之间签名。所以-1是8个。

在将<<提升为byte之后完成int转换,您将获得32个的int -1。

所以

int a = 0xFF; // Or 0b1111_1111
int b = 0xFF;
int c = 0xFF;
int d = 0xFF;

或者做:

byte[] bytes = { (byte)-1, (byte)-1, (byte)-1, (byte)-1 };
int n = ByteBuffer.wrap(bytes).getInt();

所有人都可以得到:

int n = -1;
int n = ~0; // Ones complement