16 int Decimal::exponent(
const char * integralPart,
int integralPartLength,
const char * fractionalPart,
int fractionalPartLength,
const char * exponent,
int exponentLength,
bool exponentNegative) {
19 for (
int i = 0; i < exponentLength; i++) {
24 if (exponentNegative) {
27 const char * integralPartEnd = integralPart + integralPartLength;
28 if (integralPart !=
nullptr) {
29 while (*integralPart ==
'0' && integralPart < integralPartEnd) {
33 exp += integralPartEnd-integralPart-1;
34 if (integralPart == integralPartEnd) {
35 const char * fractionalPartEnd = fractionalPart + fractionalPartLength;
36 if (fractionalPart !=
nullptr) {
37 while (*fractionalPart ==
'0' && fractionalPart < fractionalPartEnd) {
42 if (fractionalPart == fractionalPartEnd) {
43 exp += fractionalPartLength+1;
61 Integer Decimal::mantissa(
const char * integralPart,
int integralPartLength,
const char * fractionalPart,
int fractionalPartLength,
bool negative) {
65 for (
int i = 0; i < fractionalPartLength; i++) {
85 if (f != 0 && logBase10 == (
int)logBase10 &&
std::fabs(f) <
std::pow(10, logBase10)) {
88 double m = f*
std::pow(10, (
double)-exponentInBase10);
89 m = m *
std::pow(10, (
double)(k_doublePrecision-1));
94 if (m >= k_biggestMantissaFromDouble+0.5) {
97 m_mantissa =
Integer(integerMantissa);
99 m_exponent = exponentInBase10;
107 return new Decimal(m_mantissa, m_exponent);
112 int numberOfDigits = numberOfDigitsInMantissaWithoutSign();
117 if (bufferSize == 0) {
120 buffer[bufferSize-1] = 0;
122 if (currentChar >= bufferSize-1) {
return bufferSize-1; }
123 if (m_mantissa.
isZero()) {
124 buffer[currentChar++] =
'0';
125 buffer[currentChar] = 0;
128 char tempBuffer[200];
130 if (
strcmp(tempBuffer,
"undef") == 0) {
131 strlcpy(buffer, tempBuffer, bufferSize);
132 return mantissaLength;
134 int nbOfDigitsInMantissaWithoutSign = numberOfDigitsInMantissaWithoutSign();
135 int numberOfRequiredDigits = nbOfDigitsInMantissaWithoutSign > m_exponent ? nbOfDigitsInMantissaWithoutSign : m_exponent;
136 numberOfRequiredDigits = m_exponent < 0 ? 1+nbOfDigitsInMantissaWithoutSign-m_exponent : numberOfRequiredDigits;
138 if (numberOfRequiredDigits > k_maxLength) {
139 if (nbOfDigitsInMantissaWithoutSign == 1) {
140 currentChar +=
strlcpy(buffer, tempBuffer, bufferSize);
143 if (currentChar >= bufferSize-1) {
return bufferSize-1; }
144 currentChar +=
strlcpy(buffer+currentChar, tempBuffer, bufferSize-currentChar);
145 int decimalMarkerPosition = 1;
146 if (buffer[1] ==
'-') {
147 decimalMarkerPosition++;
148 buffer[0] = buffer[1];
150 buffer[decimalMarkerPosition-1] = buffer[decimalMarkerPosition];
151 buffer[decimalMarkerPosition] =
'.';
153 if (m_exponent == 0) {
156 if (currentChar >= bufferSize-1) {
return bufferSize-1; }
162 int deltaCharMantissa = m_exponent < 0 ? -m_exponent+1 : 0;
163 strlcpy(buffer+deltaCharMantissa, tempBuffer, bufferSize-deltaCharMantissa);
165 buffer[currentChar++] =
'-';
167 if (m_exponent < 0) {
168 for (
int i = 0; i <= -m_exponent; i++) {
169 if (currentChar >= bufferSize-1) {
return bufferSize-1; }
171 buffer[currentChar++] =
'.';
174 buffer[currentChar++] =
'0';
181 int tempCharPosition = 0;
184 tempChar = buffer[currentChar];
185 tempCharPosition = currentChar;
187 currentChar += mantissaLength;
189 buffer[tempCharPosition] = tempChar;
191 int currentExponent = m_mantissa.
isNegative() ? currentChar-2 : currentChar-1;
192 if (m_exponent >= 0 && m_exponent < currentExponent) {
193 if (currentChar+1 >= bufferSize-1) {
return bufferSize-1; }
194 int decimalMarkerPosition = m_mantissa.
isNegative() ? m_exponent +1 : m_exponent;
195 for (
int i = currentChar-1; i > decimalMarkerPosition; i--) {
196 buffer[i+1] = buffer[i];
198 buffer[decimalMarkerPosition+1] =
'.';
201 if (m_exponent >= 0 && m_exponent > currentExponent) {
202 int decimalMarkerPosition = m_mantissa.
isNegative() ? m_exponent+1 : m_exponent;
203 for (
int i = currentChar-1; i < decimalMarkerPosition; i++) {
204 if (currentChar+1 >= bufferSize-1) {
return bufferSize-1; }
205 buffer[currentChar++] =
'0';
208 buffer[currentChar] = 0;
212 bool Decimal::needParenthesisWithParent(
const Expression * e)
const {
217 return e->isOfType(types, 7);
220 ExpressionLayout * Decimal::privateCreateLayout(
PrintFloat::Mode floatDisplayMode, ComplexFormat complexFormat)
const {
223 return new StringLayout(buffer, numberOfChars);
226 Expression * Decimal::shallowReduce(Context& context, AngleUnit angleUnit) {
227 Expression * e = Expression::shallowReduce(context, angleUnit);
232 if (m_exponent > k_maxDoubleExponent || m_exponent < -k_maxDoubleExponent) {
235 int numberOfDigits = numberOfDigitsInMantissaWithoutSign();
236 Integer numerator = m_mantissa;
237 Integer denominator = Integer(1);
238 if (m_exponent >= numberOfDigits-1) {
241 denominator =
Integer::Power(Integer(10), Integer(numberOfDigits-1-m_exponent));
246 Expression * Decimal::shallowBeautify(Context & context, AngleUnit angleUnit) {
255 int Decimal::simplificationOrderSameType(
const Expression * e,
bool canBeInterrupted)
const {
265 int unsignedComparison = 0;
266 if (
exponent() < other->exponent()) {
267 unsignedComparison = -1;
268 }
else if (
exponent() > other->exponent()) {
269 unsignedComparison = 1;
274 return ((
int)
sign())*unsignedComparison;
277 int Decimal::numberOfDigitsInMantissaWithoutSign()
const {
278 int numberOfDigits = 1;
279 Integer mantissaCopy = m_mantissa;
282 while (!d.quotient.isZero()) {
283 mantissaCopy = d.quotient;
287 return numberOfDigits;
static Integer Power(const Integer &i, const Integer &j)
int writeTextInBuffer(char *buffer, int bufferSize) const
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
int writeTextInBuffer(char *buffer, int bufferSize, int numberOfSignificantDigits=PrintFloat::k_numberOfStoredSignificantDigits) const override
size_t strlcpy(char *dst, const char *src, size_t len)
void removeZeroAtTheEnd(Integer &i)
void setNegative(bool negative)
static Integer Addition(const Integer &i, const Integer &j)
Decimal(Integer mantissa, int exponent)
static int NaturalOrder(const Integer &i, const Integer &j)
static Complex< T > Float(T x)
Sign sign() const override
Type type() const override
int strcmp(const char *s1, const char *s2)
static Integer Multiplication(const Integer &i, const Integer &j)
static IntegerDivision Division(const Integer &numerator, const Integer &denominator)
Expression * clone() const override