The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ MathObject

  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. namespace Microsoft.JScript
  16. {
  17.    
  18.     using System;
  19.    
  20.     public class MathObject : JSObject
  21.     {
  22.         public const double E = 2.71828182845905;
  23.         public const double LN10 = 2.30258509299405;
  24.         public const double LN2 = 0.693147180559945;
  25.         public const double LOG2E = 1.44269504088896;
  26.         public const double LOG10E = 0.434294481903252;
  27.         public const double PI = 3.14159265358979;
  28.         public const double SQRT1_2 = 0.707106781186548;
  29.         public const double SQRT2 = 1.4142135623731;
  30.        
  31.         private static readonly System.Random internalRandom = new System.Random();
  32.         static internal MathObject ob = null;
  33.        
  34.         internal MathObject(ScriptObject parent) : base(parent)
  35.         {
  36.         }
  37.        
  38.         [JSFunctionAttribute(0, JSBuiltin.Math_abs)]
  39.         public static double abs(double d)
  40.         {
  41.             if (d < 0)
  42.                 return -d;
  43.             else if (d > 0)
  44.                 return d;
  45.             else if (d == d)
  46.                 return 0.0;
  47.             else
  48.                 return d;
  49.         }
  50.        
  51.         [JSFunctionAttribute(0, JSBuiltin.Math_acos)]
  52.         public static double acos(double x)
  53.         {
  54.             return System.Math.Acos(x);
  55.         }
  56.        
  57.         [JSFunctionAttribute(0, JSBuiltin.Math_asin)]
  58.         public static double asin(double x)
  59.         {
  60.             return System.Math.Asin(x);
  61.         }
  62.        
  63.         [JSFunctionAttribute(0, JSBuiltin.Math_atan)]
  64.         public static double atan(double x)
  65.         {
  66.             return System.Math.Atan(x);
  67.         }
  68.        
  69.         [JSFunctionAttribute(0, JSBuiltin.Math_atan2)]
  70.         public static double atan2(double dy, double dx)
  71.         {
  72.             return System.Math.Atan2(dy, dx);
  73.         }
  74.        
  75.         [JSFunctionAttribute(0, JSBuiltin.Math_ceil)]
  76.         public static double ceil(double x)
  77.         {
  78.             return System.Math.Ceiling(x);
  79.         }
  80.        
  81.         private static double Compare(double x, double y)
  82.         {
  83.             if (x != 0 || y != 0)
  84.                 if (x == y)
  85.                     return 0;
  86.                 else
  87.                 //x and y could be infinities, in which case - will not return 0.
  88.                     return x - y;
  89.             double x1 = 1 / x;
  90.             //will be < 0 if x == -0
  91.             double y1 = 1 / y;
  92.             if (x1 < 0) {
  93.                 return y1 < 0 ? 0 : -1;
  94.             }
  95.             else if (y1 < 0)
  96.                 return 1;
  97.             else
  98.                 return 0;
  99.         }
  100.        
  101.         [JSFunctionAttribute(0, JSBuiltin.Math_cos)]
  102.         public static double cos(double x)
  103.         {
  104.             return System.Math.Cos(x);
  105.         }
  106.        
  107.         [JSFunctionAttribute(0, JSBuiltin.Math_exp)]
  108.         public static double exp(double x)
  109.         {
  110.             return System.Math.Exp(x);
  111.         }
  112.        
  113.         [JSFunctionAttribute(0, JSBuiltin.Math_floor)]
  114.         public static double floor(double x)
  115.         {
  116.             return System.Math.Floor(x);
  117.         }
  118.        
  119.         internal override string GetClassName()
  120.         {
  121.             return "Math";
  122.         }
  123.        
  124.         [JSFunctionAttribute(0, JSBuiltin.Math_log)]
  125.         public static double log(double x)
  126.         {
  127.             return System.Math.Log(x);
  128.         }
  129.        
  130.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasVarArgs, JSBuiltin.Math_max)]
  131.         public static double max(object x, object y, params object[] args)
  132.         {
  133.             if (x is Missing)
  134.                 return Double.NegativeInfinity;
  135.             double dx = Convert.ToNumber(x);
  136.             if (y is Missing)
  137.                 return dx;
  138.             double dy = Convert.ToNumber(y);
  139.             double result = MathObject.Compare(dx, dy);
  140.             if (result != result)
  141.                 return result;
  142.             double lhMax = dx;
  143.             if (result < 0)
  144.                 lhMax = dy;
  145.             if (args.Length == 0)
  146.                 return lhMax;
  147.             return MathObject.maxv(lhMax, args, 0);
  148.         }
  149.        
  150.         private static double maxv(double lhMax, object[] args, int start)
  151.         {
  152.             if (args.Length == start)
  153.                 return lhMax;
  154.             double head = Convert.ToNumber(args[start]);
  155.             double result = MathObject.Compare(lhMax, head);
  156.             if (result != result)
  157.                 return result;
  158.             if (result > 0)
  159.                 head = lhMax;
  160.             return MathObject.maxv(head, args, start + 1);
  161.         }
  162.        
  163.         [JSFunctionAttribute(JSFunctionAttributeEnum.HasVarArgs, JSBuiltin.Math_min)]
  164.         public static double min(object x, object y, params object[] args)
  165.         {
  166.             if (x is Missing)
  167.                 return Double.PositiveInfinity;
  168.             double dx = Convert.ToNumber(x);
  169.             if (y is Missing)
  170.                 return dx;
  171.             double dy = Convert.ToNumber(y);
  172.             double result = MathObject.Compare(dx, dy);
  173.             if (result != result)
  174.                 return result;
  175.             double lhMin = dx;
  176.             if (result > 0)
  177.                 lhMin = dy;
  178.             if (args.Length == 0)
  179.                 return lhMin;
  180.             return MathObject.minv(lhMin, args, 0);
  181.         }
  182.        
  183.         private static double minv(double lhMin, object[] args, int start)
  184.         {
  185.             if (args.Length == start)
  186.                 return lhMin;
  187.             double head = Convert.ToNumber(args[start]);
  188.             double result = MathObject.Compare(lhMin, head);
  189.             if (result != result)
  190.                 return result;
  191.             if (result < 0)
  192.                 head = lhMin;
  193.             return MathObject.minv(head, args, start + 1);
  194.         }
  195.        
  196.         [JSFunctionAttribute(0, JSBuiltin.Math_pow)]
  197.         public static double pow(double dx, double dy)
  198.         {
  199.             if (dy == 0)
  200.                 return 1.0;
  201.             if ((dx == 1.0 || dx == -1.0) && (dy == Double.PositiveInfinity || dy == Double.NegativeInfinity))
  202.                 return Double.NaN;
  203.             if (Double.IsNaN(dy))
  204.                 return Double.NaN;
  205.            
  206.             // If dy is an odd integer, return -0. This case is inconsistent between x86 and amd64.
  207.             if (dx == Double.NegativeInfinity && dy < 0.0) {
  208.                 if (Math.IEEERemainder((-dy) + 1.0, 2.0) == 0.0)
  209.                     return -0.0;
  210.             }
  211.            
  212.             try {
  213.                 return System.Math.Pow(dx, dy);
  214.             }
  215.             catch {
  216.                 if (dx != dx || dy != dy)
  217.                     return Double.NaN;
  218.                 if (dx == 0.0)
  219.                     if (dy < 0.0) {
  220.                         if ((double)(long)dy == dy && ((long)(-dy)) % 2 > 0) {
  221.                             double f = 1.0 / dx;
  222.                             if (!(f >= 0.0))
  223.                                 return Double.NegativeInfinity;
  224.                         }
  225.                         return Double.PositiveInfinity;
  226.                     }
  227.                 return Double.NaN;
  228.             }
  229.         }
  230.        
  231.         [JSFunctionAttribute(0, JSBuiltin.Math_random)]
  232.         public static double random()
  233.         {
  234.             return MathObject.internalRandom.NextDouble();
  235.         }
  236.        
  237.         [JSFunctionAttribute(0, JSBuiltin.Math_round)]
  238.         public static double round(double d)
  239.         {
  240.             if (d == 0)
  241.                 return d;
  242.             else
  243.                 return System.Math.Floor(d + 0.5);
  244.         }
  245.        
  246.         [JSFunctionAttribute(0, JSBuiltin.Math_sin)]
  247.         public static double sin(double x)
  248.         {
  249.             return System.Math.Sin(x);
  250.         }
  251.        
  252.         [JSFunctionAttribute(0, JSBuiltin.Math_sqrt)]
  253.         public static double sqrt(double x)
  254.         {
  255.             return System.Math.Sqrt(x);
  256.         }
  257.        
  258.         [JSFunctionAttribute(0, JSBuiltin.Math_tan)]
  259.         public static double tan(double x)
  260.         {
  261.             return System.Math.Tan(x);
  262.         }
  263.        
  264.     }
  265. }

Developer Fusion