这与“将股票价格四舍五入到最接近的刻度大小”更相关。
schnaader 提供的答案是正确的,但是缺少一些内容。
- 首先,你必须检查股价是否需要四舍五入。不必要的舍入会弄乱小数部分。
- 然后你还需要处理在divide函数
ArithmeticException
中可能出现的问题BigDecimal
这是我的解决方案。解释它需要很多时间。我建议尝试一些样品来感受一下。寻找功能roundTick()
。
import static java.math.RoundingMode.HALF_UP;
import java.math.BigDecimal;
/**
* Utility class for stock price related operations.
*/
public final class PriceFormatter {
public static final float DELTA = 0.0001f;
private PriceFormatter() {
}
/**
* Rounds the price to the nearest tick size.
*
* @param price price
* @param tickSize tick size
* @return price rounded to the nearest tick size
*/
public static final float roundTick(final float price, final float tickSize) {
if (tickSize < DELTA) {
return price;
}
if (!isRoundingNeeded(price, tickSize)) {
return price;
}
final BigDecimal p = new BigDecimal(price);
final BigDecimal t = new BigDecimal(tickSize);
final BigDecimal roundedPrice = p.divide(t, 0, HALF_UP).multiply(t);
return roundedPrice.floatValue();
}
/**
* Checks whether price needs rounding to the nearest tick size.
*
* @param price price
* @param tickSize tick size
* @return true, if rounding is needed; false otherwise
*/
public static final boolean isRoundingNeeded(final float price, final float tickSize) {
final int mult = calculateTickMultiplier(tickSize);
final int mod = (int) (tickSize * mult);
final float reminder = (((price * mult) % mult) % mod);
final boolean needsRounding = reminder > DELTA;
return needsRounding;
}
public static final int calculateTickMultiplier(final float tickSize) {
int result = 1;
while (((tickSize * result) < 1) || (((tickSize * result) - (int) (tickSize * result)) > DELTA)) {
result *= 10;
}
return result;
}
}