दिलचस्प पोस्ट
सी (सी) और सी ++ में मुख्य () क्या रिटर्न चाहिए? क्या मुझे विंडोज़ में संकलन करने के लिए यूनिक्स के pthread.h मिल सकता है? ईएफ कोड प्रथम डीबीसीटीक्स्ट और लेनदेन ग्रहण त्रुटि: एक चर को हल नहीं किया जा सकता सी कोड में C ++ लाइब्रेरी का उपयोग करना जब एक एक्सेल VBA चर मारा जाना चाहिए या कुछ नहीं करने के लिए सेट? क्या मैं सामान्यतः / हमेशा std :: move के बजाय std :: forward का उपयोग कर सकता हूं? एंड्रॉइड में वर्तमान में चल रहे कार्य को कैसे मारना समानांतर में स्वतंत्र आरडीडी के रूप में कई फाइलों को प्रोसेस करना geom_rect और अल्फा – कड़ी कोडित मानों के साथ यह काम करता है? InvokeRequired कोड पैटर्न को स्वचालित करना ग्राफ़ एपीआई का उपयोग करके फेसबुक 'फ्रेंड्सजेटएपयूजर' मैं कैसे जांच सकता हूं कि कोई विकल्प पहले से ही JQuery के चयन में मौजूद है या नहीं अंतःप्रक्रम संचार मैं एंड्रॉइड पर एसडी कार्ड में डेटाबेस फ़ाइल कैसे बैकअप करूं?

सी # के लिए फ़्लोटिंग बिंदु तुलना फ़ंक्शन

क्या कोई फ्लोटिंग प्वाइंट वैल्यू की तुलना करने के लिए सी # के लिए कुछ अच्छा सामान्य फ्लोटिंग प्वाइंट तुलना फ़ंक्शन की ओर इशारा करता है? मैं IsEqual , IsGreater लिए कार्यों को कार्यान्वित करना चाहता हूँ एक IsLess मैं केवल वास्तव में डबल्स की बजाए फ्लोट नहीं करता।

Solutions Collecting From Web of "सी # के लिए फ़्लोटिंग बिंदु तुलना फ़ंक्शन"

