Исключение в потоке «main» java.lang.NumberFormatException: для входной строки: «90000000000000» под индексом 16

#java #long-integer

#ява #длинное целое число #java

Вопрос:

Я пытаюсь запустить этот код, но возникает ошибка.

 System.out.println(Long.parseLong("9000000000000000", 16));
  

Поскольку мы знаем, что минимальное количество long равно -9,223,372,036,854,775,808, а 0x9000000000000000 равно -8,070,450,532,247,928,832, почему произойдет ошибка?

Ответ №1:

90000000000000 основание 16 является положительным числом, поскольку нет знака. Поскольку long подписано, наибольшее число, которое оно может содержать, равно 0x7fff_ffff_ff_ff_ffff. Так что ваш слишком велик.

Если вы хотите -8 070 450 532 247 928 832, используйте parseUnsignedLong() :

         System.out.println(Long.parseUnsignedLong("9000000000000000", 16));
  

Вывод:

-8070450532247928832

Теперь принимаются значения до 0XFFFF_FF_FF_FF_FF_FFFF.

Ответ №2:

Ссылка на Long#parseLong(String,int)

Исключение типа NumberFormatException генерируется, если возникает любая из следующих ситуаций:

  • Первый аргумент равен нулю или представляет собой строку нулевой длины.
  • Основание либо меньше символа.MIN_RADIX или больше символа.MAX_RADIX.
  • Любой символ строки не является цифрой указанного основания, за исключением того, что первый символ может быть знаком минус ‘-‘ (‘u002d’) или знаком плюс ‘ ‘ (‘u002B’) при условии, что строка длиннее длины 1.
  • Значение, представленное строкой, не является значением типа long.

Примеры:
parseLong(«0», 10) возвращает 0L
parseLong(«473», 10) возвращает 473L
parseLong(» 42″, 10) возвращает 42L
parseLong(«-0», 10) возвращает 0L
parseLong(«-FF», 16) возвращает -255L
parseLong(«1100110», 2) возвращает 102 L
parseLong(«99», 8) вызывает исключение NumberFormatException
parseLong(«Фундук», 10) вызывает исключение NumberFormatException
parseLong(«Фундук», 36) возвращает 1356099454469L

Десятичное значение, проанализированное с использованием radix 16, равно 10376293541461622784, что больше, чем Long.MAX_VALUE(9223372036854775807), нарушает следующее условие:

Значение, представленное строкой, не является значением типа long

следовательно, выбрасывание NumberFormatException .

 import java.math.BigInteger;

public class ParseLong {
    public static void main(String[] args) {
        System.out.println("Max Long value :"   Long.MAX_VALUE);
        System.out.println("Min Long value :"   Long.MIN_VALUE);
        System.out.println("Value without overflow "   new BigInteger("9000000000000000", 16));
        System.out.println("Value by parseUnsigned "   Long.parseUnsignedLong("9000000000000000", 16));
        System.out.println("Value by literal "   0x9000000000000000L);
    }
}
  

Комментарии:

1. но почему g 0x9000000000000000 не может использовать Long.parseLong() , он имеет длину 64 байта со знаком.

Ответ №3:

Long.parseLong() не «переполняется» до отрицательного числа, как это делает арифметика — это не синтаксический анализ битового представления, а скорее цифр целого числа.

Наибольшее значение long в базе 16 равно 7FFFFFFFFFFFFFFF ; ваше значение больше этого.

Для сравнения в десятичном:

 Base 16            Decimal
7FFFFFFFFFFFFFFF    9,223,372,036,854,775,807
9000000000000000   10,376,293,541,461,622,784