| Index: icu46/source/i18n/digitlst.h
|
| ===================================================================
|
| --- icu46/source/i18n/digitlst.h (revision 0)
|
| +++ icu46/source/i18n/digitlst.h (revision 0)
|
| @@ -0,0 +1,399 @@
|
| +/*
|
| +******************************************************************************
|
| +*
|
| +* Copyright (C) 1997-2010, International Business Machines
|
| +* Corporation and others. All Rights Reserved.
|
| +*
|
| +******************************************************************************
|
| +*
|
| +* File DIGITLST.H
|
| +*
|
| +* Modification History:
|
| +*
|
| +* Date Name Description
|
| +* 02/25/97 aliu Converted from java.
|
| +* 03/21/97 clhuang Updated per C++ implementation.
|
| +* 04/15/97 aliu Changed MAX_COUNT to DBL_DIG. Changed Digit to char.
|
| +* 09/09/97 aliu Adapted for exponential notation support.
|
| +* 08/02/98 stephen Added nearest/even rounding
|
| +* 06/29/99 stephen Made LONG_DIGITS a macro to satisfy SUN compiler
|
| +* 07/09/99 stephen Removed kMaxCount (unused, for HP compiler)
|
| +******************************************************************************
|
| +*/
|
| +
|
| +#ifndef DIGITLST_H
|
| +#define DIGITLST_H
|
| +
|
| +#include "unicode/uobject.h"
|
| +
|
| +#if !UCONFIG_NO_FORMATTING
|
| +#include "unicode/decimfmt.h"
|
| +#include <float.h>
|
| +#include "decContext.h"
|
| +#include "decNumber.h"
|
| +#include "cmemory.h"
|
| +
|
| +// Decimal digits in a 64-bit int
|
| +#define INT64_DIGITS 19
|
| +
|
| +typedef enum EDigitListValues {
|
| + MAX_DBL_DIGITS = DBL_DIG,
|
| + MAX_I64_DIGITS = INT64_DIGITS,
|
| + MAX_DIGITS = MAX_I64_DIGITS,
|
| + MAX_EXPONENT = DBL_DIG,
|
| + DIGIT_PADDING = 3,
|
| + DEFAULT_DIGITS = 40, // Initial storage size, will grow as needed.
|
| +
|
| + // "+." + fDigits + "e" + fDecimalAt
|
| + MAX_DEC_DIGITS = MAX_DIGITS + DIGIT_PADDING + MAX_EXPONENT
|
| +} EDigitListValues;
|
| +
|
| +U_NAMESPACE_BEGIN
|
| +
|
| +class CharString;
|
| +
|
| +// Export an explicit template instantiation of the MaybeStackHeaderAndArray that
|
| +// is used as a data member of DigitList.
|
| +//
|
| +// MSVC requires this, even though it should not be necessary.
|
| +// No direct access to the MaybeStackHeaderAndArray leaks out of the i18n library.
|
| +//
|
| +// Macintosh produces duplicate definition linker errors with the explicit template
|
| +// instantiation.
|
| +//
|
| +#if !defined(U_DARWIN)
|
| +template class U_I18N_API MaybeStackHeaderAndArray<decNumber, char, DEFAULT_DIGITS>;
|
| +#endif
|
| +
|
| +
|
| +/**
|
| + * Digit List is actually a Decimal Floating Point number.
|
| + * The original implementation has been replaced by a thin wrapper onto a
|
| + * decimal number from the decNumber library.
|
| + *
|
| + * The original DigitList API has been retained, to minimize the impact of
|
| + * the change on the rest of the ICU formatting code.
|
| + *
|
| + * The change to decNumber enables support for big decimal numbers, and
|
| + * allows rounding computations to be done directly in decimal, avoiding
|
| + * extra, and inaccurate, conversions to and from doubles.
|
| + *
|
| + * Original DigitList comments:
|
| + *
|
| + * Digit List utility class. Private to DecimalFormat. Handles the transcoding
|
| + * between numeric values and strings of characters. Only handles
|
| + * non-negative numbers. The division of labor between DigitList and
|
| + * DecimalFormat is that DigitList handles the radix 10 representation
|
| + * issues; DecimalFormat handles the locale-specific issues such as
|
| + * positive/negative, grouping, decimal point, currency, and so on.
|
| + * <P>
|
| + * A DigitList is really a representation of a floating point value.
|
| + * It may be an integer value; we assume that a double has sufficient
|
| + * precision to represent all digits of a long.
|
| + * <P>
|
| + * The DigitList representation consists of a string of characters,
|
| + * which are the digits radix 10, from '0' to '9'. It also has a radix
|
| + * 10 exponent associated with it. The value represented by a DigitList
|
| + * object can be computed by mulitplying the fraction f, where 0 <= f < 1,
|
| + * derived by placing all the digits of the list to the right of the
|
| + * decimal point, by 10^exponent.
|
| + *
|
| + * --------
|
| + *
|
| + * DigitList vs. decimalNumber:
|
| + *
|
| + * DigitList stores digits with the most significant first.
|
| + * decNumber stores digits with the least significant first.
|
| + *
|
| + * DigitList, decimal point is before the most significant.
|
| + * decNumber, decimal point is after the least signficant digit.
|
| + *
|
| + * digitList: 0.ddddd * 10 ^ exp
|
| + * decNumber: ddddd. * 10 ^ exp
|
| + *
|
| + * digitList exponent = decNumber exponent + digit count
|
| + *
|
| + * digitList, digits are platform invariant chars, '0' - '9'
|
| + * decNumber, digits are binary, one per byte, 0 - 9.
|
| + *
|
| + * (decNumber library is configurable in how digits are stored, ICU has configured
|
| + * it this way for convenience in replacing the old DigitList implementation.)
|
| + */
|
| +class U_I18N_API DigitList : public UMemory { // Declare external to make compiler happy
|
| +public:
|
| +
|
| + DigitList();
|
| + ~DigitList();
|
| +
|
| + /* copy constructor
|
| + * @param DigitList The object to be copied.
|
| + * @return the newly created object.
|
| + */
|
| + DigitList(const DigitList&); // copy constructor
|
| +
|
| + /* assignment operator
|
| + * @param DigitList The object to be copied.
|
| + * @return the newly created object.
|
| + */
|
| + DigitList& operator=(const DigitList&); // assignment operator
|
| +
|
| + /**
|
| + * Return true if another object is semantically equal to this one.
|
| + * @param other The DigitList to be compared for equality
|
| + * @return true if another object is semantically equal to this one.
|
| + * return false otherwise.
|
| + */
|
| + UBool operator==(const DigitList& other) const;
|
| +
|
| + int32_t compare(const DigitList& other);
|
| +
|
| +
|
| + inline UBool operator!=(const DigitList& other) const { return !operator==(other); };
|
| +
|
| + /**
|
| + * Clears out the digits.
|
| + * Use before appending them.
|
| + * Typically, you set a series of digits with append, then at the point
|
| + * you hit the decimal point, you set myDigitList.fDecimalAt = myDigitList.fCount;
|
| + * then go on appending digits.
|
| + */
|
| + void clear(void);
|
| +
|
| + /**
|
| + * Remove, by rounding, any fractional part of the decimal number,
|
| + * leaving an integer value.
|
| + */
|
| + void toIntegralValue();
|
| +
|
| + /**
|
| + * Appends digits to the list.
|
| + * CAUTION: this function is not recommended for new code.
|
| + * In the original DigitList implementation, decimal numbers were
|
| + * parsed by appending them to a digit list as they were encountered.
|
| + * With the revamped DigitList based on decNumber, append is very
|
| + * inefficient, and the interaction with the exponent value is confusing.
|
| + * Best avoided.
|
| + * TODO: remove this function once all use has been replaced.
|
| + * TODO: describe alternative to append()
|
| + * @param digit The digit to be appended.
|
| + */
|
| + void append(char digit);
|
| +
|
| + /**
|
| + * Utility routine to get the value of the digit list
|
| + * Returns 0.0 if zero length.
|
| + * @return the value of the digit list.
|
| + */
|
| + double getDouble(void) const;
|
| +
|
| + /**
|
| + * Utility routine to get the value of the digit list
|
| + * Make sure that fitsIntoLong() is called before calling this function.
|
| + * Returns 0 if zero length.
|
| + * @return the value of the digit list, return 0 if it is zero length
|
| + */
|
| + int32_t getLong(void) /*const*/;
|
| +
|
| + /**
|
| + * Utility routine to get the value of the digit list
|
| + * Make sure that fitsIntoInt64() is called before calling this function.
|
| + * Returns 0 if zero length.
|
| + * @return the value of the digit list, return 0 if it is zero length
|
| + */
|
| + int64_t getInt64(void) /*const*/;
|
| +
|
| + /**
|
| + * Utility routine to get the value of the digit list as a decimal string.
|
| + */
|
| + void getDecimal(CharString &str, UErrorCode &status);
|
| +
|
| + /**
|
| + * Return true if the number represented by this object can fit into
|
| + * a long.
|
| + * @param ignoreNegativeZero True if negative zero is ignored.
|
| + * @return true if the number represented by this object can fit into
|
| + * a long, return false otherwise.
|
| + */
|
| + UBool fitsIntoLong(UBool ignoreNegativeZero) /*const*/;
|
| +
|
| + /**
|
| + * Return true if the number represented by this object can fit into
|
| + * an int64_t.
|
| + * @param ignoreNegativeZero True if negative zero is ignored.
|
| + * @return true if the number represented by this object can fit into
|
| + * a long, return false otherwise.
|
| + */
|
| + UBool fitsIntoInt64(UBool ignoreNegativeZero) /*const*/;
|
| +
|
| + /**
|
| + * Utility routine to set the value of the digit list from a double.
|
| + * @param source The value to be set
|
| + */
|
| + void set(double source);
|
| +
|
| + /**
|
| + * Utility routine to set the value of the digit list from a long.
|
| + * If a non-zero maximumDigits is specified, no more than that number of
|
| + * significant digits will be produced.
|
| + * @param source The value to be set
|
| + */
|
| + void set(int32_t source);
|
| +
|
| + /**
|
| + * Utility routine to set the value of the digit list from an int64.
|
| + * If a non-zero maximumDigits is specified, no more than that number of
|
| + * significant digits will be produced.
|
| + * @param source The value to be set
|
| + */
|
| + void set(int64_t source);
|
| +
|
| + /**
|
| + * Utility routine to set the value of the digit list from a decimal number
|
| + * string.
|
| + * @param source The value to be set. The string must be nul-terminated.
|
| + */
|
| + void set(const StringPiece &source, UErrorCode &status);
|
| +
|
| + /**
|
| + * Multiply this = this * arg
|
| + * This digitlist will be expanded if necessary to accomodate the result.
|
| + * @param arg the number to multiply by.
|
| + */
|
| + void mult(const DigitList &arg, UErrorCode &status);
|
| +
|
| + /**
|
| + * Divide this = this / arg
|
| + */
|
| + void div(const DigitList &arg, UErrorCode &status);
|
| +
|
| + // The following functions replace direct access to the original DigitList implmentation
|
| + // data structures.
|
| +
|
| + void setRoundingMode(DecimalFormat::ERoundingMode m);
|
| +
|
| + /** Test a number for zero.
|
| + * @return TRUE if the number is zero
|
| + */
|
| + UBool isZero(void) const;
|
| +
|
| + /** Test for a Nan
|
| + * @return TRUE if the number is a NaN
|
| + */
|
| + UBool isNaN(void) const {return decNumberIsNaN(fDecNumber);};
|
| +
|
| + UBool isInfinite() const {return decNumberIsInfinite(fDecNumber);};
|
| +
|
| + /** Reduce, or normalize. Removes trailing zeroes, adjusts exponent appropriately. */
|
| + void reduce();
|
| +
|
| + /** Remove trailing fraction zeros, adjust exponent accordingly. */
|
| + void trim();
|
| +
|
| + /** Set to zero */
|
| + void setToZero() {uprv_decNumberZero(fDecNumber);};
|
| +
|
| + /** get the number of digits in the decimal number */
|
| + int32_t digits() const {return fDecNumber->digits;};
|
| +
|
| + /**
|
| + * Round the number to the given number of digits.
|
| + * @param maximumDigits The maximum number of digits to be shown.
|
| + * Upon return, count will be less than or equal to maximumDigits.
|
| + */
|
| + void round(int32_t maximumDigits);
|
| +
|
| + void roundFixedPoint(int32_t maximumFractionDigits);
|
| +
|
| + /** Ensure capacity for digits. Grow the storage if it is currently less than
|
| + * the requested size. Capacity is not reduced if it is already greater
|
| + * than requested.
|
| + */
|
| + void ensureCapacity(int32_t requestedSize, UErrorCode &status);
|
| +
|
| + UBool isPositive(void) const { return decNumberIsNegative(fDecNumber) == 0;};
|
| + void setPositive(UBool s);
|
| +
|
| + void setDecimalAt(int32_t d);
|
| + int32_t getDecimalAt();
|
| +
|
| + void setCount(int32_t c);
|
| + int32_t getCount() const;
|
| +
|
| + /**
|
| + * Set the digit in platform (invariant) format, from '0'..'9'
|
| + * @param i index of digit
|
| + * @param v digit value, from '0' to '9' in platform invariant format
|
| + */
|
| + void setDigit(int32_t i, char v);
|
| +
|
| + /**
|
| + * Get the digit in platform (invariant) format, from '0'..'9' inclusive
|
| + * @param i index of digit
|
| + * @return invariant format of the digit
|
| + */
|
| + char getDigit(int32_t i);
|
| +
|
| +
|
| + /**
|
| + * Get the digit's value, as an integer from 0..9 inclusive.
|
| + * Note that internally this value is a decNumberUnit, but ICU configures it to be a uint8_t.
|
| + * @param i index of digit
|
| + * @return value of that digit
|
| + */
|
| + uint8_t getDigitValue(int32_t i);
|
| +
|
| +
|
| +private:
|
| + /*
|
| + * These data members are intentionally public and can be set directly.
|
| + *<P>
|
| + * The value represented is given by placing the decimal point before
|
| + * fDigits[fDecimalAt]. If fDecimalAt is < 0, then leading zeros between
|
| + * the decimal point and the first nonzero digit are implied. If fDecimalAt
|
| + * is > fCount, then trailing zeros between the fDigits[fCount-1] and the
|
| + * decimal point are implied.
|
| + * <P>
|
| + * Equivalently, the represented value is given by f * 10^fDecimalAt. Here
|
| + * f is a value 0.1 <= f < 1 arrived at by placing the digits in fDigits to
|
| + * the right of the decimal.
|
| + * <P>
|
| + * DigitList is normalized, so if it is non-zero, fDigits[0] is non-zero. We
|
| + * don't allow denormalized numbers because our exponent is effectively of
|
| + * unlimited magnitude. The fCount value contains the number of significant
|
| + * digits present in fDigits[].
|
| + * <P>
|
| + * Zero is represented by any DigitList with fCount == 0 or with each fDigits[i]
|
| + * for all i <= fCount == '0'.
|
| + *
|
| + * int32_t fDecimalAt;
|
| + * int32_t fCount;
|
| + * UBool fIsPositive;
|
| + * char *fDigits;
|
| + * DecimalFormat::ERoundingMode fRoundingMode;
|
| + */
|
| +
|
| +private:
|
| +
|
| + decContext fContext;
|
| + decNumber *fDecNumber;
|
| + MaybeStackHeaderAndArray<decNumber, char, DEFAULT_DIGITS> fStorage;
|
| +
|
| + /* Cached double value corresponding to this decimal number.
|
| + * This is an optimization for the formatting implementation, which may
|
| + * ask for the double value multiple times.
|
| + */
|
| + double fDouble;
|
| + UBool fHaveDouble;
|
| +
|
| +
|
| +
|
| + UBool shouldRoundUp(int32_t maximumDigits) const;
|
| +};
|
| +
|
| +
|
| +U_NAMESPACE_END
|
| +
|
| +#endif // #if !UCONFIG_NO_FORMATTING
|
| +#endif // _DIGITLST
|
| +
|
| +//eof
|
|
|
| Property changes on: icu46/source/i18n/digitlst.h
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|