ICU-1271 Be more friendly to non-IEEE754 platforms and use the putil.h functions.

X-SVN-Rev: 6198
This commit is contained in:
George Rhoten 2001-10-11 21:41:11 +00:00
parent 6fb93470d2
commit 1aa7e6714d
9 changed files with 160 additions and 255 deletions

View file

@ -134,6 +134,7 @@ static double fgInf;
/* protos */
static char* u_topNBytesOfDouble(double* d, int n);
static char* u_bottomNBytesOfDouble(double* d, int n);
static void uprv_longBitsFromDouble(double d, int32_t *hi, uint32_t *lo);
/*---------------------------------------------------------------------------
@ -369,6 +370,12 @@ uprv_ceil(double x)
return ceil(x);
}
double
uprv_round(double x)
{
return uprv_floor(x + 0.5);
}
double
uprv_fabs(double x)
{
@ -388,127 +395,18 @@ uprv_fmod(double x, double y)
}
double
uprv_pow10(int32_t x)
uprv_pow(double x, double y)
{
/* This is declared as "double pow(double x, double y)" */
return pow(x, y);
}
double
uprv_pow10(int32_t x)
{
return pow(10.0, (double)x);
}
/**
* Computes the remainder of an implied division of its operands, as
* defined by the IEEE 754 standard. Commonly used to bring a value
* into range without losing accuracy; e.g., bringing a large argument
* to sin() into range.
*
* Returns r, where x = n * p + r. Here n is the integer nearest to
* x / p. If two integers are equidistant from x / p, n is the even
* integer. If r is zero, then it should have the same sign as the
* dividend x.
*
* The IEEE remainder may be negative or positive.
* IEEEremainder(5,3) = -1. IEEEremainder(4,3) = 1.
*
* The IEEE remainder r is always less than or equal to p/2 in
* absolute value. That is, |r| <= |p/2|. By comparison, fmod()
* returns a remainder r such that |r| <= |p|.
*
* Some floating point processors can compute this value in hardware.
* We provide two implementations here, one that manipulates the IEEE
* bit pattern directly, and one that is built upon other floating
* point operations. The former implementation has superior accuracy
* and is preferred; the latter may work on platforms where the former
* fails, but will introduce inaccuracies.
*/
#if 0
/* Several compilers can't optimize this properly, and no one uses it. */
double
uprv_IEEEremainder(double x, double p)
{
#if IEEE_754
int32_t hx, hp;
uint32_t sx, lx, lp;
double p_half;
hx = *(int32_t*)u_topNBytesOfDouble(&x, sizeof(int32_t));
lx = *(uint32_t*)u_bottomNBytesOfDouble(&x, sizeof(uint32_t));
hp = *(int32_t*)u_topNBytesOfDouble(&p, sizeof(int32_t));
lp = *(uint32_t*)u_bottomNBytesOfDouble(&p, sizeof(uint32_t));
sx = hx & SIGN;
hp &= 0x7fffffff;
hx &= 0x7fffffff;
/* purge off exception values */
if((hp|lp) == 0)
{
return (x*p) / (x*p); /* p = 0 */
}
if((hx >= 0x7ff00000)|| /* x not finite */
((hp>=0x7ff00000) && /* p is NaN */
(((hp-0x7ff00000)|lp) != 0)))
{
return uprv_getNaN();
}
if(hp <= 0x7fdfffff)
{
x = uprv_fmod(x, p + p); /* now x < 2p */
}
if(((hx-hp)|(lx-lp)) == 0)
{
return 0.0 * x;
}
x = uprv_fabs(x);
p = uprv_fabs(p);
if (hp < 0x00200000) {
if(x + x > p) {
x -= p;
if(x + x >= p)
x -= p;
}
}
else {
p_half = 0.5 * p;
if(x > p_half) {
x -= p;
if(x >= p_half)
x -= p;
}
}
*(int32_t*)u_topNBytesOfDouble(&x, sizeof(int32_t)) ^= sx;
return x;
#else
/* INACCURATE but portable implementation of IEEEremainder. This
* implementation should work on platforms that do not have IEEE
* bit layouts. Deficiencies of this implementation are its
* inaccuracy and that it does not attempt to handle NaN or
* infinite parameters and it returns the dividend if the divisor
* is zero. This is probably not an issue on non-IEEE
* platforms. - aliu
*/
if (p != 0.0) { /* exclude zero divisor */
double a = x / p;
double aint = uprv_floor(a);
double afrac = a - aint;
if (afrac > 0.5) {
aint += 1.0;
} else if (!(afrac < 0.5)) { /* avoid == comparison */
if (uprv_modf(aint / 2.0, &a) > 0.0) {
aint += 1.0;
}
}
x -= (p * aint);
}
return x;
#endif
}
#endif
double
uprv_fmax(double x, double y)
{
@ -524,12 +422,10 @@ uprv_fmax(double x, double y)
if(x == 0.0 && y == 0.0 && (lowBits & SIGN))
return y;
return (x > y ? x : y);
#else
#endif
/* this should work for all flt point w/o NaN and Infpecial cases */
return (x > y ? x : y);
#endif
}
int32_t
@ -553,12 +449,10 @@ uprv_fmin(double x, double y)
if(x == 0.0 && y == 0.0 && (lowBits & SIGN))
return y;
return (x > y ? y : x);
#else
#endif
/* this should work for all flt point w/o NaN and Inf special cases */
return (x > y ? y : x);
#endif
}
int32_t
@ -593,18 +487,27 @@ uprv_trunc(double d)
return floor(d);
#else
return d >= 0 ? floor(d) : ceil(d);
return d >= 0 ? floor(d) : ceil(d);
#endif
}
void
static void
uprv_longBitsFromDouble(double d, int32_t *hi, uint32_t *lo)
{
*hi = *(int32_t*)u_topNBytesOfDouble(&d, sizeof(int32_t));
*lo = *(uint32_t*)u_bottomNBytesOfDouble(&d, sizeof(uint32_t));
}
/**
* Return the largest positive number that can be represented by an integer
* type of arbitrary bit length.
*/
double
uprv_maxMantissa(void)
{
return pow(2.0, DBL_MANT_DIG + 1.0) - 1.0;
}
/**
* Return the floor of the log base 10 of a given double.
@ -640,6 +543,12 @@ uprv_log10(double d)
#endif
}
double
uprv_log(double d)
{
return log(d);
}
int32_t
uprv_digitsAfterDecimal(double x)
{

View file

@ -39,30 +39,31 @@
/**
* Platform utilities isolates the platform dependencies of the
* libarary. For each platform which this code is ported to, these
* functions may have to be re-implemented. */
* functions may have to be re-implemented.
*/
/* Floating point utilities
* @draft
*/
U_CAPI UBool U_EXPORT2 uprv_isNaN(double);
U_CAPI UBool U_EXPORT2 uprv_isInfinite(double);
U_CAPI UBool U_EXPORT2 uprv_isNaN(double);
U_CAPI UBool U_EXPORT2 uprv_isInfinite(double);
U_CAPI UBool U_EXPORT2 uprv_isPositiveInfinity(double);
U_CAPI UBool U_EXPORT2 uprv_isNegativeInfinity(double);
U_CAPI double U_EXPORT2 uprv_getNaN(void);
U_CAPI double U_EXPORT2 uprv_getInfinity(void);
U_CAPI double U_EXPORT2 uprv_getNaN(void);
U_CAPI double U_EXPORT2 uprv_getInfinity(void);
U_CAPI double U_EXPORT2 uprv_floor(double x);
U_CAPI double U_EXPORT2 uprv_ceil(double x);
U_CAPI double U_EXPORT2 uprv_fabs(double x);
U_CAPI double U_EXPORT2 uprv_modf(double x, double* y);
U_CAPI double U_EXPORT2 uprv_fmod(double x, double y);
U_CAPI double U_EXPORT2 uprv_pow10(int32_t x);
U_CAPI double U_EXPORT2 uprv_fmax(double x, double y);
U_CAPI double U_EXPORT2 uprv_fmin(double x, double y);
U_CAPI int32_t U_EXPORT2 uprv_max(int32_t x, int32_t y);
U_CAPI int32_t U_EXPORT2 uprv_min(int32_t x, int32_t y);
U_CAPI double U_EXPORT2 uprv_trunc(double d);
U_CAPI void U_EXPORT2 uprv_longBitsFromDouble(double d, int32_t *hi, uint32_t *lo);
U_CAPI double U_EXPORT2 uprv_trunc(double d);
U_CAPI double U_EXPORT2 uprv_floor(double x);
U_CAPI double U_EXPORT2 uprv_ceil(double x);
U_CAPI double U_EXPORT2 uprv_fabs(double x);
U_CAPI double U_EXPORT2 uprv_modf(double x, double* y);
U_CAPI double U_EXPORT2 uprv_fmod(double x, double y);
U_CAPI double U_EXPORT2 uprv_pow(double x, double y);
U_CAPI double U_EXPORT2 uprv_pow10(int32_t x);
U_CAPI double U_EXPORT2 uprv_fmax(double x, double y);
U_CAPI double U_EXPORT2 uprv_fmin(double x, double y);
U_CAPI int32_t U_EXPORT2 uprv_max(int32_t x, int32_t y);
U_CAPI int32_t U_EXPORT2 uprv_min(int32_t x, int32_t y);
#if U_IS_BIG_ENDIAN
# define uprv_isNegative(number) (*((signed char *)&(number))<0)
@ -70,15 +71,18 @@ U_CAPI void U_EXPORT2 uprv_longBitsFromDouble(double d, int32_t *hi, uint32_
# define uprv_isNegative(number) (*((signed char *)&(number)+sizeof(number)-1)<0)
#endif
/*
/**
* Return the largest positive number that can be represented by an integer
* type of arbitrary bit length.
*/
U_CAPI double U_EXPORT2 uprv_maxMantissa(void);
/**
* Return the floor of the log base 10 of a given double.
* This method compensates for inaccuracies which arise naturally when
* computing logs, and always gives the correct value. The parameter
* must be positive and finite.
* (Thanks to Alan Liu for supplying this function.)
*/
/**
* Returns the common log of the double value d.
*
* @param d the double value to apply the common log function for.
* @return the log of value d.
@ -86,6 +90,11 @@ U_CAPI void U_EXPORT2 uprv_longBitsFromDouble(double d, int32_t *hi, uint32_
*/
U_CAPI int16_t U_EXPORT2 uprv_log10(double d);
U_CAPI double U_EXPORT2 uprv_log(double d);
/** Does common notion of rounding e.g. uprv_floor(x + 0.5); */
U_CAPI double U_EXPORT2 uprv_round(double x);
/**
* Returns the number of digits after the decimal point in a double number x.
*

View file

@ -14,6 +14,9 @@
*/
#include "llong.h"
#include <float.h>
U_NAMESPACE_BEGIN
#if 0
/*
@ -29,7 +32,6 @@ const llong& llong::kOne = llong(0x0, 0x1);
const llong& llong::kTwo = llong(0x0, 0x2);
const llong& llong::kMaxDouble = llong(0x200000, 0x0);
const llong& llong::kMinDouble = -kMaxDouble;
#endif
static llong kMaxValueObj(0x7fffffff, 0xffffffff);
static llong kMinValueObj(0x80000000, 0x0);
@ -49,11 +51,38 @@ const llong& llong::kTwo = kTwoObj;
const llong& llong::kMaxDouble = kMaxDoubleObj;
const llong& llong::kMinDouble = kMinDoubleObj;
const double llong::kDMax = llong_asDouble(kMaxDouble);
const double llong::kDMin = -kDMax;
#endif
#define SQRT231 46340
const double llong::kD32 = ((double)(0xffffffffu)) + 1;
const double llong::kDMax = llong_asDouble(kMaxDouble);
const double llong::kDMin = -kDMax;
llong::llong(double d) { // avoid dependency on bit representation of double
if (uprv_isNaN(d)) {
hi = 0;
lo = 0; /* zero */
} else {
double mant = uprv_maxMantissa();
if (d < -mant) {
d = -mant;
} else if (d > mant) {
d = mant;
}
UBool neg = d < 0;
if (neg) {
d = -d;
}
d = uprv_floor(d);
hi = (int32_t)uprv_floor(d / kD32);
d -= kD32 * hi;
lo = (uint32_t)d;
if (neg) {
negate();
}
}
}
llong& llong::operator*=(const llong& rhs)
{
@ -119,11 +148,12 @@ llong& llong::operator/=(const llong& rhs)
}
if (b.isZero()) { // should throw div by zero error
*this = sign < 0 ? kMinValue : kMaxValue;
*this = sign < 0 ? -uprv_maxMantissa() : uprv_maxMantissa();
} else if (a.hi == 0 && b.hi == 0) {
*this = (int32_t)(sign * (a.lo / b.lo));
} else if (b > a) {
*this = kZero;
hi = 0;
lo = 0; /* zero */
} else if (b == a) {
*this = sign;
} else {
@ -322,3 +352,5 @@ uint32_t u_lltoa(const llong& val, UChar* buf, uint32_t len, uint32_t radix, UBo
return len;
}
U_NAMESPACE_END

View file

@ -16,11 +16,10 @@
#ifndef LLONG_H
#define LLONG_H
// debug
#include <stdio.h>
#include "unicode/utypes.h"
U_NAMESPACE_BEGIN
// machine dependent value, need to move
//#define __u_IntBits 32
@ -29,20 +28,17 @@ private:
uint32_t lo;
int32_t hi;
private:
enum {
MASK32 = 0xffffffffu
};
static const double kD32; // 2^^32 as a double
static const double kDMin; // -(2^^54), minimum double with full integer precision
static const double kDMax; // 2^^54, maximum double with full integer precision
// private constructor
// should be private, but we can't construct the way we want using SOLARISCC
// so make public in order that file statics can access this constructor
public:
public:
static const double kD32; // 2^^32 as a double
static const double kDMin; // -(2^^54), minimum double with full integer precision
static const double kDMax; // 2^^54, maximum double with full integer precision
llong(int32_t h, uint32_t l) : lo(l), hi(h) {}
private:
private:
// convenience, size reduction in inline code
llong& nnot() { hi = ~hi; lo = ~lo; return *this; }
llong& negate() { hi = ~hi; lo = ~lo; if (!++lo) ++hi; return *this; }
@ -64,23 +60,7 @@ public:
//#if __u_IntBits == 64
// llong(unsigned int i) : lo(i & MASK32), hi(i >> 32) {}
//#endif
llong(double d) { // avoid dependency on bit representation of double
if (uprv_isNaN(d)) {
*this = llong::kZero;
} else if (d < kDMin) {
*this = llong::kMinDouble;
} else if (d > kDMax) {
*this = llong::kMaxDouble;
} else {
int neg = d < 0;
if (neg) d = -d;
d = uprv_floor(d);
hi = (int32_t)uprv_floor(d / kD32);
d -= kD32 * hi;
lo = (uint32_t)d;
if (neg) negate();
}
}
llong(double d);
llong(const llong& rhs) : lo(rhs.lo), hi(rhs.hi) {}
@ -217,16 +197,12 @@ public:
friend uint32_t u_lltoa(const llong& lhs, UChar* buffer, uint32_t buflen, uint32_t radix = 10, UBool raw = FALSE);
// useful public constants - perhaps should not have class statics
static const llong& kMaxValue;
static const llong& kMinValue;
static const llong& kMinusOne;
static const llong& kZero;
static const llong& kOne;
static const llong& kTwo;
// static const llong getZero();
// static const llong getOne();
private:
static const llong& kMaxDouble;
static const llong& kMinDouble;
static const llong getMaxDouble();
static const llong getMinDouble();
// right shift without sign extension
llong& ushr(int32_t shift) {
@ -292,9 +268,9 @@ inline double llong_asDouble(const llong& lhs) { return llong::kD32 * lhs.hi +
inline llong llong_pow(const llong& lhs, uint32_t n) {
if (lhs.isZero()) {
return llong::kZero;
return llong(0, 0); /* zero */
} else if (n == 0) {
return llong::kOne;
return llong(0, 1); /* one */
} else {
llong r(lhs);
while (--n > 0) {
@ -321,5 +297,7 @@ inline UBool operator>=(const llong& lhs, const uint32_t rhs) { return lhs.hi ==
inline UBool operator<=(const llong& lhs, const uint32_t rhs) { return lhs.hi == 0 ? lhs.lo <= rhs : lhs.hi <= 0; }
#endif
U_NAMESPACE_END
// LLONG_H
#endif

View file

@ -13,8 +13,6 @@
* 10/11/2001 Doug Ported from ICU4J
*/
#include <math.h>
#include "nfrs.h"
#include "nfrule.h"
#include "nfrlist.h"
@ -447,7 +445,7 @@ NFRuleSet::findFractionRuleSetRule(double number) const
}
// for each rule, do the following...
llong tempDifference;
llong difference = llong::kMaxValue;
llong difference(uprv_maxMantissa());
int32_t winner = 0;
for (uint32_t i = 0; i < rules.size(); ++i) {
// "numerator" is the numerator of the fraction if the

View file

@ -78,9 +78,9 @@ static const UChar gEmptyString[] = {0}; /* "" */
static const UChar gGreaterGreaterGreater[] = {0x3E, 0x3E, 0x3E, 0}; /* ">>>" */
static const UChar * const tokenStrings[] = {
gLessLess, gLessPercent, gLessHash, gLessZero,
gGreaterGreater, gGreaterPercent,gGreaterHash, gGreaterZero,
gEqualPercent, gEqualHash, gEqualZero, NULL
gLessLess, gLessPercent, gLessHash, gLessZero,
gGreaterGreater, gGreaterPercent,gGreaterHash, gGreaterZero,
gEqualPercent, gEqualHash, gEqualZero, NULL
};
void
@ -492,7 +492,7 @@ NFRule::expectedExponent() const
// we get rounding error in some cases-- for example, log 1000 / log 10
// gives us 1.9999999996 instead of 2. The extra logic here is to take
// that into account
int16_t tempResult = (int16_t)(log(llong_asDouble(baseValue)) / log((double)radix));
int16_t tempResult = (int16_t)(uprv_log(llong_asDouble(baseValue)) / uprv_log((double)radix));
llong temp = llong_pow(radix, tempResult + 1);
if (temp <= baseValue) {
tempResult += 1;
@ -709,7 +709,7 @@ NFRule::shouldRollBack(double number) const
// multiple of 100. This is called the "rollback rule."
if ((sub1->isModulusSubstitution()) || (sub2->isModulusSubstitution())) {
llong re = llong_pow(radix, exponent);
return java_fmod(number, llong_asDouble(re)) == 0 && (baseValue % re) != 0;
return uprv_fmod(number, llong_asDouble(re)) == 0 && (baseValue % re) != 0;
}
return FALSE;
}

View file

@ -12,8 +12,6 @@
#include "llong.h"
#include <math.h>
U_NAMESPACE_BEGIN
class FieldPosition;
@ -26,7 +24,7 @@ class RuleBasedNumberFormat;
class UnicodeString;
class NFRule {
public:
public:
enum ERuleType {
kNoBase = 0,
@ -56,7 +54,7 @@ class NFRule {
llong getBaseValue() const { return baseValue; }
void setBaseValue(llong value);
double getDivisor() const { return pow(radix, exponent); }
double getDivisor() const { return uprv_pow(radix, exponent); }
void doFormat(llong number, UnicodeString& toAppendTo, int32_t pos) const;
void doFormat(double number, UnicodeString& toAppendTo, int32_t pos) const;
@ -71,7 +69,7 @@ class NFRule {
void appendRuleText(UnicodeString& result) const;
private:
private:
void parseRuleDescriptor(UnicodeString& descriptor, UErrorCode& status);
void extractSubstitutions(const NFRuleSet* ruleSet, const NFRule* predecessor, const RuleBasedNumberFormat* rbnf, UErrorCode& status);
NFSubstitution* extractSubstitution(const NFRuleSet* ruleSet, const NFRule* predecessor, const RuleBasedNumberFormat* rbnf, UErrorCode& status);
@ -80,13 +78,13 @@ class NFRule {
int32_t indexOfAny(const UChar* const strings[]) const;
double matchToDelimiter(const UnicodeString& text, int32_t startPos, double baseValue,
const UnicodeString& delimiter, ParsePosition& pp, const NFSubstitution* sub,
double upperBound) const;
double upperBound) const;
void stripPrefix(UnicodeString& text, const UnicodeString& prefix, ParsePosition& pp) const;
int32_t prefixLength(const UnicodeString& str, const UnicodeString& prefix) const;
UBool allIgnorable(const UnicodeString& str) const;
int32_t findText(const UnicodeString& str, const UnicodeString& key,
int32_t startingAt, int32_t* resultCount) const;
int32_t prefixLength(const UnicodeString& str, const UnicodeString& prefix) const;
UBool allIgnorable(const UnicodeString& str) const;
int32_t findText(const UnicodeString& str, const UnicodeString& key,
int32_t startingAt, int32_t* resultCount) const;
private:
llong baseValue;

View file

@ -292,7 +292,7 @@ NFSubstitution::doSubstitution(llong number, UnicodeString& toInsertInto, int32_
// to format the result
double numberToFormat = transformNumber(llong_asDouble(number));
if (numberFormat->getMaximumFractionDigits() == 0) {
numberToFormat = floor(numberToFormat);
numberToFormat = uprv_floor(numberToFormat);
}
UnicodeString temp;
@ -319,7 +319,7 @@ NFSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32
// if the result is an integer, from here on out we work in integer
// space (saving time and memory and preserving accuracy)
if (numberToFormat == floor(numberToFormat) && ruleSet != NULL) {
if (numberToFormat == uprv_floor(numberToFormat) && ruleSet != NULL) {
ruleSet->format(llong(numberToFormat), toInsertInto, _pos + this->pos);
// if the result isn't an integer, then call either our rule set's
@ -490,7 +490,7 @@ SameValueSubstitution::SameValueSubstitution(int32_t _pos,
}
}
char SameValueSubstitution::fgClassID;
const char SameValueSubstitution::fgClassID = 0;
UClassID
SameValueSubstitution::getDynamicClassID() const {
@ -749,7 +749,7 @@ FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser
// (this is slower, but more accurate, than doing it from the
// other end)
} else {
int32_t numberToFormat = (int32_t)round(transformNumber(number) * pow(10, kMaxDecimalDigits));
int32_t numberToFormat = (int32_t)uprv_round(transformNumber(number) * uprv_pow(10, kMaxDecimalDigits));
// this flag keeps us from formatting trailing zeros. It starts
// out false because we're pulling from the right, and switches
// to true the first time we encounter a non-zero digit

View file

@ -21,34 +21,15 @@
#include "nfrs.h"
#include "nfrule.h"
#include "llong.h"
#include "float.h"
U_NAMESPACE_BEGIN
static double MAX_DOUBLE = 1.7976931348623157e+308;
static double java_fmod(double n, double d)
{
// c doesn't define '%' for floating point, but java does.
// from the java language spec 15.17:
// "In the remaining cases, where neither an infinity, nor a zero,
// nor NaN is involved, the floating-point remainder r from the
// division of a dividend n by a divisor d is defined by the
// mathematical relation r = n - (d . q) where q is an integer
// that is negative only if n/d is negative and positive only if
// n/d is positive, and whose magnitude is as large as possible
// without exceeding the magnitude of the true mathematical
// quotient of n and d."
//
// I'm not sure if fmod (from what header?) has the same implemenation
double q = n/d;
q = q < 0 ? -floor(-q) : floor(q);
return n - d * q;
}
static double round(double n)
{
return floor(n + .5);
}
//static double round(double n)
//{
// return floor(n + .5);
//}
class NFSubstitution {
int32_t pos;
@ -242,7 +223,7 @@ public:
double calcUpperBound(double oldUpperBound) const { return oldUpperBound; }
UChar tokenChar() const { return (UChar)0x003d; } // '='
private:
static char fgClassID;
static const char fgClassID;
public:
static UClassID getStaticClassID(void) { return (UClassID)&fgClassID; }
@ -266,7 +247,7 @@ public:
}
void setDivisor(int32_t radix, int32_t exponent) {
divisor = pow(radix, exponent);
divisor = uprv_pow(radix, exponent);
ldivisor = divisor;
}
@ -277,7 +258,7 @@ public:
}
double transformNumber(double number) const {
return floor(number / divisor);
return uprv_floor(number / divisor);
}
double composeRuleValue(double newRuleValue, double oldRuleValue) const {
@ -309,7 +290,7 @@ public:
UErrorCode& status);
void setDivisor(int32_t radix, int32_t exponent) {
divisor = pow(radix, exponent);
divisor = uprv_pow(radix, exponent);
ldivisor = divisor;
}
@ -319,7 +300,7 @@ public:
void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
llong transformNumber(llong number) const { return number % ldivisor; }
double transformNumber(double number) const { return java_fmod(number, divisor); }
double transformNumber(double number) const { return uprv_fmod(number, divisor); }
UBool doParse(const UnicodeString& text,
ParsePosition& parsePosition,
@ -329,7 +310,7 @@ public:
Formattable& result) const;
double composeRuleValue(double newRuleValue, double oldRuleValue) const {
return oldRuleValue - java_fmod(oldRuleValue, divisor) + newRuleValue;
return oldRuleValue - uprv_fmod(oldRuleValue, divisor) + newRuleValue;
}
double calcUpperBound(double oldUpperBound) const { return divisor; }
@ -355,9 +336,9 @@ public:
: NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
llong transformNumber(llong number) const { return number; }
double transformNumber(double number) const { return floor(number); }
double transformNumber(double number) const { return uprv_floor(number); }
double composeRuleValue(double newRuleValue, double oldRuleValue) const { return newRuleValue + oldRuleValue; }
double calcUpperBound(double oldUpperBound) const { return MAX_DOUBLE; }
double calcUpperBound(double oldUpperBound) const { return DBL_MAX; }
UChar tokenChar() const { return (UChar)0x003c; } // '<'
private:
static const char fgClassID;
@ -381,8 +362,8 @@ public:
UBool operator==(const NFSubstitution& rhs) const;
void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos) const;
llong transformNumber(llong number) const { return llong::kZero; }
double transformNumber(double number) const { return number - floor(number); }
llong transformNumber(llong number) const { return llong(0,0); }
double transformNumber(double number) const { return number - uprv_floor(number); }
UBool doParse(const UnicodeString& text,
ParsePosition& parsePosition,
@ -412,9 +393,9 @@ public:
: NFSubstitution(_pos, _ruleSet, formatter, description, status) {}
llong transformNumber(llong number) const { return llong_abs(number); }
double transformNumber(double number) const { return fabs(number); }
double transformNumber(double number) const { return uprv_fabs(number); }
double composeRuleValue(double newRuleValue, double oldRuleValue) const { return -newRuleValue; }
double calcUpperBound(double oldUpperBound) const { return MAX_DOUBLE; }
double calcUpperBound(double oldUpperBound) const { return DBL_MAX; }
UChar tokenChar() const { return (UChar)0x003e; } // '>'
private:
static const char fgClassID;
@ -442,7 +423,7 @@ public:
UBool operator==(const NFSubstitution& rhs) const;
llong transformNumber(llong number) const { return number * ldenominator; }
double transformNumber(double number) const { return round(number * denominator); }
double transformNumber(double number) const { return uprv_round(number * denominator); }
UBool doParse(const UnicodeString& text,
ParsePosition& parsePosition,
@ -479,15 +460,15 @@ public:
void toString(UnicodeString& result) const {}
void doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos) const {}
void doSubstitution(llong number, UnicodeString& toInsertInto, int32_t _pos) const {}
llong transformNumber(llong number) const { return llong::kZero; }
llong transformNumber(llong number) const { return llong(0,0); }
double transformNumber(double number) const { return 0; }
UBool doParse(const UnicodeString& text,
ParsePosition& parsePosition,
double baseValue,
double upperBound,
UBool lenientParse,
Formattable& result) const
{ result.setDouble(baseValue); return TRUE; }
ParsePosition& parsePosition,
double baseValue,
double upperBound,
UBool lenientParse,
Formattable& result) const
{ result.setDouble(baseValue); return TRUE; }
double composeRuleValue(double newRuleValue, double oldRuleValue) const { return 0; } // never called
double calcUpperBound(double oldUpperBound) const { return 0; } // never called
UBool isNullSubstitution() const { return TRUE; }