/*
Copyright (C) 2009 Ueli Hofstetter
This source code is release under the BSD License.
This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/
JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license. You should have received a
copy of the license along with this program; if not, please email
. The license is also available online at
.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
*/
package org.jquantlib.math;
import org.jquantlib.lang.exceptions.LibraryException;
/**
* Basic rounding class.
*
* @author Ueli Hofstetter
*/
public class Rounding {
private int precision_;
public Type type_;
private int digit_;
/**
* The rounding methods follow the OMG specification available at ftp://ftp.omg.org/pub/docs/formal/00-06-29.pdf
*
* Warning the names of the Floor and Ceiling methods might be misleading. Check the provided reference.
*/
public enum Type {
/**
* Do not round: return the number unmodified
*/
None,
/**
* The first decimal place past the precision will be rounded up. This differs from the OMG rule which rounds up only
* if the decimal to be rounded is greater than or equal to the rounding digit
*/
Up,
/**
* All decimal places past the precision will be truncated
*/
Down,
/**
* The first decimal place past the precision will be rounded up if greater than or equal to the rounding digit;
* this corresponds to the OMG round-up rule. When the rounding digit is 5, the result will be the one closest to
* the original number, hence the name.
*/
Closest,
/**
* Positive numbers will be rounded up and negative numbers will be rounded down using the OMG round up and round
* down rules
*/
Floor,
/**
* Positive numbers will be rounded down and negative numbers will be rounded up using the OMG round up and round down
* rules
*/
Ceiling
};
/**
* Instances built through this constructor don't perform any rounding.
*/
public Rounding() {
this.type_ = Type.None;
}
public Rounding(final int precision) {
this(precision, Type.Closest, 5);
}
public Rounding(final int precision, final Type type /* = Closest */, final int digit /* = 5 */) {
this.precision_ = (precision);
this.type_ = (type);
this.digit_ = (digit);
}
public int precision() {
return precision_;
}
public Type type() {
return type_;
}
public int roundingDigit() {
return digit_;
}
final public /*Decimal*/ double operator(/*Decimal*/final double value) {
if (type_ == Rounding.Type.None)
return value;
/*Real*/ final double mult = Math.pow(10.0,precision_);
final boolean neg = (value < 0.0);
/*Real*/ double lvalue = Math.abs(value)*mult;
/*Real*/ final double integral = ((int)lvalue);
/*Real*/ final double modVal = (lvalue-(int)lvalue );
lvalue -= modVal;
switch (type_) {
case Down:
break;
case Up:
lvalue += 1.0;
break;
case Closest:
if (modVal >= (digit_/10.0)){
lvalue += 1.0;
}
break;
case Floor:
if (!neg) {
if (modVal >= (digit_/10.0)){
lvalue += 1.0;
}
}
break;
case Ceiling:
if (neg) {
if (modVal >= (digit_/10.0)) {
lvalue += 1.0;
}
}
break;
default:
throw new LibraryException("unknown rounding method"); // TODO: message
}
return (neg) ? -(lvalue/mult) : lvalue/mult;
}
// Up-rounding.
public static class UpRounding extends Rounding {
public UpRounding(final int precision) {
this(precision, 5);
}
public UpRounding(final int precision, final int digit) {
super(precision, Type.Up, digit);
}
};
// Down-rounding.
public static class DownRounding extends Rounding {
public DownRounding(final int precision) {
this(precision, 5);
}
public DownRounding(final int precision, final int digit) {
super(precision, Type.Down, digit);
}
};
// Closest rounding.
public static class ClosestRounding extends Rounding {
public ClosestRounding(final int precision) {
this(precision, 5);
}
public ClosestRounding(final int precision, final int digit) {
super(precision, Type.Closest, digit);
}
};
// Ceiling truncation.
public static class CeilingTruncation extends Rounding {
public CeilingTruncation(final int precision) {
this(precision, 5);
}
public CeilingTruncation(final int precision, final int digit) {
super(precision, Type.Ceiling, digit);
}
};
// Floor truncation.
public static class FloorTruncation extends Rounding {
public FloorTruncation(final int precision) {
this(precision, 5);
}
public FloorTruncation(final int precision, final int digit) {
super(precision, Type.Floor, digit);
}
};
}
Ads help maintain this website.