java - Why is the largest testable integer parsed from user input as a string (10^8)-1? -
accepting user input 1 character @ time, largest acceptable integer before have limit input seems (10^8)-1. mildly surprised wasn't integer.max_value
. why isn't it?
code written out in keyboard
class extends keyadapter
:
import java.awt.event.keyadapter; import java.awt.event.keyevent; public class keyboard extends keyadapter{ private final int max_testable = 99999999; private final int vk_number = 48; //ascii 0 starts here private final int vk_numberpad = 96; //ascii numberpad offset public void keypressed(keyevent e){ int key = e.getkeycode(); if(((char)key == '0' || (char)key == '1' || (char)key == '2' || (char)key == '3' || (char)key == '4' || (char)key == '5' || (char)key == '6' || (char)key == '7' || (char)key == '8' || (char)key == '9')){ if(integer.parseint(launcher.inputstring+(char)key) <= max_testable){ launcher.inputstring += (char)key; } }else if (e.getkeylocation() == keyevent.key_location_numpad){ if(integer.parseint(launcher.inputstring+(char)(vk_number+key-vk_numberpad)) <= max_testable){ launcher.inputstring += (char)(vk_number+key-vk_numberpad); } } system.out.println( "key "+key+" pressed\n"+ "input string: "+launcher.inputstring ); } }
other classes linked here:
- launcher: http://pastebin.com/a5xpydse
- window: http://pastebin.com/bdknsuya
edit: here ended being solution, found vaysym. i'm pasting here make easier in future might up:
the answer in question: (10^8)-1
here's why:
in java, primitive type
int
allowed 4 bytes of memory: 2^32. because signed, have allocate half of 32 bits negative spectrum. have subtract 1 total (which, because it's odd number, happens subtract positive spectrum). our total range becomes (2^(32-1))-1 = 2,147,483,647because testing using int here, maximum testable number. on right operand can check (2^31)-1, code:
if(integer.parseint(inputstring+(char)key) < 2147483647){}
this still throw exception because left operand can end being higher
integer.max_value
, have limitinputstring
before gets there. because input received 1 character @ time , the largest digit can input, 9, greater left-most digit of (2^31)-1, 2, closest caninteger.max_value
entire order of magnitude short;integer.max_value
has 10 digits, cannot test further 9 digits: (10^(10-1))-1 = (10^9)-1 = 999,999,999because we're testing
inputstring
plus next inputted digit, have go down another order of magnitude, bringing final answer of (10^8)-1final code:
if(integer.parseint(inputstring+(char)key) < 999999999){}
--------------------
original answer:
the problem how you're using integer.parseint (quoted comment):
if pass in value larger 2147483647 integer.parseint(), throw exception before can compare < 2147483647, because you're trying assign value large integer in call parseint().
the exception thrown if pass in anything other number under 2147483647, including empty string.
to around this, try using try-catch block:
try { integer.parseint(inputstring); //no exception thrown, valid integer! } catch(numberformatexception e) { //numberformatexception! "inputstring" can not integer! }
if exception thrown integer.parseint(), code in catch
block run, otherwise code in try
block continue running. catching exception, won't cause program crash.
if don't want use try/catch, you'll have limit user can type. can use long
, parselong
instead of integer
allow larger numbers, still throw exception if enter non-number.
update: use check if input string fit integer (if number smaller long, probably be), unfortunately still throw exception if enter isn't number.
if(long.parselong(inputstring+(char)key) > 2147483647) { //"inputstring+(char)key" fit integer! inputstring += (char)key; } else { //"inputstring+(char)key" not fit integer! }
update 2: looking @ edit, you're quite close. what's happening when add char, getting added end of string, then parseint preformed on it. adding string "999999999" char (let's has value of 1), equal 9999999991 (or 9,999,999,991 when it's converted number) not 1,000,000,000. number larger integer time parseint() preformed on it.
also, casting int
char
print out ascii character corresponding int
's number, see this question more on that.
to output you're looking for, try casting inputstring
, key
before adding them together. example: (with inputstring = 50
, key = 50
)
integer.parseint(inputstring) + (int)key // = 100
instead of:
integer.parseint(inputstring+(char)key) // equal 5050, because 50 ascci character 2, 502.
note still throw exception if try parse number larger 2147483647, please consider enclosing try/catch block.
hope helps understand what's happening.
Comments
Post a Comment