001: /*
002: * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003: * Copyright (C) 2006 - JScience (http://jscience.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package org.jscience.mathematics.number;
010:
011: import org.jscience.mathematics.structure.Field;
012:
013: import javolution.lang.MathLib;
014: import javolution.context.HeapContext;
015: import javolution.context.LocalContext;
016: import javolution.context.ObjectFactory;
017: import javolution.text.Text;
018: import javolution.text.TypeFormat;
019: import javolution.xml.XMLFormat;
020: import javolution.xml.stream.XMLStreamException;
021:
022: /**
023: * <p> This class represents a real number of arbitrary precision with
024: * known/guaranteed uncertainty. A real number consists of a
025: * {@link #getSignificand significand}, a maximum {@link #getError error}
026: * (on the significand value) and a decimal {@link #getExponent exponent}:
027: * (<code>(significand ± error) · 10<sup>exponent</sup></code>).</p>
028: *
029: * <p> Reals number can be {@link #isExact exact} (e.g. integer values
030: * scaled by a power of ten). Exactness is maintained for
031: * {@link org.jscience.mathematics.structure.Ring Ring} operations
032: * (e.g. addition, multiplication), but typically lost when a
033: * multiplicative {@link #inverse() inverse} is calculated. The minimum
034: * precision used for exact numbers is set by
035: * {@link #setExactPrecision(int)} ({@link
036: * javolution.context.LocalContext context local} setting, default
037: * <code>19</code> digits).<p>
038: *
039: * <p> The actual {@link #getPrecision precision} and {@link #getAccuracy
040: * accuracy} of any real number is available and <b>guaranteed</b>
041: * (the true/exact value is always within the precision/accuracy range).</p>
042: *
043: * <p> Operations on instances of this class are quite fast
044: * as information substantially below the precision level (aka noise)
045: * is not processed/stored. There is no limit on a real precision
046: * but precision degenerates (due to numeric errors) and calculations
047: * accelerate as more and more operations are performed.</p>
048: *
049: * <p> Instances of this class can be utilized to find approximate
050: * solutions to linear equations using the
051: * {@link org.jscience.mathematics.vector.Matrix Matrix} class for which
052: * high-precision reals is often required, the primitive type
053: * <code>double</code> being not accurate enough to resolve equations
054: * when the matrix's size exceeds 100x100. Furthermore, even for small
055: * matrices the "qualified" result is indicative of possible system
056: * singularities.</p>
057: *
058: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
059: * @version 3.3, January 8, 2006
060: * @see <a href="http://en.wikipedia.org/wiki/Real_number">
061: * Wikipedia: Real number</a>
062: */
063: public final class Real extends Number<Real> implements Field<Real> {
064:
065: /**
066: * Holds the default XML representation for real numbers.
067: * This representation consists of a simple <code>value</code> attribute
068: * holding the {@link #toText() textual} representation.
069: */
070: static final XMLFormat<Real> XML = new XMLFormat<Real>(Real.class) {
071:
072: @Override
073: public Real newInstance(Class<Real> cls, InputElement xml)
074: throws XMLStreamException {
075: return Real.valueOf(xml.getAttribute("value"));
076: }
077:
078: public void write(Real real, OutputElement xml)
079: throws XMLStreamException {
080: xml.setAttribute("value", real.toText());
081: }
082:
083: public void read(InputElement xml, Real real) {
084: // Nothing to do, immutable.
085: }
086: };
087:
088: /**
089: * Holds a Not-a-Number instance (infinite error).
090: */
091: public static final Real NaN = new Real(); // Unique (0 ± 1E2147483647)
092: static {
093: NaN._significand = LargeInteger.ZERO;
094: NaN._error = LargeInteger.ONE;
095: NaN._exponent = Integer.MAX_VALUE;
096: }
097:
098: /**
099: * Holds the exact ZERO instance.
100: */
101: public static final Real ZERO;
102:
103: /**
104: * Holds the exact ONE instance.
105: */
106: public static final Real ONE;
107:
108: /**
109: * Holds local precision for exact number.
110: */
111: private static final LocalContext.Reference<Integer> EXACT_PRECISION = new LocalContext.Reference<Integer>(
112: new Integer(19));
113:
114: /**
115: * The significand value.
116: */
117: private LargeInteger _significand;
118:
119: /**
120: * The significand error (0 for exact number).
121: */
122: private LargeInteger _error;
123:
124: /**
125: * The decimal exponent.
126: */
127: private int _exponent;
128:
129: /**
130: * Default constructor.
131: */
132: private Real() {
133: }
134:
135: /**
136: * Returns the {@link javolution.context.LocalContext local} minimum
137: * precision (number of exact digits) when exact numbers have to be
138: * approximated.
139: *
140: * @return the minimum number of digits assumed exact for {@link #isExact
141: * exact} real numbers.
142: */
143: public static int getExactPrecision() {
144: return EXACT_PRECISION.get();
145: }
146:
147: /**
148: * Sets the {@link javolution.context.LocalContext local} minimum precision
149: * (number of exact digits) when exact numbers have to be approximated.
150: *
151: * @param precision the minimum number of digits assumed exact for
152: * {@link #isExact exact} numbers.
153: */
154: public static void setExactPrecision(int precision) {
155: EXACT_PRECISION.set(precision);
156: }
157:
158: /**
159: * Returns a real having the specified significand, error and exponent values.
160: * If the error is <code>0</code>, the real is assumed exact.
161: * For example:[code]
162: *
163: * // x = 0.0 ± 0.01
164: * Real x = Real.valueOf(LargeInteger.ZERO, 1, -2);
165: *
166: * // y = -12.3 exact
167: * Real y = Real.valueOf(LargeInteger.valueOf(-123), 0, -1);
168: *
169: * [/code]
170: *
171: * @param significand this real significand.
172: * @param error the maximum error on the significand.
173: * @param exponent the decimal exponent.
174: * @return <code>(significand ± error)·10<sup>exponent</sup>)</code>
175: * @throws IllegalArgumentException if <code>error < 0</code>
176: */
177: public static Real valueOf(LargeInteger significand, int error,
178: int exponent) {
179: if (error < 0)
180: throw new IllegalArgumentException(
181: "Error cannot be negative");
182: Real real = FACTORY.object();
183: real._significand = significand;
184: real._error = LargeInteger.valueOf(error);
185: real._exponent = exponent;
186: return real;
187: }
188:
189: /**
190: * Returns the real number (inexact except for <code>0.0</code>)
191: * corresponding to the specified <code>double</code> value.
192: * The error is derived from the inexact representation of
193: * <code>double</code> values intrinsic to the 64 bits IEEE 754 format.
194: *
195: * @param doubleValue the <code>double</code> value to convert.
196: * @return the corresponding real number.
197: */
198: public static Real valueOf(double doubleValue) {
199: if (doubleValue == 0.0)
200: return Real.ZERO;
201: if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue))
202: return Real.NaN;
203: // Find the exponent e such as: value == x.xxx * 10^e
204: int e = MathLib.floorLog10(doubleValue) - 18 + 1; // 18 digits significand.
205: long significand = MathLib.toLongPow10(doubleValue, -e);
206: int error = (int) MathLib
207: .toLongPow10(Math.ulp(doubleValue), -e) + 1;
208: return Real
209: .valueOf(LargeInteger.valueOf(significand), error, e);
210: }
211:
212: /**
213: * Returns the exact real number corresponding to the specified
214: * <code>long</code> value (convenience method).
215: *
216: * @param longValue the exact long value.
217: * @return <code>Real.valueOf(LargeInteger.valueOf(longValue), 0, 0)</code>
218: */
219: public static Real valueOf(long longValue) {
220: return Real.valueOf(LargeInteger.valueOf(longValue), 0, 0);
221: }
222:
223: /**
224: * Returns the real for the specified character sequence.
225: * If the precision is not specified (using the <code>±</code> symbol),
226: * the real is supposed exact. Example of valid character sequences:
227: * <li>"1.2E3" (1200 exact)</li>
228: * <li>"1.2E3±1E-2" (1200 ± 0.01)</li></ul>
229: *
230: * @param chars the character sequence.
231: * @return the corresponding real number.
232: * @throws NumberFormatException if the character sequence does not contain
233: * a parsable real.
234: */
235: public static Real valueOf(CharSequence chars)
236: throws NumberFormatException {
237: Text txt = Text.valueOf(chars); // TODO Use TextFormat...
238: if ((txt.length() == 3) && (txt.indexOf("NaN", 0) == 0))
239: return NaN;
240: if (txt.equals("0"))
241: return ZERO;
242: int exponentIndex = txt.indexOf("E", 0);
243: if (exponentIndex >= 0) {
244: int exponent = TypeFormat.parseInt(txt.subtext(
245: exponentIndex + 1, txt.length()));
246: Real r = valueOf(txt.subtext(0, exponentIndex));
247: if (r == ZERO)
248: return valueOf(LargeInteger.ZERO, 1, exponent);
249: r._exponent += exponent;
250: return r;
251: }
252: Real real = FACTORY.object();
253: int errorIndex = txt.indexOf("±", 0);
254: if (errorIndex >= 0) {
255: real._significand = LargeInteger.valueOf(txt.subtext(0,
256: errorIndex));
257: real._error = LargeInteger.valueOf(txt.subtext(
258: errorIndex + 1, txt.length()));
259: if (real._error.isNegative())
260: throw new NumberFormatException(chars
261: + " not parsable (error cannot be negative)");
262: real._exponent = 0;
263: return real;
264: }
265: int decimalPointIndex = txt.indexOf(".", 0);
266: if (decimalPointIndex >= 0) {
267: LargeInteger integer = LargeInteger.valueOf(txt.subtext(0,
268: decimalPointIndex));
269: LargeInteger fraction = LargeInteger.valueOf(txt.subtext(
270: decimalPointIndex + 1, txt.length()));
271: int fractionDigits = chars.length() - decimalPointIndex - 1;
272: real._significand = integer.isNegative() ? integer
273: .times10pow(fractionDigits).minus(fraction)
274: : integer.times10pow(fractionDigits).plus(fraction);
275: real._error = LargeInteger.ZERO;
276: real._exponent = -fractionDigits;
277: return real;
278: } else {
279: real._significand = LargeInteger.valueOf(chars);
280: real._error = LargeInteger.ZERO;
281: real._exponent = 0;
282: return real;
283: }
284: }
285:
286: /**
287: * Returns this real <a href="http://en.wikipedia.org/wiki/Significand">
288: * significand</a> value.
289: *
290: * @return the significand.
291: */
292: public LargeInteger getSignificand() {
293: return _significand;
294: }
295:
296: /**
297: * Returns the maximum error (positive) on this real significand.
298: *
299: * @return the maximum error on the significand.
300: */
301: public int getError() {
302: return _error.intValue();
303: }
304:
305: /**
306: * Returns the exponent of the power of 10 multiplier.
307: *
308: * @return the decimal exponent.
309: */
310: public int getExponent() {
311: return _exponent;
312: }
313:
314: /**
315: * Indicates if this real number is exact (<code>{@link #getError() error}
316: * == 0</code>).
317: *
318: * @return <code>getError() == 0</code>
319: */
320: public boolean isExact() {
321: return _error.isZero();
322: }
323:
324: /**
325: * Returns the number of decimal digits guaranteed exact which appear to
326: * the right of the decimal point (absolute error).
327: *
328: * @return a measure of the absolute error of this real number.
329: */
330: public int getAccuracy() {
331: if (_error.isZero())
332: return Integer.MAX_VALUE;
333: if (this == NaN)
334: return Integer.MIN_VALUE;
335: return -_exponent - _error.digitLength();
336: }
337:
338: /**
339: * Returns the total number of decimal digits guaranteed exact
340: * (relative error).
341: *
342: * @return a measure of the relative error of this real number.
343: */
344: public final int getPrecision() {
345: if (_error.isZero())
346: return Integer.MAX_VALUE;
347: if (this == NaN)
348: return Integer.MIN_VALUE;
349: return _significand.digitLength() - _error.digitLength();
350: }
351:
352: /**
353: * Indicates if this real is greater than zero.
354: *
355: * @return <code>this > 0</code>
356: */
357: public boolean isPositive() {
358: return _significand.isPositive();
359: }
360:
361: /**
362: * Indicates if this real is less than zero.
363: *
364: * @return <code>this < 0</code>
365: */
366: public boolean isNegative() {
367: return _significand.isNegative();
368: }
369:
370: /**
371: * Indicates if this real is Not-a-Number (unbounded value interval).
372: *
373: * @return <code>true</code> if this number has unbounded value interval;
374: * <code>false</code> otherwise.
375: */
376: public boolean isNaN() {
377: return this == NaN;
378: }
379:
380: /**
381: * Indicates if this real approximates the one specified.
382: * This method takes into account possible errors (e.g. numeric
383: * errors) to make this determination.
384: *
385: * <p>Note: This method returns <code>true</code> if <code>this</code> or
386: * <code>that</code> {@link #isNaN} (basically Not-A-Number
387: * approximates anything).</p>
388: *
389: * @param that the real to compare with.
390: * @return <code>this ≈ that</code>
391: */
392: public boolean approximates(Real that) {
393: Real diff = this .minus(that);
394: if (diff == NaN)
395: return false;
396: return diff._error.isLargerThan(diff._significand);
397: }
398:
399: /**
400: * Returns the closest integer value to this rational number.
401: *
402: * @return this real rounded to the nearest integer.
403: * @throws ArithmeticException if <code>this.isNaN()</code>
404: */
405: public LargeInteger round() {
406: if (this == NaN)
407: throw new ArithmeticException(
408: "Cannot convert NaN to integer value");
409: LargeInteger half = LargeInteger.FIVE.times10pow(_exponent - 1);
410: return isNegative() ? _significand.minus(half).times10pow(
411: _exponent) : _significand.plus(half).times10pow(
412: _exponent);
413: }
414:
415: /**
416: * Returns the negation of this real number.
417: *
418: * @return <code>-this</code>.
419: */
420: public Real opposite() {
421: if (this == NaN)
422: return NaN;
423: Real real = FACTORY.object();
424: real._significand = _significand.opposite();
425: real._exponent = _exponent;
426: real._error = _error;
427: return real;
428: }
429:
430: /**
431: * Returns the sum of this real number with the one specified.
432: *
433: * @param that the real to be added.
434: * @return <code>this + that</code>.
435: */
436: public Real plus(Real that) {
437: if ((this == NaN) || (that == NaN))
438: return NaN;
439: if (this ._exponent > that._exponent)
440: return that.plus(this ); // Adds to the real with smallest exponent.
441: int scale = that._exponent - this ._exponent; // >= 0
442: Real real = FACTORY.object();
443: real._exponent = _exponent;
444: real._significand = this ._significand.plus(that._significand
445: .times10pow(scale));
446: real._error = this ._error.plus(that._error.times10pow(scale));
447: return real.normalize();
448: }
449:
450: /**
451: * Returns the difference between this real number and the one
452: * specified.
453: *
454: * @param that the real to be subtracted.
455: * @return <code>this - that</code>.
456: */
457: public Real minus(Real that) {
458: return this .plus(that.opposite());
459: }
460:
461: /**
462: * Returns the product of this real number with the specified
463: * <code>long</code> multiplier.
464: *
465: * @param multiplier the <code>long</code> multiplier.
466: * @return <code>this · multiplier</code>.
467: */
468: public Real times(long multiplier) {
469: if (this == NaN)
470: return NaN;
471: Real real = FACTORY.object();
472: real._exponent = this ._exponent;
473: real._significand = this ._significand.times(multiplier);
474: real._error = this ._error.times(multiplier);
475: return real.normalize();
476: }
477:
478: /**
479: * Returns the product of this real number with the one specified.
480: *
481: * @param that the real multiplier.
482: * @return <code>this · that</code>.
483: */
484: public Real times(Real that) {
485: if ((this == NaN) || (that == NaN))
486: return NaN;
487: long exp = ((long) this ._exponent) + that._exponent;
488: if (exp > Integer.MAX_VALUE || (exp < Integer.MIN_VALUE))
489: return NaN; // Exponent overflow.
490: LargeInteger this Min = this ._significand.minus(this ._error);
491: LargeInteger this Max = this ._significand.plus(this ._error);
492: LargeInteger thatMin = that._significand.minus(that._error);
493: LargeInteger thatMax = that._significand.plus(that._error);
494: LargeInteger min, max;
495: if (this Min.compareTo(this Max.opposite()) > 0) {
496: if (thatMin.compareTo(thatMax.opposite()) > 0) {
497: min = this Min.times(thatMin);
498: max = this Max.times(thatMax);
499: } else {
500: min = this Max.times(thatMin);
501: max = this Min.times(thatMax);
502: }
503: } else {
504: if (thatMin.compareTo(thatMax.opposite()) > 0) {
505: min = this Min.times(thatMax);
506: max = this Max.times(thatMin);
507: } else {
508: min = this Max.times(thatMax);
509: max = this Min.times(thatMin);
510: }
511: }
512: Real real = FACTORY.object();
513: real._exponent = (int) exp;
514: real._significand = min.plus(max).shiftRight(1);
515: real._error = max.minus(min);
516: return real.normalize();
517: }
518:
519: /**
520: * Returns this real number divided by the specified <code>int</code>
521: * divisor.
522: *
523: * @param divisor the <code>int</code> divisor.
524: * @return <code>this / divisor</code>
525: */
526: public Real divide(long divisor) {
527: return this .divide(Real.valueOf(divisor));
528: }
529:
530: /**
531: * Returns this real number divided by the one specified.
532: *
533: * @param that the real divisor.
534: * @return <code>this / that</code>.
535: * @throws ArithmeticException if <code>that.equals(ZERO)</code>
536: */
537: public Real divide(Real that) {
538: return this .times(that.inverse());
539: }
540:
541: /**
542: * Returns the reciprocal (or inverse) of this real number.
543: *
544: * @return <code>1 / this</code>.
545: */
546: public Real inverse() {
547: if ((this == NaN) || (this == ZERO))
548: return NaN;
549: if (this .isExact())
550: return this .toInexact().inverse();
551: LargeInteger this Min = this ._significand.minus(this ._error);
552: LargeInteger this Max = this ._significand.plus(this ._error);
553: if (this Min.isNegative() && this Max.isPositive()) // Encompasses 0
554: return NaN;
555: int digits = MathLib.max(this Min.digitLength(), this Max
556: .digitLength());
557: long exp = ((long) -this ._exponent) - digits - digits;
558: if ((exp > Integer.MAX_VALUE || (exp < Integer.MIN_VALUE)))
559: return NaN; // Exponent overflow.
560: LargeInteger min = div(2 * digits, this Max);
561: LargeInteger max = div(2 * digits, this Min);
562: Real real = FACTORY.object();
563: real._exponent = (int) exp;
564: real._significand = min.plus(max).shiftRight(1);
565: real._error = max.minus(min).plus(LargeInteger.ONE);
566: return real.normalize();
567: }
568:
569: private static LargeInteger div(int exp, LargeInteger significand) {
570: int expBitLength = (int) (exp * DIGITS_TO_BITS);
571: int precision = expBitLength - significand.bitLength() + 1;
572: LargeInteger reciprocal = significand.inverseScaled(precision);
573: LargeInteger result = reciprocal.times10pow(exp);
574: return result.shiftRight(expBitLength + 1);
575: }
576:
577: private static final double DIGITS_TO_BITS = MathLib.LOG10
578: / MathLib.LOG2;
579:
580: private Real toInexact() {
581: int digits = _significand.digitLength();
582: int scale = Real.getExactPrecision() - digits + 1;
583: Real z = FACTORY.object();
584: z._significand = _significand.times10pow(scale);
585: z._error = LargeInteger.ONE;
586: z._exponent = _exponent - scale;
587: return z;
588: }
589:
590: /**
591: * Returns the absolute value of this real number.
592: *
593: * @return <code>|this|</code>.
594: */
595: public Real abs() {
596: return _significand.isNegative() ? this .opposite() : this ;
597: }
598:
599: /**
600: * Compares the absolute value of two real numbers.
601: *
602: * @param that the real number to be compared with.
603: * @return <code>|this| > |that|</code>
604: */
605: public boolean isLargerThan(Real that) {
606: return this .abs().compareTo(that.abs()) > 0;
607: }
608:
609: /**
610: * Returns the square root of this real number, the more accurate is this
611: * real number, the more accurate the square root.
612: *
613: * @return the positive square root of this real number.
614: */
615: public Real sqrt() {
616: if (this == NaN)
617: return NaN;
618: if (this .isExact())
619: return this .toInexact().sqrt();
620: LargeInteger this Min = this ._significand.minus(this ._error);
621: LargeInteger this Max = this ._significand.plus(this ._error);
622: if (this Min.isNegative())
623: return NaN;
624: int exponent = _exponent >> 1;
625: if ((_exponent & 1) == 1) { // Odd exponent.
626: this Min = this Min.times10pow(1);
627: this Max = this Max.times10pow(1);
628: }
629: LargeInteger minSqrt = this Min.sqrt();
630: LargeInteger maxSqrt = this Max.sqrt().plus(LargeInteger.ONE);
631: LargeInteger sqrt = minSqrt.plus(maxSqrt).shiftRight(1);
632: Real z = FACTORY.object();
633: z._significand = sqrt;
634: z._error = maxSqrt.minus(sqrt);
635: z._exponent = exponent;
636: return z.normalize();
637: }
638:
639: /**
640: * Returns the decimal text representation of this number.
641: *
642: * @return the text representation of this number.
643: */
644: public Text toText() {
645: if (this == NaN)
646: return Text.valueOf("NaN");
647: if (isExact()) {
648: return (_exponent == 0) ? _significand.toText()
649: : _significand.toText().plus("E").plus(
650: Text.valueOf(_exponent));
651: }
652: int errorDigits = _error.digitLength();
653: LargeInteger m = (_significand.isPositive()) ? _significand
654: .plus(FIVE.times10pow(errorDigits - 1)) : _significand
655: .plus(MINUS_FIVE.times10pow(errorDigits - 1));
656: m = m.times10pow(-errorDigits);
657: int exp = _exponent + errorDigits;
658: Text txt = m.toText();
659: int digits = (m.isNegative()) ? txt.length() - 1 : txt.length();
660: if (digits > 1) {
661: if ((exp < 0) && (-exp < digits)) {
662: txt = txt.insert(txt.length() + exp, Text.valueOf('.'));
663: } else { // Scientific notation.
664: txt = txt.insert(txt.length() - digits + 1, Text
665: .valueOf('.'));
666: txt = txt.concat(Text.valueOf('E')).concat(
667: Text.valueOf(exp + digits - 1));
668: }
669: } else {
670: txt = txt.concat(Text.valueOf('E')).concat(
671: Text.valueOf(exp));
672: }
673: return txt;
674: }
675:
676: /**
677: * Compares this real number against the specified object.
678: *
679: * <p>Note: This method returns <code>true</code> if <code>this</code> or
680: * <code>that</code> {@link #isNaN is Not-A-Number}, even though
681: * <code>Double.NaN == Double.NaN</code> has the value
682: * <code>false</code>.</p>
683: *
684: * @param that the object to compare with.
685: * @return <code>true</code> if the objects are two reals with same
686: * significand, error and exponent;<code>false</code> otherwise.
687: */
688: public boolean equals(Object that) {
689: if (this == that)
690: return true;
691: if (!(that instanceof Real))
692: return false;
693: Real thatReal = (Real) that;
694: return this ._significand.equals(thatReal._significand)
695: && this ._error.equals(thatReal._error)
696: && (this ._exponent == thatReal._exponent);
697: }
698:
699: /**
700: * Returns the hash code for this real number.
701: *
702: * @return the hash code value.
703: */
704: public int hashCode() {
705: return _significand.hashCode() + _error.hashCode() + _exponent
706: * 31;
707: }
708:
709: /**
710: * Returns the value of this real number as a <code>long</code>.
711: *
712: * @return the numeric value represented by this real after conversion
713: * to type <code>long</code>.
714: */
715: public long longValue() {
716: return (long) doubleValue();
717: }
718:
719: /**
720: * Returns the value of this real number as a <code>double</code>.
721: *
722: * @return the numeric value represented by this real after conversion
723: * to type <code>double</code>.
724: */
725: public double doubleValue() {
726: if (this == NaN)
727: return Double.NaN;
728: if (this == ZERO)
729: return 0.0;
730: // Shift the significand to a >18 digits integer (long compatible).
731: int nbrDigits = _significand.digitLength();
732: int digitShift = nbrDigits - 18;
733: long reducedSignificand = _significand.times10pow(-digitShift)
734: .longValue();
735: int exponent = _exponent + digitShift;
736: return MathLib.toDoublePow10(reducedSignificand, exponent);
737: }
738:
739: /**
740: * Compares two real numbers numerically.
741: *
742: * @param that the real to compare with.
743: * @return -1, 0 or 1 as this real is numerically less than, equal to,
744: * or greater than <code>that</code>.
745: * @throws ClassCastException <code>that</code> is not a {@link Real}.
746: */
747: public int compareTo(Real that) {
748: Real diff = this .minus(that);
749: if (diff.isPositive()) {
750: return 1;
751: } else if (diff.isNegative()) {
752: return -1;
753: } else {
754: return 0;
755: }
756: }
757:
758: /**
759: * Normalizes this real (maintains error less than 31 bits).
760: *
761: * @return the normalized real.
762: */
763: private Real normalize() {
764: int digitError = this ._error.digitLength();
765: int scale = 9 - digitError;
766: if (scale >= 0)
767: return this ; // Small error.
768: Real z = FACTORY.object();
769: z._significand = _significand.times10pow(scale);
770: z._error = _error.times10pow(scale).plus(LargeInteger.ONE);
771: z._exponent = _exponent - scale;
772: return z;
773: }
774:
775: @Override
776: public Real copy() {
777: if (this == NaN)
778: return NaN; // Maintains unicity.
779: return Real.valueOf(_significand.copy(), getError(), _exponent);
780: }
781:
782: /**
783: * Holds the factory constructing real instances.
784: */
785: private static final ObjectFactory<Real> FACTORY = new ObjectFactory<Real>() {
786:
787: protected Real create() {
788: return new Real();
789: }
790: };
791:
792: private static final LargeInteger FIVE;
793:
794: private static final LargeInteger MINUS_FIVE;
795:
796: static { // Immortal memory allocation.
797: HeapContext.enter();
798: try {
799: ZERO = Real.valueOf(0);
800: ONE = Real.valueOf(1);
801: FIVE = LargeInteger.valueOf(5);
802: MINUS_FIVE = LargeInteger.valueOf(-5);
803: } finally {
804: HeapContext.exit();
805: }
806: }
807:
808: private static final long serialVersionUID = 1L;
809: }
|