001/* A collection of methods for creating fixed point values. 002 003 Copyright (c) 1998-2014 The Regents of the University of California 004 and Research in Motion Limited. All rights reserved. 005 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the above 009 copyright notice and the following two paragraphs appear in all copies 010 of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA OR RESEARCH IN MOTION 013 LIMITED BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 014 INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS 015 SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA 016 HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION LIMITED 019 SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 020 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 021 PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 022 THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION LIMITED HAS NO 023 OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR 024 MODIFICATIONS. 025 026 PT_COPYRIGHT_VERSION_2 027 COPYRIGHTENDKEY 028 029 */ 030package ptolemy.math; 031 032import java.math.BigDecimal; 033 034/////////////////////////////////////////////////////////////////// 035//// Quantizer 036 037/** 038 This class provides a set of static methods for creating instances of 039 the FixPoint class from doubles, integers, or fixed point numbers. 040 The various round() methods return a fixed point value that is nearest 041 to the specified number, but has the specified precision. The various 042 roundToZero() and truncate() methods return a fixed point value that 043 is nearest to the specified number, but no greater in magnitude. The 044 various roundDown() methods return a the nearest fixed point less than 045 the argument. The intention is to fill out this class with roundUp(), 046 and roundNearestEven(). All of these methods may introduce 047 quantization errors and/or overflow. 048 049 This class has been reimplemented to perform all rounding by first 050 constructing a FixPointQuantization and then using either the quantizing 051 constructor of FixPoint or FixPoint.quantize. Users may find that their 052 code simplifies if they do likewise. 053 054 @author Bart Kienhuis, Edward A. Lee, Ed Willink 055 @version $Id$ 056 @since Ptolemy II 0.4 057 @Pt.ProposedRating Yellow (kienhuis) 058 @Pt.AcceptedRating Red (kienhuis) 059 @see FixPoint 060 @see Overflow 061 @see Precision 062 @see Rounding 063 @see Quantization 064 */ 065public class Quantizer { 066 // The only constructor is private so that this class cannot 067 // be instantiated. 068 private Quantizer() { 069 } 070 071 /////////////////////////////////////////////////////////////////// 072 //// public methods //// 073 074 /** Return the fixed point number that is nearest to the specified 075 * value, but has the given precision, possibly introducing 076 * quantization or overflow errors. 077 * An overflow error occurs if the specified number does not fit 078 * within the range possible with the specified precision. In that 079 * case, the returned value is either the maximum or minimum value 080 * possible with the given precision, depending on the sign of the 081 * specified number. 082 * 083 * @param value The value to represent. 084 * @param precision The precision of the representation. 085 * @return A fixed-point representation of the value. 086 */ 087 public static FixPoint round(double value, Precision precision) { 088 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 089 Rounding.NEAREST); 090 return new FixPoint(new BigDecimal(value), q); 091 } 092 093 /** Return the fixed point number that is nearest to the specified 094 * value, but has the given precision, possibly introducing 095 * quantization or overflow errors. 096 * An overflow error occurs if the specified number does not fit 097 * within the range possible with the specified precision. In that 098 * case, the returned value is either the maximum or minimum value 099 * possible with the given precision, depending on the sign of the 100 * specified number. 101 * 102 * @param value The value to represent. 103 * @param precision The precision of the representation. 104 * @return A fixed-point representation of the value. 105 */ 106 public static FixPoint round(BigDecimal value, Precision precision) { 107 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 108 Rounding.NEAREST); 109 return new FixPoint(value, q); 110 } 111 112 /** Return the fixed point number that is nearest to the specified 113 * value, but has the given precision, possibly introducing 114 * quantization or overflow errors. 115 * An overflow error occurs if the specified number does not fit 116 * within the range possible with the specified precision. In that 117 * case, the returned value depends on the specified mode. 118 * If the mode is SATURATE, then the return value is either 119 * the maximum or minimum value possible with the given 120 * precision, depending on the sign of the 121 * specified number. If the mode is OVERFLOW_TO_ZERO, 122 * then the return value is zero. 123 * 124 * @param value The value to represent. 125 * @param newPrecision The precision of the representation. 126 * @param mode The overflow mode. 127 * @return A new fixed-point representation of the value. 128 */ 129 public static FixPoint round(FixPoint value, Precision newPrecision, 130 Overflow mode) { 131 Quantization q = new FixPointQuantization(newPrecision, mode, 132 Rounding.NEAREST); 133 return value.quantize(q); 134 } 135 136 /** Return the nearest fixed point number with less than or equal 137 * magnitude that has the given precision, possibly introducing 138 * quantization or overflow errors. 139 * An overflow error occurs if the specified number does not fit 140 * within the range possible with the specified precision. In that 141 * case, the returned value is either the maximum or minimum value 142 * possible with the given precision, depending on the sign of the 143 * specified number. 144 * 145 * @param value The value to represent. 146 * @param precision The precision of the representation. 147 * @return A fixed-point representation of the value. 148 */ 149 public static FixPoint roundDown(double value, Precision precision) { 150 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 151 Rounding.DOWN); 152 return new FixPoint(new BigDecimal(value), q); 153 } 154 155 /** Return the nearest fixed point number with less than or equal 156 * magnitude that has the given precision, possibly introducing 157 * quantization or overflow errors. 158 * An overflow error occurs if the specified number does not fit 159 * within the range possible with the specified precision. In that 160 * case, the returned value is either the maximum or minimum value 161 * possible with the given precision, depending on the sign of the 162 * specified number. 163 * 164 * @param value The value to represent. 165 * @param precision The precision of the representation. 166 * @return A fixed-point representation of the value. 167 */ 168 public static FixPoint roundDown(BigDecimal value, Precision precision) { 169 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 170 Rounding.DOWN); 171 return new FixPoint(value, q); 172 } 173 174 /** Return the nearest fixed point number with less than or equal 175 * magnitude that has the given precision, possibly introducing 176 * quantization or overflow errors. 177 * An overflow error occurs if the specified number does not fit 178 * within the range possible with the specified precision. In that 179 * case, the returned value depends on the specified mode. 180 * If the mode is SATURATE, then the return value is either 181 * the maximum or minimum value possible with the given 182 * precision, depending on the sign of the 183 * specified number. If the mode is OVERFLOW_TO_ZERO, 184 * then the return value is zero. 185 * 186 * @param value The value to represent. 187 * @param newPrecision The precision of the representation. 188 * @param mode The overflow mode. 189 * @return A new fixed-point representation of the value. 190 */ 191 public static FixPoint roundDown(FixPoint value, Precision newPrecision, 192 Overflow mode) { 193 Quantization q = new FixPointQuantization(newPrecision, mode, 194 Rounding.DOWN); 195 return value.quantize(q); 196 } 197 198 /** Return the fixed point number that is nearest to the specified 199 * value, but has the given precision, possibly introducing 200 * quantization or overflow errors. If the rounded digit is 201 * five, then the last digit that is not discarded will be 202 * rounded to make it even. An overflow error occurs if the 203 * specified number does not fit within the range possible with 204 * the specified precision. In that case, the returned value is 205 * either the maximum or minimum value possible with the given 206 * precision, depending on the sign of the specified number. 207 * 208 * @param value The value to represent. 209 * @param precision The precision of the representation. 210 * @return A fixed-point representation of the value. 211 */ 212 public static FixPoint roundNearestEven(double value, Precision precision) { 213 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 214 Rounding.HALF_EVEN); 215 return new FixPoint(new BigDecimal(value), q); 216 } 217 218 /** Return the fixed point number that is nearest to the specified 219 * value, but has the given precision, possibly introducing 220 * quantization or overflow errors. If the rounded digit is 221 * five, then the last digit that is not discarded will be 222 * rounded to make it even. An overflow error occurs if the 223 * specified number does not fit within the range possible with 224 * the specified precision. In that case, the returned value is 225 * either the maximum or minimum value possible with the given 226 * precision, depending on the sign of the specified number. 227 * 228 * @param value The value to represent. 229 * @param precision The precision of the representation. 230 * @return A fixed-point representation of the value. 231 */ 232 public static FixPoint roundNearestEven(BigDecimal value, 233 Precision precision) { 234 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 235 Rounding.HALF_EVEN); 236 return new FixPoint(value, q); 237 } 238 239 /** Return the fixed point number that is nearest to the specified 240 * value, but has the given precision, possibly introducing 241 * quantization or overflow errors. If the rounded digit is 242 * five, then the last digit that is not discarded will be 243 * rounded to make it even. An overflow error occurs if the 244 * specified number does not fit within the range possible with 245 * the specified precision. In that case, the returned value 246 * depends on the specified mode. If the mode is SATURATE, then 247 * the return value is either the maximum or minimum value 248 * possible with the given precision, depending on the sign of 249 * the specified number. If the mode is OVERFLOW_TO_ZERO, then 250 * the return value is zero. 251 * 252 * @param value The value to represent. 253 * @param newPrecision The precision of the representation. 254 * @param mode The overflow mode. 255 * @return A new fixed-point representation of the value. 256 */ 257 public static FixPoint roundNearestEven(FixPoint value, 258 Precision newPrecision, Overflow mode) { 259 Quantization q = new FixPointQuantization(newPrecision, mode, 260 Rounding.HALF_EVEN); 261 return value.quantize(q); 262 } 263 264 /** Return the fixed point number that is nearest to the specified 265 * value, but has magnitude no greater that the specified value, 266 * and has the given precision, possibly introducing 267 * quantization or overflow errors. 268 * An overflow error occurs if the specified number does not fit 269 * within the range possible with the specified precision. In that 270 * case, the returned value is either the maximum or minimum value 271 * possible with the given precision, depending on the sign of the 272 * specified number. 273 * 274 * @param value The value to represent. 275 * @param precision The precision of the representation. 276 * @return A fixed-point representation of the value. 277 */ 278 public static FixPoint roundToZero(double value, Precision precision) { 279 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 280 Rounding.DOWN); 281 return new FixPoint(new BigDecimal(value), q); 282 } 283 284 /** Return the fixed point number that is nearest to the specified 285 * value, but has magnitude no greater that the specified value, 286 * and has the given precision, possibly introducing 287 * quantization or overflow errors. 288 * An overflow error occurs if the specified number does not fit 289 * within the range possible with the specified precision. In that 290 * case, the returned value is either the maximum or minimum value 291 * possible with the given precision, depending on the sign of the 292 * specified number. 293 * 294 * @param value The value to represent. 295 * @param precision The precision of the representation. 296 * @return A fixed-point representation of the value. 297 */ 298 public static FixPoint roundToZero(BigDecimal value, Precision precision) { 299 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 300 Rounding.DOWN); 301 return new FixPoint(value, q); 302 } 303 304 /** Return the fixed point number that is nearest to the specified 305 * value, but has magnitude no greater than the specified value, 306 * and has the given precision, possibly introducing 307 * quantization or overflow errors. 308 * An overflow error occurs if the specified number does not fit 309 * within the range possible with the specified precision. In that 310 * case, the returned value depends on the specified mode. 311 * If the mode is SATURATE, then the return value is either 312 * the maximum or minimum value possible with the given 313 * precision, depending on the sign of the 314 * specified number. If the mode is OVERFLOW_TO_ZERO, 315 * then the return value is zero. 316 * 317 * @param value The value to represent. 318 * @param newPrecision The precision of the representation. 319 * @param mode The overflow mode. 320 * @return A new fixed-point representation of the value. 321 */ 322 public static FixPoint roundToZero(FixPoint value, Precision newPrecision, 323 Overflow mode) { 324 Quantization q = new FixPointQuantization(newPrecision, mode, 325 Rounding.DOWN); 326 return value.quantize(q); 327 } 328 329 /** Return the smallest greater than or equal fixed point number 330 * that has the given precision, possibly introducing 331 * quantization or overflow errors. 332 * An overflow error occurs if the specified number does not fit 333 * within the range possible with the specified precision. In that 334 * case, the returned value is either the maximum or minimum value 335 * possible with the given precision, depending on the sign of the 336 * specified number. 337 * 338 * @param value The value to represent. 339 * @param precision The precision of the representation. 340 * @return A fixed-point representation of the value. 341 */ 342 public static FixPoint roundUp(double value, Precision precision) { 343 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 344 Rounding.UP); 345 return new FixPoint(new BigDecimal(value), q); 346 } 347 348 /** Return the smallest greater than or equal fixed point number 349 * that has the given precision, possibly introducing 350 * quantization or overflow errors. 351 * An overflow error occurs if the specified number does not fit 352 * within the range possible with the specified precision. In that 353 * case, the returned value is either the maximum or minimum value 354 * possible with the given precision, depending on the sign of the 355 * specified number. 356 * 357 * @param value The value to represent. 358 * @param precision The precision of the representation. 359 * @return A fixed-point representation of the value. 360 */ 361 public static FixPoint roundUp(BigDecimal value, Precision precision) { 362 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 363 Rounding.UP); 364 return new FixPoint(value, q); 365 } 366 367 /** Return the smallest greater than or equal fixed point number 368 * that has the given precision, possibly introducing 369 * quantization or overflow errors. 370 * An overflow error occurs if the specified number does not fit 371 * within the range possible with the specified precision. In that 372 * case, the returned value depends on the specified mode. 373 * If the mode is SATURATE, then the return value is either 374 * the maximum or minimum value possible with the given 375 * precision, depending on the sign of the 376 * specified number. If the mode is OVERFLOW_TO_ZERO, 377 * then the return value is zero. 378 * 379 * @param value The value to represent. 380 * @param newPrecision The precision of the representation. 381 * @param mode The overflow mode. 382 * @return A new fixed-point representation of the value. 383 */ 384 public static FixPoint roundUp(FixPoint value, Precision newPrecision, 385 Overflow mode) { 386 Quantization q = new FixPointQuantization(newPrecision, mode, 387 Rounding.UP); 388 return value.quantize(q); 389 } 390 391 /** Return the fixed point number that is nearest to the specified 392 * value, but has magnitude no greater that the specified value, 393 * and has the given precision, possibly introducing quantization 394 * or overflow errors. An overflow error occurs if the specified 395 * number does not fit within the range possible with the 396 * specified precision. In that case, the returned value is 397 * either the maximum or minimum value possible with the given 398 * precision, depending on the sign of the specified number. 399 * 400 * <p> Note: This method does NOT perform truncation per most 401 * fixed-point DSP implementations, which simply drop the 402 * fractional bits. Most models of fixed-point algorithms will 403 * use the roundDown methods in this class instead. 404 * @param value The value to represent. 405 * @param precision The precision of the representation. 406 * @return A fixed-point representation of the value. 407 * @deprecated Use roundToZero instead. 408 */ 409 @Deprecated 410 public static FixPoint truncate(double value, Precision precision) { 411 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 412 Rounding.TRUNCATE); 413 return new FixPoint(new BigDecimal(value), q); 414 } 415 416 /** Return the fixed point number that is nearest to the specified 417 * value, but has magnitude no greater that the specified value, 418 * and has the given precision, possibly introducing 419 * quantization or overflow errors. 420 * An overflow error occurs if the specified number does not fit 421 * within the range possible with the specified precision. In that 422 * case, the returned value is either the maximum or minimum value 423 * possible with the given precision, depending on the sign of the 424 * specified number. 425 * 426 * <p> Note: This method does NOT perform truncation per most 427 * fixed-point DSP implementations, which simply drop the 428 * fractional bits. Most models of fixed-point algorithms will 429 * use the roundDown methods in this class instead. 430 * @param value The value to represent. 431 * @param precision The precision of the representation. 432 * @return A fixed-point representation of the value. 433 * @deprecated Use roundToZero instead. 434 */ 435 @Deprecated 436 public static FixPoint truncate(BigDecimal value, Precision precision) { 437 Quantization q = new FixPointQuantization(precision, Overflow.SATURATE, 438 Rounding.TRUNCATE); 439 return new FixPoint(value, q); 440 } 441 442 /** Return the fixed point number that is nearest to the specified 443 * value, but has magnitude no greater than the specified value, 444 * and has the given precision, possibly introducing 445 * quantization or overflow errors. 446 * An overflow error occurs if the specified number does not fit 447 * within the range possible with the specified precision. In that 448 * case, the returned value depends on the specified mode. 449 * If the mode is SATURATE, then the return value is either 450 * the maximum or minimum value possible with the given 451 * precision, depending on the sign of the 452 * specified number. If the mode is OVERFLOW_TO_ZERO, 453 * then the return value is zero. 454 * 455 * <p> Note: This method does NOT perform truncation per most 456 * fixed-point DSP implementations, which simply drop the 457 * fractional bits. Most models of fixed-point algorithms will 458 * use the roundDown methods in this class instead. 459 * @param value The value to represent. 460 * @param newPrecision The precision of the representation. 461 * @param mode The overflow mode. 462 * @return A new fixed-point representation of the value. 463 * @deprecated Use roundToZero instead. 464 */ 465 @Deprecated 466 public static FixPoint truncate(FixPoint value, Precision newPrecision, 467 Overflow mode) { 468 Quantization q = new FixPointQuantization(newPrecision, mode, 469 Rounding.TRUNCATE); 470 return value.quantize(q); 471 } 472 473 /////////////////////////////////////////////////////////////////// 474 //// public variables //// 475 476 /** Indicate that overflow should saturate. */ 477 public static final Overflow SATURATE = Overflow.SATURATE; 478 479 /** Indicate that overflow should result in a zero value. */ 480 public static final Overflow OVERFLOW_TO_ZERO = Overflow.TO_ZERO; 481}