1 // $Id: double.h,v 1.30 2004/06/02 11:26:22 elliott-oss Exp $ -*- c++ -*-
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2003 IBM Corporation and others.  All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9 //
10 // NOTES: The IEEE 754 emulation code in double.h and double.cpp within
11 // Jikes are adapted from code written by Alan M. Webb of IBM's Hursley
12 // lab in porting the Sun JDK to System/390.
13 //
14 //
15 //
16 // In addition, the code for emulating the remainder operator, %, is
17 // adapted from e_fmod.c, part of fdlibm, the Freely Distributable Math
18 // Library mentioned in the documentation of java.lang.StrictMath.  The
19 // original library is available at http://netlib2.cs.utk.edu/fdlibm.
20 //
21 // The code from fdlibm is copyrighted, as follows:
22 // ====================================================
23 // Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
24 //
25 // Developed at SunSoft, a Sun Microsystems, Inc. business.
26 // Permission to use, copy, modify, and distribute this
27 // software is freely granted, provided that this notice
28 // is preserved.
29 // ====================================================
30 //
31 //
32 //
33 // Likewise, the code for accurate conversions between floating point
34 // and decimal strings, in double.h, double.cpp, platform.h, and
35 // platform.cpp, is adapted from dtoa.c.  The original code can be
36 // found at http://netlib2.cs.utk.edu/fp/dtoa.c.
37 //
38 // The code in dtoa.c is copyrighted as follows:
39 //****************************************************************
40 //*
41 //* The author of this software is David M. Gay.
42 //*
43 //* Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
44 //*
45 //* Permission to use, copy, modify, and distribute this software for any
46 //* purpose without fee is hereby granted, provided that this entire notice
47 //* is included in all copies of any software which is or includes a copy
48 //* or modification of this software and in all copies of the supporting
49 //* documentation for such software.
50 //*
51 //* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
52 //* WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
53 //* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
54 //* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
55 //*
56 //***************************************************************/
57 //
58 //
59 
60 #ifndef double_INCLUDED
61 #define double_INCLUDED
62 
63 #include "platform.h"
64 #include "long.h"
65 
66 #ifdef HAVE_JIKES_NAMESPACE
67 namespace Jikes { // Open namespace Jikes block
68 #endif
69 
70 class LongInt;
71 class IEEEdouble;
72 class BigInt;
73 
74 class IEEEfloat
75 {
76     //
77     // If HAVE_IEEE754 is defined, this class is simply a wrapper for
78     // compiler-supported IEEE operations.  If not, then this class
79     // emulates IEEE 754 behavior, in accordance with the Java Language,
80     // using only integer arithmetic.
81     //
82 private:
83     friend class FloatToString;
84 
85     union
86     {
87         float float_value;
88         u4 word; // unsigned
89         i4 iword; // signed
90     } value;
91 
92     //
93     // two enums, so that first is signed, and second may be unsigned
94     //
95     enum
96     {
97         FRACT_SIZE = 23,         // number of bits in mantissa
98         BIAS = 127,              // exponent bias
99         MAX_DEC_EXP = 38,        // maximum decimal exponent
100         // maximum digits in precise decimal
101         MAX_DIGITS = BIAS + FRACT_SIZE + 1 - MAX_DEC_EXP
102     };
103     enum
104     {
105         SIGN_BIT = 0x80000000, // sign bit mask
106         EXP_BITS = 0x7F800000, // exponent bit mask
107         FRACT_BITS = 0x007FFFFF, // mantissa bit mask
108         ABS_BITS = EXP_BITS | FRACT_BITS, // absolute value
109         MAX_FRACT = 0x01000000, // upper limit of mantissa
110         MIN_FRACT = 0x00800000, // lower limit of normalized mantissa
111         NEG_ZERO = 0x80000000, // -0.0
112         POS_ZERO = 0x00000000, // 0.0
113         NEG_INF = 0xFF800000, // -Inf
114         POS_INF = 0x7F800000, // +Inf
115         NAN_BITS = 0x7FC00000, // canonical NaN
116         BYTE_MASK = 0x000000FF, // mask off least significant byte
117         MIN_LONG_F = 0xDF000000, // bit pattern of (float)LongInt::MIN_LONG()
118         MIN_INT_F = 0xCF000000 // bit pattern of (float)Int::MIN_INT()
119     };
120 
SignBit()121     inline u4 SignBit() const { return value.word & SIGN_BIT; }
ExpBits()122     inline u4 ExpBits() const { return value.word & EXP_BITS; }
FractBits()123     inline u4 FractBits() const { return value.word & FRACT_BITS; }
124 
125     // takes the (possibly) unnormalized fraction with its corresponding
126     // exponent and sign, and creates the normalized float
127     static IEEEfloat Normalize(int, int, u4);
128     // takes the float and splits it into a normalized fraction and exponent;
129     // the exponent is returned, the parameter fraction is modified
130     int SplitInto(u4& fraction) const;
131 
132     // returns the value of 1 ulp (unit in last place) for this float
133     IEEEfloat Ulp() const;
134     // returns the ratio between two floats represented in BigInts
135     static IEEEfloat Ratio(const BigInt&, const BigInt&);
136     // adjusts the value of this based on the ratio of the BigInts, and
137     // in direction determined by the boolean
138     bool Adjust(const BigInt&, const BigInt&, const bool);
139 
140 #ifndef HAVE_MEMBER_CONSTANTS
141     // VC++ can't cope with constant class members
142     static IEEEfloat tens[]; // powers of 10 exactly represented in float
143     static IEEEfloat bigtens[]; // powers of 10 by powers of 2
144 #else
145     static const IEEEfloat tens[]; // powers of 10 exactly represented in float
146     static const IEEEfloat bigtens[]; // powers of 10 by powers of 2
147 #endif
148 
149 public:
150     //
151     // Information methods, for evaluating components of the float
152     //
Word()153     inline u4 Word() const { return value.word; }
154 
Sign()155     inline int Sign() const { return value.word >> 31; }
Exponent()156     inline int Exponent() const
157     {
158         return ((value.word & EXP_BITS) >> FRACT_SIZE) - BIAS;
159     }
Fraction()160     inline u4 Fraction() const
161     {
162         return (value.word & FRACT_BITS) | (ExpBits() ? (u4) MIN_FRACT : 0);
163     }
Bias()164     static inline int Bias() { return BIAS; }
FractSize()165     static inline int FractSize() { return FRACT_SIZE; }
166 
IsNaN()167     inline bool IsNaN() const { return (value.word & ABS_BITS) > EXP_BITS; }
168 
IsNegative()169     inline bool IsNegative() const { return (value.iword < 0) && ! IsNaN(); }
IsPositive()170     inline bool IsPositive() const { return (value.iword >= 0) && ! IsNaN(); }
171 
IsNegativeZero()172     inline bool IsNegativeZero() const { return value.word == NEG_ZERO; }
IsPositiveZero()173     inline bool IsPositiveZero() const { return value.word == POS_ZERO; }
IsZero()174     inline bool IsZero() const { return (value.word & ABS_BITS) == POS_ZERO; }
175 
IsNegativeInfinity()176     inline bool IsNegativeInfinity() const { return value.word == NEG_INF; }
IsPositiveInfinity()177     inline bool IsPositiveInfinity() const { return value.word == POS_INF; }
IsInfinite()178     inline bool IsInfinite() const
179     {
180         return (value.word & ABS_BITS) == POS_INF;
181     }
182 
183 
184     //
185     // Generation methods, for creating common constants.
186     // TODO: These methods should be converted to return static const
187     // fields, rather than generating a non-const every time.  However,
188     // adding const support is a big undertaking.
189     //
190     // Note: the (u4) cast is necessary to prevent MSVC from promoting the
191     // enum constants to integer, which causes an infinite loop.
NaN()192     static inline const IEEEfloat NaN() { return IEEEfloat((u4) NAN_BITS); }
POSITIVE_INFINITY()193     static inline const IEEEfloat POSITIVE_INFINITY()
194     {
195         return IEEEfloat((u4) POS_INF);
196     }
NEGATIVE_INFINITY()197     static inline const IEEEfloat NEGATIVE_INFINITY()
198     {
199         return IEEEfloat((u4) NEG_INF);
200     }
POSITIVE_ZERO()201     static inline const IEEEfloat POSITIVE_ZERO()
202     {
203         return IEEEfloat((u4) POS_ZERO);
204     }
NEGATIVE_ZERO()205     static inline const IEEEfloat NEGATIVE_ZERO()
206     {
207         return IEEEfloat((u4) NEG_ZERO);
208     }
209 
210     //
211     // Constructors
212     //
213     // Create a float from the given value
IEEEfloat(float f)214     inline IEEEfloat(float f) { value.float_value = f; }
215 
216     // Convert string to float, the float is NaN if check_invalid is true
217     // and input is invalid by JLS
218     IEEEfloat(const char*, bool check_invalid = false);
219     // Widening conversion of int to float, may lose precision
220     IEEEfloat(i4);
221     // Forwarding constructor, if needed, so that IEEEfloat(0) works.
222 #ifndef TYPE_I4_IS_INT
IEEEfloat(int i)223     inline IEEEfloat(int i) { *this = IEEEfloat((i4) i); }
224 #endif // TYPE_I4_IS_INT
225     // Widening conversion of long to float, may lose precision
226     IEEEfloat(const LongInt&);
227     // Narrowing conversion of double to float, may lose precision
228 #ifdef HAVE_EXPLICIT
229     explicit
230 #endif
231              IEEEfloat(const IEEEdouble&);
232     // Create a float without initializing it
IEEEfloat()233     inline IEEEfloat() {}
234 
235     // Load a specified bit pattern (contrast to IEEEfloat(i4))
IEEEfloat(u4 bits)236     inline IEEEfloat(u4 bits) { value.word = bits; }
237 
238 
239     //
240     // Conversion routines
241     //
242     i4 IntValue() const;
243     LongInt LongValue() const;
FloatView()244     inline float FloatView() const { return value.float_value; }
245     inline IEEEdouble DoubleValue() const;
246 
247 
248     //
249     // Floating-point operations
250     // TODO: add const reference versions
251     //
252     IEEEfloat operator+(const IEEEfloat) const;   // binary addition
253     inline IEEEfloat operator+() { return *this; } // unary plus
254     inline IEEEfloat& operator+=(const IEEEfloat op) // add and assign
255     {
256         return *this = *this + op;
257     }
258     inline IEEEfloat operator++() { return *this += 1; } // pre-increment
259     inline IEEEfloat operator++(int) // post-increment
260     {
261         IEEEfloat result = *this;
262         *this += 1;
263         return result;
264     }
265 
266     IEEEfloat operator-() const;        // unary minus
267     inline IEEEfloat operator-(const IEEEfloat op) const // binary subtraction
268     {
269         return *this + (-op);
270     }
271     inline IEEEfloat& operator-=(const IEEEfloat op) // subtract and assign
272     {
273         return *this = *this - op;
274     }
275     inline IEEEfloat operator--() { return *this -= 1; } // pre-decrement
276     inline IEEEfloat operator--(int) // post-decrement
277     {
278         IEEEfloat result = *this;
279         *this -= 1;
280         return result;
281     }
282 
283     IEEEfloat operator*(const IEEEfloat) const;   // multiplication
284     inline IEEEfloat& operator*=(const IEEEfloat op) // multiply and assign
285     {
286         return *this = *this * op;
287     }
288 
289     IEEEfloat operator/(const IEEEfloat) const;   // divide
290     inline IEEEfloat& operator/=(const IEEEfloat op) // divide and assign
291     {
292         return *this = *this / op;
293     }
294 
295     IEEEfloat operator%(const IEEEfloat) const;   // modulus
296     inline IEEEfloat& operator%=(const IEEEfloat op) // modulus and assign
297     {
298         return *this = *this % op;
299     }
300 
301     //
302     // Comparison operators.  Recall that NaN does not compare, and 0.0 == -0.0
303     //
304     bool operator==(const IEEEfloat) const; // equal
305     bool operator!=(const IEEEfloat) const; // not equal
306     bool operator<(const IEEEfloat) const; // less-than
307     bool operator>(const IEEEfloat) const; // greater-than
308     bool operator<=(const IEEEfloat) const; // less-than or equal
309     bool operator>=(const IEEEfloat) const; // greater-than or equal
310 
311     //
312     // Methods for hashing floats, behave like java.lang.Float counterparts:
313     //  * -0.0f and 0.0f are different, with positive 0 comparing as greater
314     //    than negative 0.
315     //  * identical bit patterns of NaN are the same in equals, but not
316     //    unique patterns
317     //  * all bit patterns of NaN compare as greater than any other float,
318     //    including positive infinity, but the same as any other NaN pattern
319     //
equals(const IEEEfloat op)320     inline bool equals(const IEEEfloat op) const
321     {
322         return value.word == op.value.word;
323     }
hashCode()324     inline i4 hashCode() const { return value.iword; }
compareTo(const IEEEfloat op)325     inline int compareTo(const IEEEfloat op) const
326     {
327         return IsNaN() ? 1
328             : (IsZero() && op.IsZero()) ? op.Sign() - Sign()
329             : (*this < op) ? -1 : *this > op;
330     }
331 };
332 
333 
334 class IEEEdouble : public BaseLong
335     //
336     // If HAVE_IEEE754 is defined, this class is simply a wrapper for
337     // compiler-supported IEEE operations.  If not, then this class
338     // emulates IEEE 754 behavior, in accordance with the Java Language,
339     // using only integer arithmetic.
340     //
341 {
342 private:
343     friend class DoubleToString;
344 
345     //
346     // two enums, so that first is signed, and second may be unsigned
347     //
348     enum
349     {
350         FRACT_SIZE = 52,                 // number of bits in mantissa
351         FRACT_SIZE_HI = FRACT_SIZE - 32, // mantissa bits in high word
352         BIAS = 1023,                     // exponent bias
353         MAX_DEC_EXP = 308,               // maximum decimal exponent
354         // maximum digits in precise decimal
355         MAX_DIGITS = BIAS + FRACT_SIZE + 1 - MAX_DEC_EXP
356     };
357     enum
358     {
359         EXP_BITS = 0x7FF00000, // exponent bit mask
360         FRACT_BITS = 0x000FFFFF, // mantissa bit mask
361         ABS_BITS = EXP_BITS | FRACT_BITS, // absolute value
362         MAX_FRACT = 0x00200000, // upper limit of mantissa
363         MIN_FRACT = 0x00100000, // lower limit of mantissa
364         NEG_ZERO_HI = 0x80000000, // -0.0
365         POS_ZERO_HI = 0x00000000, // 0.0
366         NEG_INF_HI = 0xFFF00000, // -Inf
367         POS_INF_HI = 0x7FF00000, // +Inf
368         NAN_HI = 0x7FF80000, // canonical NaN
369         ZERO_LO = 0x00000000 // low half of special values above
370     };
371 
SignBit()372     inline u4 SignBit() const { return HighWord() & SIGN_BIT; }
ExpBits()373     inline u4 ExpBits() const { return HighWord() & EXP_BITS; }
FractBits()374     inline u4 FractBits() const { return HighWord() & FRACT_BITS; }
375 
376     // takes the (possibly) unnormalized fraction with its corresponding
377     // exponent and sign, and creates the normalized double
378     static IEEEdouble Normalize(int, int, ULongInt);
379     // takes the double and splits it into a normalized fraction and exponent;
380     // the exponent is returned, the parameter fraction is modified
381     int SplitInto(BaseLong& fraction) const;
382 
383     // returns the value of 1 ulp (unit in last place) for this double
384     IEEEdouble Ulp() const;
385     // returns the ratio between two doubles represented in BigInts
386     static IEEEdouble Ratio(const BigInt& a, const BigInt& b);
387 
388 
389 #ifndef HAVE_MEMBER_CONSTANTS
390     // VC++ can't cope with constant class members
391     static IEEEdouble tens[]; // powers of 10 exactly represented in float
392     static IEEEdouble bigtens[]; // powers of 10 by powers of 2
393 #else
394     static const IEEEdouble tens[]; // powers of 10 exactly represented in float
395     static const IEEEdouble bigtens[]; // powers of 10 by powers of 2
396 #endif
397 
398 public:
399     //
400     // Information methods, for evaluating components of the float
401     //
Sign()402     inline int Sign() const { return HighWord() >> 31; }
Exponent()403     inline int Exponent() const
404     {
405         return ((HighWord() & EXP_BITS) >> (FRACT_SIZE_HI)) - BIAS;
406     }
Fraction()407     inline LongInt Fraction() const
408     {
409         return LongInt(((HighWord() & FRACT_BITS) |
410                         (ExpBits() ? (u4) MIN_FRACT : 0)),
411                        LowWord());
412     }
Bias()413     static inline int Bias() { return BIAS; }
FractSize()414     static inline int FractSize() { return FRACT_SIZE; }
415 
IsNaN()416     inline bool IsNaN() const
417     {
418         // optimized for no branching, idea from fdlibm.c
419         u4 high = HighWord();
420         u4 low = LowWord();
421         return ((high & ABS_BITS) | ((low | -(i4) low) >> 31)) > EXP_BITS;
422     }
423 
IsNegative()424     inline bool IsNegative() const
425     {
426         return ((i4) HighWord() < 0) && ! IsNaN();
427     }
IsPositive()428     inline bool IsPositive() const
429     {
430         return ((i4) HighWord() >= 0) && ! IsNaN();
431     }
432 
IsNegativeZero()433     inline bool IsNegativeZero() const
434     {
435         return (HighWord() == NEG_ZERO_HI) && (LowWord() == ZERO_LO);
436     }
IsPositiveZero()437     inline bool IsPositiveZero() const
438     {
439         return (HighWord() == POS_ZERO_HI) && (LowWord() == ZERO_LO);
440     }
IsZero()441     inline bool IsZero() const
442     {
443         return ((HighWord() & ABS_BITS) == POS_ZERO_HI) &&
444             (LowWord() == ZERO_LO);
445     }
446 
IsNegativeInfinity()447     inline bool IsNegativeInfinity() const
448     {
449         return (HighWord() == NEG_INF_HI) && (LowWord() == ZERO_LO);
450     }
IsPositiveInfinity()451     inline bool IsPositiveInfinity() const
452     {
453         return (HighWord() == POS_INF_HI) && (LowWord() == ZERO_LO);
454     }
IsInfinite()455     inline bool IsInfinite() const
456     {
457         return ((HighWord() & ABS_BITS) == POS_INF_HI) &&
458             (LowWord() == ZERO_LO);
459     }
460 
461 
462     //
463     // Generation methods, for creating common constants
464     // TODO: These methods should be converted to return static const
465     // fields, rather than generating a non-const every time, as in
466     // BaseLong (long.h).  However, adding const support is a big undertaking.
467     //
NaN()468     static inline const IEEEdouble NaN()
469     {
470         return IEEEdouble(NAN_HI, ZERO_LO);
471     }
POSITIVE_INFINITY()472     static inline const IEEEdouble POSITIVE_INFINITY()
473     {
474         return IEEEdouble(POS_INF_HI, ZERO_LO);
475     }
NEGATIVE_INFINITY()476     static inline const IEEEdouble NEGATIVE_INFINITY()
477     {
478         return IEEEdouble(NEG_INF_HI, ZERO_LO);
479     }
POSITIVE_ZERO()480     static inline const IEEEdouble POSITIVE_ZERO()
481     {
482         return IEEEdouble(POS_ZERO_HI, ZERO_LO);
483     }
NEGATIVE_ZERO()484     static inline const IEEEdouble NEGATIVE_ZERO()
485     {
486         return IEEEdouble(NEG_ZERO_HI, ZERO_LO);
487     }
488 
489 
490     //
491     // Constructors
492     //
493     // Create a double from the given value
IEEEdouble(double d)494     inline IEEEdouble(double d) { value.double_value = d; }
495     // Convert string to double, the double is NaN if check_invalid is true
496     // and input is invalid by JLS
497     IEEEdouble(const char*, bool check_invalid = false);
498 
499     // widening conversion of int to double, no information lost
500     IEEEdouble(i4);
501     // Forwarding constructor, if needed, so that IEEEdouble(0) works.
502 #ifndef TYPE_I4_IS_INT
IEEEdouble(int i)503     inline IEEEdouble(int i) { *this = IEEEdouble((i4) i); }
504 #endif // TYPE_I4_IS_INT
505     // Widening conversion of long to double, may lose precision
506     IEEEdouble(const LongInt&);
507     // Widening conversion of float to double, no information lost
508     IEEEdouble(const IEEEfloat&);
509     // Create a double without initializing it
IEEEdouble()510     inline IEEEdouble() {}
511     // Load a specified bit pattern (contrast to IEEEfloat(LongInt))
IEEEdouble(u4 hi,u4 lo)512     inline IEEEdouble(u4 hi, u4 lo) { setHighAndLowWords(hi, lo); }
IEEEdouble(const BaseLong & bits)513     inline IEEEdouble(const BaseLong& bits) { setHighAndLowWords(bits); }
514 
515     //
516     // Conversion routines
517     //
518     i4 IntValue() const;
519     LongInt LongValue() const;
FloatValue()520     inline IEEEfloat FloatValue() const { return IEEEfloat(*this); }
521 
522 
523     //
524     // Floating-point operations
525     // TODO: add const reference versions
526     //
527     IEEEdouble operator+(const IEEEdouble) const;   // binary addition
528     inline IEEEdouble operator+() const { return *this; } // unary plus
529     inline IEEEdouble& operator+=(const IEEEdouble op) // add and assign
530     {
531         return *this = *this + op;
532     }
533     inline IEEEdouble operator++() { return *this += 1; } // pre-increment
534     inline IEEEdouble operator++(int) // post-increment
535     {
536         IEEEdouble result = *this;
537         *this += 1;
538         return result;
539     }
540 
541     IEEEdouble operator-() const;         // unary minus
542     inline IEEEdouble operator-(const IEEEdouble op) const // binary subtract
543     {
544         return *this + (-op);
545     }
546     inline IEEEdouble& operator-=(const IEEEdouble op) // subtract and assign
547     {
548         return *this = *this - op;
549     }
550     inline IEEEdouble operator--() { return *this -= 1; } // pre-decrement
551     inline IEEEdouble operator--(int) // post-decrement
552     {
553         IEEEdouble result = *this;
554         *this -= 1;
555         return result;
556     }
557 
558     IEEEdouble operator*(const IEEEdouble) const;   // multiplication
559     inline IEEEdouble& operator*=(const IEEEdouble op) // multiply and assign
560     {
561         return *this = *this * op;
562     }
563 
564     IEEEdouble operator/(const IEEEdouble) const;   // divide
565     inline IEEEdouble& operator/=(const IEEEdouble op) // divide and assign
566     {
567         return *this = *this / op;
568     }
569 
570     IEEEdouble operator%(const IEEEdouble) const;   // modulus
571     inline IEEEdouble& operator%=(const IEEEdouble op) // modulus and assign
572     {
573         return *this = *this % op;
574     }
575 
576     //
577     // Comparison operators.  Recall that NaN does not compare, and 0.0 == -0.0
578     //
579     bool operator==(const IEEEdouble) const; // equal
580     bool operator!=(const IEEEdouble) const; // not equal
581     bool operator<(const IEEEdouble) const; // less-than
582     bool operator>(const IEEEdouble) const; // greater-than
583     bool operator<=(const IEEEdouble) const; // less-than or equal
584     bool operator>=(const IEEEdouble) const; // greater-than or equal
585 
586     //
587     // Methods for hashing doubles, behave like java.lang.Double counterparts:
588     //  * -0.0 and 0.0 are different, with positive 0 comparing as greater
589     //    than negative 0.
590     //  * identical bit patterns of NaN are the same in equals, but not
591     //    unique patterns
592     //  * all bit patterns of NaN compare as greater than any other float,
593     //    including positive infinity, but the same as any other NaN pattern
594     //
equals(const IEEEdouble op)595     inline bool equals(const IEEEdouble op) const
596     {
597         return (BaseLong) *this == (BaseLong) op;
598     }
hashCode()599     inline i4 hashCode() const { return ((BaseLong) *this).hashCode(); }
compareTo(const IEEEdouble op)600     inline int compareTo(const IEEEdouble op) const
601     {
602         return IsNaN() ? 1
603             : (IsZero() && op.IsZero()) ? op.Sign() - Sign()
604             : (*this < op) ? -1 : *this > op;
605     }
606 };
607 
608 
609 //
610 // Helper class for storing precise decimal values of floating point
611 // when converting to or from decimal strings.
612 //
613 class BigInt
614 {
615 public:
616     // init with value, set exponent and bit count
617     BigInt(const IEEEfloat&, int& exp, int& bitcnt);
618     BigInt(const IEEEdouble&, int& exp, int& bitcnt);
619     // init with int
620     inline BigInt(int);
621     // init with value of string; where before is the number of digits
622     // before the '.', total is the number of digits to parse, start
623     // is the previously parsed value of the first few digits, and
624     // startsize gives the number of digits previously parsed
625     BigInt(const char*, int before, int total, u4 start, int startsize);
626     // copy constructor and assignment operator
627     BigInt& operator=(const BigInt&);
BigInt(const BigInt & op)628     BigInt(const BigInt& op) { data = NULL; *this = op; }
629     // destructor
~BigInt()630     ~BigInt() { delete data; }
631 
632 private:
633     // resize data[] to be 1<<k elements
634     inline void resize(int k);
635 
636     // return count of high-order 0's in x
637     static int hi0bits(u4 x);
638     // return count of low-order 0's in y, shift y so that
639     // least significant 1 is at right
640     static int lo0bits(u4& y);
641 
642 public:
643     // return number of leading 0's in most significant word of data
hi0bits()644     inline int hi0bits() const { assert(data); return hi0bits(data[wds - 1]); }
645 
646     // return true if this is 0
IsZero()647     inline bool IsZero() const { assert(data); return ! (data[0] || wds > 1); }
648 
649     // return true if this is negative
IsNegative()650     inline bool IsNegative() const { return neg; }
651     // set whether this is negative
IsNegative(bool value)652     inline void IsNegative(bool value) { neg = value; }
653 
654     // operators
655     BigInt operator+(const unsigned op) const;
656     inline BigInt& operator+=(const unsigned op) { return *this = *this + op; }
657     inline BigInt& operator++() { return *this += 1; } // pre-increment
658     BigInt operator-(const BigInt& op) const;
659     BigInt operator*(const BigInt& op) const;
660     BigInt operator*(unsigned op) const;
661     inline BigInt& operator*=(const BigInt& op) { return *this = *this * op; }
662     inline BigInt& operator*=(unsigned op) { return *this = *this * op; }
663     BigInt operator<<(unsigned op) const;
664     inline BigInt& operator<<=(unsigned op) { return *this = *this << op; }
665 
666     // equivalent to *this = *this * m + a, with less work
667     BigInt& multadd(unsigned m, unsigned a);
668     // return *this *= pow(5, k)
669     BigInt& pow5mult(unsigned k);
670     // return *this == b ? 0 : *this < b ? negative : positive;
671     int compareTo(const BigInt& b) const;
672     // tmp = *this % S; *this /= S; return tmp;
673     int quorem(const BigInt& S);
674 
675     // converts to scaled native value, between 1 and 2.
676     IEEEfloat FloatValue() const;
677     IEEEdouble DoubleValue() const;
678 
679 private:
680     friend class IEEEfloat;
681     friend class IEEEdouble;
682 
683     int k;      // log2 maxwds
684     int maxwds; // size of data[]
685     bool neg;   // true for negative
686     int wds;    // current memory use of data[]
687     u4* data;   // bit storage
688 
689 #ifndef HAVE_MEMBER_CONSTANTS
690     static u4 fives[];          // powers of 5 that fit in int
691     static BigInt* bigfives[];  // bigger powers of 5, by powers of 2
692 #else /* HAVE_MEMBER_CONSTANTS */
693     static const u4 fives[];
694     static const BigInt* bigfives[];
695 #endif /* HAVE_MEMBER_CONSTANTS */
696 
697 };
698 
699 
DoubleValue()700 inline IEEEdouble IEEEfloat::DoubleValue() const
701 {
702     return IEEEdouble(*this);
703 }
704 
BigInt(int i)705 inline BigInt::BigInt(int i) : data(NULL)
706 {
707     resize(0);
708     data[0] = i;
709     wds = 1;
710     neg = i < 0;
711 }
712 
resize(int k)713 inline void BigInt::resize(int k)
714 {
715     maxwds = 1 << k;
716     delete data;
717     data = new u4[maxwds];
718     this -> k = k;
719     wds = 0;
720     neg = false;
721 }
722 
723 #ifdef HAVE_JIKES_NAMESPACE
724 } // Close namespace Jikes block
725 #endif
726 
727 #endif // double_INCLUDED
728 
729