Я написал 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
, результат не может быть правильно сохранен на компьютере.
Как решить эту проблему?
Ваш лучший вариант - это, вероятно, сделать лексикографическое сравнение между входными и минимальными/максимальными числами перед началом.
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
и т.д.)
Вы могли бы сделать то же самое, что и Long # parseLong:
throw new NumberFormatException("too long (pun intended): "+s);
Я не уверен, чего вы пытаетесь достичь здесь. Если 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
Long.parseLong("102");
?