X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsysmath.c;h=d354c4d0cced1b6a82961e0078b0f1886057b3a4;hb=dfcac450fa88d1b0bd41d882817ed95b739fb282;hp=000a3279ba8842ef63856dc9b1f13c2335e96e10;hpb=c92ead7b432b5575e875959d9971bf0ad55cdf66;p=mono.git diff --git a/mono/metadata/sysmath.c b/mono/metadata/sysmath.c index 000a3279ba8..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,14 +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); - int_part = floor(value); - dec_part = value - int_part; +#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