001/**
002 * AbstractReal.java
003 * 
004 * Copyright (c) 2004-2012, Nicole C. Tedesco. All rights reserved.
005 * 
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007 * use this file except in compliance with the License. You may obtain a copy of
008 * the License at:
009 * 
010 * http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015 * License for the specific language governing permissions and limitations under
016 * the License.
017 */
018
019package net.sf.jaccumulator.reals;
020
021import java.math.BigDecimal;
022import java.math.BigInteger;
023import java.util.NoSuchElementException;
024
025import net.sf.jaccumulator.Domain;
026import net.sf.jaccumulator.scalars.AbstractScalar;
027import net.sf.jaccumulator.scalars.NumericPrecision;
028import net.sf.jaccumulator.scalars.SealedScalar;
029
030/**
031 * Common read and write behavior for any representation of {@link Domain#REAL
032 * real} numbers, either {@code boolean} vector, {@link BigDecimal unlimited}
033 * array representation or {@link String text}
034 * 
035 * @param <REAL>
036 *        this real type (used to facilitate operation chaining on write
037 *        operations)
038 * @since JAccumulator 4.0
039 * @author Nicole Tedesco (<a
040 *         href="mailto:Nicole@NicoleTedesco.com">Nicole@NicoleTedesco.com</a>)
041 */
042public abstract class AbstractReal<REAL extends Real<REAL>>
043    extends
044        AbstractScalar<REAL>
045    implements
046        Real<REAL>
047{
048    private static final long serialVersionUID = -4728750678453376439L;
049
050    public AbstractReal()
051    {
052        super();
053    }
054
055    public AbstractReal( final Domain aDomain, final NumericPrecision aPrecision )
056    {
057        super(aDomain, aPrecision);
058    }
059
060    public AbstractReal( final NumericPrecision aPrecision )
061    {
062        super(Domain.REAL, aPrecision);
063    }
064
065    @Override
066    public REAL and( final BigInteger aValue )
067        throws UnsupportedOperationException,
068            IllegalArgumentException,
069            ArithmeticException
070    {
071        return this.setReal(this.toUnlimitedInteger().and(aValue));
072    }
073
074    @Override
075    @SuppressWarnings( "unchecked" )
076    public REAL andOfNumber( final Number aNumber )
077        throws UnsupportedOperationException,
078            IllegalArgumentException,
079            ArithmeticException
080    {
081        final NumericPrecision myPrecision = this.getPrecision();
082        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
083        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
084        switch (prec) {
085        case NULL:
086            return (REAL)this; // this and aNumber are NULL
087        case BYTE:
088            return this.and(aNumber.byteValue());
089        case SHORT:
090            return this.and(aNumber.shortValue());
091        case INTEGER:
092            return this.and(aNumber.intValue());
093        case UNLIMITED_INTEGER:
094            try {
095                final BigInteger ui = (BigInteger)aNumber;
096                return this.and(ui);
097            } catch (final ClassCastException ex) {
098            }
099            break;
100        case UNLIMITED_DECIMAL:
101            try {
102                final BigDecimal ud = (BigDecimal)aNumber;
103                return this.and(ud.toBigInteger());
104            } catch (final ClassCastException ex) {
105            }
106            break;
107        }
108        return this.and(aNumber.longValue());
109    }
110
111    @Override
112    @SuppressWarnings( "unchecked" )
113    public REAL andOfReal( final SealedReal<?> aValue )
114        throws UnsupportedOperationException,
115            IllegalArgumentException,
116            ArithmeticException
117    {
118        final NumericPrecision myPrecision = this.getPrecision();
119        final NumericPrecision aPrecision = aValue.getPrecision();
120        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
121        switch (prec) {
122        case NULL:
123            return (REAL)this; // this and aNumber are NULL
124        case BIT:
125            return this.and(aValue.booleanValue());
126        case BYTE:
127            return this.and(aValue.byteValue());
128        case SHORT:
129            return this.and(aValue.shortValue());
130        case CHARACTER:
131            return this.and(aValue.charValue());
132        case INTEGER:
133            return this.and(aValue.intValue());
134        case UNLIMITED_INTEGER:
135            return this.and(aValue.toUnlimitedInteger());
136        }
137        return this.and(aValue.longValue());
138    }
139
140    @Override
141    public REAL angleWithReal( final SealedReal<?> aValue )
142        throws UnsupportedOperationException,
143            IllegalArgumentException,
144            ArithmeticException
145    {
146        return this.angleWith(aValue.doubleValue());
147    }
148
149    @Override
150    public int compareToNumber( final Number aValue ) {
151        final NumericPrecision myPrecision = this.getPrecision();
152        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
153        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
154        switch (prec) {
155        case NULL:
156            return this.compareToZero();
157        case BIT:
158        case BYTE:
159            return compareTo(this.byteValue(), aValue.byteValue());
160        case SHORT:
161            return compareTo(this.shortValue(), aValue.shortValue());
162        case CHARACTER:
163        case INTEGER:
164            return compareTo(this.intValue(), aValue.intValue());
165        case LONG:
166            return compareTo(this.longValue(), aValue.longValue());
167        case FLOAT:
168            return compareTo(this.floatValue(), aValue.floatValue());
169        case UNLIMITED_DECIMAL:
170            try {
171                final BigDecimal ud = (BigDecimal)aValue;
172                return this.compareToReal(ud);
173            } catch (final ClassCastException ex) {
174            }
175            break;
176        case UNLIMITED_INTEGER:
177            try {
178                final BigInteger ui = (BigInteger)aValue;
179                return this.compareToReal(ui);
180            } catch (final ClassCastException ex) {
181            }
182            break;
183        }
184        return compareTo(this.doubleValue(), aValue.doubleValue());
185    }
186
187    @Override
188    public int compareToReal( final BigDecimal aReal ) {
189        return this.toUnlimitedDecimal().compareTo(aReal);
190    }
191
192    @Override
193    public int compareToReal( final BigInteger aReal ) {
194        return this.toUnlimitedInteger().compareTo(aReal);
195    }
196
197    @Override
198    public int compareToReal( final SealedReal<?> aValue ) {
199        final NumericPrecision myPrecision = this.getPrecision();
200        final NumericPrecision aPrecision = aValue.getPrecision();
201        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
202        switch (prec) {
203        case NULL:
204            return this.compareToZero();
205        case BIT:
206            return this.compareToScalar(aValue.booleanValue());
207        case BYTE:
208            return this.compareToScalar(aValue.byteValue());
209        case SHORT:
210            return this.compareToScalar(aValue.shortValue());
211        case CHARACTER:
212            return this.compareToScalar(aValue.charValue());
213        case INTEGER:
214            return this.compareToScalar(aValue.intValue());
215        case LONG:
216            return this.compareToScalar(aValue.longValue());
217        case FLOAT:
218            return this.compareToScalar(aValue.floatValue());
219        case UNLIMITED_INTEGER:
220            return this.compareToReal(aValue.toUnlimitedInteger());
221        case UNLIMITED_DECIMAL:
222            return this.compareToReal(aValue.toUnlimitedDecimal());
223        }
224        return this.compareToScalar(aValue.doubleValue());
225    }
226
227    @Override
228    public REAL difference( final BigDecimal aValue )
229        throws UnsupportedOperationException,
230            IllegalArgumentException,
231            ArithmeticException
232    {
233        return this.setReal(this.toUnlimitedDecimal().subtract(aValue));
234    }
235
236    @Override
237    public REAL difference( final BigInteger aValue )
238        throws UnsupportedOperationException,
239            IllegalArgumentException,
240            ArithmeticException
241    {
242        return this.setReal(this.toUnlimitedInteger().subtract(aValue));
243    }
244
245    @SuppressWarnings( "unchecked" )
246    @Override
247    public REAL differenceOfNumber( final Number aValue )
248        throws UnsupportedOperationException,
249            IllegalArgumentException,
250            ArithmeticException
251    {
252        final NumericPrecision myPrecision = this.getPrecision();
253        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
254        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
255        switch (prec) {
256        case NULL:
257            return (REAL)this;
258        case BYTE:
259            return this.difference(aValue.byteValue());
260        case SHORT:
261            return this.difference(aValue.shortValue());
262        case INTEGER:
263            return this.difference(aValue.intValue());
264        case LONG:
265            return this.difference(aValue.longValue());
266        case FLOAT:
267            return this.difference(aValue.floatValue());
268        case UNLIMITED_DECIMAL:
269            try {
270                final BigDecimal ud = (BigDecimal)aValue;
271                return this.difference(ud);
272            } catch (final ClassCastException ex) {
273            }
274            break;
275        case UNLIMITED_INTEGER:
276            try {
277                final BigInteger ui = (BigInteger)aValue;
278                return this.difference(ui);
279            } catch (final ClassCastException ex) {
280            }
281            break;
282        }
283        return this.difference(aValue.doubleValue());
284    }
285
286    @Override
287    @SuppressWarnings( "unchecked" )
288    public REAL differenceOfReal( final SealedReal<?> aValue )
289        throws UnsupportedOperationException,
290            IllegalArgumentException,
291            ArithmeticException
292    {
293        final NumericPrecision myPrecision = this.getPrecision();
294        final NumericPrecision aPrecision = aValue.getPrecision();
295        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
296        switch (prec) {
297        case NULL:
298            return (REAL)this;
299        case BIT:
300            return this.difference(aValue.booleanValue());
301        case BYTE:
302            return this.difference(aValue.byteValue());
303        case SHORT:
304            return this.difference(aValue.shortValue());
305        case CHARACTER:
306            return this.difference(aValue.charValue());
307        case INTEGER:
308            return this.difference(aValue.intValue());
309        case LONG:
310            return this.difference(aValue.longValue());
311        case FLOAT:
312            return this.difference(aValue.floatValue());
313        case UNLIMITED_INTEGER:
314            return this.difference(aValue.toUnlimitedInteger());
315        case UNLIMITED_DECIMAL:
316            return this.difference(aValue.toUnlimitedDecimal());
317        }
318        return this.difference(aValue.doubleValue());
319    }
320
321    @Override
322    public boolean equals( final Object anObject ) {
323        if (anObject == this) return true;
324        if (anObject instanceof SealedReal<?>) {
325            final SealedReal<?> aReal = (SealedReal<?>)anObject;
326            return this.isEqualToReal(aReal);
327        }
328        if (anObject instanceof SealedScalar<?>) {
329            final SealedScalar<?> aScalar = (SealedScalar<?>)anObject;
330            return this.isEqualToScalar(aScalar);
331        }
332        return this.toString().equals(anObject.toString());
333    }
334
335    @Override
336    public REAL gcd( final BigInteger aValue )
337        throws UnsupportedOperationException,
338            ArithmeticException,
339            IllegalArgumentException
340    {
341        return this.setReal(this.toUnlimitedInteger().gcd(aValue));
342    }
343
344    @Override
345    public REAL gcdOfNumber( final Number aNumber )
346        throws UnsupportedOperationException,
347            IllegalArgumentException,
348            ArithmeticException
349    {
350        final NumericPrecision myPrecision = this.getPrecision();
351        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
352        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
353        switch (prec) {
354        case NULL:
355            return this.gcd(0);
356        case BYTE:
357            return this.gcd(aNumber.byteValue());
358        case SHORT:
359            return this.gcd(aNumber.shortValue());
360        case INTEGER:
361            return this.gcd(aNumber.intValue());
362        case UNLIMITED_INTEGER:
363            try {
364                final BigInteger ui = (BigInteger)aNumber;
365                return this.gcd(ui);
366            } catch (final ClassCastException ex) {
367            }
368            break;
369        case UNLIMITED_DECIMAL:
370            try {
371                final BigDecimal ud = (BigDecimal)aNumber;
372                return this.gcd(ud.toBigInteger());
373            } catch (final ClassCastException ex) {
374            }
375            break;
376        }
377        return this.gcd(aNumber.longValue());
378    }
379
380    @Override
381    public final REAL gcdOfReal( final Real<?> aValue )
382        throws UnsupportedOperationException,
383            ArithmeticException,
384            IllegalArgumentException
385    {
386        final NumericPrecision myPrecision = this.getPrecision();
387        final NumericPrecision aPrecision = aValue.getPrecision();
388        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
389        switch (prec) {
390        case NULL:
391            return this.gcd(0);
392        case BIT:
393        case BYTE:
394            return this.gcd(aValue.byteValue());
395        case SHORT:
396            return this.gcd(aValue.shortValue());
397        case CHARACTER:
398            return this.gcd(aValue.charValue());
399        case INTEGER:
400            return this.gcd(aValue.intValue());
401        case UNLIMITED_INTEGER:
402            return this.gcd(aValue.toUnlimitedInteger());
403        }
404        return this.gcd(aValue.longValue());
405    }
406
407    @Override
408    public final REAL hypotenuseWithReal( final SealedReal<?> aValue )
409        throws UnsupportedOperationException,
410            IllegalArgumentException,
411            ArithmeticException
412    {
413        return this.hypotenuseWith(aValue.doubleValue());
414    }
415
416    @Override
417    @SuppressWarnings( "unchecked" )
418    public <R extends Real<?>> R induceRealSize( final R aTarget )
419        throws NullPointerException,
420            NoSuchElementException,
421            UnsupportedOperationException,
422            IllegalStateException
423    {
424        return (R)aTarget.setScalar(this.size());
425    }
426
427    @Override
428    public boolean isEqual( final BigDecimal aReal ) {
429        return this.compareToReal(aReal) == 0;
430    }
431
432    @Override
433    public boolean isEqual( final BigInteger aReal ) {
434        return this.toUnlimitedInteger().equals(aReal);
435    }
436
437    @Override
438    public boolean isEqualToNumber( final Number aNumber ) {
439        final NumericPrecision myPrecision = this.getPrecision();
440        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
441        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
442        switch (prec) {
443        case NULL:
444            return this.isZero();
445        case BYTE:
446            return this.isEqual(aNumber.byteValue());
447        case SHORT:
448            return this.isEqual(aNumber.shortValue());
449        case INTEGER:
450            return this.isEqual(aNumber.intValue());
451        case LONG:
452            return this.isEqual(aNumber.longValue());
453        case FLOAT:
454            return this.isEqual(aNumber.floatValue());
455        case UNLIMITED_INTEGER:
456            try {
457                final BigInteger ui = (BigInteger)aNumber;
458                return this.isEqual(ui);
459            } catch (final ClassCastException ex) {
460            }
461            break;
462        case UNLIMITED_DECIMAL:
463            try {
464                final BigDecimal ud = (BigDecimal)aNumber;
465                return this.isEqual(ud);
466            } catch (final ClassCastException ex) {
467            }
468            break;
469        }
470        return this.isEqual(aNumber.doubleValue());
471    }
472
473    @Override
474    public boolean isEqualToReal( final SealedReal<?> aValue ) {
475        final NumericPrecision myPrecision = this.getPrecision();
476        final NumericPrecision aPrecision = aValue.getPrecision();
477        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
478        switch (prec) {
479        case NULL:
480            return this.isZero();
481        case BIT:
482            return this.isEqual(aValue.booleanValue());
483        case BYTE:
484            return this.isEqual(aValue.byteValue());
485        case SHORT:
486            return this.isEqual(aValue.shortValue());
487        case CHARACTER:
488            return this.isEqual(aValue.charValue());
489        case INTEGER:
490            return this.isEqual(aValue.intValue());
491        case LONG:
492            return this.isEqual(aValue.longValue());
493        case FLOAT:
494            return this.isEqual(aValue.floatValue());
495        case UNLIMITED_INTEGER:
496            return this.isEqual(aValue.toUnlimitedInteger());
497        case UNLIMITED_DECIMAL:
498            return this.isEqual(aValue.toUnlimitedDecimal());
499        }
500        return this.isEqual(aValue.doubleValue());
501    }
502
503    @Override
504    public boolean isGreater( final BigDecimal aReal ) {
505        return 0 < this.compareToReal(aReal);
506    }
507
508    @Override
509    public boolean isGreater( final BigInteger aReal ) {
510        return 0 < this.compareToReal(aReal);
511    }
512
513    @Override
514    public boolean isGreaterOrEqual( final BigDecimal aReal ) {
515        return 0 <= this.compareToReal(aReal);
516    }
517
518    @Override
519    public boolean isGreaterOrEqual( final BigInteger aReal ) {
520        return 0 <= this.compareToReal(aReal);
521    }
522
523    @Override
524    public boolean isGreaterOrEqualToNumber( final Number aNumber ) {
525        final NumericPrecision myPrecision = this.getPrecision();
526        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
527        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
528        switch (prec) {
529        case NULL:
530            return !this.isNegative();
531        case BYTE:
532            return this.isGreaterOrEqual(aNumber.byteValue());
533        case SHORT:
534            return this.isGreaterOrEqual(aNumber.shortValue());
535        case INTEGER:
536            return this.isGreaterOrEqual(aNumber.intValue());
537        case LONG:
538            return this.isGreaterOrEqual(aNumber.longValue());
539        case FLOAT:
540            return this.isGreaterOrEqual(aNumber.floatValue());
541        case UNLIMITED_INTEGER:
542            try {
543                final BigInteger ui = (BigInteger)aNumber;
544                return this.isGreaterOrEqual(ui);
545            } catch (final ClassCastException ex) {
546            }
547            break;
548        case UNLIMITED_DECIMAL:
549            try {
550                final BigDecimal ud = (BigDecimal)aNumber;
551                return this.isGreaterOrEqual(ud);
552            } catch (final ClassCastException ex) {
553            }
554            break;
555        }
556        return this.isGreaterOrEqual(aNumber.doubleValue());
557    }
558
559    @Override
560    public boolean isGreaterOrEqualToReal( final SealedReal<?> aValue ) {
561        final NumericPrecision myPrecision = this.getPrecision();
562        final NumericPrecision aPrecision = aValue.getPrecision();
563        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
564        switch (prec) {
565        case NULL:
566            return !this.isNegative();
567        case BIT:
568            return this.isGreaterOrEqual(aValue.booleanValue());
569        case BYTE:
570            return this.isGreaterOrEqual(aValue.byteValue());
571        case SHORT:
572            return this.isGreaterOrEqual(aValue.shortValue());
573        case CHARACTER:
574            return this.isGreaterOrEqual(aValue.charValue());
575        case INTEGER:
576            return this.isGreaterOrEqual(aValue.intValue());
577        case LONG:
578            return this.isGreaterOrEqual(aValue.longValue());
579        case FLOAT:
580            return this.isGreaterOrEqual(aValue.floatValue());
581        case UNLIMITED_INTEGER:
582            return this.isGreaterOrEqual(aValue.toUnlimitedInteger());
583        case UNLIMITED_DECIMAL:
584            return this.isGreaterOrEqual(aValue.toUnlimitedDecimal());
585        }
586        return this.isGreaterOrEqual(aValue.doubleValue());
587    }
588
589    @Override
590    public boolean isGreaterThanNumber( final Number aNumber ) {
591        final NumericPrecision myPrecision = this.getPrecision();
592        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
593        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
594        switch (prec) {
595        case NULL:
596            return this.isPositive();
597        case BYTE:
598            return this.isGreater(aNumber.byteValue());
599        case SHORT:
600            return this.isGreater(aNumber.shortValue());
601        case INTEGER:
602            return this.isGreater(aNumber.intValue());
603        case LONG:
604            return this.isGreater(aNumber.longValue());
605        case FLOAT:
606            return this.isGreater(aNumber.floatValue());
607        case UNLIMITED_INTEGER:
608            try {
609                final BigInteger ui = (BigInteger)aNumber;
610                return this.isGreater(ui);
611            } catch (final ClassCastException ex) {
612            }
613            break;
614        case UNLIMITED_DECIMAL:
615            try {
616                final BigDecimal ud = (BigDecimal)aNumber;
617                return this.isGreater(ud);
618            } catch (final ClassCastException ex) {
619            }
620            break;
621        }
622        return this.isGreater(aNumber.doubleValue());
623    }
624
625    @Override
626    public boolean isGreaterThanReal( final SealedReal<?> aValue ) {
627        final NumericPrecision myPrecision = this.getPrecision();
628        final NumericPrecision aPrecision = aValue.getPrecision();
629        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
630        switch (prec) {
631        case NULL:
632            return this.isPositive();
633        case BIT:
634            return this.isGreater(aValue.booleanValue());
635        case BYTE:
636            return this.isGreater(aValue.byteValue());
637        case SHORT:
638            return this.isGreater(aValue.shortValue());
639        case CHARACTER:
640            return this.isGreater(aValue.charValue());
641        case INTEGER:
642            return this.isGreater(aValue.intValue());
643        case LONG:
644            return this.isGreater(aValue.longValue());
645        case FLOAT:
646            return this.isGreater(aValue.floatValue());
647        case UNLIMITED_INTEGER:
648            return this.isGreater(aValue.toUnlimitedInteger());
649        case UNLIMITED_DECIMAL:
650            return this.isGreater(aValue.toUnlimitedDecimal());
651        }
652        return this.isGreater(aValue.doubleValue());
653    }
654
655    @Override
656    public boolean isLess( final BigDecimal aReal ) {
657        return this.compareToReal(aReal) < 0;
658    }
659
660    @Override
661    public boolean isLess( final BigInteger aReal ) {
662        return this.compareToReal(aReal) < 0;
663    }
664
665    @Override
666    public boolean isLessOrEqual( final BigDecimal aReal ) {
667        return this.compareToReal(aReal) <= 0;
668    }
669
670    @Override
671    public boolean isLessOrEqual( final BigInteger aReal ) {
672        return this.compareToReal(aReal) <= 0;
673    }
674
675    @Override
676    public boolean isLessOrEqualToNumber( final Number aNumber ) {
677        final NumericPrecision myPrecision = this.getPrecision();
678        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
679        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
680        switch (prec) {
681        case NULL:
682            return !this.isPositive();
683        case BYTE:
684            return this.isLessOrEqual(aNumber.byteValue());
685        case SHORT:
686            return this.isLessOrEqual(aNumber.shortValue());
687        case INTEGER:
688            return this.isLessOrEqual(aNumber.intValue());
689        case LONG:
690            return this.isLessOrEqual(aNumber.longValue());
691        case FLOAT:
692            return this.isLessOrEqual(aNumber.floatValue());
693        case UNLIMITED_INTEGER:
694            try {
695                final BigInteger ui = (BigInteger)aNumber;
696                return this.isLessOrEqual(ui);
697            } catch (final ClassCastException ex) {
698            }
699            break;
700        case UNLIMITED_DECIMAL:
701            try {
702                final BigDecimal ud = (BigDecimal)aNumber;
703                return this.isLessOrEqual(ud);
704            } catch (final ClassCastException ex) {
705            }
706            break;
707        }
708        return this.isLessOrEqual(aNumber.doubleValue());
709    }
710
711    @Override
712    public boolean isLessOrEqualToReal( final SealedReal<?> aValue ) {
713        final NumericPrecision myPrecision = this.getPrecision();
714        final NumericPrecision aPrecision = aValue.getPrecision();
715        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
716        switch (prec) {
717        case NULL:
718            return !this.isPositive();
719        case BIT:
720            return this.isLessOrEqual(aValue.booleanValue());
721        case BYTE:
722            return this.isLessOrEqual(aValue.byteValue());
723        case SHORT:
724            return this.isLessOrEqual(aValue.shortValue());
725        case CHARACTER:
726            return this.isLessOrEqual(aValue.charValue());
727        case INTEGER:
728            return this.isLessOrEqual(aValue.intValue());
729        case LONG:
730            return this.isLessOrEqual(aValue.longValue());
731        case FLOAT:
732            return this.isLessOrEqual(aValue.floatValue());
733        case UNLIMITED_INTEGER:
734            return this.isLessOrEqual(aValue.toUnlimitedInteger());
735        case UNLIMITED_DECIMAL:
736            return this.isLessOrEqual(aValue.toUnlimitedDecimal());
737        }
738        return this.isLessOrEqual(aValue.doubleValue());
739    }
740
741    @Override
742    public boolean isLessThanNumber( final Number aNumber ) {
743        final NumericPrecision myPrecision = this.getPrecision();
744        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
745        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
746        switch (prec) {
747        case NULL:
748            return this.isNegative();
749        case BYTE:
750            return this.isLess(aNumber.byteValue());
751        case SHORT:
752            return this.isLess(aNumber.shortValue());
753        case INTEGER:
754            return this.isLess(aNumber.intValue());
755        case LONG:
756            return this.isLess(aNumber.longValue());
757        case FLOAT:
758            return this.isLess(aNumber.floatValue());
759        case UNLIMITED_INTEGER:
760            try {
761                final BigInteger ui = (BigInteger)aNumber;
762                return this.isLess(ui);
763            } catch (final ClassCastException ex) {
764            }
765            break;
766        case UNLIMITED_DECIMAL:
767            try {
768                final BigDecimal ud = (BigDecimal)aNumber;
769                return this.isLess(ud);
770            } catch (final ClassCastException ex) {
771            }
772            break;
773        }
774        return this.isLess(aNumber.doubleValue());
775    }
776
777    @Override
778    public boolean isLessThanReal( final SealedReal<?> aValue ) {
779        final NumericPrecision myPrecision = this.getPrecision();
780        final NumericPrecision aPrecision = aValue.getPrecision();
781        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
782        switch (prec) {
783        case NULL:
784            return this.isNegative();
785        case BIT:
786            return this.isLess(aValue.booleanValue());
787        case BYTE:
788            return this.isLess(aValue.byteValue());
789        case SHORT:
790            return this.isLess(aValue.shortValue());
791        case CHARACTER:
792            return this.isLess(aValue.charValue());
793        case INTEGER:
794            return this.isLess(aValue.intValue());
795        case LONG:
796            return this.isLess(aValue.longValue());
797        case FLOAT:
798            return this.isLess(aValue.floatValue());
799        case UNLIMITED_INTEGER:
800            return this.isLess(aValue.toUnlimitedInteger());
801        case UNLIMITED_DECIMAL:
802            return this.isLess(aValue.toUnlimitedDecimal());
803        }
804        return this.isLess(aValue.doubleValue());
805    }
806
807    @Override
808    public boolean isNotEqual( final BigDecimal aReal ) {
809        return this.compareToReal(aReal) != 0;
810    }
811
812    @Override
813    public boolean isNotEqual( final BigInteger aReal ) {
814        return this.compareToReal(aReal) != 0;
815    }
816
817    @Override
818    public boolean isNotEqualToNumber( final Number aNumber ) {
819        final NumericPrecision myPrecision = this.getPrecision();
820        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
821        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
822        switch (prec) {
823        case NULL:
824            return !this.isZero();
825        case BYTE:
826            return this.isNotEqual(aNumber.byteValue());
827        case SHORT:
828            return this.isNotEqual(aNumber.shortValue());
829        case INTEGER:
830            return this.isNotEqual(aNumber.intValue());
831        case LONG:
832            return this.isNotEqual(aNumber.longValue());
833        case FLOAT:
834            return this.isNotEqual(aNumber.floatValue());
835        case UNLIMITED_DECIMAL:
836            try {
837                final BigDecimal ud = (BigDecimal)aNumber;
838                return this.isNotEqual(ud);
839            } catch (final ClassCastException ex) {
840            }
841        case UNLIMITED_INTEGER:
842            try {
843                final BigInteger ui = (BigInteger)aNumber;
844                return this.isNotEqual(ui);
845            } catch (final ClassCastException ex) {
846            }
847        }
848        return this.isNotEqual(aNumber.doubleValue());
849    }
850
851    @Override
852    public boolean isNotEqualToReal( final SealedReal<?> aValue ) {
853        final NumericPrecision myPrecision = this.getPrecision();
854        final NumericPrecision aPrecision = aValue.getPrecision();
855        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
856        switch (prec) {
857        case NULL:
858            return !this.isZero();
859        case BIT:
860            return this.isNotEqual(aValue.booleanValue());
861        case BYTE:
862            return this.isNotEqual(aValue.byteValue());
863        case SHORT:
864            return this.isNotEqual(aValue.shortValue());
865        case CHARACTER:
866            return this.isNotEqual(aValue.charValue());
867        case INTEGER:
868            return this.isNotEqual(aValue.intValue());
869        case LONG:
870            return this.isNotEqual(aValue.longValue());
871        case FLOAT:
872            return this.isNotEqual(aValue.floatValue());
873        case UNLIMITED_INTEGER:
874            return this.isNotEqual(aValue.toUnlimitedInteger());
875        case UNLIMITED_DECIMAL:
876            return this.isNotEqual(aValue.toUnlimitedDecimal());
877        }
878        return this.isNotEqual(aValue.doubleValue());
879    }
880
881    @Override
882    public REAL mod( final BigDecimal aValue )
883        throws UnsupportedOperationException,
884            IllegalArgumentException,
885            ArithmeticException
886    {
887        final BigDecimal ud[] = this.toUnlimitedDecimal().divideAndRemainder(
888            aValue);
889        return this.setReal(ud[1]);
890    }
891
892    @Override
893    public REAL mod( final BigInteger aValue )
894        throws UnsupportedOperationException,
895            IllegalArgumentException,
896            ArithmeticException
897    {
898        return this.setReal(this.toUnlimitedInteger().mod(aValue));
899    }
900
901    @Override
902    public REAL modOfNumber( final Number aValue )
903        throws UnsupportedOperationException,
904            IllegalArgumentException,
905            ArithmeticException
906    {
907        final NumericPrecision myPrecision = this.getPrecision();
908        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
909        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
910        switch (prec) {
911        case NULL:
912            return this.mod(0);
913        case BYTE:
914            return this.mod(aValue.byteValue());
915        case SHORT:
916            return this.mod(aValue.shortValue());
917        case INTEGER:
918            return this.mod(aValue.intValue());
919        case LONG:
920            return this.mod(aValue.longValue());
921        case FLOAT:
922            return this.mod(aValue.floatValue());
923        case UNLIMITED_DECIMAL:
924            try {
925                final BigDecimal ud = (BigDecimal)aValue;
926                return this.mod(ud);
927            } catch (final ClassCastException ex) {
928            }
929            break;
930        case UNLIMITED_INTEGER:
931            try {
932                final BigInteger ui = (BigInteger)aValue;
933                return this.mod(ui);
934            } catch (final ClassCastException ex) {
935            }
936            break;
937        }
938        return this.mod(aValue.doubleValue());
939    }
940
941    @Override
942    public REAL modOfReal( final SealedReal<?> aValue )
943        throws UnsupportedOperationException,
944            IllegalArgumentException,
945            ArithmeticException
946    {
947        final NumericPrecision myPrecision = this.getPrecision();
948        final NumericPrecision aPrecision = aValue.getPrecision();
949        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
950        switch (prec) {
951        case NULL:
952            return this.mod(0);
953        case BIT:
954            return this.mod(aValue.booleanValue());
955        case BYTE:
956            return this.mod(aValue.byteValue());
957        case SHORT:
958            return this.mod(aValue.shortValue());
959        case CHARACTER:
960            return this.mod(aValue.charValue());
961        case INTEGER:
962            return this.mod(aValue.intValue());
963        case LONG:
964            return this.mod(aValue.longValue());
965        case FLOAT:
966            return this.mod(aValue.floatValue());
967        case UNLIMITED_INTEGER:
968            return this.mod(aValue.toUnlimitedInteger());
969        case UNLIMITED_DECIMAL:
970            return this.mod(aValue.toUnlimitedDecimal());
971        }
972        return this.mod(aValue.doubleValue());
973    }
974
975    @Override
976    public REAL or( final BigInteger aValue )
977        throws UnsupportedOperationException,
978            IllegalArgumentException,
979            ArithmeticException
980    {
981        return this.setReal(this.toUnlimitedInteger().or(aValue));
982    }
983
984    @Override
985    @SuppressWarnings( "unchecked" )
986    public REAL orOfNumber( final Number aValue )
987        throws UnsupportedOperationException,
988            IllegalArgumentException,
989            ArithmeticException
990    {
991        final NumericPrecision myPrecision = this.getPrecision();
992        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
993        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
994        switch (prec) {
995        case NULL:
996            return (REAL)this;
997        case BYTE:
998            return this.or(aValue.byteValue());
999        case SHORT:
1000            return this.or(aValue.shortValue());
1001        case INTEGER:
1002            return this.or(aValue.intValue());
1003        case UNLIMITED_INTEGER:
1004            try {
1005                final BigInteger ui = (BigInteger)aValue;
1006                return this.or(ui);
1007            } catch (final ClassCastException ex) {
1008            }
1009            break;
1010        case UNLIMITED_DECIMAL:
1011            try {
1012                final BigDecimal ud = (BigDecimal)aValue;
1013                return this.or(ud.toBigInteger());
1014            } catch (final ClassCastException ex) {
1015            }
1016            break;
1017        }
1018        return this.or(aValue.longValue());
1019    }
1020
1021    @Override
1022    @SuppressWarnings( "unchecked" )
1023    public REAL orOfReal( final SealedReal<?> aValue )
1024        throws UnsupportedOperationException,
1025            IllegalArgumentException,
1026            ArithmeticException
1027    {
1028        final NumericPrecision myPrecision = this.getPrecision();
1029        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1030        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1031        switch (prec) {
1032        case NULL:
1033            return (REAL)this;
1034        case BIT:
1035            return this.or(aValue.booleanValue());
1036        case BYTE:
1037            return this.or(aValue.byteValue());
1038        case SHORT:
1039            return this.or(aValue.shortValue());
1040        case CHARACTER:
1041            return this.or(aValue.charValue());
1042        case INTEGER:
1043            return this.or(aValue.intValue());
1044        case UNLIMITED_DECIMAL:
1045        case UNLIMITED_INTEGER:
1046            return this.or(aValue.toUnlimitedInteger());
1047        }
1048        return this.or(aValue.longValue());
1049    }
1050
1051    @Override
1052    public REAL powerOfReal( final SealedReal<?> aValue )
1053        throws UnsupportedOperationException,
1054            IllegalArgumentException,
1055            ArithmeticException
1056    {
1057        return this.powerOfScalar(aValue);
1058    }
1059
1060    @Override
1061    public REAL product( final BigDecimal aValue )
1062        throws UnsupportedOperationException,
1063            IllegalArgumentException,
1064            ArithmeticException
1065    {
1066        return this.setReal(this.toUnlimitedDecimal().multiply(aValue));
1067    }
1068
1069    @Override
1070    public REAL product( final BigInteger aValue )
1071        throws UnsupportedOperationException,
1072            IllegalArgumentException,
1073            ArithmeticException
1074    {
1075        return this.setReal(this.toUnlimitedInteger().multiply(aValue));
1076    }
1077
1078    @Override
1079    public REAL productOfNumber( final Number aValue )
1080        throws UnsupportedOperationException,
1081            IllegalArgumentException,
1082            ArithmeticException
1083    {
1084        final NumericPrecision myPrecision = this.getPrecision();
1085        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1086        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1087        switch (prec) {
1088        case NULL:
1089            return this.setZero();
1090        case BYTE:
1091            return this.product(aValue.byteValue());
1092        case SHORT:
1093            return this.product(aValue.shortValue());
1094        case INTEGER:
1095            return this.product(aValue.intValue());
1096        case LONG:
1097            return this.product(aValue.longValue());
1098        case FLOAT:
1099            return this.product(aValue.floatValue());
1100        case UNLIMITED_DECIMAL:
1101            try {
1102                final BigDecimal ud = (BigDecimal)aValue;
1103                return this.product(ud);
1104            } catch (final ClassCastException ex) {
1105            }
1106            break;
1107        case UNLIMITED_INTEGER:
1108            try {
1109                final BigInteger ui = (BigInteger)aValue;
1110                return this.product(ui);
1111            } catch (final ClassCastException ex) {
1112            }
1113            break;
1114        }
1115        return this.product(aValue.doubleValue());
1116    }
1117
1118    @Override
1119    public REAL productOfReal( final SealedReal<?> aValue )
1120        throws UnsupportedOperationException,
1121            IllegalArgumentException,
1122            ArithmeticException
1123    {
1124        final NumericPrecision myPrecision = this.getPrecision();
1125        final NumericPrecision aPrecision = aValue.getPrecision();
1126        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1127        switch (prec) {
1128        case NULL:
1129            return this.setZero();
1130        case BIT:
1131            return this.product(aValue.booleanValue());
1132        case BYTE:
1133            return this.product(aValue.byteValue());
1134        case SHORT:
1135            return this.product(aValue.shortValue());
1136        case CHARACTER:
1137            return this.product(aValue.charValue());
1138        case INTEGER:
1139            return this.product(aValue.intValue());
1140        case LONG:
1141            return this.product(aValue.longValue());
1142        case FLOAT:
1143            return this.product(aValue.floatValue());
1144        case UNLIMITED_INTEGER:
1145            return this.product(aValue.toUnlimitedInteger());
1146        case UNLIMITED_DECIMAL:
1147            return this.product(aValue.toUnlimitedDecimal());
1148        }
1149        return this.product(aValue.doubleValue());
1150    }
1151
1152    @Override
1153    public REAL quotient( final BigDecimal aValue )
1154        throws UnsupportedOperationException,
1155            IllegalArgumentException,
1156            ArithmeticException
1157    {
1158        return this.setReal(this.toUnlimitedDecimal().divide(aValue));
1159    }
1160
1161    @Override
1162    public REAL quotient( final BigInteger aValue )
1163        throws UnsupportedOperationException,
1164            IllegalArgumentException,
1165            ArithmeticException
1166    {
1167        return this.setReal(this.toUnlimitedInteger().divide(aValue));
1168    }
1169
1170    @Override
1171    public REAL quotientOfNumber( final Number aValue )
1172        throws UnsupportedOperationException,
1173            IllegalArgumentException,
1174            ArithmeticException
1175    {
1176        final NumericPrecision myPrecision = this.getPrecision();
1177        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1178        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1179        switch (prec) {
1180        case NULL:
1181            return this.quotient(0);
1182        case BYTE:
1183            return this.quotient(aValue.byteValue());
1184        case SHORT:
1185            return this.quotient(aValue.shortValue());
1186        case INTEGER:
1187            return this.quotient(aValue.intValue());
1188        case LONG:
1189            return this.quotient(aValue.longValue());
1190        case FLOAT:
1191            return this.quotient(aValue.floatValue());
1192        case UNLIMITED_DECIMAL:
1193            try {
1194                final BigDecimal ud = (BigDecimal)aValue;
1195                return this.quotient(ud);
1196            } catch (final ClassCastException ex) {
1197            }
1198            break;
1199        case UNLIMITED_INTEGER:
1200            try {
1201                final BigInteger ui = (BigInteger)aValue;
1202                return this.quotient(ui);
1203            } catch (final ClassCastException ex) {
1204            }
1205            break;
1206        }
1207        return this.quotient(aValue.doubleValue());
1208    }
1209
1210    @Override
1211    public REAL quotientOfReal( final SealedReal<?> aValue )
1212        throws UnsupportedOperationException,
1213            IllegalArgumentException,
1214            ArithmeticException
1215    {
1216        final NumericPrecision myPrecision = this.getPrecision();
1217        final NumericPrecision aPrecision = aValue.getPrecision();
1218        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1219        switch (prec) {
1220        case NULL:
1221            return this.quotient(0);
1222        case BIT:
1223            return this.quotient(aValue.booleanValue());
1224        case BYTE:
1225            return this.quotient(aValue.byteValue());
1226        case SHORT:
1227            return this.quotient(aValue.shortValue());
1228        case CHARACTER:
1229            return this.quotient(aValue.charValue());
1230        case INTEGER:
1231            return this.quotient(aValue.intValue());
1232        case LONG:
1233            return this.quotient(aValue.longValue());
1234        case FLOAT:
1235            return this.quotient(aValue.floatValue());
1236        case UNLIMITED_INTEGER:
1237            return this.quotient(aValue.toUnlimitedInteger());
1238        case UNLIMITED_DECIMAL:
1239            return this.quotient(aValue.toUnlimitedDecimal());
1240        }
1241        return this.quotient(aValue.doubleValue());
1242    }
1243
1244    @Override
1245    public REAL setNumber( final Number aValue )
1246        throws UnsupportedOperationException,
1247            IllegalArgumentException,
1248            ArithmeticException,
1249            NullPointerException
1250    {
1251        final NumericPrecision myPrecision = this.getPrecision();
1252        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1253        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1254        switch (prec) {
1255        case NULL:
1256            return this.setZero();
1257        case BYTE:
1258            return this.setScalar(aValue.byteValue());
1259        case SHORT:
1260            return this.setScalar(aValue.shortValue());
1261        case INTEGER:
1262            return this.setScalar(aValue.intValue());
1263        case LONG:
1264            return this.setScalar(aValue.longValue());
1265        case FLOAT:
1266            return this.setScalar(aValue.floatValue());
1267        case UNLIMITED_DECIMAL:
1268            try {
1269                final BigDecimal ud = (BigDecimal)aValue;
1270                return this.setReal(ud);
1271            } catch (final ClassCastException ex) {
1272            }
1273        case UNLIMITED_INTEGER:
1274            try {
1275                final BigInteger ui = (BigInteger)aValue;
1276                return this.setReal(ui);
1277            } catch (final ClassCastException ex) {
1278            }
1279        }
1280        return this.setScalar(aValue.doubleValue());
1281    }
1282
1283    @Override
1284    public REAL setReal( final SealedReal<?> aValue )
1285        throws UnsupportedOperationException,
1286            IllegalArgumentException,
1287            ArithmeticException,
1288            NullPointerException
1289    {
1290        final NumericPrecision myPrecision = this.getPrecision();
1291        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1292        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1293        switch (prec) {
1294        case NULL:
1295            return this.setZero();
1296        case BIT:
1297            return this.setScalar(aValue.booleanValue());
1298        case BYTE:
1299            return this.setScalar(aValue.byteValue());
1300        case SHORT:
1301            return this.setScalar(aValue.shortValue());
1302        case CHARACTER:
1303            return this.setScalar(aValue.charValue());
1304        case INTEGER:
1305            return this.setScalar(aValue.intValue());
1306        case LONG:
1307            return this.setScalar(aValue.longValue());
1308        case FLOAT:
1309            return this.setScalar(aValue.floatValue());
1310        case UNLIMITED_INTEGER:
1311            return this.setReal(aValue.toUnlimitedInteger());
1312        case UNLIMITED_DECIMAL:
1313            return this.setReal(aValue.toUnlimitedDecimal());
1314        }
1315        return this.setScalar(aValue.doubleValue());
1316    }
1317
1318    @Override
1319    public REAL sum( final BigDecimal aValue )
1320        throws UnsupportedOperationException,
1321            IllegalArgumentException,
1322            ArithmeticException
1323    {
1324        return this.setReal(this.toUnlimitedDecimal().add(aValue));
1325    }
1326
1327    @Override
1328    public REAL sum( final BigInteger aValue )
1329        throws UnsupportedOperationException,
1330            IllegalArgumentException,
1331            ArithmeticException
1332    {
1333        return this.setReal(this.toUnlimitedInteger().add(aValue));
1334    }
1335
1336    @Override
1337    @SuppressWarnings( "unchecked" )
1338    public REAL sumOfNumber( final Number aValue )
1339        throws UnsupportedOperationException,
1340            IllegalArgumentException,
1341            ArithmeticException
1342    {
1343        final NumericPrecision myPrecision = this.getPrecision();
1344        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1345        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1346        switch (prec) {
1347        case NULL:
1348            return (REAL)this;
1349        case BYTE:
1350            return this.sum(aValue.byteValue());
1351        case SHORT:
1352            return this.sum(aValue.shortValue());
1353        case INTEGER:
1354            return this.sum(aValue.intValue());
1355        case LONG:
1356            return this.sum(aValue.longValue());
1357        case FLOAT:
1358            return this.sum(aValue.floatValue());
1359        case UNLIMITED_DECIMAL:
1360            try {
1361                final BigDecimal ud = (BigDecimal)aValue;
1362                return this.sum(ud);
1363            } catch (final ClassCastException ex) {
1364            }
1365            break;
1366        case UNLIMITED_INTEGER:
1367            try {
1368                final BigInteger ui = (BigInteger)aValue;
1369                return this.sum(ui);
1370            } catch (final ClassCastException ex) {
1371            }
1372            break;
1373        }
1374        return this.sum(aValue.doubleValue());
1375    }
1376
1377    @Override
1378    @SuppressWarnings( "unchecked" )
1379    public REAL sumOfReal( final SealedReal<?> aValue )
1380        throws UnsupportedOperationException,
1381            IllegalArgumentException,
1382            ArithmeticException
1383    {
1384        final NumericPrecision myPrecision = this.getPrecision();
1385        final NumericPrecision aPrecision = aValue.getPrecision();
1386        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1387        switch (prec) {
1388        case NULL:
1389            return (REAL)this;
1390        case BIT:
1391            return this.sum(aValue.booleanValue());
1392        case BYTE:
1393            return this.sum(aValue.byteValue());
1394        case SHORT:
1395            return this.sum(aValue.shortValue());
1396        case CHARACTER:
1397            return this.sum(aValue.charValue());
1398        case INTEGER:
1399            return this.sum(aValue.intValue());
1400        case LONG:
1401            return this.sum(aValue.longValue());
1402        case FLOAT:
1403            return this.sum(aValue.floatValue());
1404        case UNLIMITED_INTEGER:
1405            return this.sum(aValue.toUnlimitedInteger());
1406        case UNLIMITED_DECIMAL:
1407            return this.sum(aValue.toUnlimitedDecimal());
1408        }
1409        return this.sum(aValue.doubleValue());
1410    }
1411
1412    @Override
1413    public Real<?> toReal() {
1414        return this.copy();
1415    }
1416
1417    @Override
1418    public REAL xor( final BigInteger aValue )
1419        throws UnsupportedOperationException,
1420            IllegalArgumentException,
1421            ArithmeticException
1422    {
1423        return this.setReal(this.toUnlimitedInteger().xor(aValue));
1424    }
1425
1426    @Override
1427    @SuppressWarnings( "unchecked" )
1428    public REAL xorOfNumber( final Number aValue )
1429        throws UnsupportedOperationException,
1430            IllegalArgumentException,
1431            ArithmeticException
1432    {
1433        final NumericPrecision myPrecision = this.getPrecision();
1434        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1435        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1436        switch (prec) {
1437        case NULL:
1438            return (REAL)this;
1439        case BYTE:
1440            return this.xor(aValue.byteValue());
1441        case SHORT:
1442            return this.xor(aValue.shortValue());
1443        case INTEGER:
1444            return this.xor(aValue.intValue());
1445        case UNLIMITED_INTEGER:
1446            try {
1447                final BigInteger ui = (BigInteger)aValue;
1448                return this.xor(ui);
1449            } catch (final ClassCastException ex) {
1450            }
1451            break;
1452        case UNLIMITED_DECIMAL:
1453            try {
1454                final BigDecimal ud = (BigDecimal)aValue;
1455                return this.xor(ud.toBigInteger());
1456            } catch (final ClassCastException ex) {
1457            }
1458            break;
1459        }
1460        return this.xor(aValue.longValue());
1461    }
1462
1463    @Override
1464    @SuppressWarnings( "unchecked" )
1465    public REAL xorOfReal( final SealedReal<?> aValue )
1466        throws UnsupportedOperationException,
1467            IllegalArgumentException,
1468            ArithmeticException
1469    {
1470        final NumericPrecision myPrecision = this.getPrecision();
1471        final NumericPrecision aPrecision = aValue.getPrecision();
1472        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1473        switch (prec) {
1474        case NULL:
1475            return (REAL)this;
1476        case BIT:
1477            return this.xor(aValue.booleanValue());
1478        case BYTE:
1479            return this.xor(aValue.byteValue());
1480        case SHORT:
1481            return this.xor(aValue.shortValue());
1482        case CHARACTER:
1483            return this.xor(aValue.charValue());
1484        case INTEGER:
1485            return this.xor(aValue.intValue());
1486        case UNLIMITED_DECIMAL:
1487        case UNLIMITED_INTEGER:
1488            return this.xor(aValue.toUnlimitedInteger());
1489        }
1490        return this.xor(aValue.longValue());
1491    }
1492
1493    public static final BigInteger unlimitedIntegerModularInverse(
1494        final BigInteger p0,
1495        final BigInteger p1 )
1496    {
1497        BigInteger aDivisor = p0;
1498        BigInteger aModulus = p1;
1499        final BigInteger modulus0 = aModulus;
1500
1501        BigInteger x = BigInteger.ZERO;
1502        BigInteger lastX = BigInteger.ONE;
1503        BigInteger y = BigInteger.ONE;
1504        BigInteger lastY = BigInteger.ZERO;
1505
1506        while (aModulus.signum() != 0) {
1507            final BigInteger quotient = aDivisor.divide(aModulus);
1508            BigInteger temp = aModulus;
1509            aModulus = aDivisor.mod(aModulus);
1510            aDivisor = temp;
1511
1512            temp = x;
1513            x = lastX.subtract(quotient.multiply(x));
1514            lastX = temp;
1515
1516            temp = y;
1517            y = lastY.subtract(quotient.multiply(y));
1518            lastY = temp;
1519        }
1520        while (lastX.signum() == -1) {
1521            lastX = modulus0.add(lastX);
1522        }
1523        return lastX;
1524    }
1525}