X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsysmath.c;h=d354c4d0cced1b6a82961e0078b0f1886057b3a4;hb=284b8b6a50c80a2513eed411084eebe5b2bd5ac4;hp=6627009eebb98644ad62238f196cb4bbb7d41e1b;hpb=f1f8b8a867c800b21b6a03767252403c2f72cae2;p=mono.git diff --git a/mono/metadata/sysmath.c b/mono/metadata/sysmath.c index 6627009eebb..d354c4d0cce 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,8 +55,12 @@ 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; @@ -58,13 +69,29 @@ gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits) { 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