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