비트를 시프트하여 정수를 생성하는 단계. 얼마나 멀리 갈 수 있습니까?
정수 표현이 끝날 때까지 (대부분의 쉘에서 기본값).
64 비트 정수는 일반적으로로 둘러싸 2**63 - 1
입니다.
의 그 0x7fffffffffffffff
또는 9223372036854775807
12월있다.
그 숫자 '+1'은 음수가됩니다.
이는 동일 1<<63
하므로 다음과 같습니다.
$ echo "$((1<<62)) $((1<<63)) and $((1<<64))"
4611686018427387904 -9223372036854775808 and 1
그 후 프로세스가 다시 반복됩니다.
$((1<<80000)) $((1<<1022)) $((1<<1023)) $((1<<1024)) $((1<<1025)) $((1<<1026))
결과 mod 64
는 변속 값 [a] 에 따라 달라집니다 .
[a] 출처 : 인텔 ® 64 및 IA-32 아키텍처 소프트웨어 개발자 설명서 : 볼륨 2 카운트는 5 비트 (64 비트 모드에서 REX.W를 사용하는 경우 6 비트)로 마스크됩니다. 카운트 범위는 0에서 31로 제한됩니다 (또는 64 비트 모드 및 REX.W를 사용하는 경우 63). .
또한 : 그 기억 $((1<<0))
입니다1
$ for i in 80000 1022 1023 1024 1025 1026; do echo "$((i%64)) $((1<<i))"; done
0 1
62 4611686018427387904
63 -9223372036854775808
0 1
1 2
2 4
따라서 모두 64의 배수에 얼마나 가까운 지에 달려 있습니다.
한계 테스트 :
최대 양수 (및 음수) 정수인 강력한 테스트 방법은 각 1 비트를 차례로 테스트하는 것입니다. 어쨌든 대부분의 컴퓨터에서 64 단계 미만이지만 너무 느리지 않습니다.
세게 때리다
먼저 가장 큰 정수 형식이 필요합니다 2^n
(1 비트 세트 다음에 0). 다음에 쉬프트 할 때까지 "wrap around"라고 불리는 숫자가 마이너스가 될 때까지 왼쪽으로 쉬프트하면됩니다
a=1; while ((a>0)); do ((b=a,a<<=1)) ; done
b
결과는 어디에 있습니까? 루프에 실패한 마지막 교대 이전의 값입니다.
그런 다음 어떤 비트가 부호에 영향을 미치는지 알아 내기 위해 모든 비트를 시도해야합니다 e
.
c=$b;d=$b;
while ((c>>=1)); do
((e=d+c))
(( e>0 )) && ((d=e))
done;
intmax=$d
최대 정수 ( intmax
)는 마지막 값의 결과입니다.d
합니다.
부정적인 측면에서 0
) 우리는 모든 테스트를 반복하지만 감싸지 않고 비트를 0으로 만들 수있을 때 테스트를 반복합니다.
모든 단계를 인쇄 한 전체 테스트는 다음과 같습니다 (bash).
#!/bin/bash
sayit(){ printf '%020d 0x%016x\n' "$1"{,}; }
a=1; while ((a>0)) ; do((b=a,a<<=1)) ; sayit "$a"; done
c=$b;d=$b; while((c>>=1)); do((e=d+c));((e>0))&&((d=e)) ; sayit "$d"; done;
intmax=$d
a=-1; while ((a<0)) ; do((b=a,a<<=1)) ; sayit "$b"; done;
c=$b;d=$b; while ((c<-1)); do((c>>=1,e=d+c));((e<0))&&((d=e)); sayit "$d"; done
intmin=$d
printf '%20d max positive value 0x%016x\n' "$intmax" "$intmax"
printf '%20d min negative value 0x%016x\n' "$intmin" "$intmin"
쉬
거의 모든 쉘로 번역 :
#!/bin/sh
printing=false
sayit(){ "$printing" && printf '%020d 0x%016x\n' "$1" "$1"; }
a=1; while [ "$a" -gt 0 ];do b=$a;a=$((a<<1)); sayit "$a"; done
c=$b;d=$b; while c=$((c>>1)); [ "$c" -gt 0 ];do e=$((d+c)); [ "$e" -gt 0 ] && d=$e ; sayit "$d"; done;
intmax=$d
a=-1; while [ "$a" -lt 0 ];do b=$a;a=$((a<<1)); sayit "$b"; done;
c=$b;d=$b; while [ "$c" -lt -1 ];do c=$((c>>1));e=$((d+c));[ "$e" -lt 0 ] && d=$e ; sayit "$d"; done
intmin=$d
printf '%20d max positive value 0x%016x\n' "$intmax" "$intmax"
printf '%20d min negative value 0x%016x\n' "$intmin" "$intmin"
많은 셸에서 위를 실행하면
모두 (bash 2.04 및 mksh 제외) 최대 (2**63 -1
컴퓨터에서 ) .
att 쉘 을보고하는 것이 흥미 롭습니다 .
$ attsh --version
version sh (AT&T Research) 93u+ 2012-08-01
$((2^63))
ksh가 아닌의 값에 대한 오류를 인쇄했습니다 .