Difference between float and double: जब हमें Computer में ऐसे मानों को Store करना होता है, जिनमें दसमलव हो, तो ऐसी संख्याओं को Computer में Store करने के लिए हमें Floating Point Value Type के Variables Create करने पडते हैं। इस प्रकार के Data को भी तीन भागों float, double व decimal में विभाजित किया जा सकता है।
Type | Width in Bits | Range | Suffix |
float | 32 | 1.5E–45 to 3.4E+38 | F / f |
double | 64 | 5E–324 to 1.7E+308 | D /d |
decimal | 128 | 1E–28 to 7.9E+28 | M / m |
जब हमें ऐसे मान Computer में Store करने होते हैं, जो छोटे तो होते हैं लेकिन दसमलव वाले होते हैं, तब हम float प्रकार का Variable Declare करते हैं। लेकिन जब दसमलव वाले बडे मानों को Computer में Store करना होता है, तब double प्रकार के Variables Declare करने पडते हैं। जैसे:
float temperature;
double speedOfLight;
C# में जब किसी Floating, Double या Decimal Variable को Create किया जाता है और साथ ही उसे Initialize या Assign भी किया जाता है, तो Initialize या Assign किए जाने वाले मान के साथ हमें क्रमश: f/F, d/D या m/M Character का भी प्रयोग करना जरूरी होता है। जैसे:
float temperature = 95.45F;
double pi =3.1428d ;
decimal salary=15000000.00M
जिस तरह से Integer Types में int व long Data Type को .NET Framework विशेष प्राथमिकता देता है, उसी तरह Floating Pont Values के लिए double Data Type को .NET Framework द्वारा विशेष महत्व दिया जाता है और यदि Memory की परेशानी न हो, तो सभी दसमलव मानों के लिए double को ही प्राथमिकता के साथ Use किया जाना चाहिए।
जब हमें बहुत ही ज्यादा बडी दसमलव वाली संख्या के साथ प्रक्रिया करनी होती है, तब float व double दोनों ही Rounding Errors से ग्रसित रहते हैं। इसलिए decimal Type के Variable को Use करके हम कम से कम 28 Digit तक के Number को Accurate तरीके से Represent कर सकते हैं।
Floating Point Special Values
Integer Overflow की तरह ही float व double Types के साथ भी कुछ Specific Operations Perform करने पर कुछ Special Values Generate होती हैं, जिन्हें NaN, PositiveInfinity, NegativeInfinity व -0 द्वारा Represent किया जाता है। इन्हें हम निम्न Program द्वारा Represent कर सकते हैं:
// File Name: FloatingPointSpecialValues.cs using System; namespace CSharpFundamentals { class FloatingPointSpecialValues { private static void Main(string[] args) { Console.WriteLine("float.NegativeInfinity: {0}", float.NegativeInfinity); Console.WriteLine("float.PositiveInfinity: {0}", float.PositiveInfinity); Console.WriteLine("float.NaN: {0}\n", float.NaN); Console.WriteLine("-0.0: {0}\n", -0.0); Console.WriteLine("double.NegativeInfinity: {0}", double.NegativeInfinity); Console.WriteLine("double.PositiveInfinity: {0}", double.PositiveInfinity); Console.WriteLine("double.NaN: {0}", double.NaN); } } } // Output: float.NegativeInfinity: -Infinity float.PositiveInfinity: Infinity float.NaN: NaN -0.0: 0 double.NegativeInfinity: -Infinity double.PositiveInfinity: Infinity double.NaN: NaN
जब हम किसी Non-Zero Value को Zero से Divide करते हैं, तब PositiveInfinity या NegativeInfinity Special Value Generate होता है। जबकि Zero को Zero से Divide करने पर अथवा Infinity को Infinity से Subtract करने पर NaN Special Value Generate होता है।
इसी तरह से जब हम किसी NaN के साथ किसी दूसरे NaN को == Operator द्वारा Compare करते हैं, तब भी हमें प्राप्त होने वाला Result false होता है, क्योंकि NaN कोई Numerical मान नहीं है, जिसे किसी दूसरे मान के साथ Compare किया जा सके।
लेकिन फिर भी यदि हमें NaN मान को Test करना हो, तो हमें .NET Framework द्वारा Provided float.IsNan व double.IsNan नाम के दो Static Methods को Use करना होता है। हालांकि हम Object.Equals() Static Method का प्रयोग करके दो NaN Values को आपस में Compare कर सकते हैं और इस स्थिति में हमें True प्राप्त होता है।
Floating Point Related इन सभी Special Conditions को हम निम्न Program द्वारा बेहतर तरीके से Represent कर सकते हैं:
// File Name: FloatingPointSpecialValuesWithExample.cs using System; namespace CSharpFundamentals { class FloatingPointSpecialValuesWithExample { private static void Main(string[] args) { Console.WriteLine("PositiveInfinity and NegativeInfinity"); Console.WriteLine("1.0/0.0 : {0}", 1.0 / 0.0); Console.WriteLine("-1.0/-0.0 : {0}", -1.0 / -0.0); Console.WriteLine("-1.0/0.0 : {0}", -1.0 / 0.0); Console.WriteLine("1.0/-0.0 : {0}\n", 1.0 / -0.0); Console.WriteLine("NaN Examples"); Console.WriteLine("0.0/0.0 : {0}", 0.0 / 0.0); Console.WriteLine("(1.0/0.0)-(1.0/0.0) : {0}\n", (1.0 / 0.0) - (1.0 / 0.0)); Console.WriteLine("NaN Comparisons"); Console.WriteLine("0.0/0.0 == double.NaN : {0}", 0.0 / 0.0 == double.NaN); Console.WriteLine("double.IsNaN(0.0/0.0) : {0}", double.IsNaN(0.0 / 0.0)); Console.WriteLine("object.Equals(0.0/0.0 == double.NaN) : {0}", object.Equals(0.0 / 0.0, double.NaN)); } } } // Output: PositiveInfinity and NegativeInfinity 1.0/0.0 : Infinity -1.0/-0.0 : Infinity -1.0/0.0 : -Infinity 1.0/-0.0 : -Infinity NaN Examples 0.0/0.0 : NaN (1.0/0.0)-(1.0/0.0) : NaN NaN Comparisons 0.0/0.0 == double.NaN : False double.IsNaN(0.0/0.0) : True object.Equals(0.0/0.0 == double.NaN) : True
NaN को अक्सर Special Values को Represent करने के लिए Use किया जाता है। जबकि WPF में double.NaN ऐसे Measurement को Represent करता है, जिसका मान “Automatic” होता है। इसके अलावा Nullable Type व ऐसे Custom struc Type के साथ इसका प्रयोग किया जाता है, जिसमें Numerical Type को एक Additional Field के साथ Wrap किया गया होता है।
double व decimal Values के बीच मूल अन्तर ये है कि double का प्रयोग Scientific Computations विशेष रूप से Spatial Coordinates हेतु किया जाता है, जबकि decimal का प्रयोग Financial Computations यानी ऐसे Values के साथ किया जाता है, जो कि Real World Measurements के लिए नहीं बल्कि Human Being के लिए उपयोगी होता है।
Real Number Rounding Errors
float व double Data Types, Data को Internally Binary Format में Store करते हैं। इस वजह से इन Data Types द्वारा केवल उन्हीं Numbers को Represent किया जा सकता है, जिन्हें Binary Format में Convert किया जा सकता है। जिसका मतलब ये है कि दसमलव वाली संख्याओं को Perfect तरीके से float या double Data Types के माध्यम से Represent नहीं किया जा सकता।
यानी इन Data Types में जो दसमलव वाले मान Store किए जाते हैं, वे एकदम Perfect तरीके से उन्हीं मानों को Store नहीं करते, जिन्हे इनमें Assign या Initialize किया जाता है। बल्कि ये Data Type हमेंशा Approximate Values को ही Assign या Initialize करते हैं। इस प्रक्रिया को निम्नानुसार उदाहरण द्वारा बेहतर तरीके से समझा जा सकता है:
// File Name: RealNumberRoundingError.cs using System; namespace CSharpFundamentals { class RealNumberRoundingError { private static void Main(string[] args) { float one = 1f; float oneByTen = 0.1f; Console.WriteLine("one–oneByTen*10 : {0}", one – oneByTen * 10f); } } } // Output: one - oneByTen : -1.49011611938477E-08
इस Program का Output वास्तव में 0 होना चाहिए था, लेकिन हमें 0 प्राप्त नहीं हो रहा है। इसीलिए Financial Calculations में float या double को Use नहीं करना चाहिए, क्योंकि इस तरह के Result से Unknown Amount का गडबड हो सकता है।
लेकिन decimal Type के Data के साथ इस प्रकार की गडबड नहीं होती क्योंकि decimal Type का Data Decimal आधारित Calculation Perform करता है न कि Binary आधारित। लेकिन जिन Floating Point Numbers से Continuous Numbers Generate होते हैं, (3.333333333…, 0.77777777777…, etc…) उन Numbers को float, double या decimal किसी भी Data Type द्वारा Perfect तरीके से Handle नहीं किया जा सकता। इसलिए इन्हें कभी भी निश्चित रूप से Equality व Comparision हेतु Test भी नहीं किया जा सकता। जैसे:
// File Name: RealNumberRoundingErrorComparisionAndEquality.cs using System; namespace CSharpFundamentals { class RealNumberRoundingErrorComparisionAndEquality { private static void Main(string[] args) { decimal m = 1M/6M; double d = 1.0 / 6.0; decimal notQuiteWholeM = m + m + m + m + m + m; double notQuiteWholeD = d + d + d + d + d + d; Console.WriteLine("notQuiteWholeM == 1M : {0}", notQuiteWholeM == 1M); Console.WriteLine("notQuiteWholeD < 1.0: {0}", notQuiteWholeD < 1.0); } } } // Output: notQuiteWholeM == 1M : False notQuiteWholeD < 1.0: True
जैसाकि हम इस Output द्वारा समझ सकते हैं कि notQuiteWholeM का मान 1M ही होना चाहिए क्योंकि हमने निम्न Statement द्वारा 1M में 6M का भाग देने के बाद:
decimal m = 1M/6M;
निम्न Statement द्वारा m के मान को फिर से 6 बार जोडकर 6 गुना भी किया है:
decimal notQuiteWholeM = m + m + m + m + m + m;
फिर भी notQuiteWholeM का मान 1M के समान नहीं है। इसी तरह से notQuiteWholeD का मान 1.0 ही होना चाहिए, क्योंकि हमने निम्न Statement द्वारा 1.0 में 6.0 का भाग देने के बाद:
double d = 1.0 / 6.0;
निम्न Statement द्वारा d के मान को फिर से 6 बार जोडकर 6 गुना भी किया है:
double notQuiteWholeD = d + d + d + d + d + d;
फिर भी notQuiteWholeM का मान 1M के समान नहीं है। यही कारण है कि उपरोक्त दोनों Output में हमें गलत Result प्राप्त हो रहा है।
क्योंकि notQuiteWholeM में मान 1M ही होना चाहिए और पहला Output True होना चाहिए, जो कि False आ रहा है। इसी तरह से notQuiteWholeD में मान 1.0 ही होना चाहिए और दूसरा Output False आना चाहिए, क्योंकि 1.0, 1.0 से छोटा नहीं बल्कि बराबर होता है, फिर भी True आ रहा है।
यानी हम Floating Point Values पर कभी भी निश्चित भरोसा नहीं कर सकते कि किसी Calculation के बाद उनमें जो मान होना चाहिए, वही होगा। इसीलिए हम इन्हें कभी भी Comparision या Equality Testing Operations के लिए उपयोग में नहीं ले सकते। (Difference between float and double)
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook C#.NET in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
C#.NET in Hindi | Page:908 | Format: PDF