Merge pull request #376 from atomia/master
[mono.git] / mcs / class / corlib / System / Single.cs
index 0b44eed28532167ee0ffd65e13f140de9ce209f5..de0f7c4ea1a5a137cb1a78c805984adb4fc98b4a 100644 (file)
 //
 
 using System.Globalization;
-
-#if NET_2_0
 using System.Runtime.ConstrainedExecution;
-#endif
 
 namespace System
 {
        [Serializable]
-       public struct Single : IComparable, IFormattable, IConvertible
-#if NET_2_0
-               , IComparable <float>, IEquatable <float>
-#endif
+       [System.Runtime.InteropServices.ComVisible (true)]
+       public struct Single : IComparable, IFormattable, IConvertible, IComparable <float>, IEquatable <float>
        {
                public const float Epsilon = 1.4e-45f;
                public const float MaxValue =  3.40282346638528859e38f;
@@ -51,17 +46,21 @@ namespace System
                public const float PositiveInfinity =  1.0f / 0.0f;
                public const float NegativeInfinity = -1.0f / 0.0f;
 
+               // Maximum allowed rounding-error so that float.MaxValue can round-trip successfully; calculated 
+               // using: (double.Parse (float.MaxValue.ToString ("r")) - (double) float.MaxValue).ToString ("r")
+               private const double MaxValueEpsilon = 3.6147112457961776e29d;
+
                internal float m_value;
 
-               public int CompareTo (object v)
+               public int CompareTo (object value)
                {
-                       if (v == null)
+                       if (value == null)
                                return 1;
 
-                       if (!(v is System.Single))
+                       if (!(value is System.Single))
                                throw new ArgumentException (Locale.GetText ("Value is not a System.Single."));
 
-                       float fv = (float)v;
+                       float fv = (float)value;
 
                        if (IsPositiveInfinity (m_value) && IsPositiveInfinity (fv))
                                return 0;
@@ -89,19 +88,19 @@ namespace System
                                return -1;
                }
 
-               public override bool Equals (object o)
+               public override bool Equals (object obj)
                {
-                       if (!(o is System.Single))
+                       if (!(obj is System.Single))
                                return false;
 
-                       if (IsNaN ((float) o)) {
+                       float value = (float) obj;
+
+                       if (IsNaN (value))
                                return IsNaN (m_value);
-                       }
 
-                       return ((float) o) == m_value;
+                       return (value == m_value);
                }
 
-#if NET_2_0
                public int CompareTo (float value)
                {
                        if (IsPositiveInfinity (m_value) && IsPositiveInfinity (value))
@@ -130,14 +129,13 @@ namespace System
                                return -1;
                }
 
-               public bool Equals (float value)
+               public bool Equals (float obj)
                {
-                       if (IsNaN (value))
+                       if (IsNaN (obj))
                                return IsNaN (m_value);
 
-                       return value == m_value;
+                       return obj == m_value;
                }
-#endif
 
                public unsafe override int GetHashCode ()
                {
@@ -145,14 +143,44 @@ namespace System
                        return *((int*)&f);
                }
 
+#if    NET_4_0
+               public static bool operator==(float left, float right)
+               {
+                       return left == right;
+               }
+
+               public static bool operator!=(float left, float right)
+               {
+                       return left != right;
+               }
+
+               public static bool operator>(float left, float right)
+               {
+                       return left > right;
+               }
+
+               public static bool operator>=(float left, float right)
+               {
+                       return left >= right;
+               }
+
+               public static bool operator<(float left, float right)
+               {
+                       return left < right;
+               }
+
+               public static bool operator<=(float left, float right)
+               {
+                       return left <= right;
+               }
+#endif
+
                public static bool IsInfinity (float f)
                {
                        return (f == PositiveInfinity || f == NegativeInfinity);
                }
 
-#if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-#endif
                public static bool IsNaN (float f)
                {
 #pragma warning disable 1718
@@ -174,7 +202,7 @@ namespace System
                {
                        double parsed_value = Double.Parse (
                                s, (NumberStyles.Float | NumberStyles.AllowThousands), null);
-                       if (parsed_value > (double) float.MaxValue)
+                       if (parsed_value - (double) float.MaxValue > MaxValueEpsilon && (!double.IsPositiveInfinity (parsed_value)))
                                throw new OverflowException();
 
                        return (float) parsed_value;
@@ -184,7 +212,7 @@ namespace System
                {
                        double parsed_value = Double.Parse (
                                s, (NumberStyles.Float | NumberStyles.AllowThousands), provider);
-                       if (parsed_value > (double) float.MaxValue)
+                       if (parsed_value - (double) float.MaxValue > MaxValueEpsilon && (!double.IsPositiveInfinity (parsed_value)))
                                throw new OverflowException();
 
                        return (float) parsed_value;
@@ -193,7 +221,7 @@ namespace System
                public static float Parse (string s, NumberStyles style)
                {
                        double parsed_value = Double.Parse (s, style, null);
-                       if (parsed_value > (double) float.MaxValue)
+                       if (parsed_value - (double) float.MaxValue > MaxValueEpsilon && (!double.IsPositiveInfinity (parsed_value)))
                                throw new OverflowException();
 
                        return (float) parsed_value;
@@ -202,12 +230,11 @@ namespace System
                public static float Parse (string s, NumberStyles style, IFormatProvider provider) 
                {
                        double parsed_value = Double.Parse (s, style, provider);
-                       if (parsed_value > (double) float.MaxValue)
+                       if (parsed_value - (double) float.MaxValue > MaxValueEpsilon && (!double.IsPositiveInfinity (parsed_value)))
                                throw new OverflowException();
 
                        return (float) parsed_value;
                }
-#if NET_2_0
                public static bool TryParse (string s, NumberStyles style, IFormatProvider provider, out float result)
                {
                        double parsed_value;
@@ -215,7 +242,7 @@ namespace System
                        if (!Double.Parse (s, style, provider, true, out parsed_value, out exc)) {
                                result = 0;
                                return false;
-                       } else if (parsed_value > (double) float.MaxValue) {
+                       } else if (parsed_value - (double) float.MaxValue > MaxValueEpsilon && (!double.IsPositiveInfinity (parsed_value))) {
                                result = 0;
                                return false;
                        }
@@ -227,15 +254,15 @@ namespace System
                {
                        return TryParse (s, NumberStyles.Any, null, out result);
                }
-#endif
+
                public override string ToString ()
                {
-                       return ToString (null, null);
+                       return NumberFormatter.NumberToString (m_value, null);
                }
 
                public string ToString (IFormatProvider provider)
                {
-                       return ToString (null, provider);
+                       return NumberFormatter.NumberToString (m_value, provider);
                }
 
                public string ToString (string format)
@@ -245,8 +272,7 @@ namespace System
 
                public string ToString (string format, IFormatProvider provider)
                {
-                       NumberFormatInfo nfi = NumberFormatInfo.GetInstance (provider);
-                       return NumberFormatter.NumberToString (format, m_value, nfi);
+                       return NumberFormatter.NumberToString (format, m_value, provider);
                }
 
                // ============= IConvertible Methods ============ //
@@ -310,9 +336,11 @@ namespace System
                        return System.Convert.ToSingle (m_value);
                }
 
-               object IConvertible.ToType (Type conversionType, IFormatProvider provider)
+               object IConvertible.ToType (Type targetType, IFormatProvider provider)
                {
-                       return System.Convert.ToType (m_value, conversionType, provider);
+                       if (targetType == null)
+                               throw new ArgumentNullException ("targetType");
+                       return System.Convert.ToType (m_value, targetType, provider, false);
                }
 
                ushort IConvertible.ToUInt16 (IFormatProvider provider)