bash
শেলের পাটিগণিত মূল্যায়ন ক্ষমতাগুলির জন্য সীমাবদ্ধতা রয়েছে । ম্যানুয়ালটি শেল পাটিগণিতের এই দিকটি সম্পর্কে সামঞ্জস্যপূর্ণ তবে বলা হয়েছে :
অতিরিক্ত প্রবাহের জন্য কোনও পরীক্ষা ছাড়াই স্থির-প্রস্থের পূর্ণসংখ্যায় মূল্যায়ন করা হয়, যদিও 0 দ্বারা বিভাজন আটকে যায় এবং ত্রুটি হিসাবে চিহ্নিত করা হয়। অপারেটর এবং তাদের নজির, সাহচর্য এবং মানগুলি সি ভাষার মতো in
স্থায়ী-প্রস্থের কোনটি পূর্ণসংখ্যা এই বোঝায় সত্যিই যা সম্পর্কে হয় ডাটা টাইপ ব্যবহার করা হয় (এবং কেন এই এই বহির্ভূত সুনির্দিষ্ট) কিন্তু সীমা মান প্রকাশ করা হয় /usr/include/limits.h
এই ফ্যাশন:
# if __WORDSIZE == 64
# define ULONG_MAX 18446744073709551615UL
# ifdef __USE_ISOC99
# define LLONG_MAX 9223372036854775807LL
# define ULLONG_MAX 18446744073709551615ULL
এবং একবার আপনি এটি জানেন, আপনি এই মত সত্য এই অবস্থা নিশ্চিত করতে পারেন:
# getconf -a | grep 'long'
LONG_BIT 64
ULONG_MAX 18446744073709551615
এটি একটি 64 বিট পূর্ণসংখ্যা এবং এটি পাটিগণিত মূল্যায়নের প্রসঙ্গে শেলের মধ্যে সরাসরি অনুবাদ করে:
# echo $(((2**63)-1)); echo $((2**63)); echo $(((2**63)+1)); echo $((2**64))
9223372036854775807 //the practical usable limit for your everyday use
-9223372036854775808 //you're that much "away" from 2^64
-9223372036854775807
0
# echo $((9223372036854775808+9223372036854775807))
-1
সুতরাং 2 এর মধ্যে 63 2 এবং 64 -1, আপনি নেতিবাচক পূর্ণসংখ্যার আপনি কতদূর ULONG_MAX থেকে মুছে তুমি দেখাচ্ছে পেতে 1 । মূল্যায়ন যখন এই সীমাতে পৌঁছে যায় এবং প্রবাহিত হয়, যাই হোক না কেন আদেশ অনুসারে, আপনি কোনও সতর্কতা পান না এবং মূল্যায়নের সেই অংশটি 0 এ পুনরায় সেট করা হয় যা ডান-অ্যাসোসিয়েটিভ এক্সপেনসিটির মতো উদাহরণ সহ কিছু অস্বাভাবিক আচরণ করতে পারে :
echo $((6**6**6)) 0 // 6^46656 overflows to 0
echo $((6**6**6**6)) 1 // 6^(6^46656) = 6^0 = 1
echo $((6**6**6**6**6)) 6 // 6^(6(6^46656)) = 6^(6^0) = 6^1
echo $((6**6**6**6**6**6)) 46656 // 6^(6^(6^(6^46656))) = 6^6
echo $((6**6**6**6**6**6**6)) 0 // = 6^6^6^1 = 0
...
ব্যবহারের sh -c 'command'
ফলে কোনও পরিবর্তন হয় না তাই আমাকে ধরে নিতে হবে এটি স্বাভাবিক এবং কমপ্লায়েন্ট আউটপুট। এখন যেহেতু আমি মনে করি পাটিগণিতের সীমা এবং সীমা এবং এক্সপ্রেশন মূল্যায়নের জন্য শেলের মধ্যে এটির আমার কাছে একটি মৌলিক তবে কংক্রিট বোঝাপড়া আছে, আমি ভেবেছিলাম যে লিনাক্সের অন্যান্য সফ্টওয়্যারগুলি কী কী ডেটা ব্যবহার করে তা আমি খুব শীঘ্রই উঁকি দিতে পারি। bash
এই কমান্ডটির ইনপুট পরিপূরক করতে আমি কিছু উত্স ব্যবহার করেছি:
{ shopt -s globstar; for i in /path/to/source_bash-4.2/include/**/*.h /usr/include/**/*.h; do grep -HE '\b(([UL])|(UL)|())LONG|\bFLOAT|\bDOUBLE|\bINT' $i; done; } | grep -iE 'bash.*max'
bash-4.2/include/typemax.h:# define LLONG_MAX TYPE_MAXIMUM(long long int)
bash-4.2/include/typemax.h:# define ULLONG_MAX TYPE_MAXIMUM(unsigned long long int)
bash-4.2/include/typemax.h:# define INT_MAX TYPE_MAXIMUM(int)
if
বিবৃতিগুলির সাথে আরও আউটপুট রয়েছে এবং আমি awk
খুব কম ইত্যাদির মতো কমান্ডও সন্ধান করতে পারি I আমি যে নিয়মিত অভিব্যক্তিটি ব্যবহার করেছি তা লক্ষ্য করেছিলাম যেমন আমার bc
এবং সুনির্দিষ্ট যথাযথ সরঞ্জামগুলি সম্পর্কে কিছুই ধরা পড়ে না dc
।
প্রশ্নাবলি
awk
যখন আপনার গাণিতিক মূল্যায়ন উপচে পড়েছে তখন আপনাকে সতর্ক না করার যুক্তি (যেমন 2 ^ 1024 মূল্যায়ন করার সময় কী করে)? কেন 2 এর মধ্যে নেতিবাচক পূর্ণসংখ্যা 63 এবং 2 64 -1 শেষ ব্যবহারকারীর যখন তিনি কিছু মূল্যায়নের এর উন্মুক্ত?- আমি কোথাও পড়েছি যে ইউনিক্সের কিছু স্বাদ ইন্টারেক্টিভভাবে ইউলং_ম্যাক্স পরিবর্তন করতে পারে? কেউ কি এই ব্যাপারে শুনেছে?
- যদি কেউ নির্বিচারে স্বাক্ষরযুক্ত পূর্ণসংখ্যার মান সর্বাধিক পরিবর্তিত করে
limits.h
, তবে পুনরুদ্ধার করেbash
, আমরা কী আশা করতে পারি?
বিঃদ্রঃ
1. আমি যা দেখেছি তা আরও স্পষ্টভাবে চিত্রিত করতে চেয়েছিলাম, কারণ এটি খুব সাধারণ অভিজ্ঞতামূলক জিনিস। আমি যা লক্ষ্য করেছি তা হ'ল:
- (ক) যে কোনও মূল্যায়ন <2 ^ 63-1 দেয় তা সঠিক
- (খ) যে কোনও মূল্যায়ন যা => 2 ^ 63 কে 2 ^ 64 পর্যন্ত দেয় তা aণাত্মক পূর্ণসংখ্যা দেয়:
- সেই পূর্ণসংখ্যার ব্যাপ্তি x থেকে y পর্যন্ত। x = -9223372036854775808 এবং y = 0।
এটি বিবেচনা করে, (খ) এর মতো মূল্যায়ন 2 ^ 63-1 এর সাথে x_y এর মধ্যে কিছু হিসাবে প্রকাশ করা যেতে পারে। উদাহরণস্বরূপ যদি আমরা আক্ষরিকভাবে (2 ^ 63-1) +100 002 মূল্যায়ন করতে বলা হয় (তবে এর চেয়ে কম সংখ্যক (ক) হতে পারে) আমরা পেয়ে যাব -9223372036854675807। আমি যে স্পষ্টভাবে অনুমান করছি তা কেবল উল্লেখ করছি তবে এর অর্থ এটিও যে নিম্নলিখিত দুটি প্রকাশ:
- (2 ^ 63-1) + 100 002 এবং;
- (2 ^ 63-1) + (এলএলং_ম্যাক্স - the শেলটি আমাদের জন্য কী দেয় ((2 ^ 63-1) + 100 002), যা আমাদের -9 ইতিবাচক মানগুলি ব্যবহার করে ভাল করে;
- (2 ^ 63-1) + (9223372036854775807 - 9223372036854675807 = 100 000)
- = 9223372036854775807 + 100 000
সত্যিই খুব কাছাকাছি। দ্বিতীয় এক্সপ্রেশনটি "2" (2 ^ 63-1) + 100 002 বাদে যা আমরা মূল্যায়ন করছি। আমি বলতে চাইছি এটিই আপনি নেতিবাচক পূর্ণসংখ্যাগুলি দেখায় যে আপনি 2 ^ 64 থেকে কত দূরে আছেন showing আমি সেই নেতিবাচক পূর্ণসংখ্যার এবং সীমাগুলির জ্ঞানের সাথে বোঝাতে চাইছি আপনি ভাল শ্যাশের x..y রেঞ্জের মধ্যে মূল্যায়ন শেষ করতে পারবেন না তবে আপনি অন্য কোথাও করতে পারেন - সেই অর্থে ডেটা 2 ^ 64 অবধি ব্যবহারযোগ্য হয় (আমি যুক্ত করতে পারতাম এটি কাগজে আপ করুন বা এটি বিসি ব্যবহার করুন)। এর বাইরে যাইহোক আচরণটি 6 ^ 6 ^ 6 এর সমান, কারণ সীমাতে বর্ণিত সীমাটি সীমাতে পৌঁছেছে বলে ...
bc
, যেমন: ব্যবহার করুন $num=$(echo 6^6^6 | bc)
। দুর্ভাগ্যক্রমে, bc
লাইন বিরতি দেয়, তাই আপনাকে num=$(echo $num | sed 's/\\\s//g')
পরে করতে হবে; আপনি যদি এটি কোনও পাইপে করেন তবে সত্যিকারের নতুন লাইন অক্ষর রয়েছে যা num=$(echo 6^6^3 | bc | perl -pne 's/\\\s//g')
কাজ করে যদিও সেডের সাথে বিশ্রী । উভয় ক্ষেত্রেই আপনার এখন একটি পূর্ণসংখ্যা রয়েছে যা ব্যবহার করা যেতে পারে, যেমন num2=$(echo "$num * 2" | bc)
,।
bc
সেট করে এই লাইন ব্রেক বৈশিষ্ট্যটি অক্ষম করতে পারবেন BC_LINE_LENGTH=0
।