You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2007/08/07 01:46:45 UTC
svn commit: r563343 -
/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/NumberConverter.cpp
Author: tabish
Date: Mon Aug 6 16:46:44 2007
New Revision: 563343
URL: http://svn.apache.org/viewvc?view=rev&rev=563343
Log:
http://issues.apache.org/activemq/browse/AMQCPP-103
Adding in more Types wrappers
Modified:
activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/NumberConverter.cpp
Modified: activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/NumberConverter.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/NumberConverter.cpp?view=diff&rev=563343&r1=563342&r2=563343
==============================================================================
--- activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/NumberConverter.cpp (original)
+++ activemq/activemq-cpp/trunk/src/decaf/src/main/decaf/internal/util/NumberConverter.cpp Mon Aug 6 16:46:44 2007
@@ -51,36 +51,46 @@
}
////////////////////////////////////////////////////////////////////////////////
-std::string NumberConverter::convertD( double inputNumber ) {
- int p = 1023 + 52; // the power offset (precision)
- long signMask = 0x8000000000000000L; // the mask to get the sign of
- // the number
- long eMask = 0x7FF0000000000000L; // the mask to get the power bits
- long fMask = 0x000FFFFFFFFFFFFFL; // the mask to get the significand
- // bits
+std::string NumberConverter::convertD( double value ) {
- long inputNumberBits = Double.doubleToLongBits(inputNumber);
+ unsigned int p = 1023 + 52; // the power offset (precision)
+
+ // the mask to get the sign of the number
+ unsigned long long signMask = 0x8000000000000000L;
+ // the mask to get the power bits
+ unsigned long long eMask = 0x7FF0000000000000L;
+ // the mask to get the significand bits
+ unsigned long long fMask = 0x000FFFFFFFFFFFFFL;
+
+ unsigned long long inputNumberBits = Double::doubleToLongBits(value);
// the value of the sign... 0 is positive, ~0 is negative
- std::string signString = (inputNumberBits & signMask) == 0 ? "" : "-";
- // the value of the 'power bits' of the inputNumber
- int e = (int) ((inputNumberBits & eMask) >> 52);
- // the value of the 'significand bits' of the inputNumber
- long f = inputNumberBits & fMask;
- bool mantissaIsZero = f == 0;
- int pow = 0, numBits = 52;
+ std::string signString = ( inputNumberBits & signMask ) == 0 ? "" : "-";
+ // the value of the 'power bits' of the value
+ unsigned int e = (int)(( inputNumberBits & eMask ) >> 52 );
+ // the value of the 'significand bits' of the value
+ unsigned long long f = inputNumberBits & fMask;
+ bool mantissaIsZero = (f == 0);
+ unsigned int pow = 0, numBits = 52;
- if (e == 2047)
+ if( e == 2047 ) {
return mantissaIsZero ? signString + "Infinity" : "NaN";
- if (e == 0) {
- if (mantissaIsZero)
+ }
+
+ if( e == 0 ) {
+
+ if( mantissaIsZero ) {
return signString + "0.0";
- if (f == 1)
+ }
+
+ if( f == 1 ) {
// special case to increase precision even though 2 *
- // Double.MIN_VALUE is 1.0e-323
+ // Double::MIN_VALUE is 1.0e-323
return signString + "4.9E-324";
+ }
+
pow = 1 - p; // a denormalized number
- long ff = f;
- while ((ff & 0x0010000000000000L) == 0) {
+ long long ff = f;
+ while( (ff & 0x0010000000000000L) == 0 ) {
ff = ff << 1;
numBits--;
}
@@ -91,47 +101,55 @@
pow = e - p;
}
- if (-59 < pow && pow < 6 || (pow == -59 && !mantissaIsZero))
- longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits);
- else
- bigIntDigitGeneratorInstImpl(f, pow, e == 0, mantissaIsZero,
- numBits);
+ if( -59 < pow && pow < 6 || (pow == -59 && !mantissaIsZero) ) {
+ longDigitGenerator( f, pow, e == 0, mantissaIsZero, numBits );
+ } else {
+ bigIntDigitGeneratorInstImpl( f, pow, e == 0, mantissaIsZero, numBits );
+ }
- if (inputNumber >= 1e7D || inputNumber <= -1e7D
- || (inputNumber > -1e-3D && inputNumber < 1e-3D))
+ if( value >= 1e7D || value <= -1e7D ||
+ ( value > -1e-3D && value < 1e-3D ) ) {
return signString + freeFormatExponential();
+ }
return signString + freeFormat();
}
-std::string NumberConverter::convertF(float inputNumber) {
- int p = 127 + 23; // the power offset (precision)
- int signMask = 0x80000000; // the mask to get the sign of the number
- int eMask = 0x7F800000; // the mask to get the power bits
- int fMask = 0x007FFFFF; // the mask to get the significand bits
+////////////////////////////////////////////////////////////////////////////////
+std::string NumberConverter::convertF(float value) {
- int inputNumberBits = Float.floatToIntBits(inputNumber);
+ unsigned int p = 127 + 23; // the power offset (precision)
+ unsigned int signMask = 0x80000000; // the mask to get the sign of the number
+ unsigned int eMask = 0x7F800000; // the mask to get the power bits
+ unsigned int fMask = 0x007FFFFF; // the mask to get the significand bits
+
+ unsigned int inputNumberBits = Float::floatToIntBits(value);
// the value of the sign... 0 is positive, ~0 is negative
std::string signString = (inputNumberBits & signMask) == 0 ? "" : "-";
- // the value of the 'power bits' of the inputNumber
- int e = (inputNumberBits & eMask) >> 23;
- // the value of the 'significand bits' of the inputNumber
- int f = inputNumberBits & fMask;
- bool mantissaIsZero = f == 0;
- int pow = 0, numBits = 23;
+ // the value of the 'power bits' of the value
+ unsigned int e = (inputNumberBits & eMask) >> 23;
+ // the value of the 'significand bits' of the value
+ unsigned int f = inputNumberBits & fMask;
+ bool mantissaIsZero = ( f == 0 );
+ unsigned int pow = 0, numBits = 23;
- if (e == 255)
+ if( e == 255 ) {
return mantissaIsZero ? signString + "Infinity" : "NaN";
- if (e == 0) {
- if (mantissaIsZero)
+ }
+
+ if( e == 0 ) {
+
+ if( mantissaIsZero ) {
return signString + "0.0";
+ }
+
pow = 1 - p; // a denormalized number
- if (f < 8) { // want more precision with smallest values
+ if( f < 8 ) { // want more precision with smallest values
f = f << 2;
pow -= 2;
}
int ff = f;
- while ((ff & 0x00800000) == 0) {
+ while( (ff & 0x00800000) == 0) {
ff = ff << 1;
numBits--;
}
@@ -142,22 +160,26 @@
pow = e - p;
}
- if (-59 < pow && pow < 35 || (pow == -59 && !mantissaIsZero))
- longDigitGenerator(f, pow, e == 0, mantissaIsZero, numBits);
- else
- bigIntDigitGeneratorInstImpl(f, pow, e == 0, mantissaIsZero,
- numBits);
- if (inputNumber >= 1e7f || inputNumber <= -1e7f
- || (inputNumber > -1e-3f && inputNumber < 1e-3f))
+ if( -59 < pow && pow < 35 || (pow == -59 && !mantissaIsZero) ) {
+ longDigitGenerator( f, pow, e == 0, mantissaIsZero, numBits );
+ } else {
+ bigIntDigitGeneratorInstImpl( f, pow, e == 0, mantissaIsZero, numBits);
+ }
+
+ if( value >= 1e7f || value <= -1e7f ||
+ ( value > -1e-3f && value < 1e-3f ) ) {
return signString + freeFormatExponential();
+ }
return signString + freeFormat();
}
+////////////////////////////////////////////////////////////////////////////////
std::string NumberConverter::freeFormatExponential() {
+
// corresponds to process "Free-Format Exponential"
- char[] formattedDecimal = new char[25];
- formattedDecimal[0] = (char) ('0' + uArray[getCount++]);
+ char[25] formattedDecimal = {0};
+ formattedDecimal[0] = (char)( '0' + uArray[getCount++] );
formattedDecimal[1] = '.';
// the position the next character is to be inserted into
// formattedDecimal
@@ -165,61 +187,242 @@
int k = firstK;
int expt = k;
- while (true) {
+ while( true ) {
k--;
- if (getCount >= setCount)
+ if( getCount >= setCount) {
break;
+ }
- formattedDecimal[charPos++] = (char) ('0' + uArray[getCount++]);
+ formattedDecimal[charPos++] = (char)( '0' + uArray[getCount++] );
}
- if (k == expt - 1)
+ if( k == expt - 1 ) {
formattedDecimal[charPos++] = '0';
+ }
formattedDecimal[charPos++] = 'E';
- return new std::string(formattedDecimal, 0, charPos)
- + Integer.toString(expt);
+
+ return std::string( formattedDecimal, 0, charPos ) + Integer::toString( expt );
}
+////////////////////////////////////////////////////////////////////////////////
std::string NumberConverter::freeFormat() {
+
// corresponds to process "Free-Format"
- char[] formattedDecimal = new char[25];
+ char[25] formattedDecimal = {0};
// the position the next character is to be inserted into
// formattedDecimal
int charPos = 0;
int k = firstK;
- if (k < 0) {
+ if( k < 0 ) {
formattedDecimal[0] = '0';
formattedDecimal[1] = '.';
charPos += 2;
- for (int i = k + 1; i < 0; i++)
+ for( int i = k + 1; i < 0; i++ ) {
formattedDecimal[charPos++] = '0';
+ }
}
int U = uArray[getCount++];
- do {
- if (U != -1)
+ do{
+ if( U != -1 ) {
formattedDecimal[charPos++] = (char) ('0' + U);
- else if (k >= -1)
+ } else if (k >= -1) {
formattedDecimal[charPos++] = '0';
+ }
- if (k == 0)
+ if( k == 0 ) {
formattedDecimal[charPos++] = '.';
+ }
k--;
U = getCount < setCount ? uArray[getCount++] : -1;
- } while (U != -1 || k >= -1);
- return new std::string(formattedDecimal, 0, charPos);
+
+ } while( U != -1 || k >= -1 );
+
+ return std::string( formattedDecimal, 0, charPos );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void NumberConverter::bigIntDigitGeneratorInstImpl(
+ long long f, int e, bool isDenormalized, bool mantissaIsZero, int p ) {
+
+ static std::size_t RM_SIZE 21;
+ static std::size_t STemp_SIZE 22;
+
+ unsigned int RLength, SLength, TempLength, mplus_Length, mminus_Length;
+ int high, low, i;
+ int k, U;
+
+ unsigned long long R[RM_SIZE] = {0};
+ unsigned long long S[STemp_SIZE] = {0};
+ unsigned long long mplus[RM_SIZE] = {0};
+ unsigned long long mminus[RM_SIZE] = {0};
+ unsigned long long Temp[STemp_SIZE] = {0};
+
+ if( e >= 0 ) {
+
+ *R = f;
+ *mplus = *mminus = 1;
+ simpleShiftLeftHighPrecision( mminus, RM_SIZE, e );
+
+ if( f != (2 << (p - 1)) ) {
+
+ simpleShiftLeftHighPrecision( R, RM_SIZE, e + 1 );
+ *S = 2;
+
+ /*
+ * m+ = m+ << e results in 1.0e23 to be printed as
+ * 0.9999999999999999E23
+ * m+ = m+ << e+1 results in 1.0e23 to be printed as
+ * 1.0e23 (caused too much rounding)
+ * 470fffffffffffff = 2.0769187434139308E34
+ * 4710000000000000 = 2.076918743413931E34
+ */
+ simpleShiftLeftHighPrecision(mplus, RM_SIZE, e);
+
+ } else {
+
+ simpleShiftLeftHighPrecision( R, RM_SIZE, e + 2 );
+ *S = 4;
+ simpleShiftLeftHighPrecision( mplus, RM_SIZE, e + 1 );
+ }
+
+ } else {
+
+ if( isDenormalized || (f != (2 << (p - 1))) ) {
+
+ *R = f << 1;
+ *S = 1;
+ simpleShiftLeftHighPrecision( S, STemp_SIZE, 1 - e );
+ *mplus = *mminus = 1;
+
+ } else {
+
+ *R = f << 2;
+ *S = 1;
+ simpleShiftLeftHighPrecision( S, STemp_SIZE, 2 - e );
+ *mplus = 2;
+ *mminus = 1;
+ }
+ }
+
+ k = (int) ceil ((e + p - 1) * INV_LOG_OF_TEN_BASE_2 - 1e-10);
+
+ if( k > 0 ) {
+ timesTenToTheEHighPrecision( S, STemp_SIZE, k );
+ } else {
+ timesTenToTheEHighPrecision( R, RM_SIZE, -k );
+ timesTenToTheEHighPrecision( mplus, RM_SIZE, -k );
+ timesTenToTheEHighPrecision( mminus, RM_SIZE, -k );
+ }
+
+ RLength = mplus_Length = mminus_Length = RM_SIZE;
+ SLength = TempLength = STemp_SIZE;
+
+ memset( Temp + RM_SIZE, 0, (STemp_SIZE - RM_SIZE) * sizeof (U_64) );
+ memcpy( Temp, R, RM_SIZE * sizeof (U_64) );
+
+ while( RLength > 1 && R[RLength - 1] == 0 ) {
+ --RLength;
+ }
+ while( mplus_Length > 1 && mplus[mplus_Length - 1] == 0 ) {
+ --mplus_Length;
+ }
+ while( mminus_Length > 1 && mminus[mminus_Length - 1] == 0 ) {
+ --mminus_Length;
+ }
+ while( SLength > 1 && S[SLength - 1] == 0 ) {
+ --SLength;
+ }
+
+ TempLength = (RLength > mplus_Length ? RLength : mplus_Length) + 1;
+ addHighPrecision( Temp, TempLength, mplus, mplus_Length );
+
+ if( compareHighPrecision (Temp, TempLength, S, SLength) >= 0 ) {
+ firstK = k;
+ } else {
+
+ firstK = k - 1;
+ simpleAppendDecimalDigitHighPrecision( R, ++RLength, 0 );
+ simpleAppendDecimalDigitHighPrecision( mplus, ++mplus_Length, 0 );
+ simpleAppendDecimalDigitHighPrecision( mminus, ++mminus_Length, 0 );
+ while( RLength > 1 && R[RLength - 1] == 0 ) {
+ --RLength;
+ }
+ while( mplus_Length > 1 && mplus[mplus_Length - 1] == 0 ) {
+ --mplus_Length;
+ }
+ while( mminus_Length > 1 && mminus[mminus_Length - 1] == 0 ) {
+ --mminus_Length;
+ }
+ }
+
+ getCount = setCount = 0;
+ do{
+
+ U = 0;
+ for( i = 3; i >= 0; --i ) {
+ TempLength = SLength + 1;
+ Temp[SLength] = 0;
+ memcpy (Temp, S, SLength * sizeof (U_64));
+ simpleShiftLeftHighPrecision( Temp, TempLength, i );
+ if( compareHighPrecision( R, RLength, Temp, TempLength ) >= 0 ) {
+ subtractHighPrecision( R, RLength, Temp, TempLength );
+ U += 1 << i;
+ }
+ }
+
+ low = compareHighPrecision( R, RLength, mminus, mminus_Length ) <= 0;
+
+ memset( Temp + RLength, 0, (STemp_SIZE - RLength) * sizeof(U_64) );
+ memcpy( Temp, R, RLength * sizeof(U_64) );
+ TempLength = (RLength > mplus_Length ? RLength : mplus_Length) + 1;
+ addHighPrecision( Temp, TempLength, mplus, mplus_Length );
+
+ high = compareHighPrecision( Temp, TempLength, S, SLength ) >= 0;
+
+ if( low || high ) {
+ break;
+ }
+
+ simpleAppendDecimalDigitHighPrecision( R, ++RLength, 0 );
+ simpleAppendDecimalDigitHighPrecision( mplus, ++mplus_Length, 0 );
+ simpleAppendDecimalDigitHighPrecision( mminus, ++mminus_Length, 0 );
+ while( RLength > 1 && R[RLength - 1] == 0 ) {
+ --RLength;
+ }
+ while( mplus_Length > 1 && mplus[mplus_Length - 1] == 0 ) {
+ --mplus_Length;
+ }
+ while( mminus_Length > 1 && mminus[mminus_Length - 1] == 0 ) {
+ --mminus_Length;
+ }
+ uArray[setCount++] = U;
+ }
+ while( true );
+
+ simpleShiftLeftHighPrecision( R, ++RLength, 1 );
+
+ if( low && !high ) {
+ uArray[setCount++] = U;
+ } else if( high && !low ) {
+ uArray[setCount++] = U + 1;
+ } else if( compareHighPrecision( R, RLength, S, SLength) < 0 ) {
+ uArray[setCount++] = U;
+ } else {
+ uArray[setCount++] = U + 1;
+ }
}
-void NumberConverter::bigIntDigitGeneratorInstImpl(long f, int e,
- bool isDenormalized, bool mantissaIsZero, int p);
+////////////////////////////////////////////////////////////////////////////////
+void NumberConverter::longDigitGenerator(
+ long long f, int e, bool isDenormalized, bool mantissaIsZero, int p ) {
+
+ unsigned long long R, S, M;
-void NumberConverter::longDigitGenerator(long f, int e, bool isDenormalized,
- bool mantissaIsZero, int p) {
- long R, S, M;
- if (e >= 0) {
+ if( e >= 0 ) {
M = 1l << e;
- if (!mantissaIsZero) {
+ if( !mantissaIsZero ) {
R = f << (e + 1);
S = 2;
} else {
@@ -228,7 +431,7 @@
}
} else {
M = 1;
- if (isDenormalized || !mantissaIsZero) {
+ if( isDenormalized || !mantissaIsZero ) {
R = f << 1;
S = 1l << (1 - e);
} else {
@@ -237,17 +440,17 @@
}
}
- int k = (int) Math.ceil((e + p - 1) * invLogOfTenBaseTwo - 1e-10);
+ int k = (int)Math::ceil( (e + p - 1) * invLogOfTenBaseTwo - 1e-10 );
- if (k > 0) {
+ if( k > 0 ) {
S = S * TEN_TO_THE[k];
- } else if (k < 0) {
- long scale = TEN_TO_THE[-k];
+ } else if( k < 0 ) {
+ long long scale = TEN_TO_THE[-k];
R = R * scale;
M = M == 1 ? scale : M * scale;
}
- if (R + M > S) { // was M_plus
+ if( R + M > S ) { // was M_plus
firstK = k;
} else {
firstK = k - 1;
@@ -258,17 +461,17 @@
getCount = setCount = 0; // reset indices
bool low, high;
int U;
- long[] Si = new long[] { S, S << 1, S << 2, S << 3 };
- while (true) {
+ long long[] Si = new long long[] { S, S << 1, S << 2, S << 3 };
+ while( true ) {
// set U to be floor (R / S) and R to be the remainder
// using a kind of "binary search" to find the answer.
// It's a lot quicker than actually dividing since we know
// the answer will be between 0 and 10
U = 0;
- long remainder;
- for (int i = 3; i >= 0; i--) {
+ long long remainder;
+ for( int i = 3; i >= 0; i-- ) {
remainder = R - Si[i];
- if (remainder >= 0) {
+ if( remainder >= 0 ) {
R = remainder;
U += 1 << i;
}
@@ -277,19 +480,22 @@
low = R < M; // was M_minus
high = R + M > S; // was M_plus
- if (low || high)
+ if( low || high ) {
break;
+ }
R = R * 10;
M = M * 10;
uArray[setCount++] = U;
}
- if (low && !high)
+
+ if( low && !high ) {
uArray[setCount++] = U;
- else if (high && !low)
+ } else if( high && !low ) {
uArray[setCount++] = U + 1;
- else if ((R << 1) < S)
+ } else if( ( R << 1 ) < S ) {
uArray[setCount++] = U;
- else
+ } else {
uArray[setCount++] = U + 1;
+ }
}