थोड़ा सा स्थानांतरण करके पूर्णांक का निर्माण करना। मैं कितनी दूर जा सकता हूं?
जब तक पूर्णांक प्रतिनिधित्व चारों ओर लपेटता है (अधिकांश गोले में डिफ़ॉल्ट)।
64 बिट पूर्णांक आमतौर पर चारों ओर लपेटता है 2**63 - 1
।
कि 0x7fffffffffffffff
या 9223372036854775807
में है।
वह संख्या '+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] से: Intel® ६४ और IA-३२ आर्किटेक्चर सॉफ्टवेयर डेवलपर का मैनुअल: वॉल्यूम २ इस गणना को ५ बिट्स (या ६ बिट्स अगर ६४-बिट मोड और REX.W में प्रयोग किया जाता है) के लिए मास्क किया गया है। गिनती सीमा 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 की संख्या के कितने करीब है।
सीमा का परीक्षण:
परीक्षण का सबसे मजबूत तरीका जो अधिकतम सकारात्मक (और नकारात्मक) पूर्णांक है, प्रत्येक एक बिट को बारी-बारी से परीक्षण करना है। वैसे भी अधिकांश कंप्यूटरों के लिए इसका कम से कम 64 कदम है, यह बहुत धीमा नहीं होगा।
दे घुमा के
पहले हमें फॉर्म के सबसे बड़े पूर्णांक 2^n
(शून्य के बाद 1 बिट सेट) की आवश्यकता है। हम यह कर सकते हैं कि अगली पाली तक बाईं ओर शिफ्टिंग करने से संख्या नकारात्मक हो जाती है, जिसे "रैप अराउंड" भी कहा जाता है:
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
) हम सभी परीक्षणों को दोहराते हैं लेकिन परीक्षण जब थोड़ा सा बनाया जा सकता है तो चारों ओर लपेटे बिना।
सभी चरणों की छपाई के साथ एक संपूर्ण परीक्षा यह है (बैश के लिए):
#!/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
इस कंप्यूटर में ( ) तक के मानों को स्वीकार कर लिया है।
यह दिलचस्प है कि एट शेल की रिपोर्ट करना दिलचस्प है :
$ attsh --version
version sh (AT&T Research) 93u+ 2012-08-01
के मूल्यों पर एक त्रुटि मुद्रित $((2^63))
, हालांकि ksh नहीं।