홈>
Java에서 비트 조작을 배우고 있습니다. 그래서 바이너리 문자열을 정수 바이트로 변환하고 짧게 변환하고 있습니다. 여기 내 프로그램이 있습니다 :-
byte sByte,lByte; // 8 bit
short sShort,lShort; // 16 bit
int sInt,lInt; // 32 bit
sByte= (byte)(int)Integer.valueOf("10000000", 2); //Smallest Byte
lByte= (byte) ~sByte;
sShort= (short)(int)Integer.valueOf("1000000000000000", 2); //Smallest Short
lShort = (short) ~sShort;
sInt = (int) (int)Integer.valueOf("10000000000000000000000000000000", 2); //Smallest Int
lInt= (int)~sInt;
System.out.println("\"10000000\" \"8 bit\" byte=>"+sByte+"\t~byte=>"+lByte);
System.out.println("\"1000000000000000\" \"16 bit\" short=>"+sShort+"\t~short=>"+lShort);
System.out.println("\"10000000000000000000000000000000\" \"32 bit\" int=>"+sInt+"\t~int=>"+lInt);
바이트와 쇼트는 변환되고 정수가 변환되지 않는 동안 가장 작은 바이트와 가장 작은 쇼트 값을 제공합니다.
다음과 같은 NumberFormatException이 발생합니다 :-
Exception in thread "main" java.lang.NumberFormatException: For input string: "10000000000000000000000000000000"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:583)
at java.lang.Integer.valueOf(Integer.java:740)
at com.learnjava.BitsManipulation.start(BitsManipulation.java:14)
at com.learnjava.learnjava.main(learnjava.java:9)
그리고 그 3 개의 정수 변환 라인을 언급하면 :-
// sInt = (int) (int)Integer.valueOf("10000000000000000000000000000000", 2); //Smallest Int
// lInt= (int)~sInt;
// System.out.println("\"10000000000000000000000000000000\" \"32 bit\" int=>"+sInt+"\t~int=>"+lInt);
출력이 나옵니다 :-
"10000000" "8 bit" byte=>-128 ~byte=>127
"1000000000000000" "16 bit" short=>-32768 ~short=>32767
괜찮습니다 .32 길이의 문자열 길이를 두 번 확인했으며 정수는 32 비트 Java에서 32 비트입니다.이 경우에는 작동하지 않아야합니다.
32 길이 문자열에서 0 또는 1을 제거하거나 1을 0으로 바꾸면 다음과 같이 작동합니다 .-
sInt = (int) (int)Integer.valueOf("00000000000000000000000000000000", 2); //Smallest Int
lInt= (int)~sInt;
System.out.println("\"00000000000000000000000000000000\" \"32 bit\" int=>"+sInt+"\t~int=>"+lInt);
sInt = (int) (int)Integer.valueOf("1000000000000000000000000000000", 2); //Smallest Int
lInt= (int)~sInt;
System.out.println("\"1000000000000000000000000000000\" \"31 bit\" int=>"+sInt+"\t~int=>"+lInt);
출력은 다음과 같습니다 :-
"00000000000000000000000000000000" "32 bit" int=>0 ~int=>-1
"1000000000000000000000000000000" "31 bit" int=>1073741824 ~int=>-1073741825
나는 이것에 대해 혼란스러워하고있다. 왜이 문제에 대한 NumberFormatException 및 해결책이 발생하는지 이유를 알려주십시오.
-
답변 # 1
관련 자료
- python - unimplementederror - tensorflow를 사용하는 동안 문자열을 float로 캐스트하는 것은 지원되지 않습니다
- 파이썬 3에서 사전을 반복하는 동안 문자열 보간을 어떻게 사용할 수 있습니까?
- python - tuple-dict를 유효한 dict로 변환하는 동안 문제가 있습니까?
- c# - Long Money 문자열을 10 진수로 변환
- spyder - Python에서 각도 값을 라디안에서 각도로 변환하는 동안 오류가 발생했습니다
- excel - mat 파일을 csv 파일로 변환하는 동안 오류가 발생했습니다
- android - 문자열을 날짜로 변환하는 것은 예외와 함께 실패합니다형식이 정확하더라도 구문 분석 할 수없는 날짜
- 자바에서 문자열 바꾸기 메소드로 작업하는 동안 문제에 직면
- python - dtype = object를 이진 값으로 변환
- algorithm - 대체 문자가있는 하위 시퀀스를 제거하여 이진 문자열을 빈 문자열로 줄입니다
- java - 정수 또는 문자열을 읽는 동안 스캐너 중지
- c# - 문자열을 배열로 변환하고 철자를 역순으로 반환
- regex - MMM 변환 중 DD, YY 문자열에서 date9까지 SAS?
- python - 현재 시간 어딘가에 0이 있으면 바이너리로 변환하지 못합니다
- 정보 손실없이 문자열 목록을 Double 목록으로 변환 (VBnet)
- pandas - Python 차이를 찾기 위해 문자열을 datetime으로 변환
- python - valueerror - 사전을 데이터 프레임으로 변환하는 동안 배열은 모두 길이가 같아야합니다
- Kotlin에서 '예'또는 '아니요'문자열을 부울로 변환
- javascript - 하나 이상의 구분 기호를 유지하면서 여러 구분 기호로 문자열 분할
- sql - 쿼리를 실행하지 못했습니다 오류 - 테이블 xdbouser_info ', 열'uid '에서 문자열 또는 이진 데이터가 잘립니다
트렌드
- OpenCv의 폴더에서 여러 이미지 읽기 (python)
- 파이썬 셀레늄 모든 "href"속성 가져 오기
- git commit - 자식 - 로컬 커밋 된 파일에 대한 변경을 취소하는 방법
- html - 자바 스크립트 - 클릭 후 변경 버튼 텍스트 변경
- JSP에 대한 클래스를 컴파일 할 수 없습니다
- javascript - 현재 URL에서 특정 div 만 새로 고침/새로 고침
- jquery - JavaScript로 현재 세션 값을 얻으시겠습니까?
- javascript - swiperjs에서 정지, 재생 버튼 추가
- vue.js - axios를 사용하여 서버에 이미지를 업로드하는 방법
- python - 문자열에서 특정 문자 제거
빠른 답변 :
Integer.parseInt () 메소드 (Integer.valueOf ()에 의해 호출되는 메소드)는 부호있는 숫자를 처리하도록 설계되지 않았기 때문에 숫자가 음수인지를 알려야합니다. 빼기를 추가하여 코드를 "고정": <시간>긴 답변 :
스택 트레이스는 어디에서 문제가 발생했는지 알아낼 수있는 곳을 알려줍니다. Integer.valueOf () 메소드는 Integer.parseInt ()를 호출하여 583 행에서 NumberFormatException을 발생시킵니다. openjdk에서 Integer 클래스의 코드를 찾을 수 있습니다.
설명을 위해 현재 예제에서 실행하지 않는 코드 부분을 제거했습니다. 한도는 -2147483647 (MIN_VALUE 이상)입니다. 마찬가지로, multmin은 -1073741823입니다. 루프의 첫 번째 반복에서 결과는 0이므로 result * radix는 0이고 숫자는 1 (문자열의 첫 번째 숫자)이므로 결과 숫자는 -1입니다. 두 번째 반복에서 숫자는 0이되지만 결과 * 기수는 -2입니다. 세 번째 반복에서 -4, -8 등을 얻습니다. 결과가 -1073741824와 같아 질 때까지 계속됩니다. 이는 한계보다 1이 적습니다.
이제이 방법으로 숫자에 부호 (+ 또는-)를 추가했는지 확인합니다. 흥미롭게도, 빼기를 더하면 한계가 MIN_VALUE로 설정됩니다. 따라서 직관적으로, 빼기 (-)를 추가하여 코드를 간단히 "고정"할 수 있습니다.
<시간>다시 말하면, 당신은 거기에서 이상한 캐스팅을합니다. 대신 :
글을 쓸 수 있어야합니다 :
실제로는 할 수 없기 때문에 "해야한다"고 말합니다. 또 다른 예외가 발생합니다! 이는 Byte.valueOf () 메서드가 Integer.valueOf () 메서드를 간단하게 호출 한 다음 Byte에 응답을 캐스팅하기 때문입니다. 그리고 정수의 10000000은 000 ... 00010000000 = 128이므로 바이트에 비해 너무 크다는 것을 알려줍니다.
후아! 그렇다면 왜 이상한 캐스팅 트릭이 작동합니까? "자동 오버플로"라는 것이 있습니다. Java는 필자가 바이트에 숫자 128을 필사적으로 맞추기를 원한다는 것을 알고 있습니다. 가능한 한 많은 수를 넣을 수 있고 (127) 나머지 1을 추가하여 맨 아래로 감싸서 -128로 남겨 둡니다. . 나는 이것이 자동 오버플로가 설계된 것이라고 가정하지만, 그것에 따라 분명히 나쁜 생각입니다. 라인에서 일어나는 일을 설명하려면 :
따라서 부호있는 숫자에 parseInt () 또는 valueOf ()를 사용하지 마십시오.