एक उपयोगी सामान्य प्रयोजन फ़्लोटिंग प्वाइंट IsEqual बहुत मुश्किल है, अगर पूरी तरह असंभव नहीं है आपका वर्तमान कोड a==0 लिए बुरी तरह विफल हो जाएगा ऐसे मामलों के लिए विधि को कैसे व्यवहार करना चाहिए वास्तव में परिभाषा का मामला है, और यकीनन यह कोड विशिष्ट डोमेन उपयोग के मामले के लिए सर्वोत्तम होगा।

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

 public static boolean nearlyEqual(float a, float b, float epsilon) { final float absA = Math.abs(a); final float absB = Math.abs(b); final float diff = Math.abs(a - b); if (a == b) { // shortcut, handles infinities return true; } else if (a == 0 || b == 0 || diff < Float.MIN_NORMAL) { // a or b is zero or both are extremely close to it // relative error is less meaningful here return diff < (epsilon * Float.MIN_NORMAL); } else { // use relative error return diff / (absA + absB) < epsilon; } } 

आप साइट पर परीक्षण सूट भी पा सकते हैं।

परिशिष्ट: डबल्स के लिए सी # में समान कोड (जैसा कि सवाल में पूछा गया है)

 public static bool NearlyEqual(double a, double b, double epsilon) { double absA = Math.Abs(a); double absB = Math.Abs(b); double diff = Math.Abs(a - b); if (a == b) { // shortcut, handles infinities return true; } else if (a == 0 || b == 0 || diff < Double.Epsilon) { // a or b is zero or both are extremely close to it // relative error is less meaningful here return diff < epsilon; } else { // use relative error return diff / (absA + absB) < epsilon; } } 

फ्लोट्स की तुलना करने पर ब्रूस डावसन के पेपर से , आप फ़्लोट्स को पूर्णांक के रूप में भी तुलना कर सकते हैं। निकटता कम से कम महत्वपूर्ण बिट्स द्वारा निर्धारित की जाती है।

 public static bool AlmostEqual2sComplement( float a, float b, int maxDeltaBits ) { int aInt = BitConverter.ToInt32( BitConverter.GetBytes( a ), 0 ); if ( aInt < 0 ) aInt = Int32.MinValue - aInt; // Int32.MinValue = 0x80000000 int bInt = BitConverter.ToInt32( BitConverter.GetBytes( b ), 0 ); if ( bInt < 0 ) bInt = Int32.MinValue - bInt; int intDiff = Math.Abs( aInt - bInt ); return intDiff <= ( 1 << maxDeltaBits ); } 

संपादित करें: बिटसंकेतक अपेक्षाकृत धीमा है यदि आप असुरक्षित कोड का उपयोग करने के लिए तैयार हैं, तो यहां एक बहुत तेज़ संस्करण है:

  public static unsafe int FloatToInt32Bits( float f ) { return *( (int*)&f ); } public static bool AlmostEqual2sComplement( float a, float b, int maxDeltaBits ) { int aInt = FloatToInt32Bits( a ); if ( aInt < 0 ) aInt = Int32.MinValue - aInt; int bInt = FloatToInt32Bits( b ); if ( bInt < 0 ) bInt = Int32.MinValue - bInt; int intDiff = Math.Abs( aInt - bInt ); return intDiff <= ( 1 << maxDeltaBits ); } 

एंड्रयू वैंग के उत्तर के अलावा: अगर बिटकोनरवर की विधि बहुत धीमी है लेकिन आप अपने प्रोजेक्ट में असुरक्षित कोड का उपयोग नहीं कर सकते हैं, तो यह संरचना बीटकॉन्टर से 6x तेज है:

 [StructLayout(LayoutKind.Explicit)] public struct FloatToIntSafeBitConverter { public static int Convert(float value) { return new FloatToIntSafeBitConverter(value).IntValue; } public FloatToIntSafeBitConverter(float floatValue): this() { FloatValue = floatValue; } [FieldOffset(0)] public readonly int IntValue; [FieldOffset(0)] public readonly float FloatValue; } 

(संयोग से, मैंने स्वीकार किए जाते हैं समाधान का उपयोग करने की कोशिश की, लेकिन यह (कम से कम मेरा रूपांतरण कम से कम) उत्तर में उल्लिखित यूनिट परीक्षणों में से कुछ विफल हुआ। उदाहरण के लिए, assertTrue(nearlyEqual(Float.MIN_VALUE, -Float.MIN_VALUE)); )

यहां साइमन हैविट वर्ग का एक बहुत विस्तारित संस्करण है:

 /// <summary> /// Safely converts a <see cref="float"/> to an <see cref="int"/> for floating-point comparisons. /// </summary> [StructLayout(LayoutKind.Explicit)] public struct FloatToInt : IEquatable<FloatToInt>, IEquatable<float>, IEquatable<int>, IComparable<FloatToInt>, IComparable<float>, IComparable<int> { /// <summary> /// Initializes a new instance of the <see cref="FloatToInt"/> class. /// </summary> /// <param name="floatValue">The <see cref="float"/> value to be converted to an <see cref="int"/>.</param> public FloatToInt(float floatValue) : this() { FloatValue = floatValue; } /// <summary> /// Gets the floating-point value as an integer. /// </summary> [FieldOffset(0)] public readonly int IntValue; /// <summary> /// Gets the floating-point value. /// </summary> [FieldOffset(0)] public readonly float FloatValue; /// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(FloatToInt other) { return other.IntValue == IntValue; } /// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(float other) { return IntValue == new FloatToInt(other).IntValue; } /// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(int other) { return IntValue == other; } /// <summary> /// Compares the current object with another object of the same type. /// </summary> /// <returns> /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>. /// </returns> /// <param name="other">An object to compare with this object.</param> public int CompareTo(FloatToInt other) { return IntValue.CompareTo(other.IntValue); } /// <summary> /// Compares the current object with another object of the same type. /// </summary> /// <returns> /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>. /// </returns> /// <param name="other">An object to compare with this object.</param> public int CompareTo(float other) { return IntValue.CompareTo(new FloatToInt(other).IntValue); } /// <summary> /// Compares the current object with another object of the same type. /// </summary> /// <returns> /// A value that indicates the relative order of the objects being compared. The return value has the following meanings: Value Meaning Less than zero This object is less than the <paramref name="other"/> parameter.Zero This object is equal to <paramref name="other"/>. Greater than zero This object is greater than <paramref name="other"/>. /// </returns> /// <param name="other">An object to compare with this object.</param> public int CompareTo(int other) { return IntValue.CompareTo(other); } /// <summary> /// Indicates whether this instance and a specified object are equal. /// </summary> /// <returns> /// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false. /// </returns> /// <param name="obj">Another object to compare to. </param><filterpriority>2</filterpriority> public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } if (obj.GetType() != typeof(FloatToInt)) { return false; } return Equals((FloatToInt)obj); } /// <summary> /// Returns the hash code for this instance. /// </summary> /// <returns> /// A 32-bit signed integer that is the hash code for this instance. /// </returns> /// <filterpriority>2</filterpriority> public override int GetHashCode() { return IntValue; } /// <summary> /// Implicitly converts from a <see cref="FloatToInt"/> to an <see cref="int"/>. /// </summary> /// <param name="value">A <see cref="FloatToInt"/>.</param> /// <returns>An integer representation of the floating-point value.</returns> public static implicit operator int(FloatToInt value) { return value.IntValue; } /// <summary> /// Implicitly converts from a <see cref="FloatToInt"/> to a <see cref="float"/>. /// </summary> /// <param name="value">A <see cref="FloatToInt"/>.</param> /// <returns>The floating-point value.</returns> public static implicit operator float(FloatToInt value) { return value.FloatValue; } /// <summary> /// Determines if two <see cref="FloatToInt"/> instances have the same integer representation. /// </summary> /// <param name="left">A <see cref="FloatToInt"/>.</param> /// <param name="right">A <see cref="FloatToInt"/>.</param> /// <returns>true if the two <see cref="FloatToInt"/> have the same integer representation; otherwise, false.</returns> public static bool operator ==(FloatToInt left, FloatToInt right) { return left.IntValue == right.IntValue; } /// <summary> /// Determines if two <see cref="FloatToInt"/> instances have different integer representations. /// </summary> /// <param name="left">A <see cref="FloatToInt"/>.</param> /// <param name="right">A <see cref="FloatToInt"/>.</param> /// <returns>true if the two <see cref="FloatToInt"/> have different integer representations; otherwise, false.</returns> public static bool operator !=(FloatToInt left, FloatToInt right) { return !(left == right); } } 

कुछ उत्तरों से सावधान रहें …

1 – आप किसी भी संख्या को आसानी से मेमोरी में 15 अंकों के अंकों के साथ दोहरा कर सकते हैं। विकिपीडिया देखें

2 – समस्या फ्लोटिंग नंबरों की गणना से आती है, जहां आप कुछ परिशुद्धता खो सकते हैं। मेरा मतलब है कि 1 जैसे नंबर 1 की तरह कुछ हो सकता है। 1000000000000001 ==> गणना के बाद जब आप कुछ गणना करते हैं, तो परिणामों को दोहरा में प्रतिनिधित्व करने के लिए छोटा किया जा सकता है उस छिड़काव से आपको जो त्रुटि मिल सकती है

3 – दोहरे मूल्यों की तुलना करते समय समस्या को रोकने के लिए, लोग एपिसलॉन नामक एक त्रुटि मार्जिन पेश करते हैं। यदि 2 फ़्लोटिंग नंबरों में केवल एक प्रासंगिक एप्सिलॉन हा फर्क है, तो उन्हें बराबर माना जाता है। एप्सिलोन कभी दो बार नहीं होता है। एप्सिलॉन।

4 – एप्सिलॉन कभी दो बार नहीं होता है। एपिसिलोन। यह उस से हमेशा बड़ा होता है बहुत से लोग सोचते हैं कि यह दोगुना है। एप्सिलोन लेकिन वे वास्तव में गलत हैं। एक महान उत्तर पाने के लिए कृपया देखें: हंस पैसेंट का जवाब । एप्सिलॉन आपके संदर्भ पर आधारित है, जहां यह आपकी गणना के दौरान और आपके द्वारा किए जा रहे गणना की संख्या (ट्रुनेसीेशन एरर संचित) की सबसे बड़ी संख्या पर निर्भर करता है। एप्सिलॉन सबसे छोटी संख्या है जो आप 15 अंकों के साथ आपके संदर्भ में प्रतिनिधित्व कर सकते हैं।

5 – यह वह कोड है जिसका उपयोग मैं करता हूं। सावधान रहें कि मैं केवल कुछ गणनाओं के लिए अपने एप्सिलॉन का उपयोग करता हूं अन्यथा मैं अपने एप्सिलॉन को 10 या 100 तक बढ़ाना

6 – जैसा कि स्वेनएल ने कहा है, यह संभव है कि मेरा एप्सिलॉन काफी बड़ा नहीं है। मैं SvenL टिप्पणी को पढ़ने का सुझाव देते हैं इसके अलावा, शायद "दशमलव" आपके मामले के लिए नौकरी कर सकता है?

 public static class DoubleExtension { // ****************************************************************** // Base on Hans Passant Answer on: // https://stackoverflow.com/questions/2411392/double-epsilon-for-equality-greater-than-less-than-less-than-or-equal-to-gre /// <summary> /// Compare two double taking in account the double precision potential error. /// Take care: truncation errors accumulate on calculation. More you do, more you should increase the epsilon. public static bool AboutEquals(this double value1, double value2) { double epsilon = Math.Max(Math.Abs(value1), Math.Abs(value2)) * 1E-15; return Math.Abs(value1 - value2) <= epsilon; } // ****************************************************************** // Base on Hans Passant Answer on: // https://stackoverflow.com/questions/2411392/double-epsilon-for-equality-greater-than-less-than-less-than-or-equal-to-gre /// <summary> /// Compare two double taking in account the double precision potential error. /// Take care: truncation errors accumulate on calculation. More you do, more you should increase the epsilon. /// You get really better performance when you can determine the contextual epsilon first. /// </summary> /// <param name="value1"></param> /// <param name="value2"></param> /// <param name="precalculatedContextualEpsilon"></param> /// <returns></returns> public static bool AboutEquals(this double value1, double value2, double precalculatedContextualEpsilon) { return Math.Abs(value1 - value2) <= precalculatedContextualEpsilon; } // ****************************************************************** public static double GetContextualEpsilon(this double biggestPossibleContextualValue) { return biggestPossibleContextualValue * 1E-15; } // ****************************************************************** /// <summary> /// Mathlab equivalent /// </summary> /// <param name="dividend"></param> /// <param name="divisor"></param> /// <returns></returns> public static double Mod(this double dividend, double divisor) { return dividend - System.Math.Floor(dividend / divisor) * divisor; } // ****************************************************************** } 

यहां बताया गया है कि कैसे मैंने इसे सुलझाया, यह डबल डबल एक्सटेंशन विधि के साथ।

  public static bool NearlyEquals(this double? value1, double? value2, double unimportantDifference = 0.0001) { if (value1 != value2) { if(value1 == null || value2 == null) return false; return Math.Abs(value1.Value - value2.Value) < unimportantDifference; } return true; } 

  double? value1 = 100; value1.NearlyEquals(100.01); // will return false value1.NearlyEquals(100.000001); // will return true value1.NearlyEquals(100.01, 0.1); // will return true 

माइकल और परीक्षण द्वारा दिए गए उत्तरों से जारी रखने के लिए, सी # को मूल जावा कोड का अनुवाद करते समय ध्यान रखना एक महत्वपूर्ण बात यह है कि जावा और सी # उनकी स्थिरता अलग तरीके से परिभाषित करते हैं सी #, उदाहरण के लिए, जावा की MIN_NORMAL की कमी है, और MinValue के लिए परिभाषाएं बहुत भिन्न हैं

जावा MIN_VALUE को न्यूनतम संभावित सकारात्मक मान के रूप में परिभाषित करता है, जबकि सी # इसे समग्र रूप से सबसे छोटा संभव प्रतिनिधित्व योग्य मान के रूप में परिभाषित करता है। सी # में बराबर मूल्य एपसीलॉन है

MIN_NORMAL की कमी मूल एल्गोरिदम के प्रत्यक्ष अनुवाद के लिए समस्याग्रस्त है – इसके बिना, चीजें शून्य के निकट छोटी मानों के लिए नीचे तोड़ना शुरू होती हैं जावा का MIN_NORMAL, आईईईई विनिर्देशन का अनुसरण करता है जो कि सबसे महत्वपूर्ण संभव संख्या के बिना शून्य के रूप में महत्व देता है, और इसके साथ ही, हम एकल और युगल दोनों के लिए अपने खुद के नॉर्मल्स को परिभाषित कर सकते हैं (जो डीबीसी ने मूल उत्तर में टिप्पणियों में वर्णित है )।

सिंगल के लिए निम्नलिखित सी # कोड को फ़्लोटिंग प्वाइंट गाइड पर दिए गए सभी परीक्षणों से गुजरता है, और डबल संस्करण परीक्षा के मामलों में मामूली संशोधनों के साथ बढ़ती परिशुद्धता के लिए सभी परीक्षण पास करता है।

 public static bool ApproximatelyEqualEpsilon(float a, float b, float epsilon) { const float floatNormal = (1 << 23) * float.Epsilon; float absA = Math.Abs(a); float absB = Math.Abs(b); float diff = Math.Abs(a - b); if (a == b) { // Shortcut, handles infinities return true; } if (a == 0.0f || b == 0.0f || diff < floatNormal) { // a or b is zero, or both are extremely close to it. // relative error is less meaningful here return diff < (epsilon * floatNormal); } // use relative error return diff / Math.Min((absA + absB), float.MaxValue) < epsilon; } 

डबल्स का संस्करण प्रकार परिवर्तनों के लिए समान रूप से बचा है और सामान्य रूप से इसके जैसा परिभाषित किया जाता है।

 const double doubleNormal = (1L << 52) * double.Epsilon; 

हालांकि दूसरा विकल्प अधिक सामान्य है, पहला विकल्प तब बेहतर होता है जब आपके पास पूर्ण सहिष्णुता होती है, और जब आपको इन तुलनाओं में से कई निष्पादित करना पड़ता है यदि यह तुलना किसी छवि में हर पिक्सेल के लिए है, तो दूसरे विकल्प में गुणन आपके निष्पादन को अस्वीकार्य प्रदर्शन के स्तर पर धीमा कर सकता है।

मैंने नमूना का अनुवाद माइकल बोरगार्ड से किया था यह परिणाम है:

 public static bool NearlyEqual(float a, float b, float epsilon){ float absA = Math.Abs (a); float absB = Math.Abs (b); float diff = Math.Abs (a - b); if (a == b) { return true; } else if (a == 0 || b == 0 || diff < float.Epsilon) { // a or b is zero or both are extremely close to it // relative error is less meaningful here return diff < epsilon; } else { // use relative error return diff / (absA + absB) < epsilon; } } 

इस उत्तर में सुधार करने के लिए स्वतंत्र महसूस करें।

मुझे लगता है कि आपका दूसरा विकल्प सबसे अच्छा शर्त है आम तौर पर फ्लोटिंग-प्वाइंट तुलना में आप अक्सर केवल यह मानते हैं कि एक मूल्य एपिसलॉन के चयन द्वारा नियंत्रित किसी अन्य मूल्य की एक निश्चित सहिष्णुता के भीतर है।

इसके बारे में: b - delta < a && a < b + delta