Make Double purly static. Fix some bugs and exactness problems in Double::toString and Double::toDouble. Remove the Integer class.

b=96143 r=Pike sr=scc
This commit is contained in:
sicking%bigfoot.com 2001-11-04 23:27:23 +00:00
parent bc94610da9
commit fe3426b9c8
18 changed files with 206 additions and 400 deletions

View File

@ -51,7 +51,6 @@ MODULE_NAME = TransformiixModule
CPPSRCS = XSLTProcessorModule.cpp
LOBJS =../source/base/ArrayList.$(OBJ_SUFFIX) \
../source/base/Double.$(OBJ_SUFFIX) \
../source/base/Integer.$(OBJ_SUFFIX) \
../source/base/List.$(OBJ_SUFFIX) \
../source/base/TxObjectWrapper.$(OBJ_SUFFIX) \
../source/base/Map.$(OBJ_SUFFIX) \

View File

@ -42,7 +42,6 @@ CPPSRCS= \
CPP_OBJS= \
..\source\base\$(OBJDIR)\ArrayList.obj \
..\source\base\$(OBJDIR)\Double.obj \
..\source\base\$(OBJDIR)\Integer.obj \
..\source\base\$(OBJDIR)\List.obj \
..\source\base\$(OBJDIR)\TxObjectWrapper.obj \
..\source\base\$(OBJDIR)\Map.obj \

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -42,14 +43,16 @@
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif
#ifndef TX_EXE
#include "prdtoa.h"
#else
#include "stdlib.h"
#include "stdio.h"
#endif
//----------------------------/
//- Implementation of Double -/
//----------------------------/
/**
* A wrapper for the primitive double type, and provides some simple
* floating point related routines
**/
/*
* Utility class for doubles
*/
//A trick to handle IEEE floating point exceptions on FreeBSD - E.D.
#ifdef __FreeBSD__
@ -57,9 +60,9 @@ fp_except_t allmask = FP_X_INV|FP_X_OFL|FP_X_UFL|FP_X_DZ|FP_X_IMP|FP_X_DNML;
fp_except_t oldmask = fpsetmask(~allmask);
#endif
/**
/*
* Macros to workaround math-bugs bugs in various platforms
**/
*/
#ifdef IS_BIG_ENDIAN
#define TX_DOUBLE_HI32(x) (((PRUint32 *)&(x))[0])
@ -90,161 +93,181 @@ const double Double::NaN = *((double*)nanMask);
const double Double::POSITIVE_INFINITY = *((double*)infMask);
const double Double::NEGATIVE_INFINITY = *((double*)negInfMask);
/**
* Creates a new Double with it's value initialized from the given String.
* The String will be converted to a double. If the String does not
* represent an IEEE 754 double, the value will be initialized to NaN
**/
Double::Double(const String& string) {
this->value = toDouble(string);
} //-- Double
/**
* Returns the value of this Double as a double
**/
double Double::doubleValue() {
return this->value;
} //-- doubleValue
/**
* Returns the value of this Double as an int
**/
int Double::intValue() {
return (int)value;
} //-- intValue
/**
/*
* Determines whether the given double represents positive or negative
* inifinity
**/
MBool Double::isInfinite(double dbl) {
return ((TX_DOUBLE_HI32(dbl) & ~TX_DOUBLE_HI32_SIGNBIT) == TX_DOUBLE_HI32_EXPMASK &&
!TX_DOUBLE_LO32(dbl));
} //-- isInfinite
*/
MBool Double::isInfinite(double aDbl)
{
return ((TX_DOUBLE_HI32(aDbl) & ~TX_DOUBLE_HI32_SIGNBIT) == TX_DOUBLE_HI32_EXPMASK &&
!TX_DOUBLE_LO32(aDbl));
}
/**
/*
* Determines whether the given double is NaN
**/
MBool Double::isNaN(double dbl) {
return ((TX_DOUBLE_HI32(dbl) & TX_DOUBLE_HI32_EXPMASK) == TX_DOUBLE_HI32_EXPMASK &&
(TX_DOUBLE_LO32(dbl) || (TX_DOUBLE_HI32(dbl) & TX_DOUBLE_HI32_MANTMASK)));
} //-- isNaN
*/
MBool Double::isNaN(double aDbl)
{
return ((TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_EXPMASK) == TX_DOUBLE_HI32_EXPMASK &&
(TX_DOUBLE_LO32(aDbl) || (TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_MANTMASK)));
}
/**
/*
* Determines whether the given double is negative
**/
MBool Double::isNeg(double dbl) {
return (TX_DOUBLE_HI32(dbl) & TX_DOUBLE_HI32_SIGNBIT) != 0;
} //-- isNeg
*/
MBool Double::isNeg(double aDbl)
{
return (TX_DOUBLE_HI32(aDbl) & TX_DOUBLE_HI32_SIGNBIT) != 0;
}
/**
/*
* Converts the given String to a double, if the String value does not
* represent a double, NaN will be returned
**/
double Double::toDouble(const String& src) {
double dbl = 0.0;
double multiplier = 10.0;
*/
double Double::toDouble(const String& aSrc)
{
PRInt32 idx = 0;
PRInt32 len = aSrc.length();
MBool digitFound = MB_FALSE;
double sign = 1.0;
//-- trim leading whitespace
for ( ; idx < src.length(); idx++ )
if ( src.charAt(idx) != ' ' ) break;
// leading whitespace
while (idx < len &&
(aSrc.charAt(idx) == ' ' ||
aSrc.charAt(idx) == '\n' ||
aSrc.charAt(idx) == '\r' ||
aSrc.charAt(idx) == '\t'))
++idx;
//-- check first character for sign
if ( idx < src.length() ) {
PRInt32 ch = src.charAt(idx);
if ( ch == '-' ) {
sign = -1.0;
// sign char
if (idx < len && aSrc.charAt(idx) == '-')
++idx;
// integer chars
while (idx < len &&
aSrc.charAt(idx) >= '0' &&
aSrc.charAt(idx) <= '9') {
++idx;
digitFound = MB_TRUE;
}
// decimal separator
if (idx < len && aSrc.charAt(idx) == '.') {
++idx;
// fraction chars
while (idx < len &&
aSrc.charAt(idx) >= '0' &&
aSrc.charAt(idx) <= '9') {
++idx;
digitFound = MB_TRUE;
}
}
else {
return Double::NaN;
// ending whitespace
while ((aSrc.charAt(idx) == ' ' ||
aSrc.charAt(idx) == '\n' ||
aSrc.charAt(idx) == '\r' ||
aSrc.charAt(idx) == '\t') &&
idx < len)
++idx;
// "."==NaN, ".0"=="0."==0
if (digitFound && idx == len) {
char* buf = aSrc.toCharArray();
double res = buf ? atof(buf) : Double::NaN;
delete [] buf;
return res;
}
//-- convert remaining to number
for ( ; idx < src.length(); idx++ ) {
return Double::NaN;
}
PRInt32 ch = src.charAt(idx);
if (( ch >= '0') && (ch <= '9')) {
if ( multiplier > 1.0 ) {
dbl = dbl*multiplier;
dbl += (double) (ch-48);
}
else {
dbl += multiplier * (ch-48);
multiplier = multiplier * 0.1;
}
}
else if ( ch == '.') {
if ( multiplier < 1.0 ) return Double::NaN;
multiplier = 0.1;
}
else return Double::NaN;
}
dbl = dbl*sign;
return dbl;
} //-- toDouble
/**
/*
* Converts the value of the given double to a String, and places
* The result into the destination String.
* @return the given dest string
**/
String& Double::toString(double value, String& dest) {
*/
String& Double::toString(double aValue, String& aDest)
{
//-- check for special cases
// check for special cases
if ( isNaN(value) ) {
dest.append("NaN");
return dest;
if (isNaN(aValue)) {
aDest.append("NaN");
return aDest;
}
if ( isInfinite(value) ) {
if (value < 0) dest.append('-');
dest.append("Infinity");
return dest;
if (isInfinite(aValue)) {
if (aValue < 0)
aDest.append('-');
aDest.append("Infinity");
return aDest;
}
MBool isNegative = (MBool)(value<0.0);
double val = value;
if ( isNegative ) val = val * -1.0;
int bufsize;
if (fabs(aValue) > 1)
bufsize = (int)log10(fabs(aValue)) + 30;
else
bufsize = 30;
char* buf = new char[bufsize];
if (!buf) {
NS_ASSERTION(0, "out of memory");
return aDest;
}
double ival = 0;
double fval = modf(val, &ival);
#ifndef TX_EXE
String iStr;
PRIntn intDigits, sign;
char* endp;
PR_dtoa(aValue, 0, 0, &intDigits, &sign, &endp, buf, bufsize-1);
int temp = (int)ival;
if (sign)
aDest.append('-');
int i;
for (i = 0; i < endp - buf; i++) {
if (i == intDigits)
aDest.append('.');
aDest.append(buf[i]);
}
for (; i < intDigits; i++)
aDest.append('0');
if ( temp > 0.0 ) {
while ( temp > 0.0 ) {
iStr.append( (char) ((temp % 10)+48) );
temp = temp / 10;
#else
sprintf(buf, "%1.10f", aValue);
MBool deciPassed = MB_FALSE;
MBool printDeci = MB_FALSE;
int zeros=0;
int i;
for (i = 0; buf[i]; i++) {
if (buf[i] == '.') {
deciPassed = MB_TRUE;
printDeci = MB_TRUE;
}
if ( isNegative ) iStr.append('-');
iStr.reverse();
}
else iStr.append('0');
else if (deciPassed && buf[i] == '0') {
zeros++;
}
else {
if (printDeci) {
aDest.append('.');
printDeci = MB_FALSE;
}
iStr.append('.');
if ( fval > 0.0 ) {
while ( fval > 0.0000001 ) {
fval = fval*10.0;
fval = modf(fval, &ival);
iStr.append( (char) (ival+48) );
for ( ;zeros ;zeros--)
aDest.append('0');
aDest.append(buf[i]);
}
}
else iStr.append('0');
dest.append(iStr);
return dest;
} //-- toString
#endif
delete [] buf;
return aDest;
}

View File

@ -1,139 +0,0 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is The MITRE Corporation.
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
*
* Portions created by Keith Visco as a Non MITRE employee,
* (C) 1999 Keith Visco. All Rights Reserved.
*
* Contributor(s):
* Keith Visco, kvisco@ziplink.net
* -- original author.
*
*/
#include "primitives.h"
#include "baseutils.h"
//-----------------------------/
//- Implementation of Integer -/
//-----------------------------/
/**
* A wrapper for the primitive int type, and provides some simple
* integer related routines
**/
/**
* Creates a new Integer initialized to 0.
**/
Integer::Integer() {
value = 0;
} //-- Integer
/**
* Creates a new Integer initialized to the given int value.
**/
Integer::Integer(int value) {
this->value = value;
} //-- Integer
/**
* Creates a new Integer based on the value of the given String
**/
Integer::Integer(const String& str) {
PRInt32 val = 0;
for (PRInt32 i = 0; i < str.length(); i++) {
val = (val * 10) + (str.charAt(i) - 48);
}
} //-- Integer
/**
* Returns the int value of this Integer
**/
PRInt32 Integer::intValue() {
return value;
} //-- intValue;
/**
* Converts the given String to an integer
**/
int Integer::intValue(const String& src) {
int result = 0;
PRInt32 idx = 0;
int sign = 1;
//-- trim leading whitespace
for ( ; idx < src.length(); idx++ )
if ( src.charAt(idx) != ' ' ) break;
//-- check first character for sign
if ( idx < src.length() ) {
PRInt32 ch = src.charAt(idx);
if ( ch == '-' ) {
sign = -1;
++idx;
}
}
else {
return 0; //-- we should return NaN here
}
//-- convert remaining to number
for ( ; idx < src.length(); idx++ ) {
PRInt32 ch = src.charAt(idx);
if (( ch >= '0') && (ch <= '9')) {
result = result*10;
result += (ch-48);
}
else return 0;
}
result = result*sign;
return result;
} //-- toInteger
/**
* Converts the given int to a String
**/
String& Integer::toString(int value, String& dest) {
String result;
UNICODE_CHAR charDigit;
PRInt32 tempVal = value;
MBool isNegative = (value < 0);
if ( isNegative ) tempVal = -value;
if ( tempVal > 0 ) {
while (tempVal) {
charDigit = (tempVal % 10) + 48;
result.append(charDigit);
tempVal /=10;
}
if ( isNegative ) result.append('-');
result.reverse();
}
else result.append('0');
dest.append(result);
return dest;
} //-- toString
/**
* Converts the given the value of this Integer to a String
**/
String& Integer::toString(String& dest) {
return Integer::toString(value, dest);
} //-- toString

View File

@ -35,7 +35,6 @@ endif
CPPSRCS = ArrayList.cpp \
Double.cpp \
Integer.cpp \
List.cpp \
Map.cpp \
TxObjectWrapper.cpp \

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* (C) Copyright The MITRE Corporation 1999 All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License
@ -963,6 +964,8 @@ char* String::toCharArray() const
{
char* tmpBuffer = new char[strLength+1];
NS_ASSERTION(tmpBuffer, "out of memory");
return toCharArray(tmpBuffer);
}
@ -974,6 +977,9 @@ char* String::toCharArray() const
**/
char* String::toCharArray(char* dest) const
{
if (!dest)
return 0;
PRInt32 copyLoop;
for (copyLoop = 0; copyLoop < strLength; copyLoop++)

View File

@ -33,7 +33,6 @@ DEFINES= $(DEFINES) -DTX_EXE
CPPSRCS= \
ArrayList.cpp \
Double.cpp \
Integer.cpp \
List.cpp \
TxObjectWrapper.cpp \
NamedMap.cpp \
@ -58,7 +57,6 @@ CPPSRCS = $(CPPSRCS) \
CPP_OBJS= \
.\$(OBJDIR)\ArrayList.obj \
.\$(OBJDIR)\Double.obj \
.\$(OBJDIR)\Integer.obj \
.\$(OBJDIR)\List.obj \
.\$(OBJDIR)\TxObjectWrapper.obj \
.\$(OBJDIR)\NamedMap.obj \

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -38,120 +39,51 @@
#ifndef MITRE_PRIMITIVES_H
#define MITRE_PRIMITIVES_H
#include "TxObject.h"
#include "baseutils.h"
#include "TxString.h"
/**
* A wrapper for the primitive double type, and provides some simple
* floating point related routines
**/
class Double : public TxObject {
/*
* Utility class for doubles
*/
class Double {
public:
/*
* Usefull constants
*/
static const double NaN;
static const double POSITIVE_INFINITY;
static const double NEGATIVE_INFINITY;
/**
* Creates a new Double with it's value initialized from the given String.
* The String will be converted to a double. If the String does not
* represent an IEEE 754 double, the value will be initialized to NaN
**/
Double(const String& string);
/**
* Returns the value of this Double as a double
**/
double doubleValue();
/**
* Returns the value of this Double as an int
**/
int intValue();
/**
/*
* Determines whether the given double represents positive or negative
* inifinity
**/
static MBool isInfinite(double dbl);
*/
static MBool isInfinite(double aDbl);
/**
/*
* Determines whether the given double is NaN
**/
static MBool isNaN(double dbl);
*/
static MBool isNaN(double aDbl);
/**
/*
* Determines whether the given double is negative
**/
static MBool isNeg(double dbl);
*/
static MBool isNeg(double aDbl);
/**
* Converts the value of the given double to a String, and places
* The result into the destination String.
/*
* Converts the value of the given double to a String, and appends
* the result to the destination String.
* @return the given dest string
**/
static String& toString(double value, String& dest);
*/
static String& toString(double aValue, String& aDest);
private:
double value;
/**
/*
* Converts the given String to a double, if the String value does not
* represent a double, NaN will be returned
**/
static double toDouble(const String& str);
*/
static double toDouble(const String& aStr);
};
/**
* A wrapper for the primitive int type, and provides some simple
* integer related routines
**/
class Integer : public TxObject {
public:
/**
* Creates a new Integer initialized to 0.
**/
Integer();
/**
* Creates a new Integer initialized to the given int value.
**/
Integer(PRInt32 integer);
/**
* Creates a new Integer based on the value of the given String
**/
Integer(const String& str);
/**
* Returns the int value of this Integer
**/
int intValue();
/**
* Converts the value of this Integer to a String
**/
String& toString(String& dest);
/**
* Converts the given int to a String
**/
static String& toString(int value, String& dest);
private:
PRInt32 value;
/**
* converts the given String to an int
**/
static int intValue(const String& src);
}; //-- Integer
#endif

View File

@ -31,7 +31,6 @@ PROGRAM = ../transformiix
OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
../base/CommandLineUtils.$(OBJ_SUFFIX) \
../base/Double.$(OBJ_SUFFIX) \
../base/Integer.$(OBJ_SUFFIX) \
../base/List.$(OBJ_SUFFIX) \
../base/TxObjectWrapper.$(OBJ_SUFFIX) \
../base/Map.$(OBJ_SUFFIX) \

View File

@ -29,7 +29,6 @@ CPP_OBJS= \
../base/$(OBJDIR)/ArrayList.obj \
../base/$(OBJDIR)/CommandLineUtils.obj \
../base/$(OBJDIR)/Double.obj \
../base/$(OBJDIR)/Integer.obj \
../base/$(OBJDIR)/List.obj \
../base/$(OBJDIR)/TxObjectWrapper.obj \
../base/$(OBJDIR)/Map.obj \

View File

@ -328,8 +328,7 @@ Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
break;
case Token::NUMBER:
{
StringResult str(tok->value);
expr = new NumberExpr(str.numberValue());
expr = new NumberExpr(Double::toDouble(tok->value));
break;
}
default:

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -339,8 +340,7 @@ double NodeSet::numberValue() {
// of its string value.
String str;
stringValue(str);
Double dbl(str);
return dbl.doubleValue();
return Double::toDouble(str);
// OG-
} //-- numberValue

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -53,10 +54,6 @@ ExprResult* NumberExpr::evaluate(Node* context, ContextState* cs) {
* @return the String representation of this Expr.
**/
void NumberExpr::toString(String& str) {
int intVal = (int)_value;
if (intVal == _value) { //-- no fraction
Integer::toString(intVal, str);
}
else Double::toString(_value, str);
Double::toString(_value, str);
} //-- toString

View File

@ -134,8 +134,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* context, ContextState* cs) {
for (i = 0; i < nodes->size(); i++) {
String resultStr;
XMLDOMUtils::getNodeValue(nodes->get(i), &resultStr);
Double dbl(resultStr);
res += dbl.doubleValue();
res += Double::toDouble(resultStr);
}
delete exprResult;
@ -149,8 +148,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* context, ContextState* cs) {
String resultStr;
XMLDOMUtils::getNodeValue(context, &resultStr);
Double dbl(resultStr);
return new NumberResult(dbl.doubleValue());
return new NumberResult(Double::toDouble(resultStr));
}
}
return new NumberResult(Double::NaN);

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -54,11 +55,7 @@ short NumberResult::getResultType() {
} //-- getResultType
void NumberResult::stringValue(String& str) {
int intVal = (int)value;
if (intVal == value) { //-- no fraction
Integer::toString(intVal, str);
}
else Double::toString(value, str);
Double::toString(value, str);
} //-- stringValue
MBool NumberResult::booleanValue() {

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -70,7 +71,6 @@ MBool StringResult::booleanValue() {
} //-- booleanValue
double StringResult::numberValue() {
Double dbl(value);
return dbl.doubleValue();
return Double::toDouble(value);
} //-- numberValue

View File

@ -1,4 +1,5 @@
/*
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
@ -110,7 +111,7 @@ void Numbering::doNumbering
}
//-- format counts
for ( int i = 0; i < nbrOfCounts; i++) {
Integer::toString(counts[i], dest);
Double::toString(counts[i], dest);
}
delete counts;
} //-- doNumbering

View File

@ -470,8 +470,7 @@ Node* ProcessorState::findTemplate(Node* aNode,
double tmpPriority;
if (!priorityAttr.isEmpty()) {
Double dbl(priorityAttr);
tmpPriority = dbl.doubleValue();
tmpPriority = Double::toDouble(priorityAttr);
}
else {
tmpPriority = templ->mMatch->getDefaultPriority(aNode,