LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - visibledigits.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 90 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             :  * Copyright (C) 2016, International Business Machines
       5             :  * Corporation and others.  All Rights Reserved.
       6             :  *
       7             :  * file name: visibledigits.cpp
       8             :  */
       9             : 
      10             : #include <math.h>
      11             : 
      12             : #include "unicode/utypes.h"
      13             : 
      14             : #if !UCONFIG_NO_FORMATTING
      15             : 
      16             : #include "cstring.h"
      17             : #include "decNumber.h"
      18             : #include "digitlst.h"
      19             : #include "uassert.h"
      20             : #include "visibledigits.h"
      21             : 
      22             : static const int32_t kNegative = 1;
      23             : static const int32_t kInfinite = 2;
      24             : static const int32_t kNaN = 4;
      25             : 
      26             : U_NAMESPACE_BEGIN
      27             : 
      28           0 : void VisibleDigits::setNegative() {
      29           0 :     fFlags |= kNegative;
      30           0 : }
      31             : 
      32           0 : void VisibleDigits::setNaN() {
      33           0 :     fFlags |= kNaN;
      34           0 : }
      35             : 
      36           0 : void VisibleDigits::setInfinite() {
      37           0 :     fFlags |= kInfinite;
      38           0 : }
      39             : 
      40           0 : void VisibleDigits::clear() {
      41           0 :     fInterval.clear();
      42           0 :     fDigits.clear();
      43           0 :     fExponent = 0;
      44           0 :     fFlags = 0;
      45           0 :     fAbsIntValue = 0LL;
      46           0 :     fAbsIntValueSet = FALSE;
      47           0 :     fAbsDoubleValue = 0.0;
      48           0 :     fAbsDoubleValueSet = FALSE;
      49           0 : }
      50             : 
      51           0 : UBool VisibleDigits::isNegative() const {
      52           0 :     return (fFlags & kNegative);
      53             : }
      54             : 
      55           0 : UBool VisibleDigits::isNaN() const {
      56           0 :     return (fFlags & kNaN);
      57             : }
      58             : 
      59           0 : UBool VisibleDigits::isInfinite() const {
      60           0 :     return (fFlags & kInfinite);
      61             : }
      62             : 
      63           0 : int32_t VisibleDigits::getDigitByExponent(int32_t digitPos) const {
      64           0 :     if (digitPos < fExponent || digitPos >= fExponent + fDigits.length()) {
      65           0 :         return 0;
      66             :     }
      67           0 :     const char *ptr = fDigits.data();
      68           0 :     return ptr[digitPos - fExponent];
      69             : }
      70             : 
      71           0 : UBool VisibleDigits::isOverMaxDigits() const {
      72           0 :     return (fExponent + fDigits.length() > fInterval.getMostSignificantExclusive());
      73             : }
      74             : 
      75           0 : UBool VisibleDigits::isNaNOrInfinity() const {
      76           0 :     return (fFlags & (kInfinite | kNaN)) != 0;
      77             : }
      78             : 
      79           0 : double VisibleDigits::computeAbsDoubleValue() const {
      80             :     // Take care of NaN and infinity
      81           0 :     if (isNaN()) {
      82           0 :         return uprv_getNaN();
      83             :     }
      84           0 :     if (isInfinite()) {
      85           0 :         return uprv_getInfinity();
      86             :     }
      87             : 
      88             :     // stack allocate a decNumber to hold MAX_DBL_DIGITS+3 significant digits
      89             :     struct {
      90             :         decNumber  decNum;
      91             :         char       digits[MAX_DBL_DIGITS+3];
      92             :     } decNumberWithStorage;
      93           0 :     decNumber *numberPtr = &decNumberWithStorage.decNum;
      94             : 
      95           0 :     int32_t mostSig = fInterval.getMostSignificantExclusive();
      96           0 :     int32_t mostSigNonZero = fExponent + fDigits.length();
      97           0 :     int32_t end = mostSig > mostSigNonZero ? mostSigNonZero : mostSig;
      98           0 :     int32_t leastSig = fInterval.getLeastSignificantInclusive();
      99           0 :     int32_t start = leastSig > fExponent ? leastSig : fExponent;
     100           0 :     if (end <= start) {
     101           0 :         return 0.0;
     102             :     }
     103           0 :     if (start < end - (MAX_DBL_DIGITS+3)) {
     104           0 :         start = end - (MAX_DBL_DIGITS+3);
     105             :     }
     106           0 :     uint8_t *pos = numberPtr->lsu;
     107           0 :     const char *src = &(fDigits.data()[start - fExponent]);
     108           0 :     for (int32_t i = start; i < end; ++i) {
     109           0 :         *pos++ = (uint8_t) (*src++);
     110             :     }
     111           0 :     numberPtr->exponent = start;
     112           0 :     numberPtr->bits = 0;
     113           0 :     numberPtr->digits = end - start;
     114             :     char str[MAX_DBL_DIGITS+18];
     115           0 :     uprv_decNumberToString(numberPtr, str);
     116           0 :     U_ASSERT(uprv_strlen(str) < MAX_DBL_DIGITS+18);
     117           0 :     char *unused = NULL;
     118           0 :     return DigitList::decimalStrToDouble(str, &unused);
     119             : }
     120             : 
     121           0 : void VisibleDigits::getFixedDecimal(
     122             :     double &source, int64_t &intValue, int64_t &f, int64_t &t, int32_t &v, UBool &hasIntValue) const {
     123           0 :     source = 0.0;
     124           0 :     intValue = 0;
     125           0 :     f = 0;
     126           0 :     t = 0;
     127           0 :     v = 0;
     128           0 :     hasIntValue = FALSE;
     129           0 :     if (isNaNOrInfinity()) {
     130           0 :         return;
     131             :     }
     132             : 
     133             :     // source
     134           0 :     if (fAbsDoubleValueSet) {
     135           0 :         source = fAbsDoubleValue;
     136             :     } else {
     137           0 :         source = computeAbsDoubleValue();
     138             :     }
     139             : 
     140             :     // visible decimal digits
     141           0 :     v = fInterval.getFracDigitCount();
     142             : 
     143             :     // intValue
     144             : 
     145             :     // If we initialized from an int64 just use that instead of
     146             :     // calculating
     147           0 :     if (fAbsIntValueSet) {
     148           0 :         intValue = fAbsIntValue;
     149             :     } else {
     150           0 :         int32_t startPos = fInterval.getMostSignificantExclusive();
     151           0 :         if (startPos > 18) {
     152           0 :             startPos = 18;
     153             :         }
     154             :         // process the integer digits
     155           0 :         for (int32_t i = startPos - 1; i >= 0; --i) {
     156           0 :             intValue = intValue * 10LL + getDigitByExponent(i);
     157             :         }
     158           0 :         if (intValue == 0LL && startPos > 0) {
     159           0 :             intValue = 100000000000000000LL;
     160             :         }
     161             :     }
     162             : 
     163             :     // f (decimal digits)
     164             :     // skip over any leading 0's in fraction digits.
     165           0 :     int32_t idx = -1;
     166           0 :     for (; idx >= -v && getDigitByExponent(idx) == 0; --idx)
     167             :       ;
     168             : 
     169             :     // Only process up to first 18 non zero fraction digits for decimalDigits
     170             :     // since that is all we can fit into an int64.
     171           0 :     for (int32_t i = idx; i >= -v && i > idx - 18; --i) {
     172           0 :         f = f * 10LL + getDigitByExponent(i);
     173             :     }
     174             : 
     175             :     // If we have no decimal digits, we don't have an integer value
     176           0 :     hasIntValue = (f == 0LL);
     177             : 
     178             :     // t (decimal digits without trailing zeros)
     179           0 :    t = f;
     180           0 :     while (t > 0 && t % 10LL == 0) {
     181           0 :         t /= 10;
     182             :     }
     183             : }
     184             : 
     185             : U_NAMESPACE_END
     186             : #endif /* #if !UCONFIG_NO_FORMATTING */

Generated by: LCOV version 1.13