これは、 「株価を最も近いティック サイズに丸める」に関連しています。
schnaader から提供された回答は正しいですが、不足していることがいくつかあります。
- まず、株価に四捨五入が必要かどうかを確認する必要があります。不要な丸めは、小数部分を台無しにします。
- 次に、除算関数
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;
}
}