text: // © 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__
  