The whole point of this is that 'truncate' is somewhat ambiguous, and the most common usage (round To minus Infinity) is not what the truncate method in Ptolemy currently does. So, we are adding a bunch of new methods, with names that are more explicit, to implement the different interesting truncation modes. For a bit of backwards compatability, the truncate() method will still exist and perform as before (round To Zero) but will be deprecated.
Steve At 09:19 AM 4/3/2002 -0800, Jeff Patterson wrote: >How do your proposed definitions relate to those defined in IEEE-754? > >I don't have access to the full standard but I found this reference from >http://www.cs.umass.edu/~weems/CmpSci535/535lecture6.html: >"The IEEE standard has four different rounding modes. The usual mode is >to round to the nearest value, with a number that falls midway between >two others being rounded to the nearest value with an even (zero) >low-order digit. The other modes are round toward zero, round toward >plus infinity, and round toward minus infinity." > >I am concerned by your statement that truncate is "a syn. for round to >zero". I have always thought the normal truncate for two's complement >numbers was equivalent to round to minus infinity. Why not use the names >from the standard to avoid confusion? > >Jeff > >On Tue, 2002-04-02 at 09:19, Stephen Andrew Neuendorffer wrote: > > The overhead of parallel methods is rather obnoxious, but from the > point of > > view of the > > code generator, it will probably be better to just have the methods... > > I'm going to leave truncate as roundToZero for backward compatability. > > (sorry, Zoltan, but I'd > > like to have more confusion, not less... I mean less confusion, not > more.. > > ;) ) So the methods will be: > > > > round (for roundToNearest) > > roundNearestEven > > roundDown > > roundToZero > > truncate (syn. for roundToZero) > > roundUp > > > > I'll probably drop truncate from the list of choices in doubleToFix and > > FixToFix (although it will still be > > accepted as input, for backward compatability.) > > > > I've added the methods, but roundUp and roundNearestEven have bogus > > implementations. Does someone care to implement these? > > I created correct tests for roundUp. > > > > Steve > > > > At 10:40 AM 4/2/2002 -0500, Zoltan Kemenczy wrote: > > >Having one function with a mode parameter to do both would simplify the > > >coding of actors that use quantization points... Otherwise we end up > with a > > >lot of if (youwanttruncate) truncate(); else round() constructs. > > > > > >"Truncate" is equivalent to "roundDown" (nearest less or equal). In > the list > > >of modes for round(), Solomon's solution could contain both "truncate" and > > >"roundDown" modes as an alias for the same operation...? :-) > > > > > >In actor code, the Quantizer class could be queried to provide a map of > > >supported modes and associated strings that could then be used to set > up the > > >gui "ChoiceStyle" class attached to mode parameters. > > > > > >Zoltan out... > > >-----Original Message----- > > >From: Stephen Andrew Neuendorffer [mailto:[EMAIL PROTECTED]] > > >Sent: April 1, 2002 11:44 PM > > >To: Edward A. Lee > > >Cc: Zoltan Kemenczy; [EMAIL PROTECTED]; [EMAIL PROTECTED]; bart > > >Kienhuis; Sean Simmons > > >Subject: RE: [Ptolemy] Re: Quantizer bug > > > > > > > > >Sounds good to me... I think truncate is ambiguous.. > > > > > >At 07:39 PM 4/1/2002 -0800, Edward A. Lee wrote: > > > > > > >I agree... I like your names, too... > > > > > > > >But "truncate" to many people does mean "ignore the low order bits". > > > >This isn't the same as round to zero in two's complement encoding. > > > >Is there a better name for this one? I would prefer something > > > >more self-explanatory, like "roundToZero". Maybe the others > > > >would then be roundDown, roundUp, roundNearest, roundNearestEven. > > > > > > > >Edward > > > > > > > >At 03:05 PM 4/1/2002 -0800, Stephen Andrew Neuendorffer wrote: > > > >>I think the intention was always to implement other types of > > > >>quantization... Bart just never got around to it... > > > >>IEEE754 has about 5 types, I think.... > > > >>round to zero (always smaller in absolute value) > > > >>round down (always smaller) > > > >>round up (always larger) > > > >>round nearest (five rounds up) > > > >>round nearest even (five rounds up or down making the last digit > even... > > > >>also called 'bankers rounding') > > > >> > > > >>Ideally we should have all of these... I'd call them: > > > >>truncate, floor, ceiling, round and bankers, but that's just me... > > > >>Obviously it would be nice if we could fix this and come to a > concensus... > > > >> > > > >>Steve > > > >> > > > >>At 05:47 PM 4/1/2002 -0500, Zoltan Kemenczy wrote: > > > >>>For whatever it's worth, here's our version of > ptolemy.math.Quantizer. We > > > >>>ran into these bugs some time ago, fixed them, but at the same time > > >changed > > > >>>the rules about truncation towards the nearest ***LESS OR EQUAL*** > > > >>>fixed-point value that has the given precision since that is what > happens > > >in > > > >>>most fixed-point DSP implementations when you, for example, truncate a > > > >>>32-bit result to 16 bits by ignoring the 16 LSBs. That is why we > didn't > > > >>>contribute these changes back but kept them local. > > > >>>They were used to test some 16/32-bit bit-exact vocoder algorithms. > > > >>> > > > >>>Zoltan Kemenczy > > > >>>Research in Motion Limited (www.rim.net) > > > >>>305 Phillip St, Waterloo, Ontario Canada N2L 3W8 > > > >>>---------------------------------------------------------------------- > > > >>>/* A collection of methods for creating fixed point values. > > > >>> > > > >>>Copyright (c) 1998-2001 The Regents of the University of California > > > >>> and Research in Motion Limited.All rights reserved. > > > >>> > > > >>>Permission is hereby granted, without written agreement and without > > > >>>license or royalty fees, to use, copy, modify, and distribute this > > > >>>software and its documentation for any purpose, provided that the > above > > > >>>copyright notice and the following two paragraphs appear in all copies > > > >>>of this software. > > > >>> > > > >>>IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA OR RESEARCH IN MOTION > > > >>> LIMITED BE LIABLE TO ANY PARTY > > > >>>FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES > > > >>>ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF > > > >>>THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF > > > >>>SUCH DAMAGE. > > > >>> > > > >>>THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION LIMITED > > > >>>SPECIFICALLY DISCLAIMS ANY WARRANTIES, > > > >>>INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > > > >>>MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE > > > >>>PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF > > > >>>CALIFORNIA AND RESEARCH IN MOTION > > > >>> LIMITED HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, > > > >>>ENHANCEMENTS, OR MODIFICATIONS. > > > >>> > > > >>> PT_COPYRIGHT_VERSION_2 > > > >>> COPYRIGHTENDKEY > > > >>> > > > >>>@ProposedRating Yellow ([EMAIL PROTECTED]) > > > >>>@AcceptedRating Red ([EMAIL PROTECTED]) > > > >>>*/ > > > >>> > > > >>>package ptolemy.math; > > > >>> > > > >>>import java.math.BigDecimal; > > > >>>import java.math.BigInteger; > > > >>> > > > >>>/////////////////////////////////////////////////////////////////// > ////// > > >/ > > > >>>//// Quantizer > > > >>> > > > >>>/** > > > >>>This class provides a set of static methods for creating instances > > > >>>of the FixPoint class from doubles, integers, or fixed point numbers. > > > >>>The various round() methods return a fixed point value that is nearest > > > >>>to the specified number, but has the specified precision. > > > >>>The various truncate() methods return a fixed point value that is > > > >>>nearest to the specified number, but no greater in magnitude. > > > >>>All of these methods may introduce quantization errors and/or > overflow. > > > >>> > > > >>>@author Bart Kienhuis > > > >>>@contributor Edward A. Lee > > > >>>@version $Id: Quantizer.java,v 1.20 2001/10/16 04:36:13 cxh Exp $ > > > >>>@see FixPoint > > > >>>@see Precision > > > >>>*/ > > > >>> > > > >>>public class Quantizer { > > > >>> > > > >>> // The only constructor is private so that this class cannot > > > >>> // be instantiated. > > > >>> private Quantizer() {} > > > >>> > > > >>> > /////////////////////////////////////////////////////////////////// > > > >>> //// public > methods //// > > > >>> > > > >>> /** Return the fixed point number that is nearest to the > specified > > > >>> * value, but has the given precision, possibly introducing > > > >>> * quantization or overflow errors. > > > >>> * An overflow error occurs if the specified number does not fit > > > >>> * within the range possible with the specified precision. > In that > > > >>> * case, the returned value is either the maximum or minimum > value > > > >>> * possible with the given precision, depending on the sign > of the > > > >>> * specified number. In this case, a flag is set in the returned > > > >>> * value to indicate that an overflow error occurred. > > > >>> * > > > >>> * @param value The value to represent. > > > >>> * @param precision The precision of the representation. > > > >>> * @return A fixed-point representation of the value. > > > >>> */ > > > >>> public static FixPoint round(double value, Precision precision) { > > > >>> BigDecimal newValue = new BigDecimal( value ); > > > >>> return round( newValue, precision); > > > >>> } > > > >>> > > > >>> /** Return the fixed point number that is nearest to the > specified > > > >>> * value, but has the given precision, possibly introducing > > > >>> * quantization or overflow errors. > > > >>> * An overflow error occurs if the specified number does not fit > > > >>> * within the range possible with the specified precision. > In that > > > >>> * case, the returned value is either the maximum or minimum > value > > > >>> * possible with the given precision, depending on the sign > of the > > > >>> * specified number. In this case, a flag is set in the returned > > > >>> * value to indicate that an overflow error occurred. > > > >>> * > > > >>> * @param value The value to represent. > > > >>> * @param precision The precision of the representation. > > > >>> * @return A fixed-point representation of the value. > > > >>> */ > > > >>> public static FixPoint round(BigDecimal value, Precision > precision) > > >{ > > > >>> BigInteger tmpValue; > > > >>> BigInteger fxvalue; > > > >>> boolean overflow = false; > > > >>> > > > >>> BigDecimal x = value; > > > >>> BigDecimal maxValue = precision.findMaximum(); > > > >>> BigDecimal minValue = precision.findMinimum(); > > > >>> > > > >>> // check if 'x' falls within the range of this FixPoint > > > >>> // possible with the given precision > > > >>> if ( x.compareTo(maxValue) > 0 ) { > > > >>> overflow = true; > > > >>> x = maxValue; > > > >>> } > > > >>> if ( x.compareTo(minValue) < 0 ) { > > > >>> overflow = true; > > > >>> x = minValue; > > > >>> } > > > >>> > > > >>> // determine the scale factor by calculating > > > >>> // 2^fractionBitLength By multiply the given value 'x' with > > > >>> // this scale factor. An value is obtained of the fraction > > > >>> // part is dropped. The integer remaining after the scaling > > > >>> // will be represented by the BigInteger. > > > >>> int number = precision.getFractionBitLength(); > > > >>> > > > >>> // This division divides two number in a precision of 40 > > > >>> // decimal behind the point. This is equivalent with a > > > >>> // fractional precision of 128 bits. ( ln(1-^40)/ln(2) > 128) > > > >>> BigDecimal resolution = _one.divide( > _getTwoRaisedTo(number+1), > > > >>> 40, BigDecimal.ROUND_HALF_EVEN); > > > >>> > > > >>> BigDecimal multiplier; > > > >>> if ( x.signum() >= 0 ) { > > > >>> multiplier = x.add(resolution ); > > > >>> } else { > > > >>> multiplier = x.subtract(resolution); > > > >>> } > > > >>> BigDecimal kl = _getTwoRaisedTo(number).multiply( > multiplier ); > > > >>> > > > >>> // By going from BigDecimal to BigInteger, remove the > fraction > > > >>> // part. This part introduces a quantization error. > > > >>> fxvalue = kl.toBigInteger(); > > > >>> > > > >>> // Create a new FixPoint > > > >>> FixPoint fxp = new FixPoint( precision, fxvalue ); > > > >>> > > > >>> // and set the overflow flag, if overflow occurred > > > >>> if ( overflow ) { > > > >>> fxp.setError( FixPoint.OVERFLOW ); > > > >>> } > > > >>> return fxp; > > > >>> } > > > >>> > > > >>> /** Return the fixed point number that is nearest to the > specified > > > >>> * value, but has the given precision, possibly introducing > > > >>> * quantization or overflow errors. > > > >>> * An overflow error occurs if the specified number does not fit > > > >>> * within the range possible with the specified precision. > In that > > > >>> * case, the returned value depends on the specified mode. > > > >>> * If the mode is SATURATE, then the return value is either > > > >>> * the maximum or minimum value possible with the given > > > >>> * precision, depending on the sign of the > > > >>> * specified number. If the mode is OVERFLOW_TO_ZERO, > > > >>> * then the return value is zero. > > > >>> * In either case, a flag is set in the returned > > > >>> * value to indicate that an overflow error occurred. > > > >>> * > > > >>> * @param value The value to represent. > > > >>> * @param newPrecision The precision of the representation. > > > >>> * @param mode The overflow mode. > > > >>> * @return A new fixed-point representation of the value. > > > >>> */ > > > >>> public static FixPoint round( > > > >>> FixPoint value, > > > >>> Precision newPrecision, > > > >>> int mode) { > > > >>> > > > >>> FixPoint newValue = null; > > > >>> BigDecimal x = value.bigDecimalValue(); > > > >>> BigDecimal maxValue = newPrecision.findMaximum(); > > > >>> BigDecimal minValue = newPrecision.findMinimum(); > > > >>> // check if 'x' falls within the range of this FixPoint > > > >>> // possible with the given precision > > > >>> if ( x.compareTo(maxValue) < 0 && > > > >>> x.compareTo(minValue) > 0 ) { > > > >>> // In range, thus leads at most to a quantization error > > > >>> newValue = Quantizer.round(x, newPrecision); > > > >>> } else { > > > >>> FixPoint result; > > > >>> //Not in range. Can lead to an overflow problem. > > > >>> switch(mode) { > > > >>> case SATURATE: > > > >>> if ( x.signum() >= 0) { > > > >>> result = Quantizer.round( maxValue, > newPrecision ); > > > >>> } else { > > > >>> result = Quantizer.round( minValue, > newPrecision ); > > > >>> } > > > >>> result.setError(FixPoint.OVERFLOW); > > > >>> //return result; > > > >>> break; > > > >>> case OVERFLOW_TO_ZERO: > > > >>> result = new FixPoint(newPrecision, BigInteger.ZERO); > > > >>> result.setError(FixPoint.OVERFLOW); > > > >>> //return result; > > > >>> break; > > > >>> default: > > > >>> throw new IllegalArgumentException("Illegal Mode > of " + > > > >>> "overflow handling"); > > > >>> } > > > >>> newValue = result; > > > >>> } > > > >>> return newValue; > > > >>> } > > > >>> > > > >>> /** Return the nearest less than or equal fixed point number > > > >>> * that has the given precision, possibly introducing > > > >>> * quantization or overflow errors. > > > >>> * An overflow error occurs if the specified number does not fit > > > >>> * within the range possible with the specified precision. > In that > > > >>> * case, the returned value is either the maximum or minimum > value > > > >>> * possible with the given precision, depending on the sign > of the > > > >>> * specified number. In this case, a flag is set in the returned > > > >>> * value to indicate that an overflow error occurred. > > > >>> * > > > >>> * @param value The value to represent. > > > >>> * @param precision The precision of the representation. > > > >>> * @return A fixed-point representation of the value. > > > >>> */ > > > >>> public static FixPoint truncate(double value, Precision > precision) { > > > >>> BigDecimal newValue = new BigDecimal( value ); > > > >>> return truncate( newValue, precision); > > > >>> } > > > >>> > > > >>> /** Return the nearest less than or equal fixed point number > > > >>> * that has the given precision, possibly introducing > > > >>> * quantization or overflow errors. > > > >>> * An overflow error occurs if the specified number does not fit > > > >>> * within the range possible with the specified precision. > In that > > > >>> * case, the returned value is either the maximum or minimum > value > > > >>> * possible with the given precision, depending on the sign > of the > > > >>> * specified number. In this case, a flag is set in the returned > > > >>> * value to indicate that an overflow error occurred. > > > >>> * > > > >>> * @param value The value to represent. > > > >>> * @param precision The precision of the representation. > > > >>> * @return A fixed-point representation of the value. > > > >>> */ > > > >>> public static FixPoint truncate(BigDecimal value, Precision > > > >>> precision) { > > > >>> > > > >>> BigInteger tmpValue; > > > >>> BigInteger fxvalue; > > > >>> boolean overflow = false; > > > >>> > > > >>> BigDecimal x = value; > > > >>> BigDecimal maxValue = precision.findMaximum(); > > > >>> BigDecimal minValue = precision.findMinimum(); > > > >>> > > > >>> // check if 'x' falls within the range of this FixPoint with > > > >>> // given precision > > > >>> if ( x.compareTo(maxValue) > 0 ) { > > > >>> overflow = true; > > > >>> x = maxValue; > > > >>> } > > > >>> if ( x.compareTo(minValue) < 0 ) { > > > >>> overflow = true; > > > >>> x = minValue; > > > >>> } > > > >>> > > > >>> int number = precision.getFractionBitLength(); > > > >>> BigDecimal tmp = x.subtract(minValue); > > > >>> tmp = _getTwoRaisedTo(number).multiply(tmp); > > > >>> // Truncate by going from BigDecimal to BigInteger > > > >>> fxvalue = tmp.toBigInteger(); > > > >>> fxvalue = > fxvalue.add(_getTwoRaisedTo(number).multiply(minValue) > > > >>> .toBigInteger()); > > > >>> // Create a new FixPoint > > > >>> FixPoint fxp = new FixPoint( precision, fxvalue ); > > > >>> > > > >>> if ( overflow ) { > > > >>> fxp.setError( FixPoint.OVERFLOW ); > > > >>> } > > > >>> return fxp; > > > >>> } > > > >>> > > > >>> /** Return the nearest less than or equal fixed point number > > > >>> * that has the given precision, possibly introducing > > > >>> * quantization or overflow errors. > > > >>> * An overflow error occurs if the specified number does not fit > > > >>> * within the range possible with the specified precision. > In that > > > >>> * case, the returned value depends on the specified mode. > > > >>> * If the mode is SATURATE, then the return value is either > > > >>> * the maximum or minimum value possible with the given > > > >>> * precision, depending on the sign of the > > > >>> * specified number. If the mode is OVERFLOW_TO_ZERO, > > > >>> * then the return value is zero. > > > >>> * In either case, a flag is set in the returned > > > >>> * value to indicate that an overflow error occurred. > > > >>> * > > > >>> * @param value The value to represent. > > > >>> * @param newPrecision The precision of the representation. > > > >>> * @param mode The overflow mode. > > > >>> * @return A new fixed-point representation of the value. > > > >>> */ > > > >>> public static FixPoint truncate( > > > >>> FixPoint value, > > > >>> Precision newPrecision, > > > >>> int mode) { > > > >>> > > > >>> FixPoint newValue = null; > > > >>> BigDecimal x = value.bigDecimalValue(); > > > >>> BigDecimal maxValue = newPrecision.findMaximum(); > > > >>> BigDecimal minValue = newPrecision.findMinimum(); > > > >>> FixPoint result; > > > >>> if ( x.compareTo(maxValue) > 0 ) { > > > >>> switch (mode) { > > > >>> case SATURATE: > > > >>> result = Quantizer.truncate( maxValue, > newPrecision ); > > > >>> break; > > > >>> case OVERFLOW_TO_ZERO: > > > >>> result = new FixPoint(newPrecision, BigInteger.ZERO); > > > >>> break; > > > >>> default: > > > >>> throw new IllegalArgumentException("Illegal Mode > of " + > > > >>> "overflow handling"); > > > >>> } > > > >>> result.setError(FixPoint.OVERFLOW); > > > >>> } else if ( x.compareTo(minValue) < 0 ) { > > > >>> switch (mode) { > > > >>> case SATURATE: > > > >>> result = Quantizer.truncate( minValue, > newPrecision ); > > > >>> break; > > > >>> case OVERFLOW_TO_ZERO: > > > >>> result = new FixPoint(newPrecision, BigInteger.ZERO); > > > >>> break; > > > >>> default: > > > >>> throw new IllegalArgumentException("Illegal Mode > of " + > > > >>> "overflow handling"); > > > >>> } > > > >>> result.setError(FixPoint.OVERFLOW); > > > >>> } else { > > > >>> result = Quantizer.truncate(x, newPrecision); > > > >>> } > > > >>> return result; > > > >>> } > > > >>> > > > >>> > /////////////////////////////////////////////////////////////////// > > > >>> //// public > variables //// > > > >>> > > > >>> /** Indicate that overflow should saturate. */ > > > >>> public static final int SATURATE = 0; > > > >>> > > > >>> /** Indicate that overflow should result in a zero value. */ > > > >>> public static final int OVERFLOW_TO_ZERO = 1; > > > >>> > > > >>> > > > >>> > /////////////////////////////////////////////////////////////////// > > > >>> //// private > methods //// > > > >>> > > > >>> /** Get the BigDecimal which is the 2^exponent. If the value is > > > >>> * already calculated, return this cached value, else calculate > > > >>> * the value. > > > >>> * > > > >>> * @param number the exponent. > > > >>> * @return the BigDecimal representing 2^exponent. > > > >>> */ > > > >>> private static BigDecimal _getTwoRaisedTo(int number) { > > > >>> if ( number < 32 && number >= 0 ) { > > > >>> return _twoRaisedTo[number]; > > > >>> } else { > > > >>> BigInteger two = _two.toBigInteger(); > > > >>> return new BigDecimal( two.pow( number ) ); > > > >>> } > > > >>> } > > > >>> > > > >>> > /////////////////////////////////////////////////////////////////// > > > >>> //// private > variables //// > > > >>> > > > >>> /** Static reference to the BigDecimal representation of one. */ > > > >>> private static BigDecimal _one = new BigDecimal("1"); > > > >>> > > > >>> /** Calculate the table containing 2^x, with 0 < x < 64. Purpose > > > >>> * is to speed up calculations involving calculating 2^x. > The table > > >is > > > >>> * calculated using BigDecimal, since this make the > transformation > > > >>> from > > > >>> * string of bits to a double easier. > > > >>> */ > > > >>> private static BigDecimal[] _twoRaisedTo = new BigDecimal[32]; > > > >>> > > > >>> /** Static reference to the BigDecimal representation of two. */ > > > >>> private static BigDecimal _two = new BigDecimal("2"); > > > >>> > > > >>> ////////////////////// > > > >>> // static initializer > > > >>> ////////////////////// > > > >>> > > > >>> static { > > > >>> BigDecimal p2 = _one; > > > >>> for (int i = 0; i < 32; i++) { > > > >>> _twoRaisedTo[i] = p2; > > > >>> p2 = p2.multiply( _two ); > > > >>> } > > > >>> } > > > >>>} > > > >>> > > > >>>-----Original Message----- > > > >>>From: Stephen Andrew Neuendorffer [mailto:[EMAIL PROTECTED]] > > > >>>Sent: April 1, 2002 3:02 PM > > > >>>To: [EMAIL PROTECTED]; [EMAIL PROTECTED] > > > >>>Cc: [EMAIL PROTECTED]; bart Kienhuis > > > >>>Subject: Re: [Ptolemy] Re: Quantizer bug > > > >>> > > > >>> > > > >>>I've fixed this... truncation of negative numbers now rounds towards > > >zero, > > > >>>as I believe it should. > > > >>>Jeff: Here is a more correct truncate method from > ptolemy.math.Quantizer. > > > >>> > > > >>>It looks like there are other problems with the fixpoint package, > > > >>>however. I bit of quick poking seems to suggest that > > > >>>truncate(fixpoint) and round(fixpoint) both truncate the value. There > > >are > > > >>>probably other bugs as well. > > > >>>Particularly disturbing is that there were tests for the truncate > method > > > >>>that were obviously wrong (and not even returning one of the closest > > > >>>fixed-point values...) > > > >>> > > > >>>There are quite a few test suites for IEEE754/854... perhaps we could > > >grab > > > >>>one and leverage it? I don't know if it would have caught this > error or > > > >>>not, but... Unfortunately, the FixPoint code is a bit orphaned at the > > > >>>moment... > > > >>> > > > >>> public static FixPoint truncate(BigDecimal value, Precision > > >precision) > > > >>>{ > > > >>> > > > >>> BigInteger tmpValue; > > > >>> BigInteger fxvalue; > > > >>> boolean overflow = false; > > > >>> > > > >>> BigDecimal x = value; > > > >>> BigDecimal maxValue = precision.findMaximum(); > > > >>> BigDecimal minValue = precision.findMinimum(); > > > >>> > > > >>> // check if 'x' falls within the range of this FixPoint with > > > >>> // given precision > > > >>> if ( x.compareTo(maxValue) > 0 ) { > > > >>> overflow = true; > > > >>> x = maxValue; > > > >>> } > > > >>> if ( x.compareTo(minValue) < 0 ) { > > > >>> overflow = true; > > > >>> x = minValue; > > > >>> } > > > >>> > > > >>> // determine the scale factor by calculating > > >2^fractionBitLength > > > >>> // By multiply the given value 'x' with this scale > factor, we > > >get > > > >>> // a value of which we drop the fraction part. The integer > > > >>>remaining > > > >>> // will be represented by the BigInteger. > > > >>> int number = precision.getFractionBitLength(); > > > >>> BigDecimal multiplier; > > > >>> BigDecimal epsilon; > > > >>> BigDecimal tmp; > > > >>> > > > >>> // calculate epsilon > > > >>> // This division divides two number in a precision of 40 > > > >>> // decimal behind the point. This is equivalent with a > > > >>> // fractional precision of 128 bits. ( ln(1-^40)/ln(2) > > 128) > > > >>> epsilon = _one.divide(_getTwoRaisedTo(number + 11), > > > >>> 40, BigDecimal.ROUND_HALF_EVEN); > > > >>> > > > >>> // Since there is slack in floating point numbers, add or > > > >>> // subtract epsilon as appropriate to get the 'intuitively > > > >>> // correct' fixed point value. Note that this epsilon > is MUCH > > > >>>smaller > > > >>> // than the one performed with round. > > > >>> if ( x.signum() >= 0 ) { > > > >>> multiplier = x.add( epsilon ); > > > >>> } else { > > > >>> multiplier = x.subtract(epsilon); > > > >>> } > > > >>> > > > >>> // determine the scale factor. > > > >>> BigDecimal kl = _getTwoRaisedTo(number).multiply( > multiplier ); > > > >>> > > > >>> // By going from BigDecimal to BigInteger, remove the > fraction > > > >>> // part introducing a quantization error. > > > >>> fxvalue = kl.toBigInteger(); > > > >>> > > > >>> // Create a new FixPoint > > > >>> FixPoint fxp = new FixPoint( precision, fxvalue ); > > > >>> > > > >>> if ( overflow ) { > > > >>> fxp.setError( FixPoint.OVERFLOW ); > > > >>> } > > > >>> return fxp; > > > >>> } > > > >>> > > > >>> > > > >>>At 08:37 AM 4/1/2002 -0800, Christopher Hylands wrote: > > > >>> >The following appeared in comp.soft-sys.ptolemy. > > > >>> >It look like Quantizer.java has not changed since Ptolemy II 1.0 > > > >>> >Can someone take a look and see what they think? > > > >>> > > > > >>> >If you responde, please cc [EMAIL PROTECTED] > > > >>> > > > > >>> >-Christopher > > > >>> > > > > >>> >------- Forwarded Message > > > >>> > > > > >>> > > > > >>> >From: jpat <[EMAIL PROTECTED]> > > > >>> >Subject: Quantizer bug > > > >>> >Date: Sat, 30 Mar 2002 21:41:30 GMT > > > >>> > > > > >>> >ptolemy.math.Quantizer.java (PTII) gives incorrect results for > negative > > > >>> >numbers when using the truncate method. This is easily seen on the > > > >>>FixedPoint > > > >>> >demo at the ptolemy web site. > > > >>> >(http://ptolemy.eecs.berkeley.edu/ptolemyII/ptII1.0/ptII1.0/ptole > my/dom > > > >>> ains > > > >>> >> >/ > > > >>> >> > >sdf/demo/FixPoint/FixPoint.htm). Set the DoubleToFix actor's > > > >>> quantization > > > >>> >parameter to truncate and notice that the "first quantized" error > > >diverges > > > >>> >for negative numbers. It is even easier to see if you increase the > > > >>>precision. > > > >>> > > > > >>> >Looking at the code, I suspect the problem is in the calculation of > > > >>> epsilon > > > >>> >in the truncate(BigDecimal value...) method. I don't understand why > > > >>> epsilon > > > >>>is > > > >>> >being added to the number before scaling but this is one place > the code > > >is > > > >>> >different for positve vs. negative numbers. Note that in the > positive > > > >>>case, > > > >>> >5 gets added to the exponent (variable is called "number") while > in the > > > >>> >negative case 11 gets added. > > > >>> > > > > >>> >Can anyone figure this code out and post the correct method? This is > > > >>>hanging > > > >>> >me up badly as I have built my entire system in PTII but need to > model > > >the > > > >>> >quantization noise accurately. > > > >>> > > > > >>> >Thanks, > > > >>> >Jeff > > > >>> >- --------- > > > >>> > > > > >>> >Jeff Patterson > > > >>> >Senior Design Engineer > > > >>> >Synthesis Center of Technology > > > >>> >Agilent Technologies > > > >>> >[EMAIL PROTECTED] > > > >>> > > > > >>> > > > > >>> >------- End of Forwarded Message > > > >>> > > > > >>> >_______________________________________________ > > > >>> >Ptolemy maillist - [EMAIL PROTECTED] > > > >>> >http://www.gigascale.org/ptolemy/listinfo/ptolemy > > > >>> > > > >>> > > > >>>------------------------------------------------------------------- > ------ > > >--- > > > >>>Posted to the ptolemy-hackers mailing list. Please send > administrative > > > >>>mail for this list to: > [EMAIL PROTECTED] > > > >> > > > >>_______________________________________________ > > > >>Ptolemy maillist - [EMAIL PROTECTED] > > > >>http://www.gigascale.org/ptolemy/listinfo/ptolemy > > > > > > > >------------ > > > >Edward A. Lee, Professor > > > >518 Cory Hall, UC Berkeley, Berkeley, CA 94720 > > > >phone: 510-642-0455, fax: 510-642-2739 > > > >[EMAIL PROTECTED], http://ptolemy.eecs.berkeley.edu/~eal > > > > > > >_______________________________________________ > > >Ptolemy maillist - [EMAIL PROTECTED] > > >http://www.gigascale.org/ptolemy/listinfo/ptolemy > > >-- >======================================= >Jeff Patterson >Senior Design Engineer >Synthesis Center of Technology >Agilent Technologies > >email:[EMAIL PROTECTED] ---------------------------------------------------------------------------- Posted to the ptolemy-hackers mailing list. Please send administrative mail for this list to: [EMAIL PROTECTED]