Date: Friday, March 10, 2006 @ 22:15:45
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: include/BigDecimal.hpp (1.17 -> 1.18) src/BigDecimal.cpp (1.21
          -> 1.22)

Added uint64_t conversion function


------------------------+
 include/BigDecimal.hpp |   11 +++++++++--
 src/BigDecimal.cpp     |   39 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 3 deletions(-)


Index: carob/include/BigDecimal.hpp
diff -u carob/include/BigDecimal.hpp:1.17 carob/include/BigDecimal.hpp:1.18
--- carob/include/BigDecimal.hpp:1.17   Fri Mar 10 18:47:33 2006
+++ carob/include/BigDecimal.hpp        Fri Mar 10 22:15:45 2006
@@ -54,8 +54,7 @@
    * and 0 unscaled_value)
    */
   BigDecimal();
-  /**
-  
+
   /**
    * Compares scale, sign and unscaled_value
    */
@@ -105,6 +104,14 @@
    */ 
   operator int64_t() const throw (ConversionException);
   /**
+   * Convertion to uint64_t
+   * Any fractional part of this BigDecimal will be discarded, and if the
+   * resulting "BigInteger" is too big to fit in an uint64_t, throws an
+   * exception
+   * @throw ConversionException if the value is to big to be converted
+   */ 
+  operator uint64_t() const throw (ConversionException);
+  /**
    * Convertion to float
    * TODO: exact behavior description
    * @throw ConversionException if the value is to big to be converted
Index: carob/src/BigDecimal.cpp
diff -u carob/src/BigDecimal.cpp:1.21 carob/src/BigDecimal.cpp:1.22
--- carob/src/BigDecimal.cpp:1.21       Fri Mar 10 18:47:33 2006
+++ carob/src/BigDecimal.cpp    Fri Mar 10 22:15:45 2006
@@ -132,6 +132,7 @@
 
   // TODO: optimization = if scale > number of digits in unscaled_value, 
return 0
 
+  // TODO: multiply by 10^(-scale) instead of dividing by 10^(scale)
   //we have to apply scale
   mpz_t scaler; mpz_init(scaler);                       //int scaler;
   mpz_ui_pow_ui(scaler, 10, scale);                     //scaler = 10^scale;
@@ -249,6 +250,8 @@
   return (signum > 0 ? scaled_int.get_si() : -scaled_int.get_si());
 }
 
+//TODO: optimize this horribly slow stuff
+//FIXME => negative overflow
 BigDecimal::operator int64_t() const throw (ConversionException)
 {
   if (signum == 0)
@@ -259,7 +262,7 @@
   // check size
   size_t nbBitsNeeded = mpz_sizeinbase(scaled_int.get_mpz_t(), 2);
   if (signum > 0)
-    nbBitsNeeded++;
+    nbBitsNeeded++; // count the sign bit. Negative overflow will be detected 
later (TODO)
   if (nbBitsNeeded > sizeof(int64_t)*8)
     throw (ConversionException(L"BigDecimal " + static_cast<wstring>(*this)
         + L" is too big to be converted into an int64_t"));
@@ -283,6 +286,40 @@
   return result;
 }
 
+//TODO: optimize this horribly slow stuff
+BigDecimal::operator uint64_t() const throw (ConversionException)
+{
+  if (signum == 0)
+    return 0;
+  if (signum < 0)
+    throw (ConversionException(L"BigDecimal " + static_cast<wstring>(*this)
+        +L" is negative ! it cannot be converted into an int64_t"));
+  mpz_class scaled_int = toBigInteger();
+  if (mpz_cmp_d(scaled_int.get_mpz_t(), 0) == 0) // if scaled_int == 0
+    return 0;
+  // check size
+  size_t nbBitsNeeded = mpz_sizeinbase(scaled_int.get_mpz_t(), 2);
+  if (nbBitsNeeded > (sizeof(int64_t)*8))
+    throw (ConversionException(L"BigDecimal " + static_cast<wstring>(*this)
+        + L" is too big to be converted into an int64_t"));
+
+  int mag_length = -1;
+  int* mag = toIntArray(scaled_int, &mag_length);
+  if (mag_length <= 0) //should not happen, but safer
+  {
+    throw (ConversionException(L"BigDecimal " + static_cast<wstring>(*this)
+        + L" could not be converted to int64"));
+  }
+
+  uint64_t result = 0;
+  for (int i = 0; i < mag_length; i++)
+  {
+    result = (result<<(8*sizeof(int))) + (mag[i]&0xffffffffLL);
+  }
+  delete[] mag;
+  return result;
+}
+
 BigDecimal::operator float() const throw (ConversionException)
 {
   // TODO: check that we can represent the big decimal by comparing:

_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits

Reply via email to