숫자 bash 쉘 변수의 최대 값은 얼마입니까? 있습니까? 오버플로되고 부정적인 상태가되어

bash의 숫자 변수가 의도적으로 멈추지 않고 증가 할 때 어떤 일이 발생하는지 궁금합니다. 숫자는 얼마나 커질 수 있습니까? 오버플로되고 부정적인 상태가되어 영원히 계속 증가합니까? 어느 시점에서 고장 나고 미끄러질까요?

x86_64 AMD 프로세서를 사용하고 있지만 32 비트 답변도 듣고 기꺼이 말씀하십시오. Fedora21 64 비트를 실행 중입니다.

나는 멀리서 넓게 봤지만 이상한 이유로이 특별한 음식을 찾지 못했습니다. 모든 매뉴얼 및 기타 정보의 기본 정보가 될 것 같습니다.



답변

bash 버전, OS 및 CPU 아키텍처로 이어질 수 있습니다. 직접 해보지 않겠습니까? 변수를 (2 ^ 31) -1로 설정 한 다음 증가시키고 2 ^ 32로 설정 한 다음 증가시키고 2 ^ 64로 설정 한 다음 증가 시키십시오.

여기서는 OS X “El Capitan”v10.11.3을 실행하는 Core i7 Mac에서 직접 시도했으며 bash가 부호있는 64 비트 정수를 사용하는 것처럼 보입니다.

$ uname -a
다윈 스파이 로컬 15.3.0 다윈 커널 버전 15.3.0 : 12 월 10 일 목요일 18:40:58 PST 2015; 루트 : xnu-3248.30.4 ~ 1 / RELEASE_X86_64 x86_64
$ bash-버전
bash-버전
GNU bash, 버전 3.2.57 (1)-릴리스 (x86_64-apple-darwin15)
저작권 (C) 2007 자유 소프트웨어 재단, Inc.
$
$ ((X = 2 ** 16)); 에코 $ X
65536 <-적어도 UInt16
$ ((X = 2 ** 32)); 에코 $ X
4294967296 <-좋아, 적어도 UInt32
$ ((X = 2 ** 64)); 에코 $ X
0 <-UInt64가 아닌 oops
$ ((X = (2 ** 63) -1)); 에코 $ X
9223372036854775807 <-좋아, 적어도 SInt64
$ ((X ++)); 에코 $ X
-9223372036854775808 <-오버플로되어 음수로 줄 바꿈되었습니다. SInt64 여야합니다

답변

루프를 설정했습니다. while return status is 0 increment a variable with addition and print the variable to stdout
나는 2 ^ 31 바로 아래에서 시작했고 문제없이 2 ^ 31과 2 ^ 32를 모두 전달하고 중지 한 다음 초기 값을 2 ^ 63 바로 아래로 설정했습니다. 그 결과 9.22e18에서 -9.22e18로 완벽하게 롤오버되고 계속해서 양의 증가가있었습니다. (0을 향하여)

while [ $? -eq 0 ]이전 스크립트의 종료 상태 또는 이상한 점을 사용하지 않고 while 루프 내에서 명령의 종료 상태를 실제로 사용하고 있는지 확인하기 위해 루프 내에서 여분의 명령으로 실행하여 0이 아닌 종료를 만들었습니다. 특정 증분 상태.

따라서 서명되어 최대 값에서 멈추지 않고 롤오버되며 오류 메시지없이 수행됩니다. 따라서 무한 루프로 끝날 수 있습니다. 64 비트 하드웨어 및 64 비트 Linux OS를 이전 16 또는 32 비트 표준으로 제한하지 않습니다.


답변

bash 는 64 비트 정수를 사용합니다. 따라서 변수가 최대 수에 도달 한 후 증가하면 변수가 오버플로됩니다. 아래는 부호없는 int 및 부호있는 정수를 사용한 테스트입니다.

MAX_UINT = 18446744073709551615
MAX_INT = 9223372036854775807

$ printf "%llu\n" $((2**64))
0
$ printf "%llu\n" $((2**64-1))
18446744073709551615

$ printf "%lld\n" $((2**63-1))
9223372036854775807
$ printf "%lld\n" $((2**63))
-9223372036854775808
$ printf "%lld\n" $((2**64-1))
-1