1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 31b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert* Copyright (C) 1997-2015, International Business Machines 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************** 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File DIGITLST.CPP 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History: 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Date Name Description 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/21/97 clhuang Converted from java. 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/21/97 clhuang Implemented with new APIs. 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/27/97 helena Updated to pass the simple test after code review. 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/31/97 aliu Moved isLONG_MIN to here, and fixed it. 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 04/15/97 aliu Changed MAX_COUNT to DBL_DIG. Changed Digit to char. 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Reworked representation by replacing fDecimalAt 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* with fExponent. 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 04/16/97 aliu Rewrote set() and getDouble() to use sprintf/atof 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* to do digit conversion. 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 09/09/97 aliu Modified for exponential notation support. 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 08/02/98 stephen Added nearest/even rounding 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Fixed bug in fitsIntoLong 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "digitlst.h" 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/putil.h" 3127f654740f2a26ad62a5c155af9199af9e69b889claireho#include "charstr.h" 3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 34103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "mutex.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "putilimp.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h" 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h> 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <limits.h> 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h> 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <limits> 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// *************************************************************************** 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// class DigitList 4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// A wrapper onto decNumber. 4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Used to be standalone. 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// *************************************************************************** 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This is the zero digit. The base for the digits returned by getDigit() 5127f654740f2a26ad62a5c155af9199af9e69b889claireho * Note that it is the platform invariant digit, and is not Unicode. 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kZero '0' 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Only for 32 bit numbers. Ignore the negative sign. */ 5754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const char LONG_MIN_REP[] = "2147483648"; 5854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const char I64_MIN_REP[] = "9223372036854775808"; 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// default constructor 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::DigitList() 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decContextDefault(&fContext, DEC_INIT_BASE); 6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fContext.traps = 0; 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN); 7127f654740f2a26ad62a5c155af9199af9e69b889claireho fContext.digits = fStorage.getCapacity(); 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 7327f654740f2a26ad62a5c155af9199af9e69b889claireho fDecNumber = fStorage.getAlias(); 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberZero(fDecNumber); 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 76103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalSetDouble(0.0); 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 79bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru// ------------------------------------- 80bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruDigitList::~DigitList() 82bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru{ 83bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru} 84bbb04983e06b0e11d9f393bbd3850bbe8f47f6d0Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// copy constructor 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::DigitList(const DigitList &other) 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 9027f654740f2a26ad62a5c155af9199af9e69b889claireho fDecNumber = fStorage.getAlias(); 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *this = other; 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// assignment operator 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList& 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::operator=(const DigitList& other) 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this != &other) 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(&fContext, &other.fContext, sizeof(decContext)); 10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10527f654740f2a26ad62a5c155af9199af9e69b889claireho if (other.fStorage.getCapacity() > fStorage.getCapacity()) { 10627f654740f2a26ad62a5c155af9199af9e69b889claireho fDecNumber = fStorage.resize(other.fStorage.getCapacity()); 10727f654740f2a26ad62a5c155af9199af9e69b889claireho } 10827f654740f2a26ad62a5c155af9199af9e69b889claireho // Always reset the fContext.digits, even if fDecNumber was not reallocated, 10927f654740f2a26ad62a5c155af9199af9e69b889claireho // because above we copied fContext from other.fContext. 11027f654740f2a26ad62a5c155af9199af9e69b889claireho fContext.digits = fStorage.getCapacity(); 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberCopy(fDecNumber, other.fDecNumber); 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 113103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 114103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // fDouble is lazily created and cached. 115103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Avoid potential races with that happening with other.fDouble 116103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // while we are doing the assignment. 117103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius Mutex mutex; 118103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 119103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(other.fHave==kDouble) { 120103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fUnion.fDouble = other.fUnion.fDouble; 121103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if(other.fHave==kInt64) { 122103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fUnion.fInt64 = other.fUnion.fInt64; 123103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 124103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fHave = other.fHave; 125103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// operator == (does not exactly match the old DigitList function) 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::operator==(const DigitList& that) const 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (this == &that) { 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return TRUE; 13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho decNumber n; // Has space for only a none digit value. 14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho decContext c; 14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decContextDefault(&c, DEC_INIT_BASE); 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho c.digits = 1; 14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho c.traps = 0; 14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberCompare(&n, this->fDecNumber, that.fDecNumber, &c); 14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool result = decNumberIsZero(&n); 14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return result; 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// comparison function. Returns 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Not Comparable : -2 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// < : -1 15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// == : 0 15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// > : +1 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t DigitList::compare(const DigitList &other) { 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho decNumber result; 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t savedDigits = fContext.digits; 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fContext.digits = 1; 16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberCompare(&result, this->fDecNumber, other.fDecNumber, &fContext); 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fContext.digits = savedDigits; 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsZero(&result)) { 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (decNumberIsSpecial(&result)) { 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return -2; 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (result.bits & DECNEG) { 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return -1; 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 1; 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Reduce - remove trailing zero digits. 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::reduce() { 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberReduce(fDecNumber, fDecNumber, &fContext); 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// trim - remove trailing fraction zero digits. 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::trim() { 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberTrim(fDecNumber); 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Resets the digit list; sets all the digits to zero. 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::clear() 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberZero(fDecNumber); 19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decContextSetRounding(&fContext, DEC_ROUND_HALF_EVEN); 197103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalSetDouble(0.0); 19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Formats a int64_t number into a base 10 string representation, and NULL terminates it. 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param number The number to format 20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param outputStr The string to output to. Must be at least MAX_DIGITS+2 in length (21), 20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * to hold the longest int64_t value. 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the number of digits written, not including the sign. 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t 20950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoformatBase10(int64_t number, char *outputStr) { 21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The number is output backwards, starting with the LSD. 21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Fill the buffer from the far end. After the number is complete, 21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // slide the string contents to the front. 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t MAX_IDX = MAX_DIGITS+2; 21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t destIdx = MAX_IDX; 21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho outputStr[--destIdx] = 0; 21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int64_t n = number; 21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (number < 0) { // Negative numbers are slightly larger than a postive 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho outputStr[--destIdx] = (char)(-(n % 10) + kZero); 22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho n /= -10; 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho do { 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho outputStr[--destIdx] = (char)(n % 10 + kZero); 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho n /= 10; 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } while (n > 0); 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (number < 0) { 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho outputStr[--destIdx] = '-'; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Slide the number to the start of the output str 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(destIdx >= 0); 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length = MAX_IDX - destIdx; 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memmove(outputStr, outputStr+MAX_IDX-length, length); 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return length; 23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// setRoundingMode() 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// For most modes, the meaning and names are the same between the decNumber library 245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// (which DigitList follows) and the ICU Formatting Rounding Mode values. 246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// The flag constants are different, however. 247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// 248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Note that ICU's kRoundingUnnecessary is not implemented directly by DigitList. 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// This mode, inherited from Java, means that numbers that would not format exactly 250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// will return an error when formatting is attempted. 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setRoundingMode(DecimalFormat::ERoundingMode m) { 25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho enum rounding r; 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch (m) { 25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case DecimalFormat::kRoundCeiling: r = DEC_ROUND_CEILING; break; 25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case DecimalFormat::kRoundFloor: r = DEC_ROUND_FLOOR; break; 25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case DecimalFormat::kRoundDown: r = DEC_ROUND_DOWN; break; 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case DecimalFormat::kRoundUp: r = DEC_ROUND_UP; break; 26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case DecimalFormat::kRoundHalfEven: r = DEC_ROUND_HALF_EVEN; break; 26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case DecimalFormat::kRoundHalfDown: r = DEC_ROUND_HALF_DOWN; break; 26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case DecimalFormat::kRoundHalfUp: r = DEC_ROUND_HALF_UP; break; 264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case DecimalFormat::kRoundUnnecessary: r = DEC_ROUND_HALF_EVEN; break; 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // TODO: how to report the problem? 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Leave existing mode unchanged. 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho r = uprv_decContextGetRounding(&fContext); 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decContextSetRounding(&fContext, r); 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 27850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setPositive(UBool s) { 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (s) { 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->bits &= ~DECNEG; 28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->bits |= DECNEG; 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 28950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setDecimalAt(int32_t d) { 29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0); // Not Infinity or NaN 29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(d-1>-999999999); 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(d-1< 999999999); 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t adjustedDigits = fDecNumber->digits; 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsZero(fDecNumber)) { 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Account for difference in how zero is represented between DigitList & decNumber. 29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho adjustedDigits = 0; 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->exponent = d - adjustedDigits; 299103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t 30350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getDecimalAt() { 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT((fDecNumber->bits & DECSPECIAL) == 0); // Not Infinity or NaN 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsZero(fDecNumber) || ((fDecNumber->bits & DECSPECIAL) != 0)) { 30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return fDecNumber->exponent; // Exponent should be zero for these cases. 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return fDecNumber->exponent + fDecNumber->digits; 30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 31250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setCount(int32_t c) { 31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(c <= fContext.digits); 31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (c == 0) { 31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // For a value of zero, DigitList sets all fields to zero, while 31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // decNumber keeps one digit (with that digit being a zero) 31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho c = 1; 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->lsu[0] = 0; 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->digits = c; 321103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getCount() const { 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsZero(fDecNumber) && fDecNumber->exponent==0) { 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The extra test for exponent==0 is needed because parsing sometimes appends 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // zero digits. It's bogus, decimalFormatter parsing needs to be cleaned up. 32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return fDecNumber->digits; 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 33550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 33650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::setDigit(int32_t i, char v) { 33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t count = fDecNumber->digits; 33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(i<count); 33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(v>='0' && v<='9'); 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho v &= 0x0f; 34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->lsu[count-i-1] = v; 342103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehochar 34650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getDigit(int32_t i) { 34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t count = fDecNumber->digits; 34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(i<count); 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return fDecNumber->lsu[count-i-1] + '0'; 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 35227f654740f2a26ad62a5c155af9199af9e69b889claireho// copied from DigitList::getDigit() 35327f654740f2a26ad62a5c155af9199af9e69b889clairehouint8_t 35427f654740f2a26ad62a5c155af9199af9e69b889clairehoDigitList::getDigitValue(int32_t i) { 35527f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t count = fDecNumber->digits; 35627f654740f2a26ad62a5c155af9199af9e69b889claireho U_ASSERT(i<count); 35727f654740f2a26ad62a5c155af9199af9e69b889claireho return fDecNumber->lsu[count-i-1]; 35827f654740f2a26ad62a5c155af9199af9e69b889claireho} 35927f654740f2a26ad62a5c155af9199af9e69b889claireho 36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Appends the digit to the digit list if it's not out of scope. 36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// Ignores the digit, otherwise. 36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// This function is horribly inefficient to implement with decNumber because 36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// the digits are stored least significant first, which requires moving all 36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// existing digits down one to make space for the new one to be appended. 36750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 36850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 36950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::append(char digit) 37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(digit>='0' && digit<='9'); 37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Ignore digits which exceed the precision we can represent 37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // And don't fix for larger precision. Fix callers instead. 37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsZero(fDecNumber)) { 37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Zero needs to be special cased because of the difference in the way 37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // that the old DigitList and decNumber represent it. 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // digit cout was zero for digitList, is one for decNumber 37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->lsu[0] = digit & 0x0f; 37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->digits = 1; 38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->exponent--; // To match the old digit list implementation. 38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t nDigits = fDecNumber->digits; 38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (nDigits < fContext.digits) { 38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int i; 38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i=nDigits; i>0; i--) { 38650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->lsu[i] = fDecNumber->lsu[i-1]; 38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->lsu[0] = digit & 0x0f; 38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->digits++; 39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // DigitList emulation - appending doesn't change the magnitude of existing 39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // digits. With decNumber's decimal being after the 39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // least signficant digit, we need to adjust the exponent. 39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fDecNumber->exponent--; 39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 396103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 402103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Currently, getDouble() depends on strtod() to do its conversion. 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * WARNING!! 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This is an extremely costly function. ~1/2 of the conversion time 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * can be linked to this function. 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudouble 40950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::getDouble() const 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 411103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius static char gDecimal = 0; 412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius char decimalSeparator; 413103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 414103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius Mutex mutex; 415103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fHave == kDouble) { 416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return fUnion.fDouble; 417103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if(fHave == kInt64) { 418103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (double)fUnion.fInt64; 419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius decimalSeparator = gDecimal; 42150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 423103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (decimalSeparator == 0) { 424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // We need to know the decimal separator character that will be used with strtod(). 425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Depends on the C runtime global locale. 426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Most commonly is '.' 427103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // TODO: caching could fail if the global locale is changed on the fly. 42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char rep[MAX_DIGITS]; 42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho sprintf(rep, "%+1.1f", 1.0); 430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius decimalSeparator = rep[2]; 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 433103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius double tDouble = 0.0; 43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (isZero()) { 435103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tDouble = 0.0; 43650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsNegative(fDecNumber)) { 437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tDouble /= -1; 43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (isInfinite()) { 44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (std::numeric_limits<double>::has_infinity) { 441103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tDouble = std::numeric_limits<double>::infinity(); 44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 443103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tDouble = std::numeric_limits<double>::max(); 44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (!isPositive()) { 446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tDouble = -tDouble; //this was incorrectly "-fDouble" originally. 447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MaybeStackArray<char, MAX_DBL_DIGITS+18> s; 45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Note: 14 is a magic constant from the decNumber library documentation, 45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // the max number of extra characters beyond the number of digits 45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // needed to represent the number in string form. Add a few more 45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // for the additional digits we retain. 45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Round down to appx. double precision, if the number is longer than that. 45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Copy the number first, so that we don't modify the original. 45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (getCount() > MAX_DBL_DIGITS + 3) { 45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DigitList numToConvert(*this); 45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho numToConvert.reduce(); // Removes any trailing zeros, so that digit count is good. 46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho numToConvert.round(MAX_DBL_DIGITS+3); 46154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius uprv_decNumberToString(numToConvert.fDecNumber, s.getAlias()); 46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // TODO: how many extra digits should be included for an accurate conversion? 46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 46454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius uprv_decNumberToString(this->fDecNumber, s.getAlias()); 46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(uprv_strlen(&s[0]) < MAX_DBL_DIGITS+18); 46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 468103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (decimalSeparator != '.') { 46954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius char *decimalPt = strchr(s.getAlias(), '.'); 47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decimalPt != NULL) { 471103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *decimalPt = decimalSeparator; 47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *end = NULL; 47554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius tDouble = uprv_strtod(s.getAlias(), &end); 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 477103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 478103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius Mutex mutex; 479103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius DigitList *nonConstThis = const_cast<DigitList *>(this); 480103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius nonConstThis->internalSetDouble(tDouble); 481103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius gDecimal = decimalSeparator; 482103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 483103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return tDouble; 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * convert this number to an int32_t. Round if there is a fractional part. 49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Return zero if the number cannot be represented. 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t DigitList::getLong() /*const*/ 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t result = 0; 49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->digits + fDecNumber->exponent > 10) { 49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Overflow, absolute value too big. 49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return result; 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->exponent != 0) { 50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Force to an integer, with zero exponent, rounding if necessary. 50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // (decNumberToInt32 will only work if the exponent is exactly zero.) 50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DigitList copy(*this); 50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DigitList zero; 50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberQuantize(copy.fDecNumber, copy.fDecNumber, zero.fDecNumber, &fContext); 50550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_decNumberToInt32(copy.fDecNumber, &fContext); 50650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 50750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_decNumberToInt32(fDecNumber, &fContext); 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return result; 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 5143ef011cb2ded20c46f764e284c6a10f49a9923f8claireho * convert this number to an int64_t. Truncate if there is a fractional part. 51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Return zero if the number cannot be represented. 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 51750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint64_t DigitList::getInt64() /*const*/ { 518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(fHave==kInt64) { 519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return fUnion.fInt64; 520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 5213ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // Truncate if non-integer. 52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Return 0 if out of range. 52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Range of in64_t is -9223372036854775808 to 9223372036854775807 (19 digits) 52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // 52550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->digits + fDecNumber->exponent > 19) { 52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Overflow, absolute value too big. 52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5303ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // The number of integer digits may differ from the number of digits stored 5313ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // in the decimal number. 5323ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // for 12.345 numIntDigits = 2, number->digits = 5 5333ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // for 12E4 numIntDigits = 6, number->digits = 2 5343ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // The conversion ignores the fraction digits in the first case, 5353ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // and fakes up extra zero digits in the second. 5363ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // TODO: It would be faster to store a table of powers of ten to multiply by 5373ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // instead of looping over zero digits, multiplying each time. 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 5393ef011cb2ded20c46f764e284c6a10f49a9923f8claireho int32_t numIntDigits = fDecNumber->digits + fDecNumber->exponent; 54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint64_t value = 0; 5413ef011cb2ded20c46f764e284c6a10f49a9923f8claireho for (int32_t i = 0; i < numIntDigits; i++) { 5423ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // Loop is iterating over digits starting with the most significant. 5433ef011cb2ded20c46f764e284c6a10f49a9923f8claireho // Numbers are stored with the least significant digit at index zero. 5443ef011cb2ded20c46f764e284c6a10f49a9923f8claireho int32_t digitIndex = fDecNumber->digits - i - 1; 5453ef011cb2ded20c46f764e284c6a10f49a9923f8claireho int32_t v = (digitIndex >= 0) ? fDecNumber->lsu[digitIndex] : 0; 54650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho value = value * (uint64_t)10 + (uint64_t)v; 54750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 5483ef011cb2ded20c46f764e284c6a10f49a9923f8claireho 5493ef011cb2ded20c46f764e284c6a10f49a9923f8claireho if (decNumberIsNegative(fDecNumber)) { 55050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho value = ~value; 55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho value += 1; 55250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 55350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int64_t svalue = (int64_t)value; 55450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 55550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Check overflow. It's convenient that the MSD is 9 only on overflow, the amount of 55650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // overflow can't wrap too far. The test will also fail -0, but 55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // that does no harm; the right answer is 0. 5583ef011cb2ded20c46f764e284c6a10f49a9923f8claireho if (numIntDigits == 19) { 55950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (( decNumberIsNegative(fDecNumber) && svalue>0) || 56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (!decNumberIsNegative(fDecNumber) && svalue<0)) { 56150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho svalue = 0; 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 56550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return svalue; 56650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 56750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 568103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 56950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 57050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Return a string form of this number. 57150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Format is as defined by the decNumber library, for interchange of 57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * decimal numbers. 57350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 57427f654740f2a26ad62a5c155af9199af9e69b889clairehovoid DigitList::getDecimal(CharString &str, UErrorCode &status) { 57550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 57650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 57827f654740f2a26ad62a5c155af9199af9e69b889claireho 57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // A decimal number in string form can, worst case, be 14 characters longer 58050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // than the number of digits. So says the decNumber library doc. 58127f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t maxLength = fDecNumber->digits + 14; 58227f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t capacity = 0; 58327f654740f2a26ad62a5c155af9199af9e69b889claireho char *buffer = str.clear().getAppendBuffer(maxLength, 0, capacity, status); 58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; // Memory allocation error on growing the string. 58650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 58727f654740f2a26ad62a5c155af9199af9e69b889claireho U_ASSERT(capacity >= maxLength); 58827f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_decNumberToString(this->fDecNumber, buffer); 58927f654740f2a26ad62a5c155af9199af9e69b889claireho U_ASSERT((int32_t)uprv_strlen(buffer) <= maxLength); 59027f654740f2a26ad62a5c155af9199af9e69b889claireho str.append(buffer, -1, status); 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 59450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Return true if this is an integer value that can be held 59550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * by an int32_t type. 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::fitsIntoLong(UBool ignoreNegativeZero) /*const*/ 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 60050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsSpecial(this->fDecNumber)) { 60150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // NaN or Infinity. Does not fit in int32. 60250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 60450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberTrim(this->fDecNumber); 60550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->exponent < 0) { 60650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Number contains fraction digits. 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 60850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 60950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && 61050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (fDecNumber->bits & DECNEG) != 0) { 61150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Negative Zero, not ingored. Cannot represent as a long. 61250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 61350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 61450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->digits + fDecNumber->exponent < 10) { 61550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The number is 9 or fewer digits. 61650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The max and min int32 are 10 digts, so this number fits. 61750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // This is the common case. 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 61950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 62150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // TODO: Should cache these constants; construction is relatively costly. 62250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // But not of huge consequence; they're only needed for 10 digit ints. 62350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode status = U_ZERO_ERROR; 62450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DigitList min32; min32.set("-2147483648", status); 62550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (this->compare(min32) < 0) { 62650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 62750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 62850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DigitList max32; max32.set("2147483647", status); 62950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (this->compare(max32) > 0) { 63050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 63250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return true; 63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return true if the number represented by this object can fit into 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a long. 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::fitsIntoInt64(UBool ignoreNegativeZero) /*const*/ 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 64750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsSpecial(this->fDecNumber)) { 64850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // NaN or Infinity. Does not fit in int32. 64950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 65150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberTrim(this->fDecNumber); 65250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->exponent < 0) { 65350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Number contains fraction digits. 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 65650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (decNumberIsZero(this->fDecNumber) && !ignoreNegativeZero && 65750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (fDecNumber->bits & DECNEG) != 0) { 65850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Negative Zero, not ingored. Cannot represent as a long. 65950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 66050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 66150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->digits + fDecNumber->exponent < 19) { 66250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The number is 18 or fewer digits. 66350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The max and min int64 are 19 digts, so this number fits. 66450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // This is the common case. 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 66650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 66850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // TODO: Should cache these constants; construction is relatively costly. 66950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // But not of huge consequence; they're only needed for 19 digit ints. 67050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode status = U_ZERO_ERROR; 67150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DigitList min64; min64.set("-9223372036854775808", status); 67250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (this->compare(min64) < 0) { 67350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 67450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 67550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DigitList max64; max64.set("9223372036854775807", status); 67650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (this->compare(max64) > 0) { 67750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 67850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 67950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 68050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 68150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 68250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return true; 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 68950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::set(int32_t source) 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 69150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho set((int64_t)source); 692103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalSetDouble(source); 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 697103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Set an int64, via decnumber 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 70050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::set(int64_t source) 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 70250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char str[MAX_DIGITS+2]; // Leave room for sign and trailing nul. 70350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho formatBase10(source, str); 70450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(uprv_strlen(str) < sizeof(str)); 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 70650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberFromString(fDecNumber, str, &fContext); 7071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert internalSetDouble(static_cast<double>(source)); 708103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 709103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 710103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/** 711103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius * Set an int64, with no decnumber 712103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius */ 713103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 714103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusDigitList::setInteger(int64_t source) 715103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{ 716103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fDecNumber=NULL; 717103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalSetInt64(source); 71850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 72150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 72250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/** 72350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Set the DigitList from a decimal number string. 72450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 72527f654740f2a26ad62a5c155af9199af9e69b889claireho * The incoming string _must_ be nul terminated, even though it is arriving 72650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * as a StringPiece because that is what the decNumber library wants. 72750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * We can get away with this for an internal function; it would not 72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * be acceptable for a public API. 72950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 73050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 73154dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusDigitList::set(const StringPiece &source, UErrorCode &status, uint32_t /*fastpathBits*/) { 73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 73550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 73654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if 0 73754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(fastpathBits==(kFastpathOk|kNoDecimal)) { 73854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t size = source.size(); 73954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const char *data = source.data(); 74054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int64_t r = 0; 74154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int64_t m = 1; 74254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // fast parse 74354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius while(size>0) { 74454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius char ch = data[--size]; 74554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(ch=='+') { 74654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius break; 74754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else if(ch=='-') { 74854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius r = -r; 74954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius break; 75054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else { 75154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int64_t d = ch-'0'; 75254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius //printf("CH[%d]=%c, %d, *=%d\n", size,ch, (int)d, (int)m); 75354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius r+=(d)*m; 75454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius m *= 10; 75554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 75654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 75754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius //printf("R=%d\n", r); 75854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius set(r); 75954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else 76054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif 76154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 76254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Figure out a max number of digits to use during the conversion, and 76354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // resize the number up if necessary. 76454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t numDigits = source.length(); 76554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (numDigits > fContext.digits) { 76627f654740f2a26ad62a5c155af9199af9e69b889claireho // fContext.digits == fStorage.getCapacity() 76727f654740f2a26ad62a5c155af9199af9e69b889claireho decNumber *t = fStorage.resize(numDigits, fStorage.getCapacity()); 76850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (t == NULL) { 76954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius status = U_MEMORY_ALLOCATION_ERROR; 77054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return; 77150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 77227f654740f2a26ad62a5c155af9199af9e69b889claireho fDecNumber = t; 77327f654740f2a26ad62a5c155af9199af9e69b889claireho fContext.digits = numDigits; 77454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 77527f654740f2a26ad62a5c155af9199af9e69b889claireho 77654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius fContext.status = 0; 77754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius uprv_decNumberFromString(fDecNumber, source.data(), &fContext); 77854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if ((fContext.status & DEC_Conversion_syntax) != 0) { 77950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho status = U_DECIMAL_NUMBER_SYNTAX_ERROR; 78054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 78150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 782103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 78350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Set the digit list to a representation of the given double value. 787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This method supports both fixed-point and exponential notation. 78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * @param source Value to be converted. 789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 79150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::set(double source) 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // for now, simple implementation; later, do proper IEEE stuff 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char rep[MAX_DIGITS + 8]; // Extra space for '+', '.', e+NNN, and '\0' (actually +8 is enough) 795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 796103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Generate a representation of the form /[+-][0-9].[0-9]+e[+-][0-9]+/ 797103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Can also generate /[+-]nan/ or /[+-]inf/ 798103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // TODO: Use something other than sprintf() here, since it's behavior is somewhat platform specific. 799103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // That is why infinity is special cased here. 800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (uprv_isInfinite(source)) { 801103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (uprv_isNegativeInfinity(source)) { 802103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_strcpy(rep,"-inf"); // Handle negative infinity 803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_strcpy(rep,"inf"); 805103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 806103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sprintf(rep, "%+1.*e", MAX_DBL_DIGITS - 1, source); 808103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 80950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(uprv_strlen(rep) < sizeof(rep)); 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 811103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // uprv_decNumberFromString() will parse the string expecting '.' as a 812103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // decimal separator, however sprintf() can use ',' in certain locales. 813103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Overwrite a ',' with '.' here before proceeding. 814103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius char *decimalSeparator = strchr(rep, ','); 815103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (decimalSeparator != NULL) { 816103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *decimalSeparator = '.'; 817103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 818103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 81950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Create a decNumber from the string. 82050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberFromString(fDecNumber, rep, &fContext); 82150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberTrim(fDecNumber); 822103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalSetDouble(source); 82350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 82550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 82750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 82850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Multiply 82950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * The number will be expanded if need be to retain full precision. 83050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * In practice, for formatting, multiply is by 10, 100 or 1000, so more digits 83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * will not be required for this use. 83250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 83350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 83450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::mult(const DigitList &other, UErrorCode &status) { 83550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fContext.status = 0; 83650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t requiredDigits = this->digits() + other.digits(); 83750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (requiredDigits > fContext.digits) { 83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho reduce(); // Remove any trailing zeros 83950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t requiredDigits = this->digits() + other.digits(); 84050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ensureCapacity(requiredDigits, status); 841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 84250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberMultiply(fDecNumber, fDecNumber, other.fDecNumber, &fContext); 843103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 84450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 84750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 84850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 84950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Divide 85050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * The number will _not_ be expanded for inexact results. 85150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * TODO: probably should expand some, for rounding increments that 85250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * could add a few digits, e.g. .25, but not expand arbitrarily. 85350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 85450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 85550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::div(const DigitList &other, UErrorCode &status) { 85650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 85950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberDivide(fDecNumber, fDecNumber, other.fDecNumber, &fContext); 860103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 86150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 86350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 86550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 86650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * ensureCapacity. Grow the digit storage for the number if it's less than the requested 86750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * amount. Never reduce it. Available size is kept in fContext.digits. 86850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 86950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 87050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::ensureCapacity(int32_t requestedCapacity, UErrorCode &status) { 87150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 87250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 87450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (requestedCapacity <= 0) { 87550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho status = U_ILLEGAL_ARGUMENT_ERROR; 87650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 87750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 87850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (requestedCapacity > DEC_MAX_DIGITS) { 87950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Don't report an error for requesting too much. 88050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Arithemetic Results will be rounded to what can be supported. 88150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // At 999,999,999 max digits, exceeding the limit is not too likely! 88250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho requestedCapacity = DEC_MAX_DIGITS; 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 88450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (requestedCapacity > fContext.digits) { 88527f654740f2a26ad62a5c155af9199af9e69b889claireho decNumber *newBuffer = fStorage.resize(requestedCapacity, fStorage.getCapacity()); 88650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (newBuffer == NULL) { 88750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho status = U_MEMORY_ALLOCATION_ERROR; 88850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 88950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 89050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fContext.digits = requestedCapacity; 89127f654740f2a26ad62a5c155af9199af9e69b889claireho fDecNumber = newBuffer; 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Round the representation to the given number of digits. 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param maximumDigits The maximum number of digits to be shown. 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Upon return, count will be less than or equal to maximumDigits. 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::round(int32_t maximumDigits) 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 90550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t savedDigits = fContext.digits; 90650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fContext.digits = maximumDigits; 90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberPlus(fDecNumber, fDecNumber, &fContext); 90850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fContext.digits = savedDigits; 90950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberTrim(fDecNumber); 910103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 91450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 91550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::roundFixedPoint(int32_t maximumFractionDigits) { 91650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho trim(); // Remove trailing zeros. 91750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (fDecNumber->exponent >= -maximumFractionDigits) { 91850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 92050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho decNumber scale; // Dummy decimal number, but with the desired number of 92150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberZero(&scale); // fraction digits. 92250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho scale.exponent = -maximumFractionDigits; 92350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho scale.lsu[0] = 1; 92450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 92550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberQuantize(fDecNumber, fDecNumber, &scale, &fContext); 92650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho trim(); 927103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius internalClear(); 928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 93350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoDigitList::toIntegralValue() { 93450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_decNumberToIntegralValue(fDecNumber, fDecNumber, &fContext); 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 93750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 93850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// ------------------------------------- 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDigitList::isZero() const 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 94250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return decNumberIsZero(fDecNumber); 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif // #if !UCONFIG_NO_FORMATTING 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof 949