[Mono-list] -- Math.cs --

yoros@wanadoo.es yoros@wanadoo.es
Sun, 2 Feb 2003 09:42:36 +0100


--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit


Hi,

Here are the final files that I got. I think that the Math performance
is good and that the results are the most accurate that can be with
"libm" because MS.NET are using another kind of numerical algorithms.

I changed the following files:

	mcs/class/corlib/System/Math.cs
	mono/mono/metadata/icall.c
	mono/mono/metadata/sysmath.h
	mono/mono/metadata/sysmath.c

With this mail, there is the changelog file for Math.cs (please, be
careful with the "tildes").

Sorry for the other posts, I was trying to get this out quickly because
I have a lot of work and I must study.

See you,

    Pedro

-- 
Pedro Martinez Juliá
\  yoros@terra.es
)|    yoros@wanadoo.es
/        http://yoros.cjb.net
Socio HispaLinux #311
Usuario Linux #275438 - http://counter.li.org
GnuPG public information:  pub  1024D/74F1D3AC
Key fingerprint = 8431 7B47 D2B4 5A46 5F8E  534F 588B E285 74F1 D3AC

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="Math.cs.patch"
Content-Transfer-Encoding: 8bit

Index: Math.cs
===================================================================
RCS file: /mono/mcs/class/corlib/System/Math.cs,v
retrieving revision 1.15
diff -u -p -r1.15 Math.cs
--- Math.cs	24 Jan 2003 16:10:01 -0000	1.15
+++ Math.cs	2 Feb 2003 08:29:34 -0000
@@ -4,8 +4,10 @@
 // Author:
 //   Bob Smith (bob@thestuff.net)
 //   Dan Lewis (dihlewis@yahoo.co.uk)
+//   Pedro Martínez Juliá (yoros@wanadoo.es)
 //
 // (C) 2001 Bob Smith.  http://www.thestuff.net
+// Copyright (C) 2003 Pedro Martínez Juliá <yoros@wanadoo.es>
 //
 
 using System;
@@ -62,37 +64,16 @@ namespace System
 
                 public static double Ceiling(double a)
                 {
-			if (Double.IsNaN(a)){
-				return Double.NaN;
-			}
-
-			if (Double.IsNegativeInfinity(a)){
-				return Double.NegativeInfinity;
-			}
-
-			if (Double.IsPositiveInfinity(a)){
-				return Double.PositiveInfinity;
-			}
-
-			double b = (double)((long)a);
-                        return (b < a)? b+1: b;
-                }
-                public static double Floor(double d) {
-			if (Double.IsNaN(d)){
-				return Double.NaN;
-			}
-
-			if (Double.IsNegativeInfinity(d)){
-				return Double.NegativeInfinity;
-			}
-
-			if (Double.IsPositiveInfinity(d)){
-				return Double.PositiveInfinity;
-			}
-
-			double b = (double)((long)d);
-			return (d < 0 && d != b) ? --b : b;
+                        double result = Floor(a);
+                        if (result != a) {
+                                result++;
+                        }
+                        return result;
                 }
+
+                [MethodImplAttribute (MethodImplOptions.InternalCall)]
+                public extern static double Floor (double value);
+
                 public static double IEEERemainder(double x, double y)
                 {
                         double r;
@@ -103,9 +84,8 @@ namespace System
                 }
                 public static double Log(double a, double newBase)
                 {
-                        if (a == 0) return Double.NegativeInfinity;
-                        else if (a < 0) return Double.NaN;
-                        return Log(a)/Log(newBase);
+                        double result = Log(a) / Log(newBase);
+                        return (result == -0)? 0: result;
                 }
 
                 public static byte Max(byte val1, byte val2)
@@ -215,58 +195,31 @@ namespace System
 
                 public static decimal Round(decimal d)
                 {
-                        decimal r = (decimal)((long)d);
-                        decimal a = Abs (d - r);
-                        if (a > .5M) return (r >= 0 ? ++r : --r);
-                        else if (a <.5M) return r;
-                        else
-                        {
-                                if (r%2 == 0) return r;
-                                else return ++r;
-                        }
+                        return Decimal.Round(d, 0);
                 }
                 public static decimal Round(decimal d, int decimals)
                 {
-                        long p = 1;
-                        int c;
-                        decimal retval = d;
-                        if (decimals < 0 || decimals > 15)
-                                throw new ArgumentOutOfRangeException(Locale.GetText (
-					"Value is too small or too big."));
-                        else if (decimals == 0)
-                                return Math.Round(d);
-                        for (c=0; c<decimals; c++) p*=10;
-                        retval*=p;
-                        retval=Math.Round(retval);
-                        retval/=p;
-                        return retval;
-                }
-                public static double Round(double d)
-                {
-                        double r = (double)((long)d);
-                        double a = Abs (d - r);
-                        if (a > .5) return (r >= 0 ? ++r : --r);
-                        else if (a <.5) return r;
-                        else
-                        {
-                                if (r%2 == 0) return r;
-                                else return ++r;
-                        }
+                        return Decimal.Round(d, decimals);
                 }
