1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* * Copyright (C) 2015, International Business Machines 5 * Corporation and others. All Rights Reserved. 6 ******************************************************************************* 7 * visibledigits.h 8 * 9 * created on: 2015jun20 10 * created by: Travis Keep 11 */ 12 13 #ifndef __VISIBLEDIGITS_H__ 14 #define __VISIBLEDIGITS_H__ 15 16 #include "unicode/utypes.h" 17 18 #if !UCONFIG_NO_FORMATTING 19 20 #include "unicode/uobject.h" 21 22 #include "charstr.h" 23 #include "digitinterval.h" 24 25 U_NAMESPACE_BEGIN 26 27 class DigitList; 28 29 /** 30 * VisibleDigits represents the digits visible for formatting. 31 * Once initialized using a FixedPrecision instance, VisibleDigits instances 32 * remain unchanged until they are initialized again. A VisibleDigits with 33 * a numeric value equal to 3.0 could be "3", "3.0", "3.00" or even "003.0" 34 * depending on settings of the FixedPrecision instance used to initialize it. 35 */ 36 class U_I18N_API VisibleDigits : public UMemory { 37 public: VisibleDigits()38 VisibleDigits() : fExponent(0), fFlags(0), fAbsIntValue(0), fAbsIntValueSet(FALSE), fAbsDoubleValue(0.0), fAbsDoubleValueSet(FALSE) { } 39 40 UBool isNegative() const; 41 UBool isNaN() const; 42 UBool isInfinite() const; 43 UBool isNaNOrInfinity() const; 44 45 /** 46 * Gets the digit at particular exponent, if number is 987.6, then 47 * getDigit(2) == 9 and gitDigit(0) == 7 and gitDigit(-1) == 6. 48 * If isNaN() or isInfinity() return TRUE, then the result of this 49 * function is undefined. 50 */ 51 int32_t getDigitByExponent(int32_t digitPos) const; 52 53 /** 54 * Returns the digit interval which indicates the leftmost and rightmost 55 * position of this instance. 56 * If isNaN() or isInfinity() return TRUE, then the result of this 57 * function is undefined. 58 */ getInterval()59 const DigitInterval &getInterval() const { return fInterval; } 60 61 /** 62 * Gets the parameters needed to create a FixedDecimal. 63 */ 64 void getFixedDecimal(double &source, int64_t &intValue, int64_t &f, int64_t &t, int32_t &v, UBool &hasIntValue) const; 65 66 67 private: 68 /** 69 * The digits, least significant first. Both the least and most 70 * significant digit in this list are non-zero; however, digits in the 71 * middle may be zero. This field contains values between (char) 0, and 72 * (char) 9 inclusive. 73 */ 74 CharString fDigits; 75 76 /** 77 * The range of displayable digits. This field is needed to account for 78 * any leading and trailing zeros which are not stored in fDigits. 79 */ 80 DigitInterval fInterval; 81 82 /** 83 * The exponent value of the least significant digit in fDigits. For 84 * example, fExponent = 2 and fDigits = {7, 8, 5} represents 58700. 85 */ 86 int32_t fExponent; 87 88 /** 89 * Contains flags such as NaN, Inf, and negative. 90 */ 91 int32_t fFlags; 92 93 /** 94 * Contains the absolute value of the digits left of the decimal place 95 * if fAbsIntValueSet is TRUE 96 */ 97 int64_t fAbsIntValue; 98 99 /** 100 * Indicates whether or not fAbsIntValue is set. 101 */ 102 UBool fAbsIntValueSet; 103 104 /** 105 * Contains the absolute value of the value this instance represents 106 * if fAbsDoubleValueSet is TRUE 107 */ 108 double fAbsDoubleValue; 109 110 /** 111 * Indicates whether or not fAbsDoubleValue is set. 112 */ 113 UBool fAbsDoubleValueSet; 114 115 void setNegative(); 116 void setNaN(); 117 void setInfinite(); 118 void clear(); 119 double computeAbsDoubleValue() const; 120 UBool isOverMaxDigits() const; 121 122 VisibleDigits(const VisibleDigits &); 123 VisibleDigits &operator=(const VisibleDigits &); 124 125 friend class FixedPrecision; 126 friend class VisibleDigitsWithExponent; 127 }; 128 129 /** 130 * A VisibleDigits with a possible exponent. 131 */ 132 class U_I18N_API VisibleDigitsWithExponent : public UMemory { 133 public: VisibleDigitsWithExponent()134 VisibleDigitsWithExponent() : fHasExponent(FALSE) { } getMantissa()135 const VisibleDigits &getMantissa() const { return fMantissa; } getExponent()136 const VisibleDigits *getExponent() const { 137 return fHasExponent ? &fExponent : NULL; 138 } clear()139 void clear() { 140 fMantissa.clear(); 141 fExponent.clear(); 142 fHasExponent = FALSE; 143 } isNegative()144 UBool isNegative() const { return fMantissa.isNegative(); } isNaN()145 UBool isNaN() const { return fMantissa.isNaN(); } isInfinite()146 UBool isInfinite() const { return fMantissa.isInfinite(); } 147 private: 148 VisibleDigitsWithExponent(const VisibleDigitsWithExponent &); 149 VisibleDigitsWithExponent &operator=( 150 const VisibleDigitsWithExponent &); 151 VisibleDigits fMantissa; 152 VisibleDigits fExponent; 153 UBool fHasExponent; 154 155 friend class ScientificPrecision; 156 friend class FixedPrecision; 157 }; 158 159 160 U_NAMESPACE_END 161 #endif /* #if !UCONFIG_NO_FORMATTING */ 162 #endif // __VISIBLEDIGITS_H__ 163