Преобразовать строку в длинную, нет встроенной библиотеки

1

Я написал Java-код для преобразования String в long. Однако, когда вы сталкиваетесь с проблемой переполнения, у меня нет подсказок, как его решить. Если число переполнено, компьютер считает, что каждый номер является законным в хранилище. Основная проблема заключается в том, чтобы позволить программе с 64-битным jdk обнаруживать, что реальное число переполнено. И мне не разрешено использовать встроенную библиотеку, такую как parseLong или другие.

public static long strTolong(String s){
        //error checking
        if(s == null) return 0;
        s = s.trim();//remove all space character
        boolean neg = false;//judge the number is negative or positive
        int pos = 0 ; //index of string
        long result = 0;
        //check positive or negative
        if(s.charAt(pos) == '-'){
            neg = true;
            pos++;
        }else if(s.charAt(pos) == '+') pos++;

        //calculate result
        while(pos<s.length()){
            if(s.charAt(pos) >='0' && s.charAt(pos) <='9'){
                result = result*10+(s.charAt(pos) - '0');
            }else
                break;
            pos++;
        }
        if(neg) result =-result;

        //check overflow
        if(result >Long.MAX_VALUE) {
            return Long.MAX_VALUE;
        }
        if(result<Long.MIN_VALUE){
            return Long.MIN_VALUE;
        }


        return result;
    }

Если данные больше, чем long.maxvalue, результат не может быть правильно сохранен на компьютере.

Как решить эту проблему?

  • 3
    в чем проблема в Long.parseLong("102"); ?
Теги:
string
long-integer
overflow

3 ответа

1
Лучший ответ

Ваш лучший вариант - это, вероятно, сделать лексикографическое сравнение между входными и минимальными/максимальными числами перед началом.

static int compare(String v1, String v2) {
    boolean neg1 = v1.startsWith("-");
    boolean neg2 = v2.startsWith("-");
    return neg1 ? (neg2 ? -comparePositives(v1.substring(1),v2.substring(1)):-1)
                : (neg2 ? 1 : comparePositives(v1, v2));
}

static int comparePositives(String v1, String v2) {
    // Is one longer?
    if (v1.length() != v2.length())
        return v1.length() < v2.length() ? -1 : 1;

    // Both empty?
    if (v1.isEmpty())
        return 0;

    // First digit differs?
    if (v1.charAt(0) != v2.charAt(0))
        return v1.charAt(0) < v2.charAt(0) ? -1 : 1;

    // Recurse on rest of number
    return comparePositives(v1.substring(1), v2.substring(1));
}

Используйте его, например, следующим образом:

if (compare(s, ""+Long.MIN_VALUE) == -1)
    throw new NumberFormatException("Input too small");

if (compare(s, ""+Long.MAX_VALUE) == 1)
    throw new NumberFormatException("Input too large");

Протестировано здесь: http://ideone.com/HmMkJ3

Обратите внимание, что код не проверяет правильность ввода. Я предлагаю вам сделать такую проверку. (Имейте в -0 случаи, такие как 0 и -0 и т.д.)

  • 0
    Ваше решение впечатляет. Однако здесь используется встроенная библиотека. И способ регулярных выражений так же хорош.
  • 0
    Основная проблема в том, что компьютер не заметил бы, что данные переполнены.
Показать ещё 3 комментария
0

Вы могли бы сделать то же самое, что и Long # parseLong:

 throw new NumberFormatException("too long (pun intended): "+s);
  • 0
    Проблема в том, что компьютер не заметит, что данные переполнены.
0

Я не уверен, чего вы пытаетесь достичь здесь. Если String больше Long.MAX_VALUE означает, что это больше не Long значение.

Если ваше значение String имеет диапазон Long, вы можете использовать Long.parseLong() без каких-либо трудных способов.

Если вы хотите иметь огромное количество, вы можете легко использовать BigDecimal

String max = Long.MAX_VALUE+"";
System.out.println(max);
long maxL=Long.parseLong(max)+1;
System.out.println(maxL);
BigDecimal bigDecimal=new BigDecimal(max).add(new BigDecimal("1"));
System.out.println(bigDecimal); 

Вывод:

9223372036854775807 // long max value
-9223372036854775808 // incorrect result in long
9223372036854775808 // BigDecimal gives you correct one

Для вашего случая вы можете Long.MAX_VALUE исключение, если значение больше Long.MAX_VALUE или ниже Long.MIN_VALUE

  • 0
    Посмотрите на код, где написано "// check overflow".
  • 0
    @aioobe что ты пытаешься сказать?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню