यहाँ बाइनरी में क्या हो रहा है। जैसा कि हम जानते हैं, कुछ फ्लोटिंग-पॉइंट वैल्यूज़ को बाइनरी में बिल्कुल नहीं दर्शाया जा सकता है, भले ही उन्हें दशमलव में बिल्कुल प्रतिनिधित्व किया जा सके। ये 3 नंबर उस तथ्य के उदाहरण हैं।
इस कार्यक्रम के साथ मैं प्रत्येक संख्या के हेक्साडेसिमल निरूपण और प्रत्येक जोड़ के परिणामों का उत्पादन करता हूं।
public class Main{
public static void main(String args[]) {
double x = 23.53; // Inexact representation
double y = 5.88; // Inexact representation
double z = 17.64; // Inexact representation
double s = 47.05; // What math tells us the sum should be; still inexact
printValueAndInHex(x);
printValueAndInHex(y);
printValueAndInHex(z);
printValueAndInHex(s);
System.out.println("--------");
double t1 = x + y;
printValueAndInHex(t1);
t1 = t1 + z;
printValueAndInHex(t1);
System.out.println("--------");
double t2 = x + z;
printValueAndInHex(t2);
t2 = t2 + y;
printValueAndInHex(t2);
}
private static void printValueAndInHex(double d)
{
System.out.println(Long.toHexString(Double.doubleToLongBits(d)) + ": " + d);
}
}
printValueAndInHex
विधि सिर्फ एक हेक्स-प्रिंटर सहायक है।
आउटपुट इस प्रकार है:
403787ae147ae148: 23.53
4017851eb851eb85: 5.88
4031a3d70a3d70a4: 17.64
4047866666666666: 47.05
--------
403d68f5c28f5c29: 29.41
4047866666666666: 47.05
--------
404495c28f5c28f6: 41.17
4047866666666667: 47.050000000000004
पहले 4 नंबर दिए गए हैं x
, y
, z
, और s
के हेक्साडेसिमल अभ्यावेदन। IEEE फ़्लोटिंग पॉइंट प्रतिनिधित्व में, बिट्स 2-12 बाइनरी एक्सपोनेंट का प्रतिनिधित्व करता है , अर्थात, संख्या का पैमाना। (पहला बिट सांकेतिक बिट है, और मंटिसा के लिए शेष बिट्स ।) प्रस्तुत किया गया घातांक वास्तव में द्विआधारी संख्या मीन 1023 है।
पहले 4 नंबरों के एक्सपोजर निकाले जाते हैं:
sign|exponent
403 => 0|100 0000 0011| => 1027 - 1023 = 4
401 => 0|100 0000 0001| => 1025 - 1023 = 2
403 => 0|100 0000 0011| => 1027 - 1023 = 4
404 => 0|100 0000 0100| => 1028 - 1023 = 5
परिवर्धन का पहला सेट
दूसरी संख्या ( y
) छोटी परिमाण की है। प्राप्त करने के लिए इन दोनों संख्याओं को जोड़ते समय x + y
, दूसरी संख्या के अंतिम 2 बिट्स ( 01
) सीमा से बाहर स्थानांतरित कर दिए जाते हैं और गणना में शामिल नहीं होते हैं।
दूसरा इसके अलावा कहते हैं x + y
और z
और एक ही पैमाने के दो नंबर कहते हैं।
परिवर्धन का दूसरा सेट
यहाँ, x + z
पहले होता है। वे समान पैमाने के होते हैं, लेकिन वे एक संख्या प्राप्त करते हैं जो बड़े पैमाने पर होती है:
404 => 0|100 0000 0100| => 1028 - 1023 = 5
दूसरा जोड़ जोड़ता है x + z
और y
, और अब संख्याओं को जोड़ने के लिए 3 बिट्स गिराए y
गए हैं ( 101
)। यहां, एक गोल ऊपर की ओर होना चाहिए, क्योंकि परिणाम अगला फ़्लोटिंग पॉइंट नंबर अप है: 4047866666666666
परिवर्धन के पहले सेट के 4047866666666667
लिए बनाम जोड़ के दूसरे सेट के लिए। यह त्रुटि कुल के प्रिंटआउट में दिखाने के लिए पर्याप्त महत्वपूर्ण है।
निष्कर्ष में, IEEE नंबर पर गणितीय कार्य करते समय सावधान रहें। कुछ निरूपण निरर्थक होते हैं, और तराजू अलग होने पर वे और भी अधिक निष्प्राण हो जाते हैं। यदि आप कर सकते हैं तो समान पैमाने की संख्याएँ जोड़ें और घटाएँ।
(2.0^53 + 1) - 1 == 2.0^53 - 1 != 2^53 == 2^53 + (1 - 1)
)। इसलिए, हाँ: सावधान रहें जब रकम और अन्य कार्यों के आदेश का चयन करें। कुछ भाषाएं "उच्च-सटीक" sums (उदाहरण python'smath.fsum
) करने के लिए बिल्ट-इन प्रदान करती हैं , इसलिए आप भोले योग एल्गोरिथ्म के बजाय इन कार्यों का उपयोग करने पर विचार कर सकते हैं।