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/ptolemy/domains/
>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]

Reply via email to