समस्या
समस्या वह तरीका है जिसमें डीसी (और बीसी) संख्यात्मक स्थिरांक को समझते हैं।
उदाहरण के लिए, मान (हेक्स में) 0.3
(1 से विभाजित) पास के मूल्य में बदल जाता है0.2
$ dc <<<"20k 16 d i o 0.3 1 / p"
.199999999999999999999999999
वास्तव में, सादा स्थिरांक 0.3
भी बदल जाता है:
$ dc <<<"20 k 16 d i o 0.3 p"
.1
ऐसा लगता है कि यह एक अजीब तरीके से है, लेकिन यह (अधिक बाद में) नहीं है।
अधिक शून्य जोड़ने से उत्तर दृष्टिकोण सही मूल्य हो जाता है:
$ dc <<<"20 k 16 d i o 0.30 p"
.2E
$ dc <<<"20 k 16 d i o 0.300 p"
.2FD
$ dc <<<"20 k 16 d i o 0.3000 p"
.3000
अंतिम मान सटीक है और अधिक शून्य शून्य जोड़े जाने पर कोई फर्क नहीं पड़ता।
$ dc <<<"20 k 16 d i o 0.30000000 p"
.3000000
समस्या ई.पू. में भी मौजूद है:
$ bc <<< "scale=20; obase=16; ibase=16; 0.3 / 1"
.19999999999999999
$ bc <<< "scale=20; obase=16; ibase=16; 0.30 / 1"
.2E147AE147AE147AE
$ bc <<< "scale=20; obase=16; ibase=16; 0.300 / 1"
.2FDF3B645A1CAC083
$ bc <<< "scale=20; obase=16; ibase=16; 0.3000 / 1"
.30000000000000000
प्रति बिट एक अंक?
फ़्लोटिंग पॉइंट नंबरों के लिए बहुत ही गैर-सहज तथ्य यह है कि अंकों की संख्या (डॉट के बाद) बाइनरी बिट्स की संख्या (डॉट के बाद भी) के बराबर है। एक द्विआधारी संख्या 0.101 दशमलव में 0.625 के बराबर है। बाइनरी नंबर 0.0001110001 (बिल्कुल) 0.1103515625
दस दशमलव अंकों के बराबर है
$ bc <<<'scale=30;obase=10;ibase=2; 0.101/1; 0.0001110001/1'; echo ".1234567890"
.625000000000000000000000000000
.110351562500000000000000000000
.1234567890
इसके अलावा, 2 ^ (- 10) जैसे फ्लोटिंग पॉइंट नंबर के लिए, जिसमें बाइनरी में केवल एक (सेट) बिट है:
$ bc <<<"scale=20; a=2^-10; obase=2;a; obase=10; a"
.0000000001000000000000000000000000000000000000000000000000000000000
.00097656250000000000
.0000000001
दशमलव अंकों .0009765625
(10) के रूप में बाइनरी अंकों (10) की समान संख्या है । अन्य आधारों में ऐसा नहीं हो सकता है लेकिन आधार 10 डीसी और बीसी दोनों में संख्याओं का आंतरिक प्रतिनिधित्व है और इसलिए एकमात्र आधार है जिसके बारे में हमें वास्तव में ध्यान रखने की आवश्यकता है।
गणित प्रमाण इस उत्तर के अंत में है।
बीसी स्केल
डॉट के बाद अंकों की संख्या बिल्ट-इन फ़ंक्शन scale()
फॉर्म bc के साथ गिनी जा सकती है :
$ bc <<<'obase=16;ibase=16; a=0.FD; scale(a); a; a*100'
2
.FA
FA.E1
जैसा कि दिखाया गया है, निरंतर का प्रतिनिधित्व करने के लिए 2 अंक अपर्याप्त है 0.FD
।
और, केवल, डॉट के बाद उपयोग किए जाने वाले वर्णों की संख्या की गणना करना, संख्या के पैमाने को रिपोर्ट (और उपयोग) करने का एक बहुत ही गलत तरीका है। संख्या के पैमाने (किसी भी आधार में) को आवश्यक बिट्स की संख्या की गणना करनी चाहिए।
हेक्स फ्लोट में बाइनरी अंक।
जैसा कि ज्ञात है, प्रत्येक हेक्स अंक 4 बिट का उपयोग करता है। इसलिए, दशमलव बिंदु के बाद प्रत्येक हेक्स अंक को 4 बाइनरी अंकों की आवश्यकता होती है, जो ऊपर (विषम?) तथ्य के कारण भी 4 दशमलव अंकों की आवश्यकता होती है।
इसलिए, एक संख्या की तरह 0.FD
8 दशमलव अंकों को सही ढंग से दर्शाने की आवश्यकता होगी:
$ bc <<<'obase=10;ibase=16;a=0.FD000000; scale(a);a;a*100'
8
.98828125
253.00000000
शून्य जोड़ें
गणित सीधा है (हेक्स संख्या के लिए):
h
डॉट के बाद हेक्स अंकों की संख्या ( ) गिनें ।
h
4 से गुणा करें ।
h×4 - h = h × (4-1) = h × 3 = 3×h
शून्य जोड़ें ।
शेल कोड में (श के लिए):
a=F423F.FD
h=${a##*.}
h=${#h}
a=$a$(printf '%0*d' $((3*h)) 0)
echo "$a"
echo "obase=16;ibase=16;$a*100" | bc
echo "20 k 16 d i o $a 100 * p" | dc
जो प्रिंट करेगा (सही ढंग से डीसी और बीसी दोनों में):
$ sh ./script
F423F.FD000000
F423FFD.0000000
F423FFD.0000000
आंतरिक रूप से, bc (या dc) आवश्यक अंकों की संख्या को ऊपर की गणना की गई संख्या से मेल कर सकता है ( 3*h
) हेक्स फ़्लोट्स को आंतरिक दशमलव प्रतिनिधित्व में बदलने के लिए। या अन्य आधारों के लिए कुछ अन्य कार्य (अंकों की संख्या मानकर आधार 10 (bc और dc का आंतरिक) ऐसे अन्य आधार में) के संबंध में परिमित है। जैसे 2 i (2,4,8,16, ...) और 5,10।
POSIX
पॉज़िक्स विनिर्देश बताता है कि (bc के लिए, जो dc पर आधारित है):
आंतरिक संगणनाएँ तब की जाएंगी जैसे कि दशमलव में, इनपुट अंकों और आउटपुट आधारों की परवाह किए बिना, दशमलव अंकों की निर्दिष्ट संख्या तक।
लेकिन "... दशमलव अंकों की निर्दिष्ट संख्या।" समझा जा सकता है "" संख्यात्मक स्थिर का प्रतिनिधित्व करने के लिए दशमलव अंकों की आवश्यक संख्या "(जैसा कि ऊपर वर्णित है)" दशमलव आंतरिक संगणना "को प्रभावित किए बिना।
इसलिये:
bc <<<'scale=50;obase=16;ibase=16; a=0.FD; a+1'
1.FA
bc वास्तव में ऊपर सेट के रूप में 50 ("दशमलव अंकों की निर्दिष्ट संख्या") का उपयोग नहीं कर रहा है।
केवल तभी विभाजित किया जाता है जब इसे परिवर्तित किया जाता है (फिर भी गलत तरीके से यह 2 के पैमाने का उपयोग करता है 0.FD
इसे 50 अंकों में विस्तारित करने से पहले निरंतर पढ़ने के लिए )
$ bc <<<'scale=50;obase=16;ibase=16; a=0.FD/1; a'
.FAE147AE147AE147AE147AE147AE147AE147AE147A
हालांकि, यह सटीक है:
$ bc <<<'scale=50;obase=16;ibase=16; a=0.FD000000/1; a'
.FD0000000000000000000000000000000000000000
फिर से, संख्यात्मक स्ट्रिंग्स (स्थिरांक) को पढ़ना सही संख्या में बिट्स का उपयोग करना चाहिए।
गणित का प्रमाण
दो चरणों में:
एक बाइनरी अंश को / 2 n के रूप में लिखा जा सकता है
एक द्विआधारी अंश दो की नकारात्मक शक्तियों का एक परिमित योग है।
उदाहरण के लिए:
= 0.00110101101 =
= 0. 0 0 1 1 0 1 0 1 1 0 1
= 0 + 0 × 2 -1 + 0 × 2 -2 + 1 × 2 -3 + 1 × 2 -4 + 0 × 2 -5 + 1 × 2 -6 + 0 × 2 -7 + 1 × 2 -8 + 1 × 2 -9 + 0 × 2 -10 + 1 × 2 -11
= 2 -3 + 2 -4 + 2 -6 + 2 -8 + 2 -9 + 2 -11 = (शून्य हटाकर)
एन बिट्स के एक द्विआधारी अंश में, अंतिम बिट का मान 2 -एन , या 1/2 एन है । इस उदाहरण में: 2 -11 या 1/2 11 ।
= 1/2 3 + 1/2 4 + 1/2 6 + 1/2 8 + 1/2 9 + 1/2 11 = (व्युत्क्रम के साथ)
सामान्य तौर पर, भाजक दो के सकारात्मक अंश घातांक के साथ 2 n हो सकता है । सभी शब्दों को तब एक मान / a 2 n में जोड़ा जा सकता है । इस उदाहरण के लिए:
= 2 8 /2 11 + 2 7 /2 11 + 2 5 /2 11 + 2 3 /2 11 + 2 2 /2 11 + 1/2 11 = (2 के साथ व्यक्त 11 )
= (2 8 + 2 7 + 2 5 + 2 3 + 2 2 + 1) / 2 11 = (निकालने आम कारक)
= (256 + 128 + 32 + 8 + 4 + 1) / 2 11 = (मूल्य में परिवर्तित)
= 429/2 11
प्रत्येक बाइनरी अंश को b / 10 n के रूप में व्यक्त किया जा सकता है
5 n
/ 5 n से गुणा a / 2 n , (a × 5 n ) / (2 n × 5 n ) = (a × 5 n ) / 10 n = b / 10 n , जहाँ b = a × 5 n । इसके n अंक हैं।
उदाहरण के लिए, हमारे पास:
(429 · 5 11 ) / 10 11 = 20947265625/10 11 = 0.20947265625
यह दिखाया गया है कि प्रत्येक बाइनरी अंश एक दशमलव अंश है जिसमें समान अंकों की संख्या होती है।
dc
उपयोग करने के लिए संख्याओं की मालिश करने के लिए अधिक कोड लेना समाप्त हो जाएगा, फिर बस सीधे एक पार्सर लिखने के लिए! (इनपुट में दशमलव नहीं हो सकता है, और अन्य ठिकानों में हो सकता है, इसलिए पैडिंग की मात्रा भिन्न हो सकती है।)