+
+                [MethodImplAttribute (MethodImplOptions.InternalCall)]
+                public extern static double Round(double d);
+
                 public static double Round(double value, int digits) {
-                        long p = 1;
-                        int c;
-                        double retval = value;
                         if (digits < 0 || digits > 15)
                                 throw new ArgumentOutOfRangeException(Locale.GetText (
 					"Value is too small or too big."));
-                        else if (digits == 0)
-                                return Math.Round(value);
-                        for (c=0; c<digits; c++) p*=10;
-                        retval*=p;
-                        retval=Math.Round(retval);
-                        retval/=p;
-                        return retval;
+                        if (Double.IsInfinity(value))
+                                return value;
+                        double integral_part = Round(value);
+                        if (digits == 0)
+                                return integral_part;
+                        double p = Math.Pow(10, digits);
+                        double decimal_part = value - integral_part;
+                        decimal_part *= p;
+                        decimal_part = Math.Round(decimal_part);
+                        decimal_part /= p;
+                        return integral_part + decimal_part;
                 }
                 public static int Sign(decimal value)
                 {
@@ -275,11 +228,15 @@ namespace System
                 }
                 public static int Sign(double value)
                 {
+                        if (Double.IsNaN(value))
+                                throw new ArithmeticException("NAN");
                         if (value > 0) return 1;
                         return (value == 0)? 0: -1;
                 }
                 public static int Sign(float value)
                 {
+                        if (Single.IsNaN(value))
+                                throw new ArithmeticException("NAN");
                         if (value > 0) return 1;
                         return (value == 0)? 0: -1;
                 }

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="icall.c.patch"

Index: icall.c
===================================================================
RCS file: /mono/mono/mono/metadata/icall.c,v
retrieving revision 1.256
diff -u -p -r1.256 icall.c
--- icall.c	31 Jan 2003 18:38:14 -0000	1.256
+++ icall.c	2 Feb 2003 02:53:50 -0000
@@ -3552,6 +3552,8 @@ static gconstpointer icall_map [] = {
 	/*
 	 * System.Math
 	 */
+	"System.Math::Floor", ves_icall_System_Math_Floor,
+	"System.Math::Round", ves_icall_System_Math_Round,
 	"System.Math::Sin", ves_icall_System_Math_Sin,
         "System.Math::Cos", ves_icall_System_Math_Cos,
         "System.Math::Tan", ves_icall_System_Math_Tan,

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sysmath.h.patch"

Index: sysmath.h
===================================================================
RCS file: /mono/mono/mono/metadata/sysmath.h,v
retrieving revision 1.1
diff -u -p -r1.1 sysmath.h
--- sysmath.h	18 Mar 2002 16:49:45 -0000	1.1
+++ sysmath.h	2 Feb 2003 08:28:44 -0000
@@ -13,6 +13,9 @@
 #include <config.h>
 #include <glib.h>
 
+extern gdouble ves_icall_System_Math_Floor (gdouble x);
+extern gdouble ves_icall_System_Math_Round (gdouble x);
+
 extern gdouble 
 ves_icall_System_Math_Sin (gdouble x);
 

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sysmath.c.patch"

Index: sysmath.c
===================================================================
RCS file: /mono/mono/mono/metadata/sysmath.c,v
retrieving revision 1.7
diff -u -p -r1.7 sysmath.c
--- sysmath.c	28 Nov 2002 10:02:07 -0000	1.7
+++ sysmath.c	2 Feb 2003 08:28:36 -0000
@@ -29,6 +29,16 @@ static __huge_val_t __huge_val = { __HUG
 #  define HUGE_VAL      (__huge_val.__d)
 #endif
 
+gdouble ves_icall_System_Math_Floor (gdouble x) {
+	MONO_ARCH_SAVE_REGS;
+	return floor(x);
+}
+
+gdouble ves_icall_System_Math_Round (gdouble x) {
+	MONO_ARCH_SAVE_REGS;
+	return round(x);
+}
+
 gdouble 
 ves_icall_System_Math_Sin (gdouble x)
 {
@@ -112,7 +122,14 @@ ves_icall_System_Math_Atan2 (gdouble y, 
 {
 	MONO_ARCH_SAVE_REGS;
 
-	return atan2 (y, x);
+	if ((y == HUGE_VAL && x == HUGE_VAL) ||
+		(y == HUGE_VAL && x == -HUGE_VAL) ||
+		(y == -HUGE_VAL && x == HUGE_VAL) ||
+		(y == -HUGE_VAL && x == -HUGE_VAL)) {
+		return NAN;
+	}
+	double result = atan2 (y, x);
+	return (result == -0)? 0: result;
 }
 
 gdouble 
@@ -154,7 +171,16 @@ ves_icall_System_Math_Pow (gdouble x, gd
 {
 	MONO_ARCH_SAVE_REGS;
 
-	return pow (x, y);
+	if ((x == 1 || x == -1) && (y == HUGE_VAL || y == -HUGE_VAL)) {
+		return NAN;
+	}
+
+	if (x == NAN || y == NAN) {
+		return NAN;
+	}
+
+	double result = pow (x, y);
+	return (result == -0)? 0: result;
 }
 
 gdouble 

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename=Math_chagelog_entry
Content-Transfer-Encoding: 8bit

2003-02-02  Pedro Martínez Juliá  <yoros@wanadoo.es>

	* Math.cs: Revision of all functions and correction of a few ones
	like Round, Floor, Ceiling, etc...

--J2SCkAp4GZ/dPZZf--