mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-12 18:27:32 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
186
intl/icu/source/i18n/visibledigits.cpp
Normal file
186
intl/icu/source/i18n/visibledigits.cpp
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
// Copyright (C) 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
* Copyright (C) 2016, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
* file name: visibledigits.cpp
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "cstring.h"
|
||||
#include "decNumber.h"
|
||||
#include "digitlst.h"
|
||||
#include "uassert.h"
|
||||
#include "visibledigits.h"
|
||||
|
||||
static const int32_t kNegative = 1;
|
||||
static const int32_t kInfinite = 2;
|
||||
static const int32_t kNaN = 4;
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void VisibleDigits::setNegative() {
|
||||
fFlags |= kNegative;
|
||||
}
|
||||
|
||||
void VisibleDigits::setNaN() {
|
||||
fFlags |= kNaN;
|
||||
}
|
||||
|
||||
void VisibleDigits::setInfinite() {
|
||||
fFlags |= kInfinite;
|
||||
}
|
||||
|
||||
void VisibleDigits::clear() {
|
||||
fInterval.clear();
|
||||
fDigits.clear();
|
||||
fExponent = 0;
|
||||
fFlags = 0;
|
||||
fAbsIntValue = 0LL;
|
||||
fAbsIntValueSet = FALSE;
|
||||
fAbsDoubleValue = 0.0;
|
||||
fAbsDoubleValueSet = FALSE;
|
||||
}
|
||||
|
||||
UBool VisibleDigits::isNegative() const {
|
||||
return (fFlags & kNegative);
|
||||
}
|
||||
|
||||
UBool VisibleDigits::isNaN() const {
|
||||
return (fFlags & kNaN);
|
||||
}
|
||||
|
||||
UBool VisibleDigits::isInfinite() const {
|
||||
return (fFlags & kInfinite);
|
||||
}
|
||||
|
||||
int32_t VisibleDigits::getDigitByExponent(int32_t digitPos) const {
|
||||
if (digitPos < fExponent || digitPos >= fExponent + fDigits.length()) {
|
||||
return 0;
|
||||
}
|
||||
const char *ptr = fDigits.data();
|
||||
return ptr[digitPos - fExponent];
|
||||
}
|
||||
|
||||
UBool VisibleDigits::isOverMaxDigits() const {
|
||||
return (fExponent + fDigits.length() > fInterval.getMostSignificantExclusive());
|
||||
}
|
||||
|
||||
UBool VisibleDigits::isNaNOrInfinity() const {
|
||||
return (fFlags & (kInfinite | kNaN)) != 0;
|
||||
}
|
||||
|
||||
double VisibleDigits::computeAbsDoubleValue() const {
|
||||
// Take care of NaN and infinity
|
||||
if (isNaN()) {
|
||||
return uprv_getNaN();
|
||||
}
|
||||
if (isInfinite()) {
|
||||
return uprv_getInfinity();
|
||||
}
|
||||
|
||||
// stack allocate a decNumber to hold MAX_DBL_DIGITS+3 significant digits
|
||||
struct {
|
||||
decNumber decNum;
|
||||
char digits[MAX_DBL_DIGITS+3];
|
||||
} decNumberWithStorage;
|
||||
decNumber *numberPtr = &decNumberWithStorage.decNum;
|
||||
|
||||
int32_t mostSig = fInterval.getMostSignificantExclusive();
|
||||
int32_t mostSigNonZero = fExponent + fDigits.length();
|
||||
int32_t end = mostSig > mostSigNonZero ? mostSigNonZero : mostSig;
|
||||
int32_t leastSig = fInterval.getLeastSignificantInclusive();
|
||||
int32_t start = leastSig > fExponent ? leastSig : fExponent;
|
||||
if (end <= start) {
|
||||
return 0.0;
|
||||
}
|
||||
if (start < end - (MAX_DBL_DIGITS+3)) {
|
||||
start = end - (MAX_DBL_DIGITS+3);
|
||||
}
|
||||
uint8_t *pos = numberPtr->lsu;
|
||||
const char *src = &(fDigits.data()[start - fExponent]);
|
||||
for (int32_t i = start; i < end; ++i) {
|
||||
*pos++ = (uint8_t) (*src++);
|
||||
}
|
||||
numberPtr->exponent = start;
|
||||
numberPtr->bits = 0;
|
||||
numberPtr->digits = end - start;
|
||||
char str[MAX_DBL_DIGITS+18];
|
||||
uprv_decNumberToString(numberPtr, str);
|
||||
U_ASSERT(uprv_strlen(str) < MAX_DBL_DIGITS+18);
|
||||
char *unused = NULL;
|
||||
return DigitList::decimalStrToDouble(str, &unused);
|
||||
}
|
||||
|
||||
void VisibleDigits::getFixedDecimal(
|
||||
double &source, int64_t &intValue, int64_t &f, int64_t &t, int32_t &v, UBool &hasIntValue) const {
|
||||
source = 0.0;
|
||||
intValue = 0;
|
||||
f = 0;
|
||||
t = 0;
|
||||
v = 0;
|
||||
hasIntValue = FALSE;
|
||||
if (isNaNOrInfinity()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// source
|
||||
if (fAbsDoubleValueSet) {
|
||||
source = fAbsDoubleValue;
|
||||
} else {
|
||||
source = computeAbsDoubleValue();
|
||||
}
|
||||
|
||||
// visible decimal digits
|
||||
v = fInterval.getFracDigitCount();
|
||||
|
||||
// intValue
|
||||
|
||||
// If we initialized from an int64 just use that instead of
|
||||
// calculating
|
||||
if (fAbsIntValueSet) {
|
||||
intValue = fAbsIntValue;
|
||||
} else {
|
||||
int32_t startPos = fInterval.getMostSignificantExclusive();
|
||||
if (startPos > 18) {
|
||||
startPos = 18;
|
||||
}
|
||||
// process the integer digits
|
||||
for (int32_t i = startPos - 1; i >= 0; --i) {
|
||||
intValue = intValue * 10LL + getDigitByExponent(i);
|
||||
}
|
||||
if (intValue == 0LL && startPos > 0) {
|
||||
intValue = 100000000000000000LL;
|
||||
}
|
||||
}
|
||||
|
||||
// f (decimal digits)
|
||||
// skip over any leading 0's in fraction digits.
|
||||
int32_t idx = -1;
|
||||
for (; idx >= -v && getDigitByExponent(idx) == 0; --idx)
|
||||
;
|
||||
|
||||
// Only process up to first 18 non zero fraction digits for decimalDigits
|
||||
// since that is all we can fit into an int64.
|
||||
for (int32_t i = idx; i >= -v && i > idx - 18; --i) {
|
||||
f = f * 10LL + getDigitByExponent(i);
|
||||
}
|
||||
|
||||
// If we have no decimal digits, we don't have an integer value
|
||||
hasIntValue = (f == 0LL);
|
||||
|
||||
// t (decimal digits without trailing zeros)
|
||||
t = f;
|
||||
while (t > 0 && t % 10LL == 0) {
|
||||
t /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
Loading…
Add table
Add a link
Reference in a new issue