गोले में छोरों से बचें।
यदि आप अंकगणित करना चाहते हैं, तो उपयोग करें awk
या bc
:
awk '
BEGIN{
for (i = 4.00; i < 5.42; i+ = 0.02)
print i
}'
या
bc << EOF
for (i = 4.00; i < 5.42; i += 0.02) i
EOF
ध्यान दें कि awk
(इसके विपरीत bc
) आपके प्रोसेसर double
फ्लोटिंग पॉइंट नंबर प्रतिनिधित्व के साथ काम करता है (संभवतः IEEE 754 प्रकार)। परिणामस्वरूप, चूंकि वे संख्याएँ उन दशमलव संख्याओं के द्विआधारी सन्निकटन हैं, तो आपको कुछ आश्चर्य हो सकता है:
$ gawk 'BEGIN{for (i=0; i<=0.3; i+=0.1) print i}'
0
0.1
0.2
यदि आप जोड़ते हैं तो आप OFMT="%.17g"
गुम होने का कारण देख सकते हैं 0.3
:
$ gawk 'BEGIN{OFMT="%.17g"; for (i=0; i<=0.5; i+=0.1) print i}'
0
0.10000000000000001
0.20000000000000001
0.30000000000000004
0.40000000000000002
0.5
bc
इस तरह की समस्या नहीं है तो मनमानी परिशुद्धता करता है।
ध्यान दें कि (जब तक आप आउटपुट फॉर्मेट को संशोधित OFMT
या printf
स्पष्ट प्रारूप विनिर्देशों के साथ उपयोग नहीं करते हैं), फ़्लोटिंग पॉइंट नंबर प्रदर्शित करने के लिए awk
उपयोग करता है %.6g
, इसलिए 1e6 और इसके बाद के संस्करण 1,000,000 से ऊपर के फ़्लोटिंग पॉइंट नंबरों के लिए स्विच करेगा और उच्च संख्याओं के लिए आंशिक भाग को काट देगा (100000.02) 100000 के रूप में प्रदर्शित किया जाएगा)।
यदि आपको वास्तव में शेल लूप का उपयोग करने की आवश्यकता है, क्योंकि उदाहरण के लिए आप उस लूप के प्रत्येक पुनरावृत्ति के लिए विशिष्ट कमांड चलाना चाहते हैं, या तो फ़्लोटिंग पॉइंट अंकगणितीय समर्थन जैसे शेल का उपयोग करें zsh
, yash
या ksh93
ऊपर दिए गए एक कमांड के साथ मानों की सूची उत्पन्न करें। (या seq
यदि उपलब्ध हो) और इसके आउटपुट पर लूप।
पसंद:
unset -v IFS # configure split+glob for default word splitting
for i in $(seq 4 0.02 5.42); do
something with "$i"
done
या:
seq 4 0.02 5.42 | while IFS= read i; do
something with "$i"
done
जब तक आप अपने प्रोसेसर फ़्लोटिंग पॉइंट नंबरों की सीमा को आगे नहीं seq
बढ़ाते हैं , फ़्लोटिंग पॉइंट सन्निकटन द्वारा की गई त्रुटियों को awk
उपरोक्त संस्करण की तुलना में अधिक सुंदर तरीके से संभालता है ।
यदि आपके पास seq
(GNU कमांड) नहीं है, तो आप एक फ़ंक्शन के रूप में अधिक विश्वसनीय बना सकते हैं:
seq() { # args: first increment last
bc << EOF
for (i = $1; i <= $3; i += $2) i
EOF
}
जो कि चीजों के लिए बेहतर काम करेगा seq 100000000001 0.000000001 100000000001.000000005
। हालाँकि, ध्यान दें कि मनमाने ढंग से उच्च परिशुद्धता के साथ संख्या होने पर बहुत मदद नहीं मिलेगी अगर हम उन्हें उन आदेशों को पारित करने जा रहे हैं जो उनका समर्थन नहीं करते हैं।