1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2017 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4package android.icu.impl.number;
5
6import java.math.BigDecimal;
7import java.math.BigInteger;
8import android.icu.testsharding.MainTestShard;
9
10@MainTestShard
11public final class DecimalQuantity_64BitBCD extends DecimalQuantity_AbstractBCD {
12
13  /**
14   * The BCD of the 16 digits of the number represented by this object. Every 4 bits of the long map
15   * to one digit. For example, the number "12345" in BCD is "0x12345".
16   *
17   * <p>Whenever bcd changes internally, {@link #compact()} must be called, except in special cases
18   * like setting the digit to zero.
19   */
20  private long bcd;
21
22  @Override
23  public int maxRepresentableDigits() {
24    return 16;
25  }
26
27  public DecimalQuantity_64BitBCD(long input) {
28    setToLong(input);
29  }
30
31  public DecimalQuantity_64BitBCD(int input) {
32    setToInt(input);
33  }
34
35  public DecimalQuantity_64BitBCD(double input) {
36    setToDouble(input);
37  }
38
39  public DecimalQuantity_64BitBCD(BigInteger input) {
40    setToBigInteger(input);
41  }
42
43  public DecimalQuantity_64BitBCD(BigDecimal input) {
44    setToBigDecimal(input);
45  }
46
47  public DecimalQuantity_64BitBCD(DecimalQuantity_64BitBCD other) {
48    copyFrom(other);
49  }
50
51  @Override
52  public DecimalQuantity createCopy() {
53    return new DecimalQuantity_64BitBCD(this);
54  }
55
56  @Override
57  protected byte getDigitPos(int position) {
58    if (position < 0 || position >= 16) return 0;
59    return (byte) ((bcd >>> (position * 4)) & 0xf);
60  }
61
62  @Override
63  protected void setDigitPos(int position, byte value) {
64    assert position >= 0 && position < 16;
65    int shift = position * 4;
66    bcd = bcd & ~(0xfL << shift) | ((long) value << shift);
67  }
68
69  @Override
70  protected void shiftLeft(int numDigits) {
71    assert precision + numDigits <= 16;
72    bcd <<= (numDigits * 4);
73    scale -= numDigits;
74    precision += numDigits;
75  }
76
77  @Override
78  protected void shiftRight(int numDigits) {
79    bcd >>>= (numDigits * 4);
80    scale += numDigits;
81    precision -= numDigits;
82  }
83
84  @Override
85  protected void setBcdToZero() {
86    bcd = 0L;
87    scale = 0;
88    precision = 0;
89    isApproximate = false;
90    origDouble = 0;
91    origDelta = 0;
92  }
93
94  @Override
95  protected void readIntToBcd(int n) {
96    assert n != 0;
97    long result = 0L;
98    int i = 16;
99    for (; n != 0; n /= 10, i--) {
100      result = (result >>> 4) + (((long) n % 10) << 60);
101    }
102    // ints can't overflow the 16 digits in the BCD, so scale is always zero
103    bcd = result >>> (i * 4);
104    scale = 0;
105    precision = 16 - i;
106  }
107
108  @Override
109  protected void readLongToBcd(long n) {
110    assert n != 0;
111    long result = 0L;
112    int i = 16;
113    for (; n != 0L; n /= 10L, i--) {
114      result = (result >>> 4) + ((n % 10) << 60);
115    }
116    int adjustment = (i > 0) ? i : 0;
117    bcd = result >>> (adjustment * 4);
118    scale = (i < 0) ? -i : 0;
119    precision = 16 - i;
120  }
121
122  @Override
123  protected void readBigIntegerToBcd(BigInteger n) {
124    assert n.signum() != 0;
125    long result = 0L;
126    int i = 16;
127    for (; n.signum() != 0; i--) {
128      BigInteger[] temp = n.divideAndRemainder(BigInteger.TEN);
129      result = (result >>> 4) + (temp[1].longValue() << 60);
130      n = temp[0];
131    }
132    int adjustment = (i > 0) ? i : 0;
133    bcd = result >>> (adjustment * 4);
134    scale = (i < 0) ? -i : 0;
135  }
136
137  @Override
138  protected BigDecimal bcdToBigDecimal() {
139    long tempLong = 0L;
140    for (int shift = (precision - 1); shift >= 0; shift--) {
141      tempLong = tempLong * 10 + getDigitPos(shift);
142    }
143    BigDecimal result = BigDecimal.valueOf(tempLong);
144    result = result.scaleByPowerOfTen(scale);
145    if (isNegative()) result = result.negate();
146    return result;
147  }
148
149  @Override
150  protected void compact() {
151    // Special handling for 0
152    if (bcd == 0L) {
153      scale = 0;
154      precision = 0;
155      return;
156    }
157
158    // Compact the number (remove trailing zeros)
159    int delta = Long.numberOfTrailingZeros(bcd) / 4;
160    bcd >>>= delta * 4;
161    scale += delta;
162
163    // Compute precision
164    precision = 16 - (Long.numberOfLeadingZeros(bcd) / 4);
165  }
166
167  @Override
168  protected void copyBcdFrom(DecimalQuantity _other) {
169    DecimalQuantity_64BitBCD other = (DecimalQuantity_64BitBCD) _other;
170    bcd = other.bcd;
171  }
172
173  @Override
174  public String toString() {
175    return String.format(
176        "<DecimalQuantity2 %s:%d:%d:%s %016XE%d>",
177        (lOptPos > 1000 ? "max" : String.valueOf(lOptPos)),
178        lReqPos,
179        rReqPos,
180        (rOptPos < -1000 ? "min" : String.valueOf(rOptPos)),
181        bcd,
182        scale);
183  }
184}
185