The Labs \ Source Viewer \ SSCLI \ System \ Single

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. /*============================================================
  16. **
  17. ** Class:  Single
  18. **
  19. **
  20. ** Purpose: A wrapper class for the primitive type float.
  21. **
  22. **
  23. ===========================================================*/
  24. namespace System
  25. {
  26.    
  27.     using System.Globalization;
  28.     using System;
  29.     using System.Runtime.InteropServices;
  30.     using System.Runtime.CompilerServices;
  31.     using System.Runtime.ConstrainedExecution;
  32.    
  33.     [Serializable(), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
  34.     [System.Runtime.InteropServices.ComVisible(true)]
  35.     public struct Single : IComparable, IFormattable, IConvertible, IComparable<float>, IEquatable<float>
  36.     {
  37.         internal float m_value;
  38.        
  39.         //
  40.         // Public constants
  41.         //
  42.         public const float MinValue = (float)-3.40282346638529E+38;
  43.         public const float Epsilon = (float)1.4E-45;
  44.         public const float MaxValue = (float)3.40282346638529E+38;
  45.         public const float PositiveInfinity = (float)1.0 / (float)0.0;
  46.         public const float NegativeInfinity = (float)-1.0 / (float)0.0;
  47.         public const float NaN = (float)0.0 / (float)0.0;
  48.        
  49.         unsafe public static bool IsInfinity(float f)
  50.         {
  51.             return (*(int*)(&f) & 2147483647) == 2139095040;
  52.         }
  53.         unsafe public static bool IsPositiveInfinity(float f)
  54.         {
  55.             return *(int*)(&f) == 2139095040;
  56.         }
  57.         unsafe public static bool IsNegativeInfinity(float f)
  58.         {
  59.             return *(int*)(&f) == unchecked((int)4286578688u);
  60.         }
  61.        
  62.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  63.         public static bool IsNaN(float f)
  64.         {
  65.             //Jit will generate inlineable code with this
  66.             // warning CS1718: Comparison to same variable
  67.             #pragma warning disable 1718
  68.             if (f != f) {
  69.                 return true;
  70.             }
  71.             else {
  72.                 return false;
  73.             }
  74.             #pragma warning restore 1718
  75.         }
  76.        
  77.         // Compares this object to another object, returning an integer that
  78.         // indicates the relationship.
  79.         // Returns a value less than zero if this object
  80.         // null is considered to be less than any instance.
  81.         // If object is not of type Single, this method throws an ArgumentException.
  82.         //
  83.         public int CompareTo(object value)
  84.         {
  85.             if (value == null) {
  86.                 return 1;
  87.             }
  88.             if (value is float) {
  89.                 float f = (float)value;
  90.                 if (m_value < f)
  91.                     return -1;
  92.                 if (m_value > f)
  93.                     return 1;
  94.                 if (m_value == f)
  95.                     return 0;
  96.                
  97.                 // At least one of the values is NaN.
  98.                 if (IsNaN(m_value))
  99.                     return (IsNaN(f) ? 0 : -1);
  100.                 else
  101.                     // f is NaN.
  102.                     return 1;
  103.             }
  104.             throw new ArgumentException(Environment.GetResourceString("Arg_MustBeSingle"));
  105.         }
  106.        
  107.        
  108.         public int CompareTo(float value)
  109.         {
  110.             if (m_value < value)
  111.                 return -1;
  112.             if (m_value > value)
  113.                 return 1;
  114.             if (m_value == value)
  115.                 return 0;
  116.            
  117.             // At least one of the values is NaN.
  118.             if (IsNaN(m_value))
  119.                 return (IsNaN(value) ? 0 : -1);
  120.             else
  121.                 // f is NaN.
  122.                 return 1;
  123.         }
  124.        
  125.         public override bool Equals(object obj)
  126.         {
  127.             if (!(obj is float)) {
  128.                 return false;
  129.             }
  130.             float temp = ((float)obj).m_value;
  131.             if (temp == m_value) {
  132.                 return true;
  133.             }
  134.            
  135.             return IsNaN(temp) && IsNaN(m_value);
  136.         }
  137.        
  138.         public bool Equals(float obj)
  139.         {
  140.             if (obj == m_value) {
  141.                 return true;
  142.             }
  143.            
  144.             return IsNaN(obj) && IsNaN(m_value);
  145.         }
  146.        
  147.         unsafe public override int GetHashCode()
  148.         {
  149.             float f = m_value;
  150.             if (f == 0) {
  151.                 // Ensure that 0 and -0 have the same hash code
  152.                 return 0;
  153.             }
  154.             int v = *(int*)(&f);
  155.             return v;
  156.         }
  157.        
  158.         public override string ToString()
  159.         {
  160.             return Number.FormatSingle(m_value, null, NumberFormatInfo.CurrentInfo);
  161.         }
  162.        
  163.         public string ToString(IFormatProvider provider)
  164.         {
  165.             return Number.FormatSingle(m_value, null, NumberFormatInfo.GetInstance(provider));
  166.         }
  167.        
  168.         public string ToString(string format)
  169.         {
  170.             return Number.FormatSingle(m_value, format, NumberFormatInfo.CurrentInfo);
  171.         }
  172.        
  173.         public string ToString(string format, IFormatProvider provider)
  174.         {
  175.             return Number.FormatSingle(m_value, format, NumberFormatInfo.GetInstance(provider));
  176.         }
  177.        
  178.         // Parses a float from a String in the given style. If
  179.         // a NumberFormatInfo isn't specified, the current culture's
  180.         // NumberFormatInfo is assumed.
  181.         //
  182.         // This method will not throw an OverflowException, but will return
  183.         // PositiveInfinity or NegativeInfinity for a number that is too
  184.         // large or too small.
  185.         //
  186.         public static float Parse(string s)
  187.         {
  188.             return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
  189.         }
  190.        
  191.         public static float Parse(string s, NumberStyles style)
  192.         {
  193.             NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
  194.             return Parse(s, style, NumberFormatInfo.CurrentInfo);
  195.         }
  196.        
  197.         public static float Parse(string s, IFormatProvider provider)
  198.         {
  199.             return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.GetInstance(provider));
  200.         }
  201.        
  202.         public static float Parse(string s, NumberStyles style, IFormatProvider provider)
  203.         {
  204.             NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
  205.             return Parse(s, style, NumberFormatInfo.GetInstance(provider));
  206.         }
  207.        
  208.         private static float Parse(string s, NumberStyles style, NumberFormatInfo info)
  209.         {
  210.             try {
  211.                 return Number.ParseSingle(s, style, info);
  212.             }
  213.             catch (FormatException) {
  214.                 //If we caught a FormatException, it may be from one of our special strings.
  215.                 //Check the three with which we're concerned and rethrow if it's not one of
  216.                 //those strings.
  217.                 string sTrim = s.Trim();
  218.                 if (sTrim.Equals(info.PositiveInfinitySymbol)) {
  219.                     return PositiveInfinity;
  220.                 }
  221.                 if (sTrim.Equals(info.NegativeInfinitySymbol)) {
  222.                     return NegativeInfinity;
  223.                 }
  224.                 if (sTrim.Equals(info.NaNSymbol)) {
  225.                     return NaN;
  226.                 }
  227.                 //Rethrow the previous exception;
  228.                 throw;
  229.             }
  230.         }
  231.        
  232.         public static bool TryParse(string s, out float result)
  233.         {
  234.             return TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out result);
  235.         }
  236.        
  237.         public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out float result)
  238.         {
  239.             NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
  240.             return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
  241.         }
  242.        
  243.         private static bool TryParse(string s, NumberStyles style, NumberFormatInfo info, out float result)
  244.         {
  245.             if (s == null) {
  246.                 result = 0;
  247.                 return false;
  248.             }
  249.             bool success = Number.TryParseSingle(s, style, info, out result);
  250.             if (!success) {
  251.                 string sTrim = s.Trim();
  252.                 if (sTrim.Equals(info.PositiveInfinitySymbol)) {
  253.                     result = PositiveInfinity;
  254.                 }
  255.                 else if (sTrim.Equals(info.NegativeInfinitySymbol)) {
  256.                     result = NegativeInfinity;
  257.                 }
  258.                 else if (sTrim.Equals(info.NaNSymbol)) {
  259.                     result = NaN;
  260.                 }
  261.                 else
  262.                     return false;
  263.                 // We really failed
  264.             }
  265.             return true;
  266.            
  267.         }
  268.        
  269.         //
  270.         // IValue implementation
  271.         //
  272.        
  273.         public TypeCode GetTypeCode()
  274.         {
  275.             return TypeCode.Single;
  276.         }
  277.        
  278.        
  279.         /// <internalonly/>
  280.         bool IConvertible.ToBoolean(IFormatProvider provider)
  281.         {
  282.             return Convert.ToBoolean(m_value);
  283.         }
  284.        
  285.         /// <internalonly/>
  286.         char IConvertible.ToChar(IFormatProvider provider)
  287.         {
  288.             throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_FromTo"), "Single", "Char"));
  289.         }
  290.        
  291.         /// <internalonly/>
  292.         sbyte IConvertible.ToSByte(IFormatProvider provider)
  293.         {
  294.             return Convert.ToSByte(m_value);
  295.         }
  296.        
  297.         /// <internalonly/>
  298.         byte IConvertible.ToByte(IFormatProvider provider)
  299.         {
  300.             return Convert.ToByte(m_value);
  301.         }
  302.        
  303.         /// <internalonly/>
  304.         short IConvertible.ToInt16(IFormatProvider provider)
  305.         {
  306.             return Convert.ToInt16(m_value);
  307.         }
  308.        
  309.         /// <internalonly/>
  310.         ushort IConvertible.ToUInt16(IFormatProvider provider)
  311.         {
  312.             return Convert.ToUInt16(m_value);
  313.         }
  314.        
  315.         /// <internalonly/>
  316.         int IConvertible.ToInt32(IFormatProvider provider)
  317.         {
  318.             return Convert.ToInt32(m_value);
  319.         }
  320.        
  321.         /// <internalonly/>
  322.         uint IConvertible.ToUInt32(IFormatProvider provider)
  323.         {
  324.             return Convert.ToUInt32(m_value);
  325.         }
  326.        
  327.         /// <internalonly/>
  328.         long IConvertible.ToInt64(IFormatProvider provider)
  329.         {
  330.             return Convert.ToInt64(m_value);
  331.         }
  332.        
  333.         /// <internalonly/>
  334.         ulong IConvertible.ToUInt64(IFormatProvider provider)
  335.         {
  336.             return Convert.ToUInt64(m_value);
  337.         }
  338.        
  339.         /// <internalonly/>
  340.         float IConvertible.ToSingle(IFormatProvider provider)
  341.         {
  342.             return m_value;
  343.         }
  344.        
  345.         /// <internalonly/>
  346.         double IConvertible.ToDouble(IFormatProvider provider)
  347.         {
  348.             return Convert.ToDouble(m_value);
  349.         }
  350.        
  351.         /// <internalonly/>
  352.         decimal IConvertible.ToDecimal(IFormatProvider provider)
  353.         {
  354.             return Convert.ToDecimal(m_value);
  355.         }
  356.        
  357.         /// <internalonly/>
  358.         DateTime IConvertible.ToDateTime(IFormatProvider provider)
  359.         {
  360.             throw new InvalidCastException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("InvalidCast_FromTo"), "Single", "DateTime"));
  361.         }
  362.        
  363.         /// <internalonly/>
  364.         object IConvertible.ToType(Type type, IFormatProvider provider)
  365.         {
  366.             return Convert.DefaultToType((IConvertible)this, type, provider);
  367.         }
  368.     }
  369. }

Developer Fusion