2005-03-08 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / metadata / decimal.c
index 1218e01726291c3281e57bed286c0552dac6ab92..58d2b2407f9837f16f658865599633e5a8fb71b7 100644 (file)
@@ -13,6 +13,7 @@
  * CSharp value type System.Decimal
  */
 
+#include "config.h"
 #include <mono/metadata/exception.h>
 #include <stdio.h>
 #include <memory.h>
 #include <string.h>
 #include <math.h>
 
+#ifndef DISABLE_DECIMAL
+
 /* needed for building microsoft dll */
+#ifdef __GNUC__
 #define DECINLINE __inline
+#else
+#define DECINLINE
+#endif
 
 #define LIT_GUINT32(x) x
-#define LIT_GUINT64(x) x##L
+#define LIT_GUINT64(x) x##LL
 
 
 /* we need a UInt64 type => guint64 */
@@ -90,7 +97,7 @@
 
 #define DECIMAL_LOG_NEGINF -1000
 
-static guint32 constantsDecadeInt32Factors[DECIMAL_MAX_INTFACTORS+1] = {
+static const guint32 constantsDecadeInt32Factors[DECIMAL_MAX_INTFACTORS+1] = {
     LIT_GUINT32(1), LIT_GUINT32(10), LIT_GUINT32(100), LIT_GUINT32(1000), 
     LIT_GUINT32(10000), LIT_GUINT32(100000), LIT_GUINT32(1000000), 
     LIT_GUINT32(10000000), LIT_GUINT32(100000000), LIT_GUINT32(1000000000)
@@ -101,7 +108,7 @@ typedef struct {
     guint64 hi;
 } dec128_repr;
 
-static dec128_repr dec128decadeFactors[DECIMAL_MAX_SCALE+1] = {
+static const dec128_repr dec128decadeFactors[DECIMAL_MAX_SCALE+1] = {
     LIT_DEC128( 0, 0, 1u), /* == 1 */
     LIT_DEC128( 0, 0, 10u), /* == 10 */
     LIT_DEC128( 0, 0, 100u), /* == 100 */
@@ -345,7 +352,7 @@ DECINLINE static int div128by32(guint64* plo, guint64* phi, guint32 factor, guin
     if (pRest) *pRest = (guint32) a;
 
     a <<= 1;
-    return (a > factor || (a == factor && (c & 1) == 1)) ? 1 : 0;
+    return (a >= factor || (a == factor && (c & 1) == 1)) ? 1 : 0;
 }
 
 /* division: x(192bit) /= factor(32bit) 
@@ -920,7 +927,13 @@ gint32 mono_double2decimal(/*[Out]*/decimal_repr* pA, double val, gint32 digits)
     return pack128toDecimal(pA, alo, ahi, scale, sign);
 }
 
-/** 
+/**
+ * mono_string2decimal:
+ * @decimal_repr:
+ * @str:
+ * @decrDecimal:
+ * @sign:
+ *
  * converts a digit string to decimal
  * The significant digits must be passed as an integer in buf !
  *
@@ -1027,6 +1040,8 @@ gint32 mono_string2decimal(/*[Out]*/decimal_repr* pA, MonoString* str, gint32 de
 }
 
 /**
+ * mono_decimal2string:
+ * @
  * returns minimal number of digit string to represent decimal
  * No leading or trailing zeros !
  * Examples:
@@ -1047,7 +1062,6 @@ gint32 mono_string2decimal(/*[Out]*/decimal_repr* pA, MonoString* str, gint32 de
  *    pDecPos    receives insert position of decimal point relative to start of buffer
  *    pSign      receives sign
  */
-
 gint32 mono_decimal2string(/*[In]*/decimal_repr* pA, gint32 digits, gint32 decimals,
                                    MonoArray* pArray, gint32 bufSize, gint32* pDecPos, gint32* pSign)
 {
@@ -1143,6 +1157,9 @@ gint32 mono_decimal2string(/*[In]*/decimal_repr* pA, gint32 digits, gint32 decim
 }
 
 /**
+ * mono_decimal2UInt64:
+ * @pA
+ * @pResult
  * converts a decimal to an UInt64 without rounding
  */
 gint32 mono_decimal2UInt64(/*[In]*/decimal_repr* pA, guint64* pResult)
@@ -1166,6 +1183,9 @@ gint32 mono_decimal2UInt64(/*[In]*/decimal_repr* pA, guint64* pResult)
 }
 
 /**
+ * mono_decimal2Int64:
+ * @pA:
+ * pResult:
  * converts a decimal to an Int64 without rounding
  */
 gint32 mono_decimal2Int64(/*[In]*/decimal_repr* pA, gint64* pResult)
@@ -1508,7 +1528,7 @@ double mono_decimal2double(/*[In]*/decimal_repr* pA)
     ahi += 0x400;
     if ((ahi & LIT_GUINT64_HIGHBIT) == 0) { /* overflow ? */
         ahi >>= 1;
-        texp++;
+       texp--;
     } else if ((roundBits & 0x400) == 0) ahi &= ~1;
 
     /* 96 bit => 1 implizit bit and 52 explicit bits */
@@ -1540,3 +1560,6 @@ gint32 mono_decimalSetExponent(/*[In, Out]*/decimal_repr* pA, gint32 texp)
         return DECIMAL_SUCCESS;
     }
 }
+
+#endif /* DISABLE_DECIMAL */
+