Буквальний xyz типу int виходить за межі діапазону


90

На даний момент я працюю з типами даних на Java, і якщо я правильно зрозумів, тип longприймає значення між діапазонами від -9,223,372,036,854,775,808 до +9,223,372,036,854,775,807. Тепер, як ви можете бачити нижче, я створив longзмінну з назвою testLong, хоча коли я вставляю 9223372036854775807 як значення, я отримую повідомлення про помилку:

Буквальний 9223372036854775807 типу int виходить за межі діапазону.

Я не знаю, чому це посилається на longтип даних як int.

У когось є ідеї?

Код:

char testChar = 01;
byte testByte = -128;
int testInt = -2147483648;
short testShort = -32768;
long testLong = 9223372036854775807;
float testFoat;
double testDouble = 4.940656458412;
boolean testBool = true;

До речі: який компілятор ви використовуєте? І Eclipse, і компілятор Sun JDK дають різні (на мій погляд кращі) повідомлення про помилки щодо цієї проблеми.
— Йоахім Зауер,

Відповіді:


195

Додайте капітал Lдо кінця:

long value = 9223372036854775807L;

В іншому випадку компілятор спробує проаналізувати літерал як int, отже, повідомлення про помилку


4
Це в специфікаціях мови Java. Повний текст знайдіть тут
— Лукас Едер,

@Lukas, довге значення = 00000077029062100L; дає мені ту саму помилку, і вона менше 19 цифр. будь-яка ідея, чому вона кидає "Буквальний 0000007702062100L типу long поза межами досяжності"
— Santossh Kumhar

1
@SantosshKumhar: Це вісімковий літерал , який не може містити цифр 8або 9. Видаліть перші нулі.
— Лукас Едер,

50

Я не знаю, чому це посилається на довгий тип даних як int

Це не так. Ви повинні навчитися довіряти повідомленням компілятора (особливо коли вони надходять від здорових, сучасних компіляторів, а не давніх компіляторів C / C ++). Хоча мову, якою вони говорять, часом важко розгадати, вони, як правило, не брешуть вам.

Подивимось ще раз:

Буквал int 9223372036854775807 вийшов за межі діапазону.

Зверніть увагу, що в ній ніде не згадується ваша змінна testLongабо тип long, тому це ні про ініціалізацію. Здається, проблема виникає в якомусь іншому моменті.

Тепер давайте дослідимо деякі частини повідомлення:

  • int говорить нам, що він хоче ставитися до чогось як до int цінності (а це не те, що ти хотів!)
  • "поза діапазоном" цілком зрозуміло: щось не входить в очікуваний діапазон (ймовірно, в int )
  • "Буквал": це цікаво: що таке літерал?

Я залишу затишний список, щоб на мить поговорити про літерали: літерали - це місця, де у вашому коді є якесь значення. Існують Stringлітерали, intлітерали, classлітерали тощо. Кожен раз, коли ви прямо згадуєте значення у своєму коді, це літерал.

Отже, насправді це стосується не декларації змінної, а саме число, значення - це те, про що воно вас дратує.

Ви можете легко перевірити це, використовуючи той самий літерал у контексті, де a longта an intоднаково прийнятні:

System.out.println(9223372036854775807);

PrintStream.printlnможе приймати або або (або майже нічого іншого). Тож із цим кодом повинно бути добре, правда?intlong

Ні . Ну, може бути , це повинно бути, але в відповідно до правил , це є НЕ в порядку.

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

Якщо ви хочете написати longлітерал, то ви повинні зробити це явним, додавши L(або нижній регістр l, але я настійно рекомендую завжди використовувати верхній регістр, тому що це набагато легше читати і важче помилково прийняти за1 ).

Зверніть увагу, що подібна проблема виникає з float(postfix F/ f) та double(postfix D/d ).

Побічна примітка: ви зрозумієте, що їх немає byteабо shortлітералів, і ви все ще можете призначати значення (як правило, intлітерали) byteі shortзмінним: це можливо завдяки спеціальним правилам у п. 5.2 про Призначення перетворення : вони дозволяють призначати константні вирази більшого типу до byte, short, charабо , int якщо значення перебувають у межах типів діапазону.


3
Звідки ви берете час ;-)
— Лукас Едер,

3
@Lukas: Я час від часу пишу такі відповіді в надії, що мені не доведеться писати 300 коротших відповідей ;-) Також: допомога в інтерпретації повідомлення про помилку (сподіваюся) означає менше запитань "що означає це повідомлення про помилку".
— Йоахім Зауер,

Ваша відповідь дуже хороша ... без сумніву, саме тому голосуйте за, але будь ласка, відредагуйте її, а вгорі (початок Вашої відповіді) просто напишіть в 1 рядок точне рішення проблеми, а потім нижче своє пояснення. Оскільки багато людей шукають швидкого рішення, а не глибоких пояснень
— Ширіш Ервад

4
Вони можуть вільно переглядати інші другі відповіді (найголосніша навіть дає швидке рішення). Я думаю, що навчання людей про те, як розбирати та розуміти повідомлення про помилки, є кориснішим у довгостроковій перспективі, ніж просто робити це за них. «Дай людині рибу ...» і все таке.
— Йоахім Зауер

Дякую за примітку.
— Венкатеш Гуд

19

Спробуйте зробити 9223372036854775807L. У Lкінці повідомляє Java, що 9223372036854775807це long.


0

У мене була ця проблема в минулому, і я виправив це, написавши значення в науковій формі. наприклад:

double val = 9e300;

-2
long ak = 34778754226788444L/l;

Обидва використовують, але одночасно використовують лише одну велику літеру L або малу літеру l.

Навіщо використовувати L / l? Оскільки long є частиною цілісного типу даних.

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