summaryrefslogtreecommitdiffstats
path: root/intl/icu/source/i18n/visibledigits.h
blob: eba2a1bc9f44865620091c4c228d352a520e2569 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
******************************************************************************* * Copyright (C) 2015, International Business Machines
* Corporation and others.  All Rights Reserved.
*******************************************************************************
* visibledigits.h
*
* created on: 2015jun20
* created by: Travis Keep
*/

#ifndef __VISIBLEDIGITS_H__
#define __VISIBLEDIGITS_H__

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/uobject.h"

#include "charstr.h"
#include "digitinterval.h"

U_NAMESPACE_BEGIN

class DigitList;

/**
 * VisibleDigits represents the digits visible for formatting.
 * Once initialized using a FixedPrecision instance, VisibleDigits instances
 * remain unchanged until they are initialized again. A VisibleDigits with
 * a numeric value equal to 3.0 could be "3", "3.0", "3.00" or even "003.0"
 * depending on settings of the FixedPrecision instance used to initialize it.
 */
class U_I18N_API VisibleDigits : public UMemory {
public:
    VisibleDigits() : fExponent(0), fFlags(0), fAbsIntValue(0), fAbsIntValueSet(FALSE), fAbsDoubleValue(0.0), fAbsDoubleValueSet(FALSE) { }

    UBool isNegative() const;
    UBool isNaN() const;
    UBool isInfinite() const;
    UBool isNaNOrInfinity() const;

    /**
     * Gets the digit at particular exponent, if number is 987.6, then
     * getDigit(2) == 9 and gitDigit(0) == 7 and gitDigit(-1) == 6.
     * If isNaN() or isInfinity() return TRUE, then the result of this
     * function is undefined.
     */
    int32_t getDigitByExponent(int32_t digitPos) const;

    /**
     * Returns the digit interval which indicates the leftmost and rightmost
     * position of this instance. 
     * If isNaN() or isInfinity() return TRUE, then the result of this
     * function is undefined.
     */
    const DigitInterval &getInterval() const { return fInterval; }

    /**
     * Gets the parameters needed to create a FixedDecimal.
     */
    void getFixedDecimal(double &source, int64_t &intValue, int64_t &f, int64_t &t, int32_t &v, UBool &hasIntValue) const;


private:
    /**
     * The digits, least significant first. Both the least and most
     * significant digit in this list are non-zero; however, digits in the
     * middle may be zero. This field contains values between (char) 0, and
     * (char) 9 inclusive.
     */
    CharString fDigits;

    /**
     * The range of displayable digits. This field is needed to account for
     * any leading and trailing zeros which are not stored in fDigits.
     */
    DigitInterval fInterval;

    /**
     * The exponent value of the least significant digit in fDigits. For
     * example, fExponent = 2 and fDigits = {7, 8, 5} represents 58700.
     */
    int32_t fExponent;

    /**
     * Contains flags such as NaN, Inf, and negative.
     */
    int32_t fFlags;

    /**
     * Contains the absolute value of the digits left of the decimal place
     * if fAbsIntValueSet is TRUE
     */
    int64_t fAbsIntValue;

    /**
     * Indicates whether or not fAbsIntValue is set.
     */
    UBool fAbsIntValueSet;

    /**
     * Contains the absolute value of the value this instance represents
     * if fAbsDoubleValueSet is TRUE
     */
    double fAbsDoubleValue;

    /**
     * Indicates whether or not fAbsDoubleValue is set.
     */
    UBool fAbsDoubleValueSet;

    void setNegative();
    void setNaN();
    void setInfinite();
    void clear();
    double computeAbsDoubleValue() const;
    UBool isOverMaxDigits() const;

    VisibleDigits(const VisibleDigits &);
    VisibleDigits &operator=(const VisibleDigits &);

    friend class FixedPrecision;
    friend class VisibleDigitsWithExponent;
};

/**
 * A VisibleDigits with a possible exponent.
 */
class U_I18N_API VisibleDigitsWithExponent : public UMemory {
public:
    VisibleDigitsWithExponent() : fHasExponent(FALSE) { }
    const VisibleDigits &getMantissa() const { return fMantissa; }
    const VisibleDigits *getExponent() const {
        return fHasExponent ? &fExponent : NULL;
    }
    void clear() {
        fMantissa.clear();
        fExponent.clear();
        fHasExponent = FALSE;
    }
    UBool isNegative() const { return fMantissa.isNegative(); }
    UBool isNaN() const { return fMantissa.isNaN(); }
    UBool isInfinite() const { return fMantissa.isInfinite(); }
private:
    VisibleDigitsWithExponent(const VisibleDigitsWithExponent &);
    VisibleDigitsWithExponent &operator=(
        const VisibleDigitsWithExponent &);
    VisibleDigits fMantissa;
    VisibleDigits fExponent;
    UBool fHasExponent;

    friend class ScientificPrecision;
    friend class FixedPrecision;
};


U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif  // __VISIBLEDIGITS_H__