কিছুটা স্থানান্তরিত করে পূর্ণসংখ্যা উত্পাদন করা। আমি কতদূর যেতে পারি?
পূর্ণসংখ্যার প্রতিনিধিত্ব প্রায় মোড়ানো না হওয়া পর্যন্ত (বেশিরভাগ শেলের মধ্যে ডিফল্ট)।
একটি 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
স্থানান্তর মানটির উপর নির্ভর করে [এ] ।
[এ] থেকে: ইন্টেল ®৪ এবং আইএ -32 আর্কিটেকচার সফটওয়্যার বিকাশকারীর ম্যানুয়াল: খণ্ড 2 গণনাটি 5 বিটগুলিতে মাস্ক করা হয়েছে (বা b বিট যদি bit৪-বিট মোডে থাকে এবং আরএক্স.ডাব্লু ব্যবহৃত হয়)। গণনা পরিসীমা 0 থেকে 31 (বা 63--বিট মোড এবং 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 এর একাধিক সংখ্যার কতটা কাছাকাছি তার উপর নির্ভর করে।
সীমা পরীক্ষা করা:
সর্বাধিক ধনাত্মক (এবং negativeণাত্মক) পূর্ণসংখ্যার যা পরীক্ষা করার শক্তিশালী উপায় হ'ল প্রতিটি এক এক করে বিট পরীক্ষা করা। এটি বেশিরভাগ কম্পিউটারের জন্য 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
) আমরা সমস্ত পরীক্ষার পুনরাবৃত্তি করি তবে পরীক্ষা করে নিই যখন কিছুটা মোড়ানো না করে কিছুটা 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"
SH
প্রায় কোনও শেল অনুবাদিত:
#!/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"
অনেকগুলি শেলের জন্য
উপরেরটি চালানো, সমস্ত (ব্যাশ 2.04 এবং mksh ব্যতীত 2**63 -1
) এই কম্পিউটারে ( ) অবধি মান গ্রহণযোগ্য ।
এটি আকর্ষণীয় যে এটিটি শেল :
$ attsh --version
version sh (AT&T Research) 93u+ 2012-08-01
এর মানগুলিতে একটি ত্রুটি মুদ্রিত হয়েছে $((2^63))
, যদিও ksh নয়।