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