External/OxyPlot/OxyPlot/Foundation/DoubleExtensions.cs
author StephaneLenclud
Tue, 03 Feb 2015 10:14:18 +0100
branchMiniDisplay
changeset 450 f2d8620e2434
permissions -rw-r--r--
Rebracer update.
     1 // --------------------------------------------------------------------------------------------------------------------
     2 // <copyright file="DoubleExtensions.cs" company="OxyPlot">
     3 //   The MIT License (MIT)
     4 //
     5 //   Copyright (c) 2012 Oystein Bjorke
     6 //
     7 //   Permission is hereby granted, free of charge, to any person obtaining a
     8 //   copy of this software and associated documentation files (the
     9 //   "Software"), to deal in the Software without restriction, including
    10 //   without limitation the rights to use, copy, modify, merge, publish,
    11 //   distribute, sublicense, and/or sell copies of the Software, and to
    12 //   permit persons to whom the Software is furnished to do so, subject to
    13 //   the following conditions:
    14 //
    15 //   The above copyright notice and this permission notice shall be included
    16 //   in all copies or substantial portions of the Software.
    17 //
    18 //   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    19 //   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    20 //   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    21 //   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    22 //   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    23 //   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    24 //   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    25 // </copyright>
    26 // <summary>
    27 //   Extension methods for double values.
    28 // </summary>
    29 // --------------------------------------------------------------------------------------------------------------------
    30 namespace OxyPlot
    31 {
    32     using System;
    33     using System.Globalization;
    34 
    35     /// <summary>
    36     /// Provides extension methods for the <see cref="Double"/> type.
    37     /// </summary>
    38     public static class DoubleExtensions
    39     {
    40         /// <summary>
    41         /// Squares the specified value.
    42         /// </summary>
    43         /// <param name="x">
    44         /// The value.
    45         /// </param>
    46         /// <returns>
    47         /// Squared value.
    48         /// </returns>
    49         public static double Squared(this double x)
    50         {
    51             return x * x;
    52         }
    53 
    54         /// <summary>
    55         /// Exponent function.
    56         /// </summary>
    57         /// <param name="x">
    58         /// The value.
    59         /// </param>
    60         /// <returns>
    61         /// The exponent.
    62         /// </returns>
    63         public static double GetExponent(this double x)
    64         {
    65             return Math.Round(Math.Log(Math.Abs(x), 10));
    66         }
    67 
    68         /// <summary>
    69         /// Mantissa function.
    70         /// http://en.wikipedia.org/wiki/Mantissa
    71         /// </summary>
    72         /// <param name="x">
    73         /// The value.
    74         /// </param>
    75         /// <returns>
    76         /// The mantissa.
    77         /// </returns>
    78         public static double GetMantissa(this double x)
    79         {
    80             return x / Math.Pow(10, x.GetExponent());
    81         }
    82 
    83         /// <summary>
    84         /// Removes the floating point noise.
    85         /// </summary>
    86         /// <param name="value">
    87         /// The value.
    88         /// </param>
    89         /// <returns>
    90         /// A double without noise.
    91         /// </returns>
    92         public static double RemoveNoise2(this double value)
    93         {
    94             return (double)((decimal)value);
    95         }
    96 
    97         /// <summary>
    98         /// Removes the floating point noise.
    99         /// </summary>
   100         /// <param name="value">
   101         /// The value.
   102         /// </param>
   103         /// <param name="maxDigits">
   104         /// The maximum number of digits.
   105         /// </param>
   106         /// <returns>
   107         /// A double without noise.
   108         /// </returns>
   109         public static double RemoveNoise(this double value, int maxDigits = 8)
   110         {
   111             return double.Parse(value.ToString("e" + maxDigits));
   112         }
   113 
   114         /// <summary>
   115         /// Removes the noise from double math.
   116         /// </summary>
   117         /// <param name="value">
   118         /// The value.
   119         /// </param>
   120         /// <returns>
   121         /// A double without noise.
   122         /// </returns>
   123         public static double RemoveNoiseFromDoubleMath(this double value)
   124         {
   125             if (value.IsZero() || Math.Abs(Math.Log10(Math.Abs(value))) < 27)
   126             {
   127                 return (double)((decimal)value);
   128             }
   129 
   130             return double.Parse(value.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
   131         }
   132 
   133         /// <summary>
   134         /// Determines whether the specified value is zero.
   135         /// </summary>
   136         /// <param name="value">The value.</param>
   137         /// <returns>
   138         /// <c>true</c> if the specified value is zero; otherwise, <c>false</c>.
   139         /// </returns>
   140         public static bool IsZero(this double value)
   141         {
   142             return Math.Abs(value) < double.Epsilon;
   143         }
   144 
   145         /// <summary>
   146         /// Calculates the nearest larger multiple of the specified value.
   147         /// </summary>
   148         /// <param name="value">
   149         /// The value.
   150         /// </param>
   151         /// <param name="step">
   152         /// The multiplier.
   153         /// </param>
   154         /// <returns>
   155         /// The multiple value.
   156         /// </returns>
   157         public static double ToUpperMultiple(this double value, double step)
   158         {
   159             var i = (int)Math.Ceiling(value / step);
   160             return (step * i).RemoveNoise();
   161         }
   162 
   163         /// <summary>
   164         /// Calculates the nearest smaller multiple of the specified value.
   165         /// </summary>
   166         /// <param name="value">
   167         /// The value.
   168         /// </param>
   169         /// <param name="step">
   170         /// The multiplier.
   171         /// </param>
   172         /// <returns>
   173         /// The multiple value.
   174         /// </returns>
   175         public static double ToLowerMultiple(this double value, double step)
   176         {
   177             var i = (int)Math.Floor(value / step);
   178             return (step * i).RemoveNoise();
   179         }
   180 
   181 #if THISISNOTINUSE
   182 
   183     // <summary>
   184     // Gets the mantissa and exponent.
   185     // </summary>
   186     /// <remarks>
   187     /// From <see cref="http://stackoverflow.com/questions/389993/extracting-mantissa-and-exponent-from-double-in-c"/>
   188     /// </remarks>
   189     /// <param name="d">The d.</param>
   190     /// <param name="negative">if set to <c>true</c> [negative].</param>
   191     /// <param name="mantissa">The mantissa.</param>
   192     /// <param name="exponent">The exponent.</param>
   193         public static void GetMantissaAndExponent(this double d, out bool negative, out long mantissa, out int exponent)
   194         {
   195             // Translate the double into sign, exponent and mantissa.
   196             long bits = BitConverter.DoubleToInt64Bits(d);
   197 
   198 // Note that the shift is sign-extended, hence the test against -1 not 1
   199             negative = (bits < 0);
   200             exponent = (int)((bits >> 52) & 0x7ffL);
   201             mantissa = bits & 0xfffffffffffffL;
   202 
   203             // Subnormal numbers; exponent is effectively one higher,
   204             // but there's no extra normalisation bit in the mantissa
   205             if (exponent == 0)
   206             {
   207                 exponent++;
   208             }
   209 
   210 // Normal numbers; leave exponent as it is but add extra
   211             // bit to the front of the mantissa
   212             else
   213             {
   214                 mantissa = mantissa | (1L << 52);
   215             }
   216 
   217             // Bias the exponent. It's actually biased by 1023, but we're
   218             // treating the mantissa as m.0 rather than 0.m, so we need
   219             // to subtract another 52 from it.
   220             exponent -= 1075;
   221 
   222             if (mantissa == 0)
   223             {
   224                 return;
   225             }
   226 
   227             /* Normalize */
   228             while ((mantissa & 1) == 0)
   229             {    /*  i.e., Mantissa is even */
   230                 mantissa >>= 1;
   231                 exponent++;
   232             }
   233         }
   234 #endif
   235     }
   236 }