001/** A class representing the precision of a FixPoint number.
002
003 Copyright (c) 1998-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027
028 */
029package ptolemy.math;
030
031import java.math.BigDecimal;
032import java.math.BigInteger;
033import java.util.regex.Matcher;
034import java.util.regex.Pattern;
035
036/**
037 This class defines the precision of a signed or unsigned fixed point
038 value. The precision of a fixed point value is represented as
039 internally as three fields: the number of bits (<i>n</i>), the
040 binary exponent (<i>e</i>), and a sign bit (<i>s</i>).
041
042 The number of bits (<i>n</i>) defines the dynamic range of
043 the format (2<sup>n</sup>).
044
045 The exponent (<i>e</i>) determines the placement of the binary point
046 for all values of this format. This binary point placement is "fixed"
047 and is specified within the precision format rather than within individual
048 Fixed point values.  The mantissa bits of all fixed point values
049 using this this precision format are multiplied by 2<sup>m</sup>. Note that
050 <i>m</i> can take on a positive,  negative, or zero value. This allows
051 the binary point to be placed anywhere necessary and even beyond the bounds
052 of the mantissa (i.e. to the right of the lsb or to the left of the msb).
053
054 The sign value <i>s</i> is used to indicate whether the fixed point
055 precision value is treated as signed (s = 1) or unsigned (s = 0). <p>
056
057 <b>Signed</b> fixed point formats are represented in a 2's complement
058 format. As a consequence, a single bit is used to represent the
059 sign of the number. The value of a multi-bit signed number is: <p>
060
061 Signed(B)   = 2^m x (- b_{n-1} x 2^{n-1} + \sum_{i=0}^{n-2} b_i x 2^i),
062
063 where b_i is the value of bit i of the bit vector. <p>
064
065 <b>Unsigned</b> fixed formats are represented as unsigned binary
066 values. No bits are used to represent the sign and all values are
067 positive. The actual value of a multi-bit unsigned fixed
068 point number is:<p>
069
070 Unsigned(B) = 2^m x (\sum_{i=0}^{n-1} b_i x 2^i) <p>
071
072 <p>
073 This class supports several different String formats for specifying and
074 displaying the Precision. These String formats are supported by several
075 classes that extend the {@link PrecisionFormat} class. Several such classes
076 have been created. Any given precision string format can be represented in
077 any of the valid precision string formats. The four supported Precision
078 String formats are shown in the table below. A static singleton object of
079 each of these formats is provided in this class. Each String Representation
080 column of the table represent equivalent Precision formats:
081
082 <table border = 1>
083 <caption>Precision Formats.</caption>
084 <tr><td><b>Format Name</b></td> <td><b>Format Spec</b></td>
085 <td colspan = "6"><center><b>String Representation</b></center></td>
086 </tr>
087 <tr><td>{@link IntegerFractionPrecisionFormat}</td>
088 <td> [integer bits].[fraction bits] </td>
089 <td>3.2</td>
090 <td>0.7</td>
091 <td>-2.12</td>
092 <td>12.-4</td>
093 <td>32.0</td>
094 <td>U1.7</td>
095 </tr>
096 <tr><td>{@link LengthIntegerPrecisionFormat}</td>
097 <td>[total bits]/[integer bits]</td>
098 <td>5/3</td>
099 <td>7/0</td>
100 <td>10/-2</td>
101 <td>8/12</td>
102 <td>32/32</td>
103 <td>U8/1</td>
104 </tr>
105 <tr><td>{@link VHDLPrecisionFormat}</td>
106 <td>[MSb position]:[LSb position]</td>
107 <td>2:-2</td>
108 <td>-1:-7</td>
109 <td>-3:-12</td>
110 <td>11:4</td>
111 <td>31:0</td>
112 <td>U0:-7</td>
113 </tr>
114 <tr><td>{@link LengthExponentPrecisionFormat}</td>
115 <td>[total bits]e[binary point position]</td>
116 <td>5e-2</td>
117 <td>7e-7</td>
118 <td>10e-12</td>
119 <td>8e4</td>
120 <td>32e0</td>
121 <td>U8e-7</td>
122 </tr>
123 </table>
124
125 <p>
126 An instance of the class is immutable, meaning
127 that its value is set in the constructor and cannot then be modified.
128
129 @author Bart Kienhuis, Contributor: Mike Wirthlin
130 @version $Id$
131 @since Ptolemy II 0.4
132 @Pt.ProposedRating Yellow (kienhuis)
133 @Pt.AcceptedRating Red (kienhuis)
134 @see FixPoint
135 */
136public class Precision implements Cloneable {
137
138    /** Construct a Precision object based on the provided string. The
139     *  string can describe the precision in any of the
140     *  syntaxes explained in the description of this class.
141     *
142     *  @param str The string representing the precision.
143     *  @exception IllegalArgumentException If the precision string
144     *   supplied does not match one of the known formats.
145     */
146    public Precision(String str) throws IllegalArgumentException {
147        Precision p = null;
148
149        if ((p = INTEGER_FRACTION.parseString(str)) != null) {
150            _format = INTEGER_FRACTION;
151        } else if ((p = LENGTH_INTEGER.parseString(str)) != null) {
152            _format = LENGTH_INTEGER;
153        } else if ((p = LENGTH_EXPONENT.parseString(str)) != null) {
154            _format = LENGTH_EXPONENT;
155        } else if ((p = VHDL.parseString(str)) != null) {
156            _format = VHDL;
157        }
158
159        if (p != null) {
160            _length = p._length;
161            _exponent = p._exponent;
162            _sign = p._sign;
163            return;
164        }
165
166        throw new IllegalArgumentException(
167                "Unrecognized Precision String:" + str);
168    }
169
170    /** Construct a Precision object based on the length/integer
171     *  bits format. This constructor will create
172     *  a new <i>signed</i> Precision object with <i>length</i>
173     *  bits and an exponent of <i>-fracBits</i>.
174     *
175     *  @param length The total number of bits.
176     *  @param integerBits The number of integer bits.
177     *  @exception IllegalArgumentException If the given values are
178     *   negative or when the integer number of bits is larger than the
179     *   total number of bits.
180     */
181    public Precision(int length, int integerBits)
182            throws IllegalArgumentException {
183        this(1, length, integerBits - length);
184    }
185
186    /** Construct a Precision object based on the sign, length, and
187     *  exponent format.
188     *
189     *  @param sign The presence of a sign bit (1 = signed, 0 = unsigned).
190     *  @param length The total number of bits.
191     *  @param exponent The bit location of the exponent.
192     *  @exception IllegalArgumentException If the Precision arguments
193     *  are inconsistent.
194     */
195    public Precision(int sign, int length, int exponent)
196            throws IllegalArgumentException {
197        if (sign != 0 && sign != 1) {
198            throw new IllegalArgumentException("Incorrect definition of "
199                    + "Precision. Sign must be 0 or 1");
200        }
201
202        if (length < 0) {
203            throw new IllegalArgumentException("Incorrect definition of "
204                    + "Precision. Do not use negative total length ");
205        }
206
207        _sign = sign;
208        _length = length;
209        _exponent = exponent;
210    }
211
212    ///////////////////////////////////////////////////////////////////
213    ////                         public methods                    ////
214
215    /** Return this, that is, return the reference to this object.
216     *  @return This Precision.
217     */
218    @Override
219    public Object clone() {
220        // FIXME: Note that we do not call super.clone() here.  Is that right?
221        return this;
222    }
223
224    /** Return true if the indicated object is an instance of Precision
225     *  and the precision format matches exactly.
226     *  @param object Object to test for equality
227     *  @return True if the precisions are equal.
228     */
229    @Override
230    public boolean equals(Object object) {
231        if (object instanceof Precision) {
232            Precision other = (Precision) object;
233
234            if (other._length == _length && other._exponent == _exponent
235                    && other._sign == _sign) {
236                return true;
237            }
238        }
239
240        return false;
241    }
242
243    /** Return the maximum obtainable value in this precision.
244     *  This value is obtained by multiplying the result of
245     *  {@link #getMaximumUnscaledValue()} by 2<sup>exponent</sup>.
246     *
247     *  @return The maximum value obtainable for this precision.
248     */
249    public BigDecimal findMaximum() {
250        BigDecimal bd = new BigDecimal(getMaximumUnscaledValue());
251        return shiftBigDecimal(bd, _exponent);
252    }
253
254    /** Return the minimum obtainable value for this precision.
255     *  This value is obtained by multiplying the result of
256     *  {@link #getMinimumUnscaledValue()} by 2<sup>exponent</sup>.
257     *
258     *  @return The minimum value obtainable for the given precision.
259     */
260    public BigDecimal findMinimum() {
261        if (!isSigned()) {
262            return new BigDecimal(0);
263        }
264        BigDecimal bd = new BigDecimal(getMinimumUnscaledValue());
265        return shiftBigDecimal(bd, _exponent);
266    }
267
268    /** Return the incremental value between discrete values under
269     * the given Precision format. This is calculated as 2^exponent.
270     *
271     * @return Incremental (epsilon) value.
272     */
273    public BigDecimal getEpsilon() {
274        return new BigDecimal(Math.pow(2, _exponent));
275    }
276
277    /** Return the location of the binary exponent.
278     *  @return the location of the fixed binary exponent.
279     */
280    public int getExponent() {
281        return _exponent;
282    }
283
284    /** Return the number of bits representing the fractional part.
285     *  The is computed as -exponent.
286     *  @return The length of the fractional part.
287     */
288    public int getFractionBitLength() {
289        return -_exponent;
290    }
291
292    /** Return the number of bits representing the integer part.
293     *  This is computed as length + exponent.
294     *  @return the length of the integer part.
295     */
296    public int getIntegerBitLength() {
297        return _length + _exponent;
298    }
299
300    /**
301     * Return the bit position of the least significant bit of the
302     * given fixed point precision. This value is the same as
303     * the exponent value of this format. Bit 0 refers to
304     * the bit just to the left of the binary point.
305     *
306     * @return Least significant bit position.
307     */
308    public int getLeastSignificantBitPosition() {
309        return _exponent;
310    }
311
312    /** Return the maximum integer value <i>before</i> scaling so that
313     *  quantization levels are represented by adjacent integers.
314     *
315     *  For signed values, this number is 2^(n-1) - 1
316     *  For unsigned values, this number is 2^(n) - 1
317     *  @return The maximum inclusive value.
318     */
319    public BigInteger getMaximumUnscaledValue() {
320        // Create a positive "bit vector" that is the length
321        // of the this precision and has all ones.
322        BigInteger val = BigInteger.ZERO.setBit(_length - _sign);
323        val = val.subtract(BigInteger.ONE);
324        return val;
325    }
326
327    /** Return the minimum integer value <i>before</i> scaling so
328     * that quantization levels are represented by adjacent
329     * integers.
330     *
331     *  For signed values, this number is -(2^(n-1))
332     *  For unsigned values, this number is 0.
333     *
334     *  @return The minimum unscaled value value obtainable
335     *  for the given precision.
336     */
337    public BigInteger getMinimumUnscaledValue() {
338        if (isSigned()) {
339            return BigInteger.ZERO.setBit(_length - 1).negate();
340        }
341
342        return BigInteger.ZERO;
343    }
344
345    /**
346     * Return the bit position of the most significant bit of the
347     * given fixed point precision. Bit 0 refers to
348     * the bit just to the left of the binary point.
349     *
350     * @return Least significant bit position.
351     */
352    public int getMostSignificantBitPosition() {
353        return _exponent + _length - 1;
354    }
355
356    /**
357     * Return the bit position of the most significant
358     * data bit of the given fixed point precision. If this
359     * Precision is signed, this will return
360     * getMostSignificantBitPosition - 1. If this Precision
361     * is unsigned, this will return getMostSignificantBitPosition.
362     *
363     * @return Least significant bit position.
364     */
365    public int getMostSignificantDataBitPosition() {
366        return _exponent + _length - 1 - _sign;
367    }
368
369    /** Return the total number of bits.
370     *  @return the total number of bits.
371     */
372    public int getNumberOfBits() {
373        return _length;
374    }
375
376    /** Return the total number of discrete values possible.
377     *  @return the total number of levels.
378     */
379    public BigInteger getNumberOfLevels() {
380        int numBits = getNumberOfBits();
381        return BigInteger.ZERO.setBit(numBits);
382        //return Math.pow(2.0, _length);
383    }
384
385    /** Return the sign (0 = unsigned, 1 = signed).
386     *  @return the sign status.
387     */
388    public int getSign() {
389        return _sign;
390    }
391
392    /** Return a hash code value for this Precision. This method returns the
393     *  bitwise and of the length, exponent and sign.
394     *  @return A hash code value for this Precision.
395     */
396    @Override
397    public int hashCode() {
398        return Integer.valueOf(_length).hashCode() >>> Integer
399                .valueOf(_exponent)
400                .hashCode() >>> Integer.valueOf(_sign).hashCode();
401    }
402
403    /**
404     * Determine if the fixed point format is signed or not.
405     *
406     * @return true if format is signed
407     */
408    public boolean isSigned() {
409        return _sign == 1;
410    }
411
412    /** Return the precision that is the maximum of the two supplied
413     *  precisions in both the length and exponent. This
414     *  method is used to align instances of FixPoint onto a single
415     *  precision representation. If either Precision object is
416     *  signed, the new Precision object will be signed.
417     *
418     *  @param precisionA A precision
419     *  @param precisionB Another precision
420     *  @return A precision at least as precise as the two arguments.
421     */
422    public static Precision union(Precision precisionA, Precision precisionB) {
423
424        int minExponent = precisionA._exponent < precisionB._exponent
425                ? precisionA._exponent
426                : precisionB._exponent;
427
428        int aDataMSB = precisionA.getMostSignificantDataBitPosition();
429        int bDataMSB = precisionB.getMostSignificantDataBitPosition();
430
431        int maxDataMSB = aDataMSB > bDataMSB ? aDataMSB : bDataMSB;
432        int newLength = maxDataMSB - minExponent + 1;
433
434        int newSign = precisionA._sign == 1 || precisionB._sign == 1 ? 1 : 0;
435        newLength += newSign;
436
437        return new Precision(newSign, newLength, minExponent);
438    }
439
440    /** Shift the BigDecimal value either right or left by
441     *  a power of 2 value. This method will perform a
442     *  multiplication by 2^<sup>shiftval</sup> on the BigDecimal
443     *  value when shiftval is positive and will perform a
444     *  divide by 2^<sup>-shiftval</sup> on the BigDecimal value
445     *  when shiftval is negative.
446     *
447     *
448     * @param val BigDecimal value to shift.
449     * @param shiftval Amount of "power of 2" shifting to perform
450     * on the BigDecimal value
451     * @return shifted BigDecimal value.
452     */
453    public static BigDecimal shiftBigDecimal(BigDecimal val, int shiftval) {
454
455        // No shifting takes place. Return the BigDecimal value
456        if (shiftval == 0) {
457            return val;
458        }
459
460        // Left shifting is going to occur. Multiply value by
461        // 2^shiftval
462        if (shiftval > 0) {
463            return val.multiply(_getTwoRaisedTo(shiftval));
464        }
465
466        // Right shifting is going to occur. Divide value by
467        // 2^(-shiftval) since shiftval is negative.
468
469        // When dividing BigDecimal values, we need to know the maximum
470        // number of decimal places will be added to the right
471        // as a result of the divide
472        // to preserve the precision of the result. Since we are
473        // dividing by a number of the form, 2^n, the division
474        // is essentially a divide by 2 for n times. Every
475        // divide by two will add at most one new
476        // least significant decimal digit to the right of the decimal
477        // point. To preserve all of the precision of the divide,
478        // set the BigDecimal "scale" to n + val.scale() where
479        // n is the power of 2.
480        int scaleShift = -shiftval + val.scale();
481
482        BigDecimal result = val.divide(_getTwoRaisedTo(-shiftval), scaleShift,
483                BigDecimal.ROUND_HALF_EVEN);
484        return result;
485    }
486
487    /** Return a string representing this precision. The string is
488     *  expressed as "(<i>m.n</i>)", where <i>m</i>
489     *  indicates the number of integer bits and <i>n</i> represents
490     *  the number of fractional bits.
491     *  @return A string representing this precision.
492     */
493    @Override
494    public String toString() {
495        return _format.printPrecisionFormat(this);
496    }
497
498    /**
499     * Return a string representation of this format in one of several
500     * styles.
501     * @param format The String format represented desired for printing.
502     * @return String representation of the object using the given
503     * PrecisionFormat
504     */
505    public String toString(PrecisionFormat format) {
506        return format.printPrecisionFormat(this);
507    }
508
509    /** Defines a String format for specifying a Precision object.
510     * This abstract class defines a method for parsing the string
511     * format and a method for creating a valid String representation
512     * of a Precision object. The printing and parsing methods should
513     * be consistent (i.e. the parsing method should successfully parse
514     * the result of the printing method).
515     */
516    public static abstract class PrecisionFormat {
517
518        /**
519         * Parse the given String argument using the rules of the specific
520         * PrecisionFormat that is defined. This method will return a
521         * valid Precision object from the String. If the String parsing
522         * does not produce a valid match, this method will return a null.
523         * If the String match is successful but there is a problem in
524         * the interpretation of the match, this method will throw
525         * a IllegalArgumentException.
526         *
527         * @param str String to parse
528         * @return A Precision object. Returns a null if the String does
529         * not match the particular string format.
530         * @exception IllegalArgumentException If there is a problem
531         * parsing the String (i.e. an illegal string).
532         */
533        public abstract Precision parseString(String str)
534                throws IllegalArgumentException;
535
536        /** Creates a valid String representation of the Precision object
537         * based on the rules of the given string format. The format of this
538         * String should be consistent with the format used in the
539         * parseString method.
540         *
541         * @param p Precision object to represent as a String.
542         * @return String representing the Precision object
543         */
544        public abstract String printPrecisionFormat(Precision p);
545
546        /** Parse a String as an integer. This method calls the
547         * Integer.parseInt method but throws the IllegalArgumentException
548         * instead of the NumberFormatException when there is a problem.
549         *
550         * @param str The integer string to parse
551         * @return The integer value of the string.
552         * @exception IllegalArgumentException If the parsing of the
553         * Integer value fails (i.e. NumberFormatException).
554         */
555        public static int parseInteger(String str)
556                throws IllegalArgumentException {
557            int value = 0;
558
559            try {
560                value = Integer.parseInt(str);
561            } catch (NumberFormatException e) {
562                throw new IllegalArgumentException(
563                        "Invalid integer number:" + str + " " + e);
564            }
565
566            return value;
567        }
568
569        /** Parse the 'U' or 'S' sign specifier.
570         *
571         * @param str String to parse for a sign indicator.
572         * @return Return a 0 for unsigned and a 1 for signed.
573         * @exception IllegalArgumentException If the
574         * string does not match the 'U' or 'S' characters.
575         */
576        public static int parseSignString(String str)
577                throws IllegalArgumentException {
578            if (str.equalsIgnoreCase("U")) {
579                return 0;
580            } else if (str.equalsIgnoreCase("S")) {
581                return 1;
582            }
583
584            throw new IllegalArgumentException("Invalid signed format string:'"
585                    + str + "'. Expecting 'U' or 'S'");
586        }
587
588        /** The following static String objects are used for convenience
589         *  when performing regular expression matches on Precision
590         *  Strings. The following explanation will help explain the
591         *  meaning of some of these cryptic strings:
592         *
593         *  "\\"
594         *    This corresponds to a single "\" in the regular expression
595         *    matcher. A single "\" must be represetned within Java as an
596         *    escape sequence (i.e. "\\"). A single "\" will not compile as
597         *    the \" corresponds to the string """ (i.e. a single quotation
598         *    mark).
599         *
600         *  GROUP
601         *    Any variable with the GROUP in its name corresponds to a
602         *    regular expression with the "capturing group" parenthesis
603         *    around the regular expression. This "capturing" is used
604         *    to obtain the matching string associated with the
605         *    regular expression.
606         *
607         */
608
609        /** Regular expression definition for a comma "," or a
610         *  forward slash "/". */
611        public final static String COMMA_OR_FORWARDSLASH = "[,/]";
612
613        /** Regular expression definition for an optional left parenthesis. **/
614        public final static String OPTIONAL_L_PARAN = "\\(?";
615
616        /** Regular expression definition for an optional left parenthesis
617         *  or left bracket. **/
618        public final static String OPTIONAL_L_PARANBRACKET = "[\\(\\[]?";
619
620        /** Regular expression definition for an optional right parenthesis. **/
621        public final static String OPTIONAL_R_PARAN = "\\)?";
622
623        /** Regular expression definition for an optional right parenthesis
624         *  or left bracket. **/
625        public final static String OPTIONAL_R_PARANBRACKET = "[\\)\\]]?";
626
627        /** Regular expression definition for a Period ".". */
628        public final static String PERIOD = "\\.";
629
630        /** Regular expression for a grouped signed integer
631         * (positive or negative). **/
632        public final static String SIGNED_INTEGER_GROUP = "(-?\\d+)";
633
634        /** Regular expression for an optional 'S' or 'U' "group". */
635        public final static String OPTIONAL_U_OR_S_GROUP = "([USus])?";
636
637        /** Regular expression for a grouped unsigned integer. **/
638        public final static String UNSIGNED_INTEGER_GROUP = "(\\d+)";
639
640        /** Regular expression for optional white space. **/
641        public final static String OPTIONAL_WHITE_SPACE = "\\s*";
642    }
643
644    /** Defines a Precision string format using the INTEGER.FRACTION
645     * precision format. The INTEGER value specifies the number of
646     * integer bits and the FRACTION value specifies the number of
647     * fractional bits. Negative values are allowed for either INTEGER
648     * or FRACTION (but not both). <p>
649     *
650     * This format supports the specification of either signed or
651     * unsigned values. The character 'U' must precede the
652     * integer.fraction format to specify an unsigned value. An 'S' character
653     * may be applied to specify a signed number. If no 'U' or 'S'
654     * signed specification is provided, the precision will default
655     * to a signed value. <p>
656     *
657     * The exponent in this format is set to -fraction.
658     * <p>
659     * Parenthesis or brackets are optional around this specification.
660     *
661     * Examples:
662     * <ul>
663     *   <li> (3.5)
664     *   <li> (U2.1)
665     *   <li> [S2.1]
666     *   <li> [S6.-2]
667     *   <li> S-2.4
668     * </ul>
669     *
670     * When printed, this format will always use parenthesis and
671     * only use the signed format specification for unsigned numbers
672     * (i.e. 'U' used for unsigned numbers and NO 'S' for signed
673     * numbers).
674     *
675     */
676    public static class IntegerFractionPrecisionFormat extends PrecisionFormat {
677
678        /** Regular expression for IntegerFractionPrecisionFormat.
679         *  Example: (S3.2) */
680        protected final static String _regex = OPTIONAL_WHITE_SPACE
681                + OPTIONAL_L_PARANBRACKET + OPTIONAL_WHITE_SPACE
682                + OPTIONAL_U_OR_S_GROUP + OPTIONAL_WHITE_SPACE
683                + SIGNED_INTEGER_GROUP + PERIOD + SIGNED_INTEGER_GROUP
684                + OPTIONAL_WHITE_SPACE + OPTIONAL_R_PARANBRACKET
685                + OPTIONAL_WHITE_SPACE;
686
687        @Override
688        public Precision parseString(String str)
689                throws IllegalArgumentException {
690            int sign = 1;
691            int intLength = 0;
692            int fracLength = 0;
693            Matcher matcher;
694
695            matcher = Pattern.compile(_regex).matcher(str);
696
697            if (matcher.matches()) {
698                String signString = matcher.group(1);
699
700                if (signString != null) {
701                    sign = parseSignString(signString);
702                }
703
704                intLength = parseInteger(matcher.group(2));
705                fracLength = parseInteger(matcher.group(3));
706
707                int length = fracLength + intLength;
708                int exponent = -fracLength;
709
710                if (length < 1) {
711                    throw new IllegalArgumentException("Precision format "
712                            + " must be at least 1 bit:" + str);
713                }
714
715                return new Precision(sign, length, exponent);
716            }
717
718            return null;
719        }
720
721        @Override
722        public String printPrecisionFormat(Precision p) {
723            String sign = p.isSigned() ? "" : "U";
724            return "(" + sign + p.getIntegerBitLength() + "."
725                    + p.getFractionBitLength() + ")";
726        }
727    }
728
729    /** Defines a Precision string format using the LENGTH/INTEGER
730     * precision format. The LENGTH value specifies the length
731     * of the format in bits. The INTEGER field specifies the
732     * number of integer bits (i.e. bits to the left of the
733     * binary point). Negative values are allowed for the INTEGER
734     * field. <p>
735     *
736     * The exponent in this format is set to -(length - integer);
737     * <p>
738     *
739     * This format supports the specification of either signed or
740     * unsigned values. The character 'U' must precede the
741     * LENGTH/INTEGER format to specify an unsigned value. An 'S' character
742     * may be applied to specify a signed number. If no 'U' or 'S'
743     * signed specification is provided, the precision will default
744     * to a signed value. <p>
745     *
746     * Parenthesis or brackets are optional around this specification.
747     * A comma (,) may be used in place of the slash ('/').
748     *
749     * Examples:
750     * <ul>
751     *   <li> (3/2)
752     *   <li> (U5/0)
753     *   <li> [8,-2]
754     *   <li> [S6,6]
755     *   <li> S8/4
756     * </ul>
757     *
758     * When printed, this format will always use parenthesis, always
759     * use the slash '/', and
760     * only use the signed format specification for unsigned numbers
761     * (i.e. 'U' used for unsigned numbers and NO 'S' for signed
762     * numbers).
763     *
764     */
765    public static class LengthIntegerPrecisionFormat extends PrecisionFormat {
766        /** Regular expression for IntegerFractionPrecisionFormat.
767         *   Example (S3,2) or (S3/2) */
768        protected final static String _regex = OPTIONAL_WHITE_SPACE
769                + OPTIONAL_L_PARANBRACKET + OPTIONAL_WHITE_SPACE
770                + OPTIONAL_U_OR_S_GROUP + OPTIONAL_WHITE_SPACE
771                + UNSIGNED_INTEGER_GROUP + COMMA_OR_FORWARDSLASH
772                + OPTIONAL_WHITE_SPACE + SIGNED_INTEGER_GROUP
773                + OPTIONAL_WHITE_SPACE + OPTIONAL_R_PARANBRACKET
774                + OPTIONAL_WHITE_SPACE;
775
776        @Override
777        public Precision parseString(String str)
778                throws IllegalArgumentException {
779            int sign = 1;
780            int intLength = 0;
781            int length = 0;
782            Matcher matcher;
783
784            matcher = Pattern.compile(_regex).matcher(str);
785
786            if (matcher.matches()) {
787                String signString = matcher.group(1);
788
789                if (signString != null) {
790                    sign = parseSignString(signString);
791                }
792
793                length = parseInteger(matcher.group(2));
794                intLength = parseInteger(matcher.group(3));
795
796                int exponent = -(length - intLength);
797
798                if (length < 1) {
799                    throw new IllegalArgumentException("Precision format "
800                            + "must be at least 1 bit:" + str);
801                }
802
803                return new Precision(sign, length, exponent);
804            }
805
806            return null;
807        }
808
809        @Override
810        public String printPrecisionFormat(Precision p) {
811            String sign = p.isSigned() ? "" : "U";
812            return "(" + sign + p.getNumberOfBits() + "/"
813                    + p.getIntegerBitLength() + ")";
814        }
815    }
816
817    /** Precision format for use with the Expression Language. */
818    public static class ExpressionLanguagePrecisionFormat
819            extends LengthIntegerPrecisionFormat {
820        /** Regular expression for ExpressionLanguagePrecisionFormat.
821         *  For example: (3,2).
822         */
823        @Override
824        public String printPrecisionFormat(Precision p) {
825            return "(" + p.getNumberOfBits() + "," + p.getIntegerBitLength()
826                    + ")";
827        }
828    }
829
830    /** Defines a Precision string format using the LENGTHeEXPONENT
831     * precision format. The LENGTH value specifies the length
832     * of the format in bits and the EXPONENT specifies the
833     * location of the exponent. Negative values are allowed for the
834     * EXPONENT field. <p>
835     *
836     * This format supports the specification of either signed or
837     * unsigned values. The character 'U' must precede the
838     * LENGTH/INTEGER format to specify an unsigned value. An 'S' character
839     * may be applied to specify a signed number. If no 'U' or 'S'
840     * signed specification is provided, the precision will default
841     * to a signed value. <p>
842     *
843     * Parenthesis or brackets are optional around this specification.
844     *
845     * Examples:
846     * <ul>
847     *   <li> (3e2)
848     *   <li> (U5e0)
849     *   <li> [8e-2]
850     *   <li> [S6e6]
851     *   <li> S8e-4
852     * </ul>
853     *
854     * When printed, this format will always use parenthesis and
855     * only use the signed format specification for unsigned numbers
856     * (i.e. 'U' used for unsigned numbers and NO 'S' for signed
857     * numbers).
858     *
859     */
860    public static class LengthExponentPrecisionFormat extends PrecisionFormat {
861        /** Regular expression for IntegerFractionPrecisionFormat.
862         *   Example (S3e2) */
863        protected final String _regex = OPTIONAL_WHITE_SPACE
864                + OPTIONAL_L_PARANBRACKET + OPTIONAL_WHITE_SPACE
865                + OPTIONAL_U_OR_S_GROUP + OPTIONAL_WHITE_SPACE
866                + UNSIGNED_INTEGER_GROUP + "e" + SIGNED_INTEGER_GROUP
867                + OPTIONAL_WHITE_SPACE + OPTIONAL_R_PARANBRACKET
868                + OPTIONAL_WHITE_SPACE;
869
870        @Override
871        public Precision parseString(String str)
872                throws IllegalArgumentException {
873            int sign = 1;
874            int exponent = 0;
875            int length = 0;
876            Matcher matcher;
877
878            matcher = Pattern.compile(_regex).matcher(str);
879
880            if (matcher.matches()) {
881                String signString = matcher.group(1);
882
883                if (signString != null) {
884                    sign = parseSignString(signString);
885                }
886
887                length = parseInteger(matcher.group(2));
888                exponent = parseInteger(matcher.group(3));
889
890                if (length < 1) {
891                    throw new IllegalArgumentException("Precision format "
892                            + "must be at least 1 bit:" + str);
893                }
894
895                return new Precision(sign, length, exponent);
896            }
897
898            return null;
899        }
900
901        @Override
902        public String printPrecisionFormat(Precision p) {
903            String sign = p.isSigned() ? "" : "U";
904            return "(" + sign + p.getNumberOfBits() + "e" + p.getExponent()
905                    + ")";
906        }
907    }
908
909    /** Defines a Precision string format using the VHDL MSB:LSB
910     * precision format. The MSB value specifies the location
911     * of the most significant bit and LSB specifies the location
912     * of the least significant bit.
913     * Negative values are allowed for both MSB and LSB so long as
914     * the MSB is greater than the LSB. <p>
915     *
916     * This format supports the specification of either signed or
917     * unsigned values. The character 'U' must precede the
918     * MSB:LSB format to specify an unsigned value. An 'S' character
919     * may be applied to specify a signed number. If no 'U' or 'S'
920     * signed specification is provided, the precision will default
921     * to a signed value. <p>
922     *
923     * Parenthesis or brackets are optional around this specification.
924     *
925     * Examples:
926     * <ul>
927     *   <li> (2:3)
928     *   <li> (4:-3)
929     *   <li> [7:0]
930     *   <li> [-3:-8]
931     *   <li> 4:3
932     * </ul>
933     *
934     * When printed, this format will always use parenthesis and
935     * only use the signed format specification for unsigned numbers
936     * (i.e. 'U' used for unsigned numbers and NO 'S' for signed
937     * numbers).
938     *
939     */
940    public static class VHDLPrecisionFormat extends PrecisionFormat {
941        /** Regular expression for IntegerFractionPrecisionFormat.
942         *   Example ([US]{digit}:{digit}) */
943        protected final String _regex = OPTIONAL_WHITE_SPACE + OPTIONAL_L_PARAN
944                + OPTIONAL_WHITE_SPACE + OPTIONAL_U_OR_S_GROUP
945                + OPTIONAL_WHITE_SPACE + SIGNED_INTEGER_GROUP
946                + OPTIONAL_WHITE_SPACE + ":" + OPTIONAL_WHITE_SPACE
947                + SIGNED_INTEGER_GROUP + OPTIONAL_WHITE_SPACE + OPTIONAL_R_PARAN
948                + OPTIONAL_WHITE_SPACE;
949
950        @Override
951        public Precision parseString(String str) {
952            int sign = 1;
953            int msb = 0;
954            int lsb = 0;
955            Matcher matcher;
956
957            matcher = Pattern.compile(_regex).matcher(str);
958
959            if (matcher.matches()) {
960                String signString = matcher.group(1);
961
962                if (signString != null) {
963                    sign = parseSignString(signString);
964                }
965
966                msb = parseInteger(matcher.group(2));
967                lsb = parseInteger(matcher.group(3));
968
969                if (msb <= lsb) {
970                    throw new IllegalArgumentException("MSb of VHDL "
971                            + "format must be greater than LSb:" + str);
972                }
973
974                int length = msb - lsb + 1;
975                int exponent = lsb;
976                return new Precision(sign, length, exponent);
977            }
978
979            return null;
980        }
981
982        @Override
983        public String printPrecisionFormat(Precision p) {
984            String sign = p.isSigned() ? "" : "U";
985            return "(" + sign + p.getMostSignificantBitPosition() + ":"
986                    + p.getLeastSignificantBitPosition() + ")";
987        }
988    }
989
990    ///////////////////////////////////////////////////////////////////
991    ////                         public variables                  ////
992
993    /**
994     * static IntegerFractionPrecisionFormat object.
995     */
996    public final static PrecisionFormat INTEGER_FRACTION = new IntegerFractionPrecisionFormat();
997
998    /**
999     * static LengthExponentPrecisionFormat object.
1000     */
1001    public final static PrecisionFormat LENGTH_EXPONENT = new LengthExponentPrecisionFormat();
1002
1003    /**
1004     * static LengthIntegerPrecisionFormat object.
1005     */
1006    public final static PrecisionFormat LENGTH_INTEGER = new LengthIntegerPrecisionFormat();
1007
1008    /**
1009     * static ExpressionLanguagePrecisionFormat object.
1010     */
1011    public final static PrecisionFormat EXPRESSION_LANGUAGE = new ExpressionLanguagePrecisionFormat();
1012
1013    /**
1014     * static VHDLPrecisionFormat object.
1015     */
1016    public final static PrecisionFormat VHDL = new VHDLPrecisionFormat();
1017
1018    ///////////////////////////////////////////////////////////////////
1019    ////                         private methods                   ////
1020
1021    /** Get the BigDecimal which is the 2^exponent. If the value is
1022     *  already calculated, return this cached value, else calculate
1023     *  the value.
1024     *
1025     *  @param number the exponent.
1026     *  @return the BigDecimal representing 2^exponent.
1027     */
1028    private static BigDecimal _getTwoRaisedTo(int number) {
1029        // Since this is a private method we know that number is positive.
1030        if (number < _twoRaisedTo.length) {
1031            return _twoRaisedTo[number];
1032        } else {
1033            return new BigDecimal(BigInteger.ZERO.setBit(number));
1034        }
1035    }
1036
1037    ///////////////////////////////////////////////////////////////////
1038    ////                         private variables                 ////
1039
1040    /** The total number of bits. */
1041    private int _length = 0;
1042
1043    /** The exponent for all values of this type. */
1044    private int _exponent = 0;
1045
1046    /** The presence of a sign bit (0 = unsigned, 1 = signed) */
1047    private int _sign = 0;
1048
1049    /** The precision format used for parsing/printing precision information.
1050     */
1051    private PrecisionFormat _format = INTEGER_FRACTION;
1052
1053    ///////////////////////////////////////////////////////////////////
1054    ////                         static variables                  ////
1055
1056    /** The size of the pre-computed _twoRaisedTo powers of two array.
1057     *   65 entries are used to cache all powers of 2 from 0 to 64.
1058     **/
1059    private static final int TWORAISEDTOSIZE = 64 + 1;
1060
1061    /** Calculate the table containing 2^x, with 0 <= x < TWORAISEDTOSIZE.
1062     *   Purpose is to speed up calculations involving calculating
1063     *   2^x. The table is calculated using BigDecimal, since this
1064     *   make the transformation from string of bits to a double
1065     *   easier.
1066     **/
1067    private static BigDecimal[] _twoRaisedTo = new BigDecimal[TWORAISEDTOSIZE];
1068
1069    ///////////////////////////////////////////////////////////////////
1070    ////                      static initializers                  ////
1071    static {
1072        BigDecimal powerOf2 = BigDecimal.valueOf(1);
1073
1074        for (int i = 0; i < _twoRaisedTo.length; i++) {
1075            _twoRaisedTo[i] = powerOf2;
1076            powerOf2 = powerOf2.add(powerOf2);
1077        }
1078    }
1079
1080}