001/**
002 * AbstractScalar.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.scalars;
020
021import java.io.Serializable;
022import java.math.BigDecimal;
023import java.math.BigInteger;
024import java.util.Collections;
025import java.util.NoSuchElementException;
026
027import net.sf.jaccumulator.Domain;
028import net.sf.jaccumulator.lex.To;
029
030/**
031 * Common read and write behavior for system supported primitives
032 * 
033 * @param <SCALAR>
034 *        this scalar type (used to facilitate operation chaining on write
035 *        operations)
036 * @since JAccumulator 4.0
037 * @author Nicole Tedesco (<a
038 *         href="mailto:Nicole@NicoleTedesco.com">Nicole@NicoleTedesco.com</a>)
039 */
040public abstract class AbstractScalar<SCALAR extends Scalar<SCALAR>>
041    extends
042        Number
043    implements
044        Scalar<SCALAR>,
045        Serializable
046{
047    private static final byte BYTE_MASKS[] = new byte[Byte.SIZE];
048    private static final byte BYTE_NOT_MASKS[] = new byte[Byte.SIZE];
049    private static final char CHARACTER_MASKS[] = new char[Character.SIZE];
050    private static final char CHARACTER_NOT_MASKS[] = new char[Character.SIZE];
051    private static final int INT_MASKS[] = new int[Integer.SIZE];
052    private static final int INT_NOT_MASKS[] = new int[Integer.SIZE];
053    private static final long LONG_MASKS[] = new long[Long.SIZE];
054    private static final long LONG_NOT_MASKS[] = new long[Long.SIZE];
055    private static final long serialVersionUID = -3863844027466308650L;
056    private static final short SHORT_MASKS[] = new short[Short.SIZE];
057    private static final short SHORT_NOT_MASKS[] = new short[Short.SIZE];
058    private static final BigInteger UI_MASKS[] = new BigInteger[Long.SIZE];
059    private static final BigInteger UI_NOT_MASKS[] = new BigInteger[Long.SIZE];
060
061    public static final Double NaN = Double.NaN;
062    public static final Integer ONEI = Integer.valueOf(1);
063    public static final long ZERO_DOUBLE_LONG_BITS = Double.doubleToLongBits(0.0D);
064    public static final int ZERO_FLOAT_INT_BITS = Float.floatToIntBits(0.0F);
065    public static final Integer ZEROI = Integer.valueOf(0);
066
067    static {
068        BigInteger uimask = BigInteger.ONE;
069        BigInteger nuimask = BigInteger.valueOf(-2);
070
071        for (int i = 0; i < Byte.SIZE; i++) {
072            UI_MASKS[i] = uimask;
073            BYTE_MASKS[i] = uimask.byteValue();
074            SHORT_MASKS[i] = uimask.shortValue();
075            CHARACTER_MASKS[i] = (char)uimask.shortValue();
076            INT_MASKS[i] = uimask.intValue();
077            LONG_MASKS[i] = uimask.longValue();
078            uimask = uimask.shiftLeft(1);
079
080            UI_NOT_MASKS[i] = nuimask;
081            BYTE_NOT_MASKS[i] = nuimask.byteValue();
082            SHORT_NOT_MASKS[i] = nuimask.shortValue();
083            CHARACTER_NOT_MASKS[i] = (char)nuimask.shortValue();
084            INT_NOT_MASKS[i] = nuimask.intValue();
085            LONG_NOT_MASKS[i] = nuimask.longValue();
086            nuimask = nuimask.shiftLeft(1).or(BigInteger.ONE);
087        }
088
089        for (int i = Byte.SIZE; i < Short.SIZE; i++) {
090            UI_MASKS[i] = uimask;
091            SHORT_MASKS[i] = uimask.shortValue();
092            CHARACTER_MASKS[i] = (char)uimask.shortValue();
093            INT_MASKS[i] = uimask.intValue();
094            LONG_MASKS[i] = uimask.longValue();
095            uimask = uimask.shiftLeft(1);
096
097            UI_NOT_MASKS[i] = nuimask;
098            SHORT_NOT_MASKS[i] = nuimask.shortValue();
099            CHARACTER_NOT_MASKS[i] = (char)nuimask.shortValue();
100            INT_NOT_MASKS[i] = nuimask.intValue();
101            LONG_NOT_MASKS[i] = nuimask.longValue();
102            nuimask = nuimask.shiftLeft(1).or(BigInteger.ONE);
103        }
104
105        for (int i = Short.SIZE; i < Integer.SIZE; i++) {
106            UI_MASKS[i] = uimask;
107            INT_MASKS[i] = uimask.intValue();
108            LONG_MASKS[i] = uimask.longValue();
109            uimask = uimask.shiftLeft(1);
110
111            UI_NOT_MASKS[i] = nuimask;
112            INT_NOT_MASKS[i] = nuimask.intValue();
113            LONG_NOT_MASKS[i] = nuimask.longValue();
114            nuimask = nuimask.shiftLeft(1).or(BigInteger.ONE);
115        }
116
117        for (int i = Integer.SIZE; i < Long.SIZE; i++) {
118            UI_MASKS[i] = uimask;
119            LONG_MASKS[i] = uimask.longValue();
120            uimask = uimask.shiftLeft(1);
121
122            UI_NOT_MASKS[i] = nuimask;
123            LONG_NOT_MASKS[i] = nuimask.longValue();
124            nuimask = nuimask.shiftLeft(1).or(BigInteger.ONE);
125        }
126    }
127
128    private final Domain _theDomain;
129    private final NumericPrecision _thePrecision;
130
131    public AbstractScalar()
132    {
133        this(Domain.EMPTY, NumericPrecision.NULL);
134    }
135
136    public AbstractScalar(
137        final Domain aDomain,
138        final NumericPrecision aPrecision )
139    {
140        this._theDomain = aDomain;
141        this._thePrecision = aPrecision;
142    }
143
144    @Override
145    public SCALAR absoluteValue()
146        throws UnsupportedOperationException,
147            ArithmeticException,
148            IllegalArgumentException
149    {
150        return this.setScalar(Math.abs(this.doubleValue()));
151    };
152
153    @Override
154    public SCALAR and( final boolean aValue )
155        throws UnsupportedOperationException,
156            IllegalArgumentException,
157            ArithmeticException
158    {
159        return this.setScalar(this.booleanValue() & aValue);
160    }
161
162    @Override
163    public SCALAR and( final byte aValue )
164        throws UnsupportedOperationException,
165            IllegalArgumentException,
166            ArithmeticException
167    {
168        return this.setScalar(this.byteValue() & aValue);
169    }
170
171    @Override
172    public SCALAR and( final char aValue )
173        throws UnsupportedOperationException,
174            IllegalArgumentException,
175            ArithmeticException
176    {
177        return this.setScalar(this.charValue() & aValue);
178    }
179
180    @Override
181    public SCALAR and( final int aValue )
182        throws UnsupportedOperationException,
183            IllegalArgumentException,
184            ArithmeticException
185    {
186        return this.setScalar(this.intValue() & aValue);
187    }
188
189    @Override
190    public SCALAR and( final long aValue )
191        throws UnsupportedOperationException,
192            IllegalArgumentException,
193            ArithmeticException
194    {
195        return this.setScalar(this.longValue() & aValue);
196    }
197
198    @Override
199    public SCALAR and( final short aValue )
200        throws UnsupportedOperationException,
201            IllegalArgumentException,
202            ArithmeticException
203    {
204        return this.setScalar(this.shortValue() & aValue);
205    }
206
207    @Override
208    @SuppressWarnings( "unchecked" )
209    public SCALAR andOfNumber( final Number aValue )
210        throws UnsupportedOperationException,
211            IllegalArgumentException,
212            ArithmeticException
213    {
214        final NumericPrecision myPrecision = this.getPrecision();
215        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
216        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
217        switch (prec) {
218        case NULL:
219            return (SCALAR)this; // this and aNumber are NULL
220        case BYTE:
221            return this.and(aValue.byteValue());
222        case SHORT:
223            return this.and(aValue.shortValue());
224        case INTEGER:
225            return this.and(aValue.intValue());
226        }
227        return this.and(aValue.longValue());
228    }
229
230    @Override
231    @SuppressWarnings( "unchecked" )
232    public SCALAR andOfScalar( final SealedScalar<?> aValue )
233        throws UnsupportedOperationException,
234            IllegalArgumentException,
235            ArithmeticException
236    {
237        final NumericPrecision myPrecision = this.getPrecision();
238        final NumericPrecision aPrecision = aValue.getPrecision();
239        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
240        switch (prec) {
241        case NULL:
242            return (SCALAR)this; // this and aNumber are NULL
243        case BIT:
244            return this.and(aValue.booleanValue());
245        case BYTE:
246            return this.and(aValue.byteValue());
247        case SHORT:
248            return this.and(aValue.shortValue());
249        case CHARACTER:
250            return this.and(aValue.charValue());
251        case INTEGER:
252            return this.and(aValue.intValue());
253        }
254        return this.and(aValue.longValue());
255    }
256
257    @Override
258    public SCALAR angleWith( final double aValue )
259        throws UnsupportedOperationException,
260            IllegalArgumentException,
261            ArithmeticException
262    {
263        return this.setScalar(Math.atan2(this.doubleValue(), aValue));
264    }
265
266    @Override
267    public final SCALAR angleWithNumber( final Number y )
268        throws UnsupportedOperationException,
269            IllegalArgumentException,
270            ArithmeticException
271    {
272        return this.angleWith(y.doubleValue());
273    }
274
275    @Override
276    public final SCALAR angleWithScalar( final SealedScalar<?> aValue )
277        throws UnsupportedOperationException,
278            IllegalArgumentException,
279            ArithmeticException
280    {
281        return this.angleWith(aValue.doubleValue());
282    }
283
284    @Override
285    public SCALAR arcCosine()
286        throws UnsupportedOperationException,
287            IllegalArgumentException,
288            ArithmeticException
289    {
290        return this.setScalar(Math.acos(this.doubleValue()));
291    }
292
293    @Override
294    public SCALAR arcSine()
295        throws UnsupportedOperationException,
296            IllegalArgumentException,
297            ArithmeticException
298    {
299        return this.setScalar(Math.asin(this.doubleValue()));
300    }
301
302    @Override
303    public SCALAR arcTangent()
304        throws UnsupportedOperationException,
305            IllegalArgumentException,
306            ArithmeticException
307    {
308        return this.setScalar(Math.atan(this.doubleValue()));
309    }
310
311    @Override
312    @SuppressWarnings( "unchecked" )
313    public SCALAR assertDomain( final Domain aDomain )
314    {
315        return (SCALAR)this;
316    }
317
318    @Override
319    @SuppressWarnings( "unchecked" )
320    public SCALAR assertPrecision( final NumericPrecision prec )
321    {
322        return (SCALAR)this;
323    }
324
325    @Override
326    public SCALAR base10Log()
327        throws UnsupportedOperationException,
328            IllegalArgumentException,
329            ArithmeticException
330    {
331        return this.setScalar(Math.log10(this.doubleValue()));
332    }
333
334    @Override
335    public final SCALAR ceiling()
336        throws UnsupportedOperationException,
337            IllegalArgumentException,
338            ArithmeticException
339    {
340        return this.setScalar(Math.ceil(this.doubleValue()));
341    }
342
343    @Override
344    public int compareToNumber( final Number aValue )
345    {
346        final NumericPrecision myPrecision = this.getPrecision();
347        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
348        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
349        switch (prec) {
350        case NULL:
351            return this.compareToZero();
352        case BIT:
353        case BYTE:
354            return this.compareToScalar(aValue.byteValue());
355        case SHORT:
356            return this.compareToScalar(aValue.shortValue());
357        case CHARACTER:
358        case INTEGER:
359            return this.compareToScalar(aValue.intValue());
360        case LONG:
361            return this.compareToScalar(aValue.longValue());
362        case FLOAT:
363            return this.compareToScalar(aValue.floatValue());
364        }
365        return this.compareToScalar(aValue.doubleValue());
366    }
367
368    @Override
369    public int compareToScalar( final boolean aValue )
370    {
371        return compareTo(this.booleanValue(), aValue);
372    }
373
374    @Override
375    public int compareToScalar( final byte aValue )
376    {
377        return compareTo(this.byteValue(), aValue);
378    }
379
380    @Override
381    public int compareToScalar( final char aValue )
382    {
383        return compareTo(this.charValue(), aValue);
384    }
385
386    @Override
387    public int compareToScalar( final double aValue )
388    {
389        return compareTo(this.doubleValue(), aValue);
390    }
391
392    @Override
393    public int compareToScalar( final float aValue )
394    {
395        return compareTo(this.floatValue(), aValue);
396    }
397
398    @Override
399    public int compareToScalar( final int aValue )
400    {
401        return compareTo(this.intValue(), aValue);
402    }
403
404    @Override
405    public int compareToScalar( final long aValue )
406    {
407        return compareTo(this.longValue(), aValue);
408    }
409
410    @Override
411    public int compareToScalar( final SealedScalar<?> aValue )
412    {
413        final NumericPrecision myPrecision = this.getPrecision();
414        final NumericPrecision aPrecision = aValue.getPrecision();
415        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
416        switch (prec) {
417        case NULL:
418            return this.compareToZero();
419        case BIT:
420            return this.compareToScalar(aValue.booleanValue());
421        case BYTE:
422            return this.compareToScalar(aValue.byteValue());
423        case SHORT:
424            return this.compareToScalar(aValue.shortValue());
425        case CHARACTER:
426            return this.compareToScalar(aValue.charValue());
427        case INTEGER:
428            return this.compareToScalar(aValue.intValue());
429        case LONG:
430            return this.compareToScalar(aValue.longValue());
431        case FLOAT:
432            return this.compareToScalar(aValue.floatValue());
433        }
434        return compareTo(this.doubleValue(), aValue.doubleValue());
435    }
436
437    @Override
438    public int compareToScalar( final short aValue )
439    {
440        return compareTo(this.shortValue(), aValue);
441    }
442
443    @Override
444    public int compareToZero()
445    {
446        if (this.isZero()) return 0;
447        if (this.isPositive()) return +1;
448        return -1;
449    }
450
451    @Override
452    public SCALAR cosine()
453        throws UnsupportedOperationException,
454            IllegalArgumentException,
455            ArithmeticException
456    {
457        return this.setScalar(Math.cos(this.doubleValue()));
458    }
459
460    @Override
461    public SCALAR cubeRoot()
462        throws UnsupportedOperationException,
463            IllegalArgumentException,
464            ArithmeticException
465    {
466        return this.setScalar(Math.cbrt(this.doubleValue()));
467    }
468
469    @Override
470    public SCALAR degrees()
471        throws UnsupportedOperationException,
472            IllegalArgumentException,
473            ArithmeticException
474    {
475        return this.setScalar(Math.toDegrees(this.doubleValue()));
476    }
477
478    @Override
479    @SuppressWarnings( "unchecked" )
480    public SCALAR difference( final boolean aValue )
481        throws UnsupportedOperationException,
482            IllegalArgumentException,
483            ArithmeticException
484    {
485        if (this.booleanValue()) {
486            if (aValue) return this.setScalar(false);
487        } else if (aValue) return this.setScalar(true);
488        return (SCALAR)this;
489    }
490
491    @Override
492    public SCALAR difference( final byte aValue )
493        throws UnsupportedOperationException,
494            IllegalArgumentException,
495            ArithmeticException
496    {
497        return this.setScalar(this.byteValue() - aValue);
498    }
499
500    @Override
501    public SCALAR difference( final char aValue )
502        throws UnsupportedOperationException,
503            IllegalArgumentException,
504            ArithmeticException
505    {
506        return this.setScalar(this.charValue() - aValue);
507    }
508
509    @Override
510    public SCALAR difference( final double aValue )
511        throws UnsupportedOperationException,
512            IllegalArgumentException,
513            ArithmeticException
514    {
515        return this.setScalar(this.doubleValue() - aValue);
516    }
517
518    @Override
519    public SCALAR difference( final float aValue )
520        throws UnsupportedOperationException,
521            IllegalArgumentException,
522            ArithmeticException
523    {
524        return this.setScalar(this.floatValue() - aValue);
525    }
526
527    @Override
528    public SCALAR difference( final int aValue )
529        throws UnsupportedOperationException,
530            IllegalArgumentException,
531            ArithmeticException
532    {
533        return this.setScalar(this.intValue() - aValue);
534    }
535
536    @Override
537    public SCALAR difference( final long aValue )
538        throws UnsupportedOperationException,
539            IllegalArgumentException,
540            ArithmeticException
541    {
542        return this.setScalar(this.longValue() - aValue);
543    }
544
545    @Override
546    public SCALAR difference( final short aValue )
547        throws UnsupportedOperationException,
548            IllegalArgumentException,
549            ArithmeticException
550    {
551        return this.setScalar(this.shortValue() - aValue);
552    }
553
554    @Override
555    @SuppressWarnings( "unchecked" )
556    public SCALAR differenceOfNumber( final Number aValue )
557        throws UnsupportedOperationException,
558            IllegalArgumentException,
559            ArithmeticException
560    {
561        final NumericPrecision myPrecision = this.getPrecision();
562        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
563        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
564        switch (prec) {
565        case NULL:
566            return (SCALAR)this;
567        case BYTE:
568            return this.difference(aValue.byteValue());
569        case SHORT:
570            return this.difference(aValue.shortValue());
571        case INTEGER:
572            return this.difference(aValue.intValue());
573        case LONG:
574            return this.difference(aValue.longValue());
575        case FLOAT:
576            return this.difference(aValue.floatValue());
577        }
578        return this.difference(aValue.doubleValue());
579    }
580
581    @Override
582    @SuppressWarnings( "unchecked" )
583    public SCALAR differenceOfScalar( final SealedScalar<?> aValue )
584        throws UnsupportedOperationException,
585            IllegalArgumentException,
586            ArithmeticException
587    {
588        final NumericPrecision myPrecision = this.getPrecision();
589        final NumericPrecision aPrecision = aValue.getPrecision();
590        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
591        switch (prec) {
592        case NULL:
593            return (SCALAR)this;
594        case BIT:
595            return this.difference(aValue.booleanValue());
596        case BYTE:
597            return this.difference(aValue.byteValue());
598        case SHORT:
599            return this.difference(aValue.shortValue());
600        case CHARACTER:
601            return this.difference(aValue.charValue());
602        case INTEGER:
603            return this.difference(aValue.intValue());
604        case LONG:
605            return this.difference(aValue.longValue());
606        case FLOAT:
607            return this.difference(aValue.floatValue());
608        }
609        return this.difference(aValue.doubleValue());
610    }
611
612    @Override
613    public final SCALAR down()
614        throws UnsupportedOperationException,
615            IllegalArgumentException,
616            ArithmeticException
617    {
618        return this.round(RoundingStrategy.DOWN);
619    }
620
621    @Override
622    public boolean equals( final Object anObject )
623    {
624        if (anObject == this) return true;
625        if (anObject instanceof SealedScalar<?>) {
626            final SealedScalar<?> aScalar = (SealedScalar<?>)anObject;
627            return this.isEqualToScalar(aScalar);
628        }
629        return this.toString().equals(anObject.toString());
630    }
631
632    @Override
633    public SCALAR exponential()
634        throws UnsupportedOperationException,
635            IllegalArgumentException,
636            ArithmeticException
637    {
638        return this.setScalar(Math.exp(this.doubleValue()));
639    }
640
641    @Override
642    public SCALAR exponentialLessOne()
643        throws UnsupportedOperationException,
644            IllegalArgumentException,
645            ArithmeticException
646    {
647        return this.setScalar(Math.expm1(this.doubleValue()));
648    }
649
650    @Override
651    public final SCALAR floor()
652        throws UnsupportedOperationException,
653            IllegalArgumentException,
654            ArithmeticException
655    {
656        return this.setScalar(Math.floor(this.doubleValue()));
657    }
658
659    @Override
660    public SCALAR gcd( final byte aValue )
661        throws UnsupportedOperationException,
662            ArithmeticException,
663            IllegalArgumentException
664    {
665        return this.gcd((int)aValue);
666    }
667
668    @Override
669    public SCALAR gcd( final char aValue )
670        throws UnsupportedOperationException,
671            ArithmeticException,
672            IllegalArgumentException
673    {
674        return this.gcd((int)aValue);
675    }
676
677    @Override
678    public SCALAR gcd( final int aValue )
679        throws UnsupportedOperationException,
680            ArithmeticException,
681            IllegalArgumentException
682    {
683        return this.setScalar(intGCD(this.intValue(), aValue));
684    }
685
686    @Override
687    public SCALAR gcd( final long aValue )
688        throws UnsupportedOperationException,
689            ArithmeticException,
690            IllegalArgumentException
691    {
692        return this.setScalar(longGCD(this.longValue(), aValue));
693    };
694
695    @Override
696    public SCALAR gcd( final short aValue )
697        throws UnsupportedOperationException,
698            ArithmeticException,
699            IllegalArgumentException
700    {
701        return this.gcd((int)aValue);
702    }
703
704    @Override
705    public SCALAR gcdOfNumber( final Number aValue )
706        throws UnsupportedOperationException,
707            IllegalArgumentException,
708            ArithmeticException
709    {
710        final NumericPrecision myPrecision = this.getPrecision();
711        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
712        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
713        switch (prec) {
714        case NULL:
715            return this.gcd(0);
716        case BYTE:
717            return this.gcd(aValue.byteValue());
718        case SHORT:
719            return this.gcd(aValue.shortValue());
720        case INTEGER:
721            return this.gcd(aValue.intValue());
722        }
723        return this.gcd(aValue.longValue());
724    }
725
726    @Override
727    public final SCALAR gcdOfScalar( final Scalar<?> aScalar )
728        throws UnsupportedOperationException,
729            ArithmeticException,
730            IllegalArgumentException
731    {
732        final NumericPrecision myPrecision = this.getPrecision();
733        final NumericPrecision aPrecision = aScalar.getPrecision();
734        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
735        switch (prec) {
736        case NULL:
737            return this.gcd(0);
738        case BIT:
739        case BYTE:
740            return this.gcd(aScalar.byteValue());
741        case SHORT:
742            return this.gcd(aScalar.shortValue());
743        case CHARACTER:
744            return this.gcd(aScalar.charValue());
745        case INTEGER:
746            return this.gcd(aScalar.intValue());
747        }
748        return this.gcd(aScalar.longValue());
749    }
750
751    @Override
752    public Domain getDomain()
753    {
754        return this._theDomain;
755    }
756
757    @Override
758    public NumericPrecision getPrecision()
759    {
760        return this._thePrecision;
761    }
762
763    @Override
764    public final SCALAR halfDown()
765        throws UnsupportedOperationException,
766            IllegalArgumentException,
767            ArithmeticException
768    {
769        return this.round(RoundingStrategy.HALF_DOWN);
770    }
771
772    @Override
773    public final SCALAR halfEven()
774        throws UnsupportedOperationException,
775            IllegalArgumentException,
776            ArithmeticException
777    {
778        return this.round(RoundingStrategy.HALF_EVEN);
779    }
780
781    @Override
782    public final SCALAR halfUp()
783        throws UnsupportedOperationException,
784            IllegalArgumentException,
785            ArithmeticException
786    {
787        return this.round(RoundingStrategy.HALF_UP);
788    }
789
790    @Override
791    public SCALAR hyperbolicCosine()
792        throws UnsupportedOperationException,
793            IllegalArgumentException,
794            ArithmeticException
795    {
796        return this.setScalar(Math.cosh(this.doubleValue()));
797    }
798
799    @Override
800    public SCALAR hyperbolicSine()
801        throws UnsupportedOperationException,
802            IllegalArgumentException,
803            ArithmeticException
804    {
805        return this.setScalar(Math.sinh(this.doubleValue()));
806    }
807
808    @Override
809    public SCALAR hyperbolicTangent()
810        throws UnsupportedOperationException,
811            IllegalArgumentException,
812            ArithmeticException
813    {
814        return this.setScalar(Math.tanh(this.doubleValue()));
815    }
816
817    @Override
818    public final SCALAR hypotenuseWith( final double aValue )
819        throws UnsupportedOperationException,
820            IllegalArgumentException,
821            ArithmeticException
822    {
823        return this.setScalar(Math.hypot(this.doubleValue(), aValue));
824    }
825
826    @Override
827    public final SCALAR hypotenuseWithNumber( final Number aValue )
828        throws UnsupportedOperationException,
829            IllegalArgumentException,
830            ArithmeticException
831    {
832        return this.hypotenuseWith(aValue.doubleValue());
833    }
834
835    @Override
836    public final SCALAR hypotenuseWithScalar( final SealedScalar<?> aValue )
837        throws UnsupportedOperationException,
838            IllegalArgumentException,
839            ArithmeticException
840    {
841        return this.hypotenuseWith(aValue.doubleValue());
842    }
843
844    @Override
845    @SuppressWarnings( "unchecked" )
846    public <S extends Scalar<?>> S induceScalarSize( final S aTarget )
847        throws NullPointerException,
848            NoSuchElementException,
849            UnsupportedOperationException,
850            IllegalStateException
851    {
852        return (S)aTarget.setScalar(this.size());
853    }
854
855    @Override
856    public SCALAR invalidate()
857        throws UnsupportedOperationException,
858            ArithmeticException,
859            IllegalArgumentException
860    {
861        return this.setZero();
862    }
863
864    @Override
865    public boolean isAlphabetic()
866    {
867        return Character.isAlphabetic(this.intValue());
868    }
869
870    @Override
871    public boolean isBmpCodePoint()
872    {
873        return Character.isBmpCodePoint(this.intValue());
874    }
875
876    @Override
877    public boolean isConfigurable()
878    {
879        return true; // assume components (bits) can be replaced
880    }
881
882    @Override
883    public boolean isCountable()
884    {
885        return true; // even empty sets are countable since the empty set has a
886                     // bijection into the set of natural numbers
887    }
888
889    @Override
890    public boolean isDigit()
891    {
892        return Character.isDigit(this.intValue());
893    }
894
895    @Override
896    public boolean isElastic()
897    {
898        return false;
899    }
900
901    @Override
902    public boolean isEmpty()
903    {
904        return false;
905    }
906
907    @Override
908    public boolean isEqual( final boolean aScalar )
909    {
910        return this.booleanValue() == aScalar;
911    }
912
913    @Override
914    public boolean isEqual( final byte aScalar )
915    {
916        return this.byteValue() == aScalar;
917    }
918
919    @Override
920    public boolean isEqual( final char aScalar )
921    {
922        return this.charValue() == aScalar;
923    }
924
925    @Override
926    public boolean isEqual( final double aScalar )
927    {
928        return compareTo(this.doubleValue(), aScalar) == 0;
929    }
930
931    @Override
932    public boolean isEqual( final float aScalar )
933    {
934        return compareTo(this.floatValue(), aScalar) == 0;
935    }
936
937    @Override
938    public boolean isEqual( final int aScalar )
939    {
940        return this.intValue() == aScalar;
941    }
942
943    @Override
944    public boolean isEqual( final long aScalar )
945    {
946        return this.longValue() == aScalar;
947    }
948
949    @Override
950    public boolean isEqual( final short aScalar )
951    {
952        return this.shortValue() == aScalar;
953    }
954
955    @Override
956    public boolean isEqualToNumber( final Number aNumber )
957    {
958        assert aNumber != null;
959        final NumericPrecision myPrecision = this.getPrecision();
960        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
961        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
962        switch (prec) {
963        case NULL:
964            return this.isZero();
965        case BYTE:
966            return this.isEqual(aNumber.byteValue());
967        case SHORT:
968            return this.isEqual(aNumber.shortValue());
969        case INTEGER:
970            return this.isEqual(aNumber.intValue());
971        case LONG:
972            return this.isEqual(aNumber.longValue());
973        case FLOAT:
974            return this.isEqual(aNumber.floatValue());
975        }
976        return this.isEqual(aNumber.doubleValue());
977    }
978
979    @Override
980    public boolean isEqualToScalar( final SealedScalar<?> aScalar )
981    {
982        assert aScalar != null;
983        final NumericPrecision myPrecision = this.getPrecision();
984        final NumericPrecision aPrecision = aScalar.getPrecision();
985        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
986        switch (prec) {
987        case NULL:
988            return this.isZero();
989        case BIT:
990            return this.isEqual(aScalar.booleanValue());
991        case BYTE:
992            return this.isEqual(aScalar.byteValue());
993        case SHORT:
994            return this.isEqual(aScalar.shortValue());
995        case CHARACTER:
996            return this.isEqual(aScalar.charValue());
997        case INTEGER:
998            return this.isEqual(aScalar.intValue());
999        case LONG:
1000            return this.isEqual(aScalar.longValue());
1001        case FLOAT:
1002            return this.isEqual(aScalar.floatValue());
1003        }
1004        return this.isEqual(aScalar.doubleValue());
1005    }
1006
1007    @Override
1008    public boolean isExpandable()
1009    {
1010        return this.isElastic();
1011    }
1012
1013    @Override
1014    public final boolean isFalse()
1015    {
1016        return !this.booleanValue();
1017    }
1018
1019    @Override
1020    public boolean isFinite()
1021    {
1022        return !this.isInfinity();
1023    }
1024
1025    @Override
1026    public boolean isGreater( final boolean aScalar )
1027    {
1028        if (this.booleanValue()) return !aScalar;
1029        return false;
1030    }
1031
1032    @Override
1033    public boolean isGreater( final byte aScalar )
1034    {
1035        return aScalar < this.byteValue();
1036    }
1037
1038    @Override
1039    public boolean isGreater( final char aScalar )
1040    {
1041        return aScalar < this.charValue();
1042    }
1043
1044    @Override
1045    public boolean isGreater( final double aScalar )
1046    {
1047        return 0 < this.compareToScalar(aScalar);
1048    }
1049
1050    @Override
1051    public boolean isGreater( final float aScalar )
1052    {
1053        return 0 < this.compareToScalar(aScalar);
1054    }
1055
1056    @Override
1057    public boolean isGreater( final int aScalar )
1058    {
1059        return aScalar < this.intValue();
1060    }
1061
1062    @Override
1063    public boolean isGreater( final long aScalar )
1064    {
1065        return aScalar < this.longValue();
1066    }
1067
1068    @Override
1069    public boolean isGreater( final short aScalar )
1070    {
1071        return aScalar < this.shortValue();
1072    }
1073
1074    @Override
1075    public boolean isGreaterOrEqual( final boolean aScalar )
1076    {
1077        if (this.booleanValue()) return true;
1078        return !aScalar;
1079    }
1080
1081    @Override
1082    public boolean isGreaterOrEqual( final byte aScalar )
1083    {
1084        return aScalar <= this.byteValue();
1085    }
1086
1087    @Override
1088    public boolean isGreaterOrEqual( final char aScalar )
1089    {
1090        return aScalar <= this.charValue();
1091    }
1092
1093    @Override
1094    public boolean isGreaterOrEqual( final double aScalar )
1095    {
1096        return 0 <= this.compareToScalar(aScalar);
1097    }
1098
1099    @Override
1100    public boolean isGreaterOrEqual( final float aScalar )
1101    {
1102        return 0 <= this.compareToScalar(aScalar);
1103    }
1104
1105    @Override
1106    public boolean isGreaterOrEqual( final int aScalar )
1107    {
1108        return aScalar <= this.intValue();
1109    }
1110
1111    @Override
1112    public boolean isGreaterOrEqual( final long aScalar )
1113    {
1114        return aScalar <= this.longValue();
1115    }
1116
1117    @Override
1118    public boolean isGreaterOrEqual( final short aScalar )
1119    {
1120        return aScalar <= this.shortValue();
1121    }
1122
1123    @Override
1124    public boolean isGreaterOrEqualToNumber( final Number aNumber )
1125    {
1126        final NumericPrecision myPrecision = this.getPrecision();
1127        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
1128        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1129        switch (prec) {
1130        case NULL:
1131            return !this.isNegative();
1132        case BYTE:
1133            return this.isGreaterOrEqual(aNumber.byteValue());
1134        case SHORT:
1135            return this.isGreaterOrEqual(aNumber.shortValue());
1136        case INTEGER:
1137            return this.isGreaterOrEqual(aNumber.intValue());
1138        case LONG:
1139            return this.isGreaterOrEqual(aNumber.longValue());
1140        case FLOAT:
1141            return this.isGreaterOrEqual(aNumber.floatValue());
1142        }
1143        return this.isGreaterOrEqual(aNumber.doubleValue());
1144    }
1145
1146    @Override
1147    public boolean isGreaterOrEqualToScalar( final SealedScalar<?> aScalar )
1148    {
1149        final NumericPrecision myPrecision = this.getPrecision();
1150        final NumericPrecision aPrecision = aScalar.getPrecision();
1151        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1152        switch (prec) {
1153        case NULL:
1154            return !this.isNegative();
1155        case BIT:
1156            return this.isGreaterOrEqual(aScalar.booleanValue());
1157        case BYTE:
1158            return this.isGreaterOrEqual(aScalar.byteValue());
1159        case SHORT:
1160            return this.isGreaterOrEqual(aScalar.shortValue());
1161        case CHARACTER:
1162            return this.isGreaterOrEqual(aScalar.charValue());
1163        case INTEGER:
1164            return this.isGreaterOrEqual(aScalar.intValue());
1165        case LONG:
1166            return this.isGreaterOrEqual(aScalar.longValue());
1167        case FLOAT:
1168            return this.isGreaterOrEqual(aScalar.floatValue());
1169        }
1170        return this.isGreaterOrEqual(aScalar.doubleValue());
1171    }
1172
1173    @Override
1174    public boolean isGreaterThanNumber( final Number aNumber )
1175    {
1176        final NumericPrecision myPrecision = this.getPrecision();
1177        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
1178        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1179        switch (prec) {
1180        case NULL:
1181            return this.isPositive();
1182        case BYTE:
1183            return this.isGreater(aNumber.byteValue());
1184        case SHORT:
1185            return this.isGreater(aNumber.shortValue());
1186        case INTEGER:
1187            return this.isGreater(aNumber.intValue());
1188        case LONG:
1189            return this.isGreater(aNumber.longValue());
1190        case FLOAT:
1191            return this.isGreater(aNumber.floatValue());
1192        }
1193        return this.isGreater(aNumber.doubleValue());
1194    }
1195
1196    @Override
1197    public boolean isGreaterThanScalar( final SealedScalar<?> aScalar )
1198    {
1199        final NumericPrecision myPrecision = this.getPrecision();
1200        final NumericPrecision aPrecision = aScalar.getPrecision();
1201        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1202        switch (prec) {
1203        case NULL:
1204            return this.isPositive();
1205        case BIT:
1206            return this.isGreater(aScalar.booleanValue());
1207        case BYTE:
1208            return this.isGreater(aScalar.byteValue());
1209        case SHORT:
1210            return this.isGreater(aScalar.shortValue());
1211        case CHARACTER:
1212            return this.isGreater(aScalar.charValue());
1213        case INTEGER:
1214            return this.isGreater(aScalar.intValue());
1215        case LONG:
1216            return this.isGreater(aScalar.longValue());
1217        case FLOAT:
1218            return this.isGreater(aScalar.floatValue());
1219        }
1220        return this.isGreater(aScalar.doubleValue());
1221    }
1222
1223    @Override
1224    public boolean isHighSurrogate()
1225    {
1226        return Character.isHighSurrogate(this.charValue());
1227    }
1228
1229    @Override
1230    public boolean isIdentifierIgnorable()
1231    {
1232        return Character.isIdentifierIgnorable(this.intValue());
1233    }
1234
1235    @Override
1236    public boolean isIdeographic()
1237    {
1238        return Character.isIdeographic(this.intValue());
1239    }
1240
1241    @Override
1242    public boolean isImaginary()
1243    {
1244        return this.getDomain() == Domain.IMAGINARY;
1245    }
1246
1247    @Override
1248    public boolean isISOControl()
1249    {
1250        return Character.isISOControl(this.intValue());
1251    }
1252
1253    @Override
1254    public boolean isJavaIdentifierPart()
1255    {
1256        return Character.isJavaIdentifierPart(this.intValue());
1257    }
1258
1259    @Override
1260    public boolean isJavaIdentifierStart()
1261    {
1262        return Character.isJavaIdentifierStart(this.intValue());
1263    }
1264
1265    @Override
1266    public boolean isLess( final boolean aScalar )
1267    {
1268        if (!this.booleanValue()) return aScalar;
1269        return false;
1270    }
1271
1272    @Override
1273    public boolean isLess( final byte aScalar )
1274    {
1275        return this.byteValue() < aScalar;
1276    }
1277
1278    @Override
1279    public boolean isLess( final char aScalar )
1280    {
1281        return this.charValue() < aScalar;
1282    }
1283
1284    @Override
1285    public boolean isLess( final double aScalar )
1286    {
1287        return this.compareToScalar(aScalar) < 0;
1288    }
1289
1290    @Override
1291    public boolean isLess( final float aScalar )
1292    {
1293        return this.compareToScalar(aScalar) < 0;
1294    }
1295
1296    @Override
1297    public boolean isLess( final int aScalar )
1298    {
1299        return this.intValue() < aScalar;
1300    }
1301
1302    @Override
1303    public boolean isLess( final long aScalar )
1304    {
1305        return this.longValue() < aScalar;
1306    }
1307
1308    @Override
1309    public boolean isLess( final short aScalar )
1310    {
1311        return this.shortValue() < aScalar;
1312    }
1313
1314    @Override
1315    public boolean isLessOrEqual( final boolean aScalar )
1316    {
1317        if (this.booleanValue()) return aScalar;
1318        return true;
1319    }
1320
1321    @Override
1322    public boolean isLessOrEqual( final byte aScalar )
1323    {
1324        return this.byteValue() <= aScalar;
1325    }
1326
1327    @Override
1328    public boolean isLessOrEqual( final char aScalar )
1329    {
1330        return this.charValue() <= aScalar;
1331    }
1332
1333    @Override
1334    public boolean isLessOrEqual( final double aScalar )
1335    {
1336        return this.compareToScalar(aScalar) <= 0;
1337    }
1338
1339    @Override
1340    public boolean isLessOrEqual( final float aScalar )
1341    {
1342        return this.compareToScalar(aScalar) <= 0;
1343    }
1344
1345    @Override
1346    public boolean isLessOrEqual( final int aScalar )
1347    {
1348        return this.intValue() <= aScalar;
1349    }
1350
1351    @Override
1352    public boolean isLessOrEqual( final long aScalar )
1353    {
1354        return this.longValue() <= aScalar;
1355    }
1356
1357    @Override
1358    public boolean isLessOrEqual( final short aScalar )
1359    {
1360        return this.shortValue() <= aScalar;
1361    }
1362
1363    @Override
1364    public boolean isLessOrEqualToNumber( final Number aNumber )
1365    {
1366        final NumericPrecision myPrecision = this.getPrecision();
1367        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
1368        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1369        switch (prec) {
1370        case NULL:
1371            return !this.isPositive();
1372        case BYTE:
1373            return this.isLessOrEqual(aNumber.byteValue());
1374        case SHORT:
1375            return this.isLessOrEqual(aNumber.shortValue());
1376        case INTEGER:
1377            return this.isLessOrEqual(aNumber.intValue());
1378        case LONG:
1379            return this.isLessOrEqual(aNumber.longValue());
1380        case FLOAT:
1381            return this.isLessOrEqual(aNumber.floatValue());
1382        }
1383        return this.isLessOrEqual(aNumber.doubleValue());
1384    }
1385
1386    @Override
1387    public boolean isLessOrEqualToScalar( final SealedScalar<?> aScalar )
1388    {
1389        final NumericPrecision myPrecision = this.getPrecision();
1390        final NumericPrecision aPrecision = aScalar.getPrecision();
1391        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1392        switch (prec) {
1393        case NULL:
1394            return !this.isPositive();
1395        case BIT:
1396            return this.isLessOrEqual(aScalar.booleanValue());
1397        case BYTE:
1398            return this.isLessOrEqual(aScalar.byteValue());
1399        case SHORT:
1400            return this.isLessOrEqual(aScalar.shortValue());
1401        case CHARACTER:
1402            return this.isLessOrEqual(aScalar.charValue());
1403        case INTEGER:
1404            return this.isLessOrEqual(aScalar.intValue());
1405        case LONG:
1406            return this.isLessOrEqual(aScalar.longValue());
1407        case FLOAT:
1408            return this.isLessOrEqual(aScalar.floatValue());
1409        }
1410        return this.isLessOrEqual(aScalar.doubleValue());
1411    }
1412
1413    @Override
1414    public boolean isLessThanNumber( final Number aNumber )
1415    {
1416        final NumericPrecision myPrecision = this.getPrecision();
1417        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
1418        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1419        switch (prec) {
1420        case NULL:
1421            return this.isNegative();
1422        case BYTE:
1423            return this.isLess(aNumber.byteValue());
1424        case SHORT:
1425            return this.isLess(aNumber.shortValue());
1426        case INTEGER:
1427            return this.isLess(aNumber.intValue());
1428        case LONG:
1429            return this.isLess(aNumber.longValue());
1430        case FLOAT:
1431            return this.isLess(aNumber.floatValue());
1432        }
1433        return this.isLess(aNumber.doubleValue());
1434    }
1435
1436    @Override
1437    public boolean isLessThanScalar( final SealedScalar<?> aScalar )
1438    {
1439        final NumericPrecision myPrecision = this.getPrecision();
1440        final NumericPrecision aPrecision = aScalar.getPrecision();
1441        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1442        switch (prec) {
1443        case NULL:
1444            return this.isNegative();
1445        case BIT:
1446            return this.isLess(aScalar.booleanValue());
1447        case BYTE:
1448            return this.isLess(aScalar.byteValue());
1449        case SHORT:
1450            return this.isLess(aScalar.shortValue());
1451        case CHARACTER:
1452            return this.isLess(aScalar.charValue());
1453        case INTEGER:
1454            return this.isLess(aScalar.intValue());
1455        case LONG:
1456            return this.isLess(aScalar.longValue());
1457        case FLOAT:
1458            return this.isLess(aScalar.floatValue());
1459        }
1460        return this.isLess(aScalar.doubleValue());
1461    }
1462
1463    @Override
1464    public boolean isLetter()
1465    {
1466        return Character.isLetter(this.intValue());
1467    }
1468
1469    @Override
1470    public boolean isLetterOrDigit()
1471    {
1472        return Character.isLetterOrDigit(this.intValue());
1473    }
1474
1475    @Override
1476    public boolean isLowerCase()
1477    {
1478        return Character.isLowerCase(this.intValue());
1479    }
1480
1481    @Override
1482    public boolean isLowSurrogate()
1483    {
1484        return Character.isLowSurrogate(this.charValue());
1485    }
1486
1487    @Override
1488    public boolean isMirrored()
1489    {
1490        return Character.isMirrored(this.intValue());
1491    }
1492
1493    @Override
1494    public boolean isMutable()
1495    {
1496        return this.isConfigurable();
1497    }
1498
1499    @Override
1500    public boolean isNegativeFinite()
1501    {
1502        return this.isFinite() && this.isNegative();
1503    }
1504
1505    @Override
1506    public boolean isNotEqual( final boolean aScalar )
1507    {
1508        return this.booleanValue() != aScalar;
1509    }
1510
1511    @Override
1512    public boolean isNotEqual( final byte aScalar )
1513    {
1514        return this.byteValue() != aScalar;
1515    }
1516
1517    @Override
1518    public boolean isNotEqual( final char aScalar )
1519    {
1520        return this.charValue() != aScalar;
1521    }
1522
1523    @Override
1524    public boolean isNotEqual( final double aScalar )
1525    {
1526        return this.compareToScalar(aScalar) != 0;
1527    }
1528
1529    @Override
1530    public boolean isNotEqual( final float aScalar )
1531    {
1532        return this.compareToScalar(aScalar) != 0;
1533    }
1534
1535    @Override
1536    public boolean isNotEqual( final int aScalar )
1537    {
1538        return this.intValue() != aScalar;
1539    }
1540
1541    @Override
1542    public boolean isNotEqual( final long aScalar )
1543    {
1544        return this.longValue() != aScalar;
1545    }
1546
1547    @Override
1548    public boolean isNotEqual( final short aScalar )
1549    {
1550        return this.shortValue() != aScalar;
1551    }
1552
1553    @Override
1554    public boolean isNotEqualToNumber( final Number aNumber )
1555    {
1556        final NumericPrecision myPrecision = this.getPrecision();
1557        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
1558        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1559        switch (prec) {
1560        case NULL:
1561            return !this.isZero();
1562        case BYTE:
1563            return this.isNotEqual(aNumber.byteValue());
1564        case SHORT:
1565            return this.isNotEqual(aNumber.shortValue());
1566        case INTEGER:
1567            return this.isNotEqual(aNumber.intValue());
1568        case LONG:
1569            return this.isNotEqual(aNumber.longValue());
1570        case FLOAT:
1571            return this.isNotEqual(aNumber.floatValue());
1572        }
1573        return this.isNotEqual(aNumber.doubleValue());
1574    }
1575
1576    @Override
1577    public boolean isNotEqualToScalar( final SealedScalar<?> aScalar )
1578    {
1579        final NumericPrecision myPrecision = this.getPrecision();
1580        final NumericPrecision aPrecision = aScalar.getPrecision();
1581        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1582        switch (prec) {
1583        case NULL:
1584            return !this.isZero();
1585        case BIT:
1586            return this.isNotEqual(aScalar.booleanValue());
1587        case BYTE:
1588            return this.isNotEqual(aScalar.byteValue());
1589        case SHORT:
1590            return this.isNotEqual(aScalar.shortValue());
1591        case CHARACTER:
1592            return this.isNotEqual(aScalar.charValue());
1593        case INTEGER:
1594            return this.isNotEqual(aScalar.intValue());
1595        case LONG:
1596            return this.isNotEqual(aScalar.longValue());
1597        case FLOAT:
1598            return this.isNotEqual(aScalar.floatValue());
1599        }
1600        return this.isNotEqual(aScalar.doubleValue());
1601    }
1602
1603    @Override
1604    public boolean isOrdered()
1605    {
1606        return false;
1607    }
1608
1609    @Override
1610    public boolean isPositiveFinite()
1611    {
1612        return this.isFinite() && this.isPositive();
1613    }
1614
1615    @Override
1616    public boolean isReducible()
1617    {
1618        return this.isElastic();
1619    }
1620
1621    @Override
1622    public boolean isSupplementaryCodePoint()
1623    {
1624        return Character.isSupplementaryCodePoint(this.intValue());
1625    }
1626
1627    @Override
1628    public boolean isSurrogate()
1629    {
1630        return Character.isSurrogate(this.charValue());
1631    }
1632
1633    @Override
1634    public boolean isTitleCase()
1635    {
1636        return Character.isTitleCase(this.intValue());
1637    }
1638
1639    @Override
1640    public final boolean isTrue()
1641    {
1642        return this.booleanValue();
1643    }
1644
1645    @Override
1646    public boolean isUnicode()
1647    {
1648        return Character.isDefined(this.intValue());
1649    }
1650
1651    @Override
1652    public boolean isUnicodeIdentifierPart()
1653    {
1654        return Character.isUnicodeIdentifierPart(this.intValue());
1655    }
1656
1657    @Override
1658    public boolean isUnicodeIdentifierStart()
1659    {
1660        return Character.isUnicodeIdentifierStart(this.intValue());
1661    }
1662
1663    @Override
1664    public boolean isUnique()
1665    {
1666        return false;
1667    }
1668
1669    @Override
1670    public boolean isUpperCase()
1671    {
1672        return Character.isUpperCase(this.intValue());
1673    }
1674
1675    @Override
1676    public final boolean isValid()
1677    {
1678        return !this.isInvalid();
1679    }
1680
1681    @Override
1682    public boolean isValidCodePoint()
1683    {
1684        return Character.isValidCodePoint(this.intValue());
1685    }
1686
1687    @Override
1688    public boolean isWhitespace()
1689    {
1690        return Character.isWhitespace(this.intValue());
1691    }
1692
1693    @Override
1694    public long longSize()
1695    {
1696        return this.size();
1697    }
1698
1699    @Override
1700    public SCALAR milliseconds() throws UnsupportedOperationException
1701    {
1702        return this.setScalar(System.currentTimeMillis());
1703    }
1704
1705    @SuppressWarnings( "unchecked" )
1706    @Override
1707    public SCALAR mod( final boolean aValue )
1708        throws UnsupportedOperationException,
1709            IllegalArgumentException,
1710            ArithmeticException
1711    {
1712        if (!aValue) return this.mod(0);
1713        return (SCALAR)this;
1714    }
1715
1716    @Override
1717    public SCALAR mod( final byte aValue )
1718        throws UnsupportedOperationException,
1719            IllegalArgumentException,
1720            ArithmeticException
1721    {
1722        return this.setScalar(this.byteValue() % aValue);
1723    }
1724
1725    @Override
1726    public SCALAR mod( final char aValue )
1727        throws UnsupportedOperationException,
1728            IllegalArgumentException,
1729            ArithmeticException
1730    {
1731        return this.setScalar(this.charValue() % aValue);
1732    }
1733
1734    @Override
1735    public SCALAR mod( final double aValue )
1736        throws UnsupportedOperationException,
1737            IllegalArgumentException,
1738            ArithmeticException
1739    {
1740        return this.setScalar(this.doubleValue() % aValue);
1741    }
1742
1743    @Override
1744    public SCALAR mod( final float aValue )
1745        throws UnsupportedOperationException,
1746            IllegalArgumentException,
1747            ArithmeticException
1748    {
1749        return this.setScalar(this.floatValue() % aValue);
1750    }
1751
1752    @Override
1753    public SCALAR mod( final int aValue )
1754        throws UnsupportedOperationException,
1755            IllegalArgumentException,
1756            ArithmeticException
1757    {
1758        return this.setScalar(this.intValue() % aValue);
1759    }
1760
1761    @Override
1762    public SCALAR mod( final long aValue )
1763        throws UnsupportedOperationException,
1764            IllegalArgumentException,
1765            ArithmeticException
1766    {
1767        return this.setScalar(this.longValue() % aValue);
1768    }
1769
1770    @Override
1771    public SCALAR mod( final short aValue )
1772        throws UnsupportedOperationException,
1773            IllegalArgumentException,
1774            ArithmeticException
1775    {
1776        return this.setScalar(this.shortValue() % aValue);
1777    }
1778
1779    @Override
1780    public SCALAR modOfNumber( final Number aNumber )
1781        throws UnsupportedOperationException,
1782            IllegalArgumentException,
1783            ArithmeticException
1784    {
1785        final NumericPrecision myPrecision = this.getPrecision();
1786        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aNumber);
1787        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1788        switch (prec) {
1789        case NULL:
1790            return this.mod(0);
1791        case BYTE:
1792            return this.mod(aNumber.byteValue());
1793        case SHORT:
1794            return this.mod(aNumber.shortValue());
1795        case INTEGER:
1796            return this.mod(aNumber.intValue());
1797        case LONG:
1798            return this.mod(aNumber.longValue());
1799        case FLOAT:
1800            return this.mod(aNumber.floatValue());
1801        }
1802        return this.mod(aNumber.doubleValue());
1803    }
1804
1805    @Override
1806    public SCALAR modOfScalar( final SealedScalar<?> aValue )
1807        throws UnsupportedOperationException,
1808            IllegalArgumentException,
1809            ArithmeticException
1810    {
1811        final NumericPrecision myPrecision = this.getPrecision();
1812        final NumericPrecision aPrecision = aValue.getPrecision();
1813        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1814        switch (prec) {
1815        case NULL:
1816            return this.mod(0);
1817        case BIT:
1818            return this.mod(aValue.booleanValue());
1819        case BYTE:
1820            return this.mod(aValue.byteValue());
1821        case SHORT:
1822            return this.mod(aValue.shortValue());
1823        case CHARACTER:
1824            return this.mod(aValue.charValue());
1825        case INTEGER:
1826            return this.mod(aValue.intValue());
1827        case LONG:
1828            return this.mod(aValue.longValue());
1829        case FLOAT:
1830            return this.mod(aValue.floatValue());
1831        }
1832        return this.mod(aValue.doubleValue());
1833    }
1834
1835    @Override
1836    public SCALAR nanoseconds() throws UnsupportedOperationException
1837    {
1838        return this.setScalar(System.nanoTime());
1839    }
1840
1841    @Override
1842    public SCALAR naturalLog()
1843        throws UnsupportedOperationException,
1844            IllegalArgumentException,
1845            ArithmeticException
1846    {
1847        return this.setScalar(Math.log(this.doubleValue()));
1848    }
1849
1850    @Override
1851    public SCALAR naturalLogPlusOne()
1852        throws UnsupportedOperationException,
1853            IllegalArgumentException,
1854            ArithmeticException
1855    {
1856        return this.setScalar(Math.log1p(this.doubleValue()));
1857    }
1858
1859    @Override
1860    public SCALAR or( final boolean aValue )
1861        throws UnsupportedOperationException,
1862            IllegalArgumentException,
1863            ArithmeticException
1864    {
1865        return this.setScalar(this.booleanValue() | aValue);
1866    }
1867
1868    @Override
1869    public SCALAR or( final byte aValue )
1870        throws UnsupportedOperationException,
1871            IllegalArgumentException,
1872            ArithmeticException
1873    {
1874        return this.setScalar(this.byteValue() | aValue);
1875    }
1876
1877    @Override
1878    public SCALAR or( final char aValue )
1879        throws UnsupportedOperationException,
1880            IllegalArgumentException,
1881            ArithmeticException
1882    {
1883        return this.setScalar(this.charValue() | aValue);
1884    }
1885
1886    @Override
1887    public SCALAR or( final int aValue )
1888        throws UnsupportedOperationException,
1889            IllegalArgumentException,
1890            ArithmeticException
1891    {
1892        return this.setScalar(this.intValue() | aValue);
1893    }
1894
1895    @Override
1896    public SCALAR or( final long aValue )
1897        throws UnsupportedOperationException,
1898            IllegalArgumentException,
1899            ArithmeticException
1900    {
1901        return this.setScalar(this.longValue() | aValue);
1902    }
1903
1904    @Override
1905    public SCALAR or( final short aValue )
1906        throws UnsupportedOperationException,
1907            IllegalArgumentException,
1908            ArithmeticException
1909    {
1910        return this.setScalar(this.shortValue() | aValue);
1911    }
1912
1913    @Override
1914    @SuppressWarnings( "unchecked" )
1915    public SCALAR orOfNumber( final Number aValue )
1916        throws UnsupportedOperationException,
1917            IllegalArgumentException,
1918            ArithmeticException
1919    {
1920        final NumericPrecision myPrecision = this.getPrecision();
1921        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1922        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1923        switch (prec) {
1924        case NULL:
1925            return (SCALAR)this;
1926        case BYTE:
1927            return this.or(aValue.byteValue());
1928        case SHORT:
1929            return this.or(aValue.shortValue());
1930        case INTEGER:
1931            return this.or(aValue.intValue());
1932        }
1933        return this.or(aValue.longValue());
1934    }
1935
1936    @Override
1937    @SuppressWarnings( "unchecked" )
1938    public final SCALAR orOfScalar( final SealedScalar<?> aValue )
1939        throws UnsupportedOperationException,
1940            IllegalArgumentException,
1941            ArithmeticException
1942    {
1943        final NumericPrecision myPrecision = this.getPrecision();
1944        final NumericPrecision aPrecision = aValue.getPrecision();
1945        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1946        switch (prec) {
1947        case NULL:
1948            return (SCALAR)this;
1949        case BIT:
1950            return this.or(aValue.booleanValue());
1951        case BYTE:
1952            return this.or(aValue.byteValue());
1953        case SHORT:
1954            return this.or(aValue.shortValue());
1955        case CHARACTER:
1956            return this.or(aValue.charValue());
1957        case INTEGER:
1958            return this.or(aValue.intValue());
1959        }
1960        return this.or(aValue.longValue());
1961    }
1962
1963    @Override
1964    public SCALAR power( final double n )
1965        throws UnsupportedOperationException,
1966            IllegalArgumentException,
1967            ArithmeticException
1968    {
1969        return this.setScalar(Math.pow(this.doubleValue(), n));
1970    }
1971
1972    @Override
1973    public SCALAR power( final int n )
1974        throws UnsupportedOperationException,
1975            IllegalArgumentException,
1976            ArithmeticException
1977    {
1978        return this.setScalar(Math.pow(this.doubleValue(), n));
1979    }
1980
1981    @Override
1982    public final SCALAR powerOfNumber( final Number aValue )
1983        throws UnsupportedOperationException,
1984            IllegalArgumentException,
1985            ArithmeticException
1986    {
1987        final NumericPrecision myPrecision = this.getPrecision();
1988        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
1989        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
1990        switch (prec) {
1991        case NULL:
1992            return this.setUnity();
1993        case BYTE:
1994        case SHORT:
1995        case INTEGER:
1996            return this.power(aValue.intValue());
1997        }
1998        return this.power(aValue.doubleValue());
1999    }
2000
2001    @Override
2002    public SCALAR powerOfScalar( final SealedScalar<?> aValue )
2003        throws UnsupportedOperationException,
2004            IllegalArgumentException,
2005            ArithmeticException
2006    {
2007        final NumericPrecision myPrecision = this.getPrecision();
2008        final NumericPrecision aPrecision = aValue.getPrecision();
2009        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2010        switch (prec) {
2011        case NULL:
2012            return this.setUnity();
2013        case BIT:
2014            return this.power(To.intValue(aValue.booleanValue()));
2015        case BYTE:
2016        case SHORT:
2017        case CHARACTER:
2018        case INTEGER:
2019            return this.power(aValue.intValue());
2020        }
2021        return this.power(aValue.doubleValue());
2022    }
2023
2024    @Override
2025    @SuppressWarnings( "unchecked" )
2026    public SCALAR product( final boolean aValue )
2027        throws UnsupportedOperationException,
2028            IllegalArgumentException,
2029            ArithmeticException
2030    {
2031        if (!aValue) return this.setZero();
2032        return (SCALAR)this;
2033    }
2034
2035    @Override
2036    public SCALAR product( final byte aValue )
2037        throws UnsupportedOperationException,
2038            IllegalArgumentException,
2039            ArithmeticException
2040    {
2041        return this.setScalar(this.byteValue() * aValue);
2042    }
2043
2044    @Override
2045    public SCALAR product( final char aValue )
2046        throws UnsupportedOperationException,
2047            IllegalArgumentException,
2048            ArithmeticException
2049    {
2050        return this.setScalar(this.charValue() * aValue);
2051    }
2052
2053    @Override
2054    public SCALAR product( final double aValue )
2055        throws UnsupportedOperationException,
2056            IllegalArgumentException,
2057            ArithmeticException
2058    {
2059        return this.setScalar(this.doubleValue() * aValue);
2060    }
2061
2062    @Override
2063    public SCALAR product( final float aValue )
2064        throws UnsupportedOperationException,
2065            IllegalArgumentException,
2066            ArithmeticException
2067    {
2068        return this.setScalar(this.floatValue() * aValue);
2069    }
2070
2071    @Override
2072    public SCALAR product( final int aValue )
2073        throws UnsupportedOperationException,
2074            IllegalArgumentException,
2075            ArithmeticException
2076    {
2077        return this.setScalar(this.intValue() * aValue);
2078    }
2079
2080    @Override
2081    public SCALAR product( final long aValue )
2082        throws UnsupportedOperationException,
2083            IllegalArgumentException,
2084            ArithmeticException
2085    {
2086        return this.setScalar(this.longValue() * aValue);
2087    }
2088
2089    @Override
2090    public SCALAR product( final short aValue )
2091        throws UnsupportedOperationException,
2092            IllegalArgumentException,
2093            ArithmeticException
2094    {
2095        return this.setScalar(this.shortValue() * aValue);
2096    }
2097
2098    @Override
2099    public SCALAR productOfNumber( final Number aValue )
2100        throws UnsupportedOperationException,
2101            IllegalArgumentException,
2102            ArithmeticException
2103    {
2104        final NumericPrecision myPrecision = this.getPrecision();
2105        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
2106        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2107        switch (prec) {
2108        case NULL:
2109            return this.setZero();
2110        case BYTE:
2111            return this.product(aValue.byteValue());
2112        case SHORT:
2113            return this.product(aValue.shortValue());
2114        case INTEGER:
2115            return this.product(aValue.intValue());
2116        case LONG:
2117            return this.product(aValue.longValue());
2118        case FLOAT:
2119            return this.product(aValue.floatValue());
2120        }
2121        return this.product(aValue.doubleValue());
2122    }
2123
2124    @Override
2125    public SCALAR productOfScalar( final SealedScalar<?> aValue )
2126        throws UnsupportedOperationException,
2127            IllegalArgumentException,
2128            ArithmeticException
2129    {
2130        final NumericPrecision myPrecision = this.getPrecision();
2131        final NumericPrecision aPrecision = aValue.getPrecision();
2132        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2133        switch (prec) {
2134        case NULL:
2135            return this.setZero();
2136        case BIT:
2137            return this.product(aValue.booleanValue());
2138        case BYTE:
2139            return this.product(aValue.byteValue());
2140        case SHORT:
2141            return this.product(aValue.shortValue());
2142        case CHARACTER:
2143            return this.product(aValue.charValue());
2144        case INTEGER:
2145            return this.product(aValue.intValue());
2146        case LONG:
2147            return this.product(aValue.longValue());
2148        case FLOAT:
2149            return this.product(aValue.floatValue());
2150        }
2151        return this.product(aValue.doubleValue());
2152    }
2153
2154    @Override
2155    @SuppressWarnings( "unchecked" )
2156    public SCALAR promoteTo( final NumericPrecision prec )
2157    {
2158        return (SCALAR)this;
2159    }
2160
2161    @Override
2162    @SuppressWarnings( "unchecked" )
2163    public SCALAR quotient( final boolean aValue )
2164        throws UnsupportedOperationException,
2165            IllegalArgumentException,
2166            ArithmeticException
2167    {
2168        if (!aValue) return this.quotient(0);
2169        return (SCALAR)this;
2170    }
2171
2172    @Override
2173    public SCALAR quotient( final byte aValue )
2174        throws UnsupportedOperationException,
2175            IllegalArgumentException,
2176            ArithmeticException
2177    {
2178        return this.setScalar(this.byteValue() / aValue);
2179    }
2180
2181    @Override
2182    public SCALAR quotient( final char aValue )
2183        throws UnsupportedOperationException,
2184            IllegalArgumentException,
2185            ArithmeticException
2186    {
2187        return this.setScalar(this.charValue() / aValue);
2188    }
2189
2190    @Override
2191    public SCALAR quotient( final double aValue )
2192        throws UnsupportedOperationException,
2193            IllegalArgumentException,
2194            ArithmeticException
2195    {
2196        return this.setScalar(this.doubleValue() / aValue);
2197    }
2198
2199    @Override
2200    public SCALAR quotient( final float aValue )
2201        throws UnsupportedOperationException,
2202            IllegalArgumentException,
2203            ArithmeticException
2204    {
2205        return this.setScalar(this.floatValue() / aValue);
2206    }
2207
2208    @Override
2209    public SCALAR quotient( final int aValue )
2210        throws UnsupportedOperationException,
2211            IllegalArgumentException,
2212            ArithmeticException
2213    {
2214        return this.setScalar(this.intValue() / aValue);
2215    }
2216
2217    @Override
2218    public SCALAR quotient( final long aValue )
2219        throws UnsupportedOperationException,
2220            IllegalArgumentException,
2221            ArithmeticException
2222    {
2223        return this.setScalar(this.longValue() / aValue);
2224    }
2225
2226    @Override
2227    public SCALAR quotient( final short aValue )
2228        throws UnsupportedOperationException,
2229            IllegalArgumentException,
2230            ArithmeticException
2231    {
2232        return this.setScalar(this.shortValue() / aValue);
2233    }
2234
2235    @Override
2236    public SCALAR quotientOfNumber( final Number aValue )
2237        throws UnsupportedOperationException,
2238            IllegalArgumentException,
2239            ArithmeticException
2240    {
2241        final NumericPrecision myPrecision = this.getPrecision();
2242        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
2243        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2244        switch (prec) {
2245        case NULL:
2246            return this.quotient(0);
2247        case BYTE:
2248            return this.quotient(aValue.byteValue());
2249        case SHORT:
2250            return this.quotient(aValue.shortValue());
2251        case INTEGER:
2252            return this.quotient(aValue.intValue());
2253        case LONG:
2254            return this.quotient(aValue.longValue());
2255        case FLOAT:
2256            return this.quotient(aValue.floatValue());
2257        }
2258        return this.quotient(aValue.doubleValue());
2259    }
2260
2261    @Override
2262    public SCALAR quotientOfScalar( final SealedScalar<?> aValue )
2263        throws UnsupportedOperationException,
2264            IllegalArgumentException,
2265            ArithmeticException
2266    {
2267        final NumericPrecision myPrecision = this.getPrecision();
2268        final NumericPrecision aPrecision = aValue.getPrecision();
2269        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2270        switch (prec) {
2271        case NULL:
2272            return this.quotient(0);
2273        case BIT:
2274            return this.quotient(aValue.booleanValue());
2275        case BYTE:
2276            return this.quotient(aValue.byteValue());
2277        case SHORT:
2278            return this.quotient(aValue.shortValue());
2279        case CHARACTER:
2280            return this.quotient(aValue.charValue());
2281        case INTEGER:
2282            return this.quotient(aValue.intValue());
2283        case LONG:
2284            return this.quotient(aValue.longValue());
2285        case FLOAT:
2286            return this.quotient(aValue.floatValue());
2287        }
2288        return this.quotient(aValue.doubleValue());
2289    }
2290
2291    @Override
2292    public SCALAR radians()
2293        throws UnsupportedOperationException,
2294            IllegalArgumentException,
2295            ArithmeticException
2296    {
2297        return this.setScalar(Math.toRadians(this.doubleValue()));
2298    }
2299
2300    @Override
2301    public SCALAR random() throws UnsupportedOperationException
2302    {
2303        return this.setScalar(Math.random());
2304    }
2305
2306    @Override
2307    public SCALAR setE()
2308        throws UnsupportedOperationException,
2309            IllegalArgumentException,
2310            ArithmeticException
2311    {
2312        return this.setScalar(Math.E);
2313    }
2314
2315    @Override
2316    public <E extends Enum<E>> SCALAR setEnumeration( final E aValue )
2317        throws UnsupportedOperationException,
2318            ArithmeticException,
2319            IllegalArgumentException,
2320            NullPointerException
2321    {
2322        return this.setScalar(aValue.ordinal());
2323    }
2324
2325    @Override
2326    public SCALAR setFalse()
2327        throws UnsupportedOperationException,
2328            ArithmeticException
2329    {
2330        return this.setScalar(false);
2331    }
2332
2333    @Override
2334    public SCALAR setNegativeInfinity()
2335        throws UnsupportedOperationException,
2336            ArithmeticException,
2337            IllegalArgumentException
2338    {
2339        return this.setMinimum();
2340    }
2341
2342    @Override
2343    public SCALAR setNumber( final Number aValue )
2344        throws UnsupportedOperationException,
2345            IllegalArgumentException,
2346            ArithmeticException,
2347            NullPointerException
2348    {
2349        final NumericPrecision myPrecision = this.getPrecision();
2350        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
2351        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2352        switch (prec) {
2353        case NULL:
2354            return this.setZero();
2355        case BYTE:
2356            return this.setScalar(aValue.byteValue());
2357        case SHORT:
2358            return this.setScalar(aValue.shortValue());
2359        case INTEGER:
2360            return this.setScalar(aValue.intValue());
2361        case LONG:
2362            return this.setScalar(aValue.longValue());
2363        case FLOAT:
2364            return this.setScalar(aValue.floatValue());
2365        }
2366        return this.setScalar(aValue.doubleValue());
2367    }
2368
2369    @Override
2370    public SCALAR setPi()
2371        throws UnsupportedOperationException,
2372            IllegalArgumentException,
2373            ArithmeticException
2374    {
2375        return this.setScalar(Math.PI);
2376    }
2377
2378    @Override
2379    public SCALAR setPositiveInfinity()
2380        throws UnsupportedOperationException,
2381            ArithmeticException,
2382            IllegalArgumentException
2383    {
2384        return this.setMaximum();
2385    }
2386
2387    @Override
2388    public SCALAR setScalar( final SealedScalar<?> aValue )
2389        throws UnsupportedOperationException,
2390            IllegalArgumentException,
2391            ArithmeticException,
2392            NullPointerException
2393    {
2394        final NumericPrecision myPrecision = this.getPrecision();
2395        final NumericPrecision aPrecision = aValue.getPrecision();
2396        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2397        switch (prec) {
2398        case NULL:
2399            return this.setZero();
2400        case BIT:
2401            return this.setScalar(aValue.booleanValue());
2402        case BYTE:
2403            return this.setScalar(aValue.byteValue());
2404        case SHORT:
2405            return this.setScalar(aValue.shortValue());
2406        case CHARACTER:
2407            return this.setScalar(aValue.charValue());
2408        case INTEGER:
2409            return this.setScalar(aValue.intValue());
2410        case LONG:
2411            return this.setScalar(aValue.longValue());
2412        case FLOAT:
2413            return this.setScalar(aValue.floatValue());
2414        }
2415        return this.setScalar(aValue.doubleValue());
2416    }
2417
2418    @Override
2419    public SCALAR setTrue()
2420        throws UnsupportedOperationException,
2421            ArithmeticException
2422    {
2423        return this.setScalar(true);
2424    }
2425
2426    @Override
2427    public SCALAR setUnity()
2428        throws UnsupportedOperationException,
2429            IllegalArgumentException,
2430            ArithmeticException
2431    {
2432        return this.setScalar(1);
2433    }
2434
2435    @Override
2436    public SCALAR setZero()
2437        throws UnsupportedOperationException,
2438            IllegalArgumentException,
2439            ArithmeticException
2440    {
2441        return this.setScalar(0);
2442    }
2443
2444    @Override
2445    public SCALAR shiftRightExtendZero( final int count )
2446        throws UnsupportedOperationException,
2447            IllegalArgumentException,
2448            ArithmeticException
2449    {
2450        return this.shiftRight(count);
2451    }
2452
2453    @Override
2454    public int signum()
2455    {
2456        if (this.isZero()) return 0;
2457        if (this.isPositive()) return +1;
2458        return -1;
2459    }
2460
2461    @Override
2462    public SCALAR sine()
2463        throws UnsupportedOperationException,
2464            IllegalArgumentException,
2465            ArithmeticException
2466    {
2467        return this.setScalar(Math.sin(this.doubleValue()));
2468    }
2469
2470    @Override
2471    public int size()
2472    {
2473        return this.getPrecision().size();
2474    }
2475
2476    @Override
2477    public SCALAR squareRoot()
2478        throws UnsupportedOperationException,
2479            IllegalArgumentException,
2480            ArithmeticException
2481    {
2482        return this.setScalar(Math.sqrt(this.doubleValue()));
2483    }
2484
2485    @Override
2486    public SCALAR sum( final boolean aValue )
2487        throws UnsupportedOperationException,
2488            IllegalArgumentException,
2489            ArithmeticException
2490    {
2491        return this.xor(aValue);
2492    }
2493
2494    @Override
2495    public SCALAR sum( final byte aValue )
2496        throws UnsupportedOperationException,
2497            IllegalArgumentException,
2498            ArithmeticException
2499    {
2500        return this.setScalar(this.byteValue() + aValue);
2501    }
2502
2503    @Override
2504    public SCALAR sum( final char aValue )
2505        throws UnsupportedOperationException,
2506            IllegalArgumentException,
2507            ArithmeticException
2508    {
2509        return this.setScalar(this.charValue() + aValue);
2510    }
2511
2512    @Override
2513    public SCALAR sum( final double aValue )
2514        throws UnsupportedOperationException,
2515            IllegalArgumentException,
2516            ArithmeticException
2517    {
2518        return this.setScalar(this.doubleValue() + aValue);
2519    }
2520
2521    @Override
2522    public SCALAR sum( final float aValue )
2523        throws UnsupportedOperationException,
2524            IllegalArgumentException,
2525            ArithmeticException
2526    {
2527        return this.setScalar(this.floatValue() + aValue);
2528    }
2529
2530    @Override
2531    public SCALAR sum( final int aValue )
2532        throws UnsupportedOperationException,
2533            IllegalArgumentException,
2534            ArithmeticException
2535    {
2536        return this.setScalar(this.intValue() + aValue);
2537    }
2538
2539    @Override
2540    public SCALAR sum( final long aValue )
2541        throws UnsupportedOperationException,
2542            IllegalArgumentException,
2543            ArithmeticException
2544    {
2545        return this.setScalar(this.longValue() + aValue);
2546    }
2547
2548    @Override
2549    public SCALAR sum( final short aValue )
2550        throws UnsupportedOperationException,
2551            IllegalArgumentException,
2552            ArithmeticException
2553    {
2554        return this.setScalar(this.shortValue() + aValue);
2555    }
2556
2557    @Override
2558    @SuppressWarnings( "unchecked" )
2559    public SCALAR sumOfNumber( final Number aValue )
2560        throws UnsupportedOperationException,
2561            IllegalArgumentException,
2562            ArithmeticException
2563    {
2564        final NumericPrecision myPrecision = this.getPrecision();
2565        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
2566        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2567        switch (prec) {
2568        case NULL:
2569            return (SCALAR)this;
2570        case BYTE:
2571            return this.sum(aValue.byteValue());
2572        case SHORT:
2573            return this.sum(aValue.shortValue());
2574        case INTEGER:
2575            return this.sum(aValue.intValue());
2576        case LONG:
2577            return this.sum(aValue.longValue());
2578        case FLOAT:
2579            return this.sum(aValue.floatValue());
2580        }
2581        return this.sum(aValue.doubleValue());
2582    }
2583
2584    @Override
2585    @SuppressWarnings( "unchecked" )
2586    public SCALAR sumOfScalar( final SealedScalar<?> aValue )
2587        throws UnsupportedOperationException,
2588            IllegalArgumentException,
2589            ArithmeticException
2590    {
2591        final NumericPrecision myPrecision = this.getPrecision();
2592        final NumericPrecision aPrecision = aValue.getPrecision();
2593        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2594        switch (prec) {
2595        case NULL:
2596            return (SCALAR)this;
2597        case BIT:
2598            return this.sum(aValue.booleanValue());
2599        case BYTE:
2600            return this.sum(aValue.byteValue());
2601        case SHORT:
2602            return this.sum(aValue.shortValue());
2603        case CHARACTER:
2604            return this.sum(aValue.charValue());
2605        case INTEGER:
2606            return this.sum(aValue.intValue());
2607        case LONG:
2608            return this.sum(aValue.longValue());
2609        case FLOAT:
2610            return this.sum(aValue.floatValue());
2611        }
2612        return this.sum(aValue.doubleValue());
2613    }
2614
2615    @Override
2616    public SCALAR tangent()
2617        throws UnsupportedOperationException,
2618            IllegalArgumentException,
2619            ArithmeticException
2620    {
2621        return this.setScalar(Math.tan(this.doubleValue()));
2622    }
2623
2624    @Override
2625    public Boolean toBoolean()
2626    {
2627        return this.booleanValue() ? Boolean.TRUE : Boolean.FALSE;
2628    }
2629
2630    @Override
2631    public Character toCharacter()
2632    {
2633        return Character.valueOf(this.charValue());
2634    }
2635
2636    @Override
2637    public int toCodePoint()
2638    {
2639        return this.intValue();
2640    }
2641
2642    @Override
2643    public <E extends Enum<E>> E toEnumeration(
2644        final Class<E> anEnumerationClass )
2645        throws ArithmeticException,
2646            IllegalArgumentException,
2647            NullPointerException
2648    {
2649        if (this.isPositiveFinite() || this.isZero()) {
2650            final E[] values = anEnumerationClass.getEnumConstants();
2651            if (values.length == 0)
2652                throw new IllegalArgumentException("No values to convert to: "
2653                        + anEnumerationClass.getSimpleName());
2654            final int anIndex = this.intValue() % values.length;
2655            return values[anIndex];
2656        }
2657        throw new ArithmeticException("Cannot convert to "
2658                + anEnumerationClass.getSimpleName() + ": " + this.toString());
2659    }
2660
2661    @Override
2662    public Scalar<?> toScalar()
2663    {
2664        return this.copy();
2665    }
2666
2667    @Override
2668    public final SCALAR up()
2669        throws UnsupportedOperationException,
2670            IllegalArgumentException,
2671            ArithmeticException
2672    {
2673        return this.round(RoundingStrategy.UP);
2674    }
2675
2676    @Override
2677    public SCALAR xor( final boolean aValue )
2678        throws UnsupportedOperationException,
2679            IllegalArgumentException,
2680            ArithmeticException
2681    {
2682        return this.setScalar(this.booleanValue() ^ aValue);
2683    }
2684
2685    @Override
2686    public SCALAR xor( final byte aValue )
2687        throws UnsupportedOperationException,
2688            IllegalArgumentException,
2689            ArithmeticException
2690    {
2691        return this.setScalar(this.byteValue() ^ aValue);
2692    }
2693
2694    @Override
2695    public SCALAR xor( final char aValue )
2696        throws UnsupportedOperationException,
2697            IllegalArgumentException,
2698            ArithmeticException
2699    {
2700        return this.setScalar(this.charValue() ^ aValue);
2701    }
2702
2703    @Override
2704    public SCALAR xor( final int aValue )
2705        throws UnsupportedOperationException,
2706            IllegalArgumentException,
2707            ArithmeticException
2708    {
2709        return this.setScalar(this.intValue() ^ aValue);
2710    }
2711
2712    @Override
2713    public SCALAR xor( final long aValue )
2714        throws UnsupportedOperationException,
2715            IllegalArgumentException,
2716            ArithmeticException
2717    {
2718        return this.setScalar(this.longValue() ^ aValue);
2719    }
2720
2721    @Override
2722    public SCALAR xor( final short aValue )
2723        throws UnsupportedOperationException,
2724            IllegalArgumentException,
2725            ArithmeticException
2726    {
2727        return this.setScalar(this.shortValue() ^ aValue);
2728    }
2729
2730    @Override
2731    @SuppressWarnings( "unchecked" )
2732    public SCALAR xorOfNumber( final Number aValue )
2733        throws UnsupportedOperationException,
2734            IllegalArgumentException,
2735            ArithmeticException
2736    {
2737        final NumericPrecision myPrecision = this.getPrecision();
2738        final NumericPrecision aPrecision = NumericPrecision.getPrecisionFor(aValue);
2739        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2740        switch (prec) {
2741        case NULL:
2742            return (SCALAR)this;
2743        case BYTE:
2744            return this.xor(aValue.byteValue());
2745        case SHORT:
2746            return this.xor(aValue.shortValue());
2747        case INTEGER:
2748            return this.xor(aValue.intValue());
2749        }
2750        return this.xor(aValue.longValue());
2751    }
2752
2753    @Override
2754    public final SCALAR xorOfScalar( final SealedScalar<?> aValue )
2755        throws UnsupportedOperationException,
2756            IllegalArgumentException,
2757            ArithmeticException
2758    {
2759        final NumericPrecision myPrecision = this.getPrecision();
2760        final NumericPrecision aPrecision = aValue.getPrecision();
2761        final NumericPrecision prec = myPrecision.maximumOf(aPrecision);
2762        switch (prec) {
2763        case NULL:
2764            return this.not();
2765        case BIT:
2766            return this.xor(aValue.booleanValue());
2767        case BYTE:
2768            return this.xor(aValue.byteValue());
2769        case SHORT:
2770            return this.xor(aValue.shortValue());
2771        case CHARACTER:
2772            return this.xor(aValue.charValue());
2773        case INTEGER:
2774            return this.xor(aValue.intValue());
2775        }
2776        return this.xor(aValue.longValue());
2777    }
2778
2779    public final static void boundsCheck(
2780        final int anIndex,
2781        final int anOrdinalBound ) throws IndexOutOfBoundsException
2782    {
2783        if (anIndex < 0 || anOrdinalBound <= anIndex) {
2784            indexOutOfBoundsAt(anIndex);
2785        }
2786    }
2787
2788    public final static byte byteMaskAt( final int aBitPosition )
2789    {
2790        return BYTE_MASKS[aBitPosition];
2791    }
2792
2793    public final static byte byteNotMaskAt( final int aBitPosition )
2794    {
2795        return BYTE_NOT_MASKS[aBitPosition];
2796    }
2797
2798    public final static byte byteValue( final boolean[] aBooleanArray )
2799    {
2800        byte aValue = 0;
2801        for (int i = 0; i < aBooleanArray.length; i++) {
2802            if (aBooleanArray[i]) {
2803                final byte aMask = BYTE_MASKS[i];
2804                aValue |= aMask;
2805            }
2806        }
2807        return aValue;
2808    }
2809
2810    public final static char charMaskAt( final int aBitPosition )
2811    {
2812        return CHARACTER_MASKS[aBitPosition];
2813    }
2814
2815    public final static char charNotMaskAt( final int aBitPosition )
2816    {
2817        return CHARACTER_NOT_MASKS[aBitPosition];
2818    }
2819
2820    public final static char charValue( final boolean[] aBooleanArray )
2821    {
2822        char aValue = 0;
2823        for (int i = 0; i < aBooleanArray.length; i++) {
2824            if (aBooleanArray[i]) {
2825                final char aMask = CHARACTER_MASKS[i];
2826                aValue |= aMask;
2827            }
2828        }
2829        return aValue;
2830    }
2831
2832    public final static byte clearByteBitAt(
2833        final int anIndex,
2834        final byte myValue ) throws IndexOutOfBoundsException
2835    {
2836        final byte changed = (byte)(myValue & BYTE_NOT_MASKS[anIndex]);
2837        return changed;
2838    }
2839
2840    public final static char clearCharBitAt(
2841        final int anIndex,
2842        final char myValue )
2843        throws UnsupportedOperationException,
2844            IndexOutOfBoundsException
2845    {
2846        final char changed = (char)(myValue & CHARACTER_NOT_MASKS[anIndex]);
2847        return changed;
2848    }
2849
2850    public final static double clearDoubleBitAt(
2851        final int anIndex,
2852        final double myValue )
2853        throws UnsupportedOperationException,
2854            IndexOutOfBoundsException
2855    {
2856        final long raw = Double.doubleToLongBits(myValue);
2857        final long changed = clearLongBitAt(anIndex, raw);
2858        return Double.longBitsToDouble(changed);
2859    }
2860
2861    public final static float clearFloatBitAt(
2862        final int anIndex,
2863        final float myValue )
2864        throws UnsupportedOperationException,
2865            IndexOutOfBoundsException
2866    {
2867        final int raw = Float.floatToIntBits(myValue);
2868        final int changed = clearIntBitAt(anIndex, raw);
2869        return Float.intBitsToFloat(changed);
2870    }
2871
2872    public final static int clearIntBitAt( final int anIndex, final int myValue )
2873        throws UnsupportedOperationException,
2874            IndexOutOfBoundsException
2875    {
2876        final int changed = myValue & INT_NOT_MASKS[anIndex];
2877        return changed;
2878    }
2879
2880    public final static long clearLongBitAt(
2881        final int anIndex,
2882        final long myValue )
2883        throws UnsupportedOperationException,
2884            IndexOutOfBoundsException
2885    {
2886        final long changed = myValue & LONG_NOT_MASKS[anIndex];
2887        return changed;
2888    }
2889
2890    public final static short clearShortBitAt(
2891        final int anIndex,
2892        final short myValue )
2893        throws UnsupportedOperationException,
2894            IndexOutOfBoundsException
2895    {
2896        final short changed = (short)(myValue & SHORT_NOT_MASKS[anIndex]);
2897        return changed;
2898    }
2899
2900    public final static BigDecimal clearUnlimitedDecimalBitAt(
2901        final int anIndex,
2902        final BigDecimal myValue )
2903        throws UnsupportedOperationException,
2904            IndexOutOfBoundsException
2905    {
2906        final StringBuilder sb = new StringBuilder(myValue.toString());
2907        final char aChar = sb.charAt(anIndex);
2908        switch (aChar) {
2909        case '1':
2910        case '2':
2911        case '3':
2912        case '4':
2913        case '5':
2914        case '6':
2915        case '7':
2916        case '8':
2917        case '9':
2918            sb.setCharAt(anIndex, '0');
2919            break;
2920        case '+':
2921            sb.setCharAt(anIndex, '-');
2922            break;
2923        default:
2924            return myValue;
2925        }
2926        return new BigDecimal(sb.toString());
2927    }
2928
2929    public final static BigInteger clearUnlimitedIntegerBitAt(
2930        final int anIndex,
2931        final BigInteger myValue )
2932        throws UnsupportedOperationException,
2933            IndexOutOfBoundsException
2934    {
2935        if (anIndex < 0) {
2936            indexOutOfBoundsAt(anIndex);
2937        }
2938        return myValue.clearBit(anIndex);
2939    }
2940
2941    public static final int compareTo( final BigDecimal p0, final BigDecimal p1 )
2942    {
2943        return p0.compareTo(p1);
2944    }
2945
2946    public static final int compareTo( final BigInteger p0, final BigInteger p1 )
2947    {
2948        return p0.compareTo(p1);
2949    }
2950
2951    public static final int compareTo( final boolean p0, final boolean p1 )
2952    {
2953        return p0 == p1 ? 0 : p1 ? -1 : +1;
2954    }
2955
2956    public static final int compareTo( final byte p0, final byte p1 )
2957    {
2958        return p0 - p1;
2959    }
2960
2961    public static final int compareTo( final char p0, final char p1 )
2962    {
2963        return p0 - p1;
2964    }
2965
2966    public static final int compareTo(
2967        final CharSequence p0,
2968        final CharSequence p1 )
2969    {
2970        final int p0Length = p0.length();
2971        final int p1Length = p1.length();
2972        int i = 0;
2973        while (i < p0Length && i < p1Length) {
2974            final char c0 = p0.charAt(i);
2975            final char c1 = p1.charAt(i++);
2976            if (c0 < c1) return -1;
2977            if (c0 > c1) return +1;
2978        }
2979        return p0Length - p1Length;
2980    }
2981
2982    public static final int compareTo( final double p0, final double p1 )
2983    {
2984        return Double.compare(p0, p1);
2985    }
2986
2987    public static final int compareTo( final float p0, final float p1 )
2988    {
2989        return Float.compare(p0, p1);
2990    }
2991
2992    public static final int compareTo( final int p0, final int p1 )
2993    {
2994        return p0 - p1;
2995    }
2996
2997    public static final int compareTo( final long p0, final long p1 )
2998    {
2999        return (int)(p0 - p1);
3000    }
3001
3002    public static final int compareTo( final short p0, final short p1 )
3003    {
3004        return p0 - p1;
3005    }
3006
3007    @SuppressWarnings( "unused" )
3008    public final static void divideByZero()
3009    {
3010        final int bad = 1 / 0;
3011    }
3012
3013    public final static boolean getBooleanBitAt(
3014        final int anIndex,
3015        final boolean myValue )
3016        throws UnsupportedOperationException,
3017            IndexOutOfBoundsException
3018    {
3019        if (anIndex != 0) {
3020            indexOutOfBoundsAt(anIndex);
3021        }
3022        return myValue;
3023    }
3024
3025    public final static boolean getByteBitAt(
3026        final int anIndex,
3027        final byte myValue )
3028        throws UnsupportedOperationException,
3029            IndexOutOfBoundsException
3030    {
3031        final byte aMask = BYTE_MASKS[anIndex];
3032        final int masked = myValue & aMask;
3033        return masked != 0;
3034    }
3035
3036    public final static boolean getCharBitAt(
3037        final int anIndex,
3038        final char myValue )
3039        throws UnsupportedOperationException,
3040            IndexOutOfBoundsException
3041    {
3042        final char aMask = CHARACTER_MASKS[anIndex];
3043        final int masked = myValue & aMask;
3044        return masked != 0;
3045    }
3046
3047    public final static boolean getDoubleBitAt(
3048        final int anIndex,
3049        final double myValue )
3050        throws UnsupportedOperationException,
3051            IndexOutOfBoundsException
3052    {
3053        return getLongBitAt(anIndex, Double.doubleToRawLongBits(myValue));
3054    }
3055
3056    public final static boolean getFloatBitAt(
3057        final int anIndex,
3058        final float myValue )
3059        throws UnsupportedOperationException,
3060            IndexOutOfBoundsException
3061    {
3062        return getIntBitAt(anIndex, Float.floatToRawIntBits(myValue));
3063    }
3064
3065    public final static boolean getIntBitAt(
3066        final int anIndex,
3067        final int myValue )
3068        throws UnsupportedOperationException,
3069            IndexOutOfBoundsException
3070    {
3071        final int aMask = INT_MASKS[anIndex];
3072        final int masked = myValue & aMask;
3073        return masked != 0;
3074    }
3075
3076    public final static boolean getLongBitAt(
3077        final int anIndex,
3078        final long myValue )
3079        throws UnsupportedOperationException,
3080            IndexOutOfBoundsException
3081    {
3082        final long aMask = LONG_MASKS[anIndex];
3083        final long masked = myValue & aMask;
3084        return masked != 0L;
3085    }
3086
3087    public final static boolean getShortBitAt(
3088        final int anIndex,
3089        final short myValue )
3090        throws UnsupportedOperationException,
3091            IndexOutOfBoundsException
3092    {
3093        final short aMask = SHORT_MASKS[anIndex];
3094        final int masked = myValue & aMask;
3095        return masked != 0;
3096    }
3097
3098    public final static boolean getUnlimitedDecimalBitAt(
3099        final int anIndex,
3100        final BigDecimal myValue )
3101        throws UnsupportedOperationException,
3102            IndexOutOfBoundsException
3103    {
3104        final String aString = myValue.toString();
3105        final char aChar = aString.charAt(anIndex);
3106        switch (aChar) {
3107        case '1':
3108        case '2':
3109        case '3':
3110        case '4':
3111        case '5':
3112        case '6':
3113        case '7':
3114        case '8':
3115        case '9':
3116        case '+':
3117            return true;
3118        }
3119        return false;
3120    }
3121
3122    public final static boolean getUnlimitedIntegerBitAt(
3123        final int anIndex,
3124        final BigInteger myValue )
3125        throws UnsupportedOperationException,
3126            IndexOutOfBoundsException
3127    {
3128        if (anIndex < 0) {
3129            indexOutOfBoundsAt(anIndex);
3130        }
3131        return myValue.testBit(anIndex);
3132    }
3133
3134    public static final int hashCode( final boolean aValue )
3135    {
3136        return aValue ? Boolean.TRUE.hashCode() : Boolean.FALSE.hashCode();
3137    }
3138
3139    public static final int hashCode( final byte aValue )
3140    {
3141        return aValue;
3142    }
3143
3144    public static final int hashCode( final char aValue )
3145    {
3146        return aValue;
3147    }
3148
3149    public static final int hashCode( final double aValue )
3150    {
3151        return hashCode(Double.doubleToLongBits(aValue));
3152    }
3153
3154    public static final int hashCode( final float aValue )
3155    {
3156        return Float.floatToIntBits(aValue);
3157    }
3158
3159    public static final int hashCode( final int aValue )
3160    {
3161        return aValue;
3162    }
3163
3164    public static final int hashCode( final long aValue )
3165    {
3166        return (int)(aValue ^ aValue >>> 32);
3167    }
3168
3169    public static final int hashCode( final short aValue )
3170    {
3171        return aValue;
3172    }
3173
3174    public final static void indexOutOfBoundsAt( final int anIndex )
3175        throws IndexOutOfBoundsException
3176    {
3177        Collections.EMPTY_LIST.get(anIndex);
3178    }
3179
3180    public static final int intGCD( final int p0, final int p1 )
3181        throws UnsupportedOperationException,
3182            ArithmeticException,
3183            IllegalArgumentException
3184    {
3185        int x = p0;
3186        int y = p1;
3187        while (y != 0) {
3188            final int temp = y;
3189            y = x % y;
3190            x = temp;
3191        }
3192        return x;
3193    }
3194
3195    public final static int intMaskAt( final int aBitPosition )
3196    {
3197        return INT_MASKS[aBitPosition];
3198    }
3199
3200    public static final int intModularInverse( final int p0, final int p1 )
3201    {
3202        int aDivisor = p0;
3203        int aModulus = p1;
3204        final int modulus0 = aModulus;
3205
3206        int x = 0;
3207        int lastX = 1;
3208        int y = 1;
3209        int lastY = 0;
3210        while (aModulus != 0) {
3211            final int quotient = aDivisor / aModulus;
3212            int temp = aModulus;
3213            aModulus = aDivisor % aModulus;
3214            aDivisor = temp;
3215
3216            temp = x;
3217            x = lastX - quotient * x;
3218            lastX = temp;
3219
3220            temp = y;
3221            y = lastY - quotient * y;
3222            lastY = temp;
3223        }
3224        while (lastX < 0) {
3225            lastX = modulus0 + lastX;
3226        }
3227        return lastX;
3228    }
3229
3230    public static final int intModularQuotient(
3231        final int aDividend,
3232        final int aDivisor,
3233        final int aModulus )
3234    {
3235        final int inverse = intModularInverse(aDivisor, aModulus);
3236        final int product = aDividend * inverse % aModulus;
3237        return product;
3238    }
3239
3240    public final static int intNotMaskAt( final int aBitPosition )
3241    {
3242        return INT_NOT_MASKS[aBitPosition];
3243    }
3244
3245    public final static int intValue( final boolean[] aBooleanArray )
3246    {
3247        int aValue = 0;
3248        for (int i = 0; i < aBooleanArray.length; i++) {
3249            if (aBooleanArray[i]) {
3250                final int aMask = INT_MASKS[i];
3251                aValue |= aMask;
3252            }
3253        }
3254        return aValue;
3255    }
3256
3257    public static final long longGCD( final long p0, final long p1 )
3258        throws UnsupportedOperationException,
3259            ArithmeticException,
3260            IllegalArgumentException
3261    {
3262        long x = p0;
3263        long y = p1;
3264        while (y != 0) {
3265            final long temp = y;
3266            y = x % y;
3267            x = temp;
3268        }
3269        return x;
3270    }
3271
3272    public final static long longMaskAt( final int aBitPosition )
3273    {
3274        return LONG_MASKS[aBitPosition];
3275    }
3276
3277    public static final long longModularInverse( final long p0, final long p1 )
3278    {
3279        long aDivisor = p0;
3280        long aModulus = p1;
3281        final long modulus0 = aModulus;
3282
3283        long x = 0;
3284        long lastX = 1;
3285        long y = 1;
3286        long lastY = 0;
3287        while (aModulus != 0) {
3288            final long quotient = aDivisor / aModulus;
3289            long temp = aModulus;
3290            aModulus = aDivisor % aModulus;
3291            aDivisor = temp;
3292
3293            temp = x;
3294            x = lastX - quotient * x;
3295            lastX = temp;
3296
3297            temp = y;
3298            y = lastY - quotient * y;
3299            lastY = temp;
3300        }
3301        while (lastX < 0) {
3302            lastX = modulus0 + lastX;
3303        }
3304        return lastX;
3305    }
3306
3307    public static final long longModularQuotient(
3308        final long aDividend,
3309        final long aDivisor,
3310        final long aModulus )
3311    {
3312        final long inverse = longModularInverse(aDivisor, aModulus);
3313        final long product = aDividend * inverse % aModulus;
3314        return product;
3315    }
3316
3317    public final static long longNotMaskAt( final int aBitPosition )
3318    {
3319        return LONG_NOT_MASKS[aBitPosition];
3320    }
3321
3322    public final static long longValue( final boolean[] aBooleanArray )
3323    {
3324        long aValue = 0;
3325        for (int i = 0; i < aBooleanArray.length; i++) {
3326            if (aBooleanArray[i]) {
3327                final long aMask = LONG_MASKS[i];
3328                aValue |= aMask;
3329            }
3330        }
3331        return aValue;
3332    }
3333
3334    public final static byte setByteBitAt( final int anIndex, final byte myValue )
3335        throws IndexOutOfBoundsException
3336    {
3337        final byte changed = (byte)(myValue | BYTE_MASKS[anIndex]);
3338        return changed;
3339    }
3340
3341    public final static char setCharBitAt( final int anIndex, final char myValue )
3342        throws UnsupportedOperationException,
3343            IndexOutOfBoundsException
3344    {
3345        final char changed = (char)(myValue | CHARACTER_MASKS[anIndex]);
3346        return changed;
3347    }
3348
3349    public final static double setDoubleBitAt(
3350        final int anIndex,
3351        final double myValue )
3352        throws UnsupportedOperationException,
3353            IndexOutOfBoundsException
3354    {
3355        final long raw = Double.doubleToLongBits(myValue);
3356        final long changed = setLongBitAt(anIndex, raw);
3357        return Double.longBitsToDouble(changed);
3358    }
3359
3360    public final static float setFloatBitAt(
3361        final int anIndex,
3362        final float myValue )
3363        throws UnsupportedOperationException,
3364            IndexOutOfBoundsException
3365    {
3366        final int raw = Float.floatToIntBits(myValue);
3367        final int changed = setIntBitAt(anIndex, raw);
3368        return Float.intBitsToFloat(changed);
3369    }
3370
3371    public final static int setIntBitAt( final int anIndex, final int myValue )
3372        throws UnsupportedOperationException,
3373            IndexOutOfBoundsException
3374    {
3375        final int changed = myValue | INT_MASKS[anIndex];
3376        return changed;
3377    }
3378
3379    public final static long setLongBitAt( final int anIndex, final long myValue )
3380        throws UnsupportedOperationException,
3381            IndexOutOfBoundsException
3382    {
3383        final long changed = myValue | LONG_MASKS[anIndex];
3384        return changed;
3385    }
3386
3387    public final static short setShortBitAt(
3388        final int anIndex,
3389        final short myValue )
3390        throws UnsupportedOperationException,
3391            IndexOutOfBoundsException
3392    {
3393        final short changed = (short)(myValue | SHORT_MASKS[anIndex]);
3394        return changed;
3395    }
3396
3397    public final static BigDecimal setUnlimitedDecimalBitAt(
3398        final int anIndex,
3399        final BigDecimal myValue )
3400        throws UnsupportedOperationException,
3401            IndexOutOfBoundsException
3402    {
3403        final StringBuilder sb = new StringBuilder(myValue.toString());
3404        final char aChar = sb.charAt(anIndex);
3405        switch (aChar) {
3406        case '0':
3407            sb.setCharAt(anIndex, '1');
3408            break;
3409        case '-':
3410            sb.setCharAt(anIndex, '+');
3411            break;
3412        default:
3413            return myValue;
3414        }
3415        return new BigDecimal(sb.toString());
3416    }
3417
3418    public final static BigInteger setUnlimitedIntegerBitAt(
3419        final int anIndex,
3420        final BigInteger myValue )
3421        throws UnsupportedOperationException,
3422            IndexOutOfBoundsException
3423    {
3424        if (anIndex < 0) {
3425            indexOutOfBoundsAt(anIndex);
3426        }
3427        return myValue.setBit(anIndex);
3428    }
3429
3430    public final static short shortMaskAt( final int aBitPosition )
3431    {
3432        return SHORT_MASKS[aBitPosition];
3433    }
3434
3435    public final static short shortNotMaskAt( final int aBitPosition )
3436    {
3437        return SHORT_NOT_MASKS[aBitPosition];
3438    }
3439
3440    public final static short shortValue( final boolean[] aBooleanArray )
3441    {
3442        short aValue = 0;
3443        for (int i = 0; i < aBooleanArray.length; i++) {
3444            if (aBooleanArray[i]) {
3445                final short aMask = SHORT_MASKS[i];
3446                aValue |= aMask;
3447            }
3448        }
3449        return aValue;
3450    }
3451
3452    public final static boolean[] toBooleanArray( final BigDecimal aTuple )
3453    {
3454        final String aString = aTuple.toString();
3455        final boolean booleans[] = new boolean[aString.length()];
3456        for (int i = 0; i < aString.length(); i++) {
3457            final char aChar = aString.charAt(i);
3458            switch (aChar) {
3459            case '1':
3460            case '2':
3461            case '3':
3462            case '4':
3463            case '5':
3464            case '6':
3465            case '7':
3466            case '8':
3467            case '9':
3468            case '+':
3469                booleans[i] = true;
3470                break;
3471            default:
3472                booleans[i] = false;
3473                break;
3474            }
3475        }
3476        return booleans;
3477    }
3478
3479    public final static boolean[] toBooleanArray( final BigInteger aTuple )
3480    {
3481        final byte bytes[] = aTuple.toByteArray();
3482        final boolean booleans[] = new boolean[bytes.length * Byte.SIZE];
3483        int booleanIndex = 0;
3484        for (int byteIndex = 0; byteIndex < bytes.length; byteIndex++) {
3485            final boolean aBitSet[] = toBooleanArray(bytes[byteIndex]);
3486            for (int i = 0; i < Byte.SIZE; i++) {
3487                booleans[booleanIndex++] = aBitSet[i];
3488            }
3489        }
3490        return booleans;
3491    }
3492
3493    public final static boolean[] toBooleanArray( final boolean aTuple )
3494    {
3495        return new boolean[] { aTuple };
3496    }
3497
3498    public final static boolean[] toBooleanArray( final byte aTuple )
3499    {
3500        final boolean booleans[] = new boolean[Byte.SIZE];
3501        for (int i = 0; i < Byte.SIZE; i++) {
3502            booleans[i] = getByteBitAt(i, aTuple);
3503        }
3504        return booleans;
3505    }
3506
3507    public final static boolean[] toBooleanArray( final char aTuple )
3508    {
3509        final boolean booleans[] = new boolean[Character.SIZE];
3510        for (int i = 0; i < Character.SIZE; i++) {
3511            booleans[i] = getCharBitAt(i, aTuple);
3512        }
3513        return booleans;
3514    }
3515
3516    public final static boolean[] toBooleanArray( final CharSequence aTuple )
3517    {
3518        final boolean booleans[] = new boolean[aTuple.length()];
3519        for (int i = 0; i < aTuple.length(); i++) {
3520            final char aChar = aTuple.charAt(i);
3521            booleans[i] = aChar != '\0';
3522        }
3523        return booleans;
3524    }
3525
3526    public final static boolean[] toBooleanArray( final double aTuple )
3527    {
3528        return toBooleanArray(Double.doubleToRawLongBits(aTuple));
3529    }
3530
3531    public final static boolean[] toBooleanArray( final float aTuple )
3532    {
3533        return toBooleanArray(Float.floatToRawIntBits(aTuple));
3534    }
3535
3536    public final static boolean[] toBooleanArray( final int aTuple )
3537    {
3538        final boolean booleans[] = new boolean[Integer.SIZE];
3539        for (int i = 0; i < Integer.SIZE; i++) {
3540            booleans[i] = getIntBitAt(i, aTuple);
3541        }
3542        return booleans;
3543    }
3544
3545    public final static boolean[] toBooleanArray( final long aTuple )
3546    {
3547        final boolean booleans[] = new boolean[Long.SIZE];
3548        for (int i = 0; i < Long.SIZE; i++) {
3549            booleans[i] = getLongBitAt(i, aTuple);
3550        }
3551        return booleans;
3552    }
3553
3554    public final static boolean[] toBooleanArray( final short aTuple )
3555    {
3556        final boolean booleans[] = new boolean[Short.SIZE];
3557        for (int i = 0; i < Short.SIZE; i++) {
3558            booleans[i] = getShortBitAt(i, aTuple);
3559        }
3560        return booleans;
3561    }
3562
3563    public final static byte[] toByteArray( final boolean[] aBooleanArray )
3564    {
3565        final int byteCount = aBooleanArray.length / Byte.SIZE + 1;
3566        final byte bytes[] = new byte[byteCount];
3567        for (int i = 0; i < aBooleanArray.length; i++) {
3568            if (aBooleanArray[i]) {
3569                final int byteIndex = i / Byte.SIZE;
3570                final int bitIndex = i % Byte.SIZE;
3571                bytes[byteIndex] |= byteMaskAt(bitIndex);
3572            }
3573        }
3574        return bytes;
3575    }
3576
3577    public final static BigInteger toUnlimitedInteger(
3578        final boolean[] aBooleanArray )
3579    {
3580        final byte bytes[] = toByteArray(aBooleanArray);
3581        return new BigInteger(bytes);
3582    }
3583
3584    public final static BigInteger unlimitedIntegerMaskAt(
3585        final int aBitPosition )
3586    {
3587        return UI_MASKS[aBitPosition];
3588    }
3589
3590    public final static BigInteger unlimitedIntegerNotMaskAt(
3591        final int aBitPosition )
3592    {
3593        return UI_NOT_MASKS[aBitPosition];
3594    }
3595}