2010-03-25 18 views
18

मैंने बाश (3.2) में कुछ सरल पूर्णांक अंकगणित करने के कई तरीकों का उपयोग किया था। लेकिन मैं इसे करने के लिए सबसे अच्छा (पसंदीदा) तरीका नहीं समझ सकता।बाश अंकगणितीय अभिव्यक्ति

result=`expr 1 + 2` 
result=$((1 + 2)) 
let "result = 1 + 2" 

उन अभिव्यक्तियों के बीच मौलिक मतभेद क्या हैं?
क्या ऐसा करने के अन्य तरीके हैं?

क्या उपकरण का उपयोग bc फ़्लोटिंग पॉइंट अंकगणित के लिए अनिवार्य है?

result=`echo "7/354" | bc` 

उत्तर

17

बैश में, let एक पंक्ति में कई कार्य की अनुमति देता है कॉल ऑपरेटरों के चारों ओर रिक्त स्थान। यदि आप रिक्त स्थान का उपयोग करने से बचते हैं, तो आप उद्धरण छोड़ सकते हैं।

((a = (b + c) * 4)) 
((count++)) 
((d = --c**2)) 
((e *= 2)) 
((f = 3, g = 5)) # multiple operations require a comma separator 
:

बयान (i=$((j + 1)) प्रपत्र के बजाय) की शुरुआत में डबल कोष्ठकों का उपयोग दूसरा रूप आप बराबर के चिह्न के आसपास खाली स्थान या पोस्ट या पूर्व वेतन वृद्धि या कमी और अतिरिक्त काम संचालन करने की अनुमति देता

यदि आप help "((" करते हैं तो यह कहता है कि डबल ब्रांड्स let EXPRESSION "समतुल्य" है।

blue=2 
name=blue 
declare $name=4 
echo $blue # result: 4 
echo ${!name} # result: 4 

संपादित करें::

$(()) निर्माण "arithmetic expansion" कहा जाता है और सामग्री का कारण बनता है एक पूर्णांक के रूप में मूल्यांकन किया जाना

आप अप्रत्यक्ष रूप से सहित कार्य बनाने के लिए, declare निर्मित उपयोग कर सकते हैं अभिव्यक्ति। यह खोल का एक वाक्यविन्यास तत्व है।

यदि एक चर को एक पूर्णांक के रूप में घोषित किया गया है तो आपको डबल ब्रांड्स के रूप में उपयोग करने की आवश्यकता नहीं है, तो आप वैरिएबल नाम से (जैसे डबल-ब्रांड्स फॉर्म में) डॉलर का संकेत छोड़ सकते हैं, लेकिन आप नहीं कर सकते ऑपरेटरों के आसपास खाली स्थान:

declare -i x=1 # set integer, initialize to 1 
declare +i s=1 # clear integer, initialize to 1 
x+=1    # could also be x=x+1 
echo $x   # result: 2 (addition) 
s+=1    # could also be s=$s+1, requires a "$" 
echo $s   # result: 11 (string concatenation) 

ऊपर रूपों के विपरीत, बुला expr एक बाहरी निष्पादन योग्य जो एक पाश में गणना का एक बहुत के लिए काफी महंगा हो सकता है उत्पन्न करने वाला शामिल है। केवल समय का उपयोग किया जाना चाहिए वातावरण में जहां शेल अपने अंकगणित या पोर्टेबिलिटी के लिए नहीं कर सकता है जब एक स्क्रिप्ट ऐसे वातावरण में अपना रास्ता पा सकता है। पॉज़िक्स शैल में अंकगणितीय क्षमता होती है, इसलिए यह केवल पुराने सिस्टम के साथ चिंता का विषय होगा।

फ्लोटिंग पॉइंट अंकगणितीय के लिए bc के उपयोग के संबंध में, यह या बैश और कई अन्य गोले का उपयोग करते समय कुछ समान है। पोसिक्स का कहना है कि "केवल हस्ताक्षरित लंबे पूर्णांक अंकगणित की आवश्यकता है।"

फ़्लोट गणित का समर्थन करने वाले दो गोले ksh और zsh हैं। bc के अतिरिक्त, आप dc, एडब्ल्यूके, पायथन, पर्ल और अन्य को बैश स्क्रिप्ट के भीतर से उपयोग कर सकते हैं।

एक बात है कि बैश चल बिन्दु संख्या के साथ क्या करेंगे उन्हें printf builtin (ध्यान दें कि वहाँ भी है कि एक बाहरी printf, लेकिन builtins प्राथमिकता दी जाती है) के साथ मुद्रित है।

printf "%'14.4f\n" 1234.56 # result " 1,234.5600" (in my locale) 
+0

आप 'expr' इत्यादि के प्रभावों पर चर्चा करने में असफल रहे और क्या '$ (())' एक बुल्टिन है या नहीं। – vladr

+0

@Vlad: मुझे आशा है कि आपको जोड़ों में सुधार मिलेगा। –

+0

जोड़ों के लिए धन्यवाद। :) +1 – vladr

4

मैं यह "अनिवार्य" लेकिन bc शायद सामान्य प्रयोजन गणित के लिए अपने सबसे अच्छे शर्त है नहीं कह सकता।

कुछ प्रशंसक के लिए, आप हमेशा पर्ल के माध्यम से पाइप कर सकते हैं।

आपके दोनों दृष्टिकोणों का नकारात्मक पक्ष यह है कि वे दोनों एक बच्चे की प्रक्रिया खोलते हैं, इसलिए इसे एक तंग पाश में करना देशी बैश अभिव्यक्तियों से धीमा होगा (बैकटिक्स के उपयोग के साथ एक ही समस्या उत्पन्न होती है, आपके पहले उदाहरण में)। मुझे यकीन नहीं है कि $(()) एक बाल प्रक्रिया को कॉल करता है या नहीं।

5

मैं अपने दूसरे विकल्प पसंद करते हैं, क्योंकि यह एक बाहरी उपयोगिता की जरूरत नहीं है:

result=$((1 + 2)) 

पहला विकल्प गणित कर expr के लिए बाहर कॉल - मैं let से परिचित नहीं हूँ। bc का एक और विकल्प dc है। अपना पसंदीदा चुनें।

0

आपके पास तीसरा विकल्प बहुत कम पठनीय है क्योंकि यह असाइनमेंट ऑपरेटर की तरह नहीं दिखता है।

let a=3 b=4 c=5 

आप अपने प्रश्न में दिखाने के लिए, let को तर्क के हवाले से के रूप में आप रख सकते है: पहले, के रूप में दूसरों के द्वारा बताया गया है, एक बाहरी कमांड

3

Is the use of a tool like bc mandatory for floating point arithmetic?

नहीं, आप एक खोल चल बिन्दु का समर्थन करता है कि, जैसे zsh, ksh उपयोग कर रहे हैं। अन्यथा, यदि आप अधिक उन्नत फ़्लोटिंग पॉइंट गणित करना चाहते हैं, तो इनमें से किसी एक का उपयोग करें, bc/awk/dc। बेशक, पर्ल/पायथन आदि भी।

संबंधित मुद्दे