X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsysmath.c;h=c5943b44cc908340346131c61e31c353e1a2b190;hb=b9e97c9957ceb5a04ab1a43da3074646b196e946;hp=6627009eebb98644ad62238f196cb4bbb7d41e1b;hpb=a8b22e0e864c03b8cfd2f2cb5a8075b6611c5553;p=mono.git diff --git a/mono/metadata/sysmath.c b/mono/metadata/sysmath.c index 6627009eebb..c5943b44cc9 100644 --- a/mono/metadata/sysmath.c +++ b/mono/metadata/sysmath.c @@ -1,5 +1,12 @@ -/* math.c - these are based on bob smith's csharp routines */ - +/* + * sysmath.c: these are based on bob smith's csharp routines + * + * Author: + * Mono Project (http://www.mono-project.com) + * + * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) + * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + */ #define __USE_ISOC99 #include #include @@ -48,23 +55,41 @@ gdouble ves_icall_System_Math_Round (gdouble x) { return int_part; } -gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits) { - double p, int_part, dec_part; +gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits, gboolean away_from_zero) { +#if !defined (HAVE_ROUND) || !defined (HAVE_RINT) + double int_part, dec_part; +#endif + double p; + MONO_ARCH_SAVE_REGS; if (value == HUGE_VAL) return HUGE_VAL; if (value == -HUGE_VAL) return -HUGE_VAL; - if (digits == 0) - return ves_icall_System_Math_Round(value); p = pow(10, digits); +#if defined (HAVE_ROUND) && defined (HAVE_RINT) + if (away_from_zero) + return round (value * p) / p; + else + return rint (value * p) / p; +#else dec_part = modf (value, &int_part); dec_part *= 1000000000000000ULL; - dec_part = floor(dec_part); + if (away_from_zero && dec_part > 0) + dec_part = ceil (dec_part); + else + dec_part = floor (dec_part); dec_part /= (1000000000000000ULL / p); - dec_part = ves_icall_System_Math_Round(dec_part); + if (away_from_zero) { + if (dec_part > 0) + dec_part = floor (dec_part + 0.5); + else + dec_part = ceil (dec_part - 0.5); + } else + dec_part = ves_icall_System_Math_Round (dec_part); dec_part /= p; - return int_part + dec_part; + return ves_icall_System_Math_Round ((int_part + dec_part) * p) / p; +#endif } gdouble