I wouldn't worry too much about backward compatibility as it can be safely assumed that there are no working applications out there using the truncate method- it was too badly broken. Semantics aside, those us doing fixed-point work need round to minus infinity functionality. In your proposed list is "Round Down" equivalent to round to minus infinity?
Jeff On Wed, 2002-04-03 at 09:21, Stephen Andrew Neuendorffer wrote: > 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] > -- ======================================= Jeff Patterson Co-founder and Site Administrator The Melanoma Patients' Information Page http://www.mpip.org email:[EMAIL PROTECTED] ---------------------------------------------------------------------------- Posted to the ptolemy-hackers mailing list. Please send administrative mail for this list to: [EMAIL PROTECTED]