Tại sao 11010100 << 1 bằng 110101000 chứ không phải 10101000?


40

Tại sao khi tôi cố gắng dịch chuyển bit cho 11010100 2 , kết quả là 110101000 2 chứ không phải 10101000 2 .

int a = Integer.parseInt("11010100", 2) << 1;

Tôi cố gắng làm điều này:

int a = (byte)(Integer.parseInt("11010100", 2) << 1);

Nhưng nếu giá trị đầu ra lớn hơn 128, mọi thứ sẽ đi vào âm, điều này hợp lý. Làm thế nào tôi có thể làm cho số bit đó không thay đổi?


4
Số học số nguyên luôn được thực hiện trên ints hoặc longs.
Tom Hawtin - tackline

34
Bạn đang sử dụng số nguyên, chúng dài 32 bit. Tại sao bạn mong đợi kết quả sẽ bị cắt ngắn thành 8 bit?
jhamon

1
byte a = ... sẽ sửa nó.
Perdi Estaquel

Câu trả lời:


61

Chúng ta hãy thực hiện từng bước một.

  1. Integer.parseInt("11010100", 2)- đây là giá trị int 212. Nhân tiện, điều này là không cần thiết; bạn chỉ có thể viết : 0b11010100.

  2. 0b11010100 << 1giống như 0b110101000, và là 424.

  3. Sau đó, bạn chuyển nó thành một byte : (byte)(0b11010100 << 1). Tất cả các bit vượt quá 8 đầu tiên đều bị loại bỏ, để lại 0b10101000, là -88. Trừ, có, bởi vì trong byte java được ký.

  4. Sau đó, bạn âm thầm truyền -88 này trở lại int, khi bạn gán nó cho một giá trị int. Nó vẫn là -88, có nghĩa là tất cả các bit hàng đầu đều là 1 giây.

Do đó, giá trị cuối cùng là -88.

Nếu bạn muốn xem 168thay thế (là các bit chính xác giống nhau, nhưng được hiển thị không dấu thay vì đã ký), mẹo thông thường là sử dụng & 0xFF, đặt tất cả các bit ngoại trừ 8 đến 0 đầu tiên, do đó đảm bảo số dương:

byte b = (byte) (0b11010100 << 1);
System.out.println(b); // -88. It is not possible to print 168 when printing a byte.
int asUnsigned = b & 0xFF;
System.out.println(asUnsigned); // 168.

// or in one go:

System.out.println(((byte) (0b11010100 << 1)) & 0xFF); // 168

19
Anh ta đang lưu trữ giá trị int a, vì vậy nếu bạn có & 0xFF, thì bạn không cần phải sử dụng tất cả. int a = (0b11010100<< 1) & 0xFF;
Vịt Mooing

9

Nếu bạn muốn đặt thành 0 tất cả các bit cao hơn 8 bit dưới cùng, bạn có thể sử dụng bit khôn ngoan VÀ:

int a = (Integer.parseInt("11010100", 2) << 1) & 0xff;
System.out.println (Integer.toString(a,2));

Đầu ra:

10101000

6

Hãy thử một cái gì đó như thế này:

int anInt = Integer.parseInt("11010100", 2) << 1;
int asUnsignedInt= Byte.toUnsignedInt((byte) anInt);

toUnsignInt đã được giới thiệu trong Java SE 8.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.