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]

Reply via email to