Я искал решение квадратного корня для BigDecimal и нашел 2 варианта. Выполнил несколько тестов для обоих, они работают с 10 000 точностью. Первый:
private static final int SCALE = 10001;
public BigDecimal calculate(BigDecimal number) throws OperationException {
BigDecimal result;
if (number.compareTo(BigDecimal.ZERO) == 0 ||
number.compareTo(BigDecimal.ONE) == 0) {
result = number;
} else if (number.compareTo(BigDecimal.ZERO)<0){
throw new OperationException(NEGATIVE_VALUE_FOR_SQRT);
} else {
BigInteger integerValue = number.movePointRight(SCALE << 1).toBigInteger();
int bits = (integerValue.bitLength() + 1) >> 1;
BigInteger firstVar = integerValue.shiftRight(bits);
BigInteger secondVar;
do {
secondVar = firstVar;
firstVar = firstVar.add(integerValue.divide(firstVar))
.shiftRight(1);
} while (firstVar.compareTo(secondVar) != 0);
result = new BigDecimal(firstVar, SCALE);
}
return result;
}
Второй:
private static final int SCALE = 10001;
public BigDecimal calculate(BigDecimal number) throws OperationException {
BigDecimal first = BigDecimal.ZERO;
BigDecimal second;
try{
second = new BigDecimal(Math.sqrt(number.doubleValue()));
}catch (NumberFormatException e){
throw new OperationException(NEGATIVE_VALUE_FOR_SQRT);
}
while (!first.equals(second)){
first = second;
second = number.divide(first,SCALE,RoundingMode.HALF_UP);
second = second.add(first);
second = second.divide(BigDecimal.valueOf(2),SCALE,RoundingMode.HALF_UP);
}
return second;
}
Надеюсь, кому-то будут полезны;)
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости