Чому в Java діапазон байтів від -128 до 127?


79

Я не розумію, чому найменше значення, яке може приймати байт -128. Я бачу, що найвище значення 127, оскільки воно 01111111в двійковому вигляді, але як представляється -128лише 8 біт, один із яких використовується для знаку? Позитив 128 вже був би 8-бітовим, тобто 10000000тоді вам знадобився би 9-й біт, щоб представити негативний знак.

Хтось може допомогти мені пояснити це.



1
Це аналогічно для інших цілочисельних типів short, intі long.
starblue

11
Краще питання why java byte type is not a range of 0..255? Насправді багато хто задає це питання, у більшості мов byteтип не підписаний, але в java byteтеж підписаний, і я (і багато інших) вважаю, що це був поганий дизайн, який залишився в Java з першого дня. Є проблеми, коли ви працюєте в JNI, і повірте мені, коли ви називаєте щось, byteщо хочете 0..255!
Амір Пашазаде

Відповіді:


92

Відповідь - доповнення двох .

Коротше кажучи, Java (і більшість сучасних мов) не представляють цілі числа зі знаком, використовуючи представлення знакової величини. Іншими словами, 8-бітове ціле число не є знаковим бітом, за яким слідує 7-бітове ціле без знака.

Натомість цілі від’ємні числа представлені в системі, яка називається доповненням двох, що дозволяє простіше арифметичну обробку в апаратному забезпеченні, а також усуває потенційну неоднозначність наявності позитивного нуля та від’ємного нуля. Побічним ефектом усунення від’ємного нуля є те, що внизу діапазону завжди є одне зайве від’ємне число.

Ще однією цікавою властивістю двох комплементарних систем є те, що перший біт ефективно діє як знаковий індикатор (тобто всі числа, що починаються з біта 1, є від’ємними), але наступні сім бітів не слід інтерпретувати самостійно як число без знака для до якого застосовується знаковий біт.

Доповнення двох не дуже складно, але отримання початкового хорошого уявлення про те, що таке доповнення двох, і як і чому воно працює, ймовірно, виходить за рамки відповіді SO. Почніть зі статті у Вікіпедії або пошукайте в Google термін, щоб отримати більше ресурсів.

Щоб спробувати коротко звернутися до вашого запиту про -128, основна ідея створення додаткового числа двох полягає у прийнятті беззнакової форми числа, інвертуванні всіх бітів та додаванні одного. Отже, непідписаний 128 - це 10000000. Перевернуте, це 01111111, і додавання одного отримує 10000000 знову. Отже, у системі доповнення двох, 10000000 однозначно становить -128, а не +128. Числа, що перевищують або дорівнюють +128, просто не можуть бути представлені у 8 бітах за допомогою системи доповнення двох, оскільки вони будуть неоднозначними з формами від'ємних чисел.


Охайно! Давайте подивимось, чи правильно я все зрозумів: це все ще правда, що 8-розрядні числа, які починаються з 0 (крім 00000000), є позитивними, а починаючи з 1 - негативними? Крім того, єдина хитра річ щодо доповнення двох - це те, що бітове представлення байтів не має такого самого значення, як у математичному класі, тобто 10000000 зазвичай становить +128, але як байт це -128. Амірит?
Поганий запит

Ви маєте рацію. Перший біт дорівнює 1 тоді і тільки тоді, коли число від’ємне. Якщо перший біт дорівнює 0, число є або позитивним, або нульовим.
Tyler McHenry

@Tyler: Б'юся об заклад, ви також можете відповісти на моє запитання під цим постом: stackoverflow.com/questions/16775169/ ... Я сподіваюся, це не надто прямо вперед, але я справді дивуюсь, і через кілька місяців спорадичних пошуків у мене все ще немає підказка: ~
JBA

Що цей байт коду b1 = 0b10000000; робить помилку компіляції?
zeds

30

Доповнення двох працює наступним чином;

Байт складається з 8 бітів.

00000000 означає 0

11111111 означає 255

Однак, якби цифри подавались таким чином, ми б не розмежовували позитивне чи негативне отримане число. З цієї причини біт ліворуч дає нам цю інформацію. Якщо біт ліворуч є 0, ви можете почати додавати значення інших бітів у верхній частині zero. Якщо біт є 1, ви повинні почати додавати зверху -128. Оскільки біт на лівій стороні дорівнює двом у міру сім.

Приклади;

У цих прикладах біт ліворуч дорівнює 1, це означає, що ми додаємо значення інших бітів у верхній частині -128.

10000000 = -128 (-128 + 0)

10000001 = -127 (-128 + 1)

10000011 = -125 (-128 + 3)

10000111 = -121 (-128 + 7)

Ті самі біти, але цього разу біт ліворуч 0. Це означає, що ми починаємо додавати зверху 0.

00000000 = 0 (0 + 0)

00000001 = 1 (0 + 1)

00000011 = 3 (0 + 3)

00000111 = 7 (0 + 7)

Якщо з нами все добре, відповідь на ваше запитання,

якнайменше число

10000000 = -128

максимально можливе число

011111111 = 127

Ось чому діапазон знаходиться між -128 і 127 .


8

Як зазначив Джеймс у своєму коментарі, це тому, що так працює доповнення двох.

Якщо ми покладемо це на інші терміни, ви можете представити 2 ^ 8 = 256 типів значень. що в даному випадку використовується як 128 від’ємних чисел, 127 додатних чисел і нуля. Якби ми використовували 7 бітів для представлення значення, +1 біт для знаку, ми могли б представляти одне значення менше, а також мали б два нулі (що було б дуже прикро, оскільки порівняння двох значень було б складнішим через це).


3

Основні числові типи можуть представляти 2 ^ n чисел. Подивіться на випадок n = 2. Ви можете представити чотири випадки, давайте назвемо їх a, b, c, d. Тоді ви можете погодитися або a=-2, b=-1, c=0, d=1(це прийнято), або a=-1, b=0, c=1, d=2(Можливо, але не використовується). Отже, якщо у вас є лише один нуль і утримується 2 ^ n, ваш abs(min) != maxЗбільшення nпереміщує межі, але abs(min) != maxвсе ще тримає.


3

байт складається з 8 бітових ---> 1 бітовий знак (позитивний чи негативний) 7 бітових значень

так діапазон -2 ^ 7 від'ємний (-128) до 2 ^ 7 -1 позитивний (127)


1

у Java всі змінні, такі як байт short int long float double, записуються як підписані. так дуже просто, головний біт завжди вказує, що є (негативним чи позитивним), але оскільки цифри, що діляться на 2 половини, зміщуються як негативні, 0 за замовчуванням є додатними. так це виглядає так:

це додатне
+ | 0001001
1 | 0001001
це від'ємне
- | 0001001
0 | 0001001
як короткий байт, мінус
-000000011111111
0000000011111111


0

Не потрапляючи в доповнення двох: 2 ^ 8 (оскільки байт - це 8 цифр і може мати 1 із 2 значень) = 256, тому найбільш індивідуальні значення, які може представляти байт, - це 256. Отже, представлення чисел від -128 до -1 дорівнює половина нашого асортименту. Я вважаю, що питання тут полягає в тому, чому максимальне позитивне значення 127, а не 128. Це тому, що ми повинні представляти число 0, тому включно 0-127 - це інші 128 можливостей нашого діапазону.

Якби ми допускали лише позитивні значення, такі як непідписаний байт, де негативні числа неможливі, діапазон був би 0-255, оскільки це 256 різних значень (включаючи 0).


0

взявши комплімент числа двох, ми завжди залишали один стан, що представляє число зайвим, тому ми перетворюємо цей стан на -128.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.