Skip to content

Instantly share code, notes, and snippets.

@daanta-real
Created May 13, 2024 17:11
Show Gist options
  • Save daanta-real/e9f46b975d20e8d9bff108ffe3332d4b to your computer and use it in GitHub Desktop.
Save daanta-real/e9f46b975d20e8d9bff108ffe3332d4b to your computer and use it in GitHub Desktop.
POW with 2 BigDecimal instances. yeah
package y24.m05.d13.c01_BigDecimal_exp;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
@Slf4j
public class Test01 {
@Test
void test() {
// 1. prepare
// 소수점 아래 최대 30자리까지의 정밀도를 가지는 MathContext 객체 생성
MathContext p5 = new MathContext(30, RoundingMode.HALF_UP);
BigDecimal a = new BigDecimal("1.041");
BigDecimal b = new BigDecimal("1").divide(new BigDecimal("12"), p5);
log.debug("a = {}", a);
log.debug("b = {}", b);
// RUN
BigDecimal c = exp(a, b, p5);
log.debug("c = {}", c);
log.debug("c.컷 = {}", c.round(p5));
}
public static BigDecimal exp(BigDecimal base, BigDecimal exponent, int len) {
MathContext mc = new MathContext(len, RoundingMode.HALF_UP);
return exp(base, exponent, mc);
}
/* 이하가 실용 */
public static BigDecimal exp(BigDecimal base, BigDecimal exponent, MathContext mc) {
// 지수가 정수인 경우, 내장된 pow 메소드 사용
int intExponent = exponent.intValue();
if (new BigDecimal(intExponent).compareTo(exponent) == 0) {
return base.pow(intExponent, mc);
}
// 지수가 소수인 경우, e^(ln(base) * exponent) 공식을 사용하여 계산
return exp(ln(base, mc).multiply(exponent), mc);
}
// BigDecimal에 대한 자연로그 계산
public static BigDecimal ln(BigDecimal value, MathContext mc) {
// 1. prepare
BigDecimal result = BigDecimal.ZERO;
BigDecimal x = value.subtract(BigDecimal.ONE);
BigDecimal xPowN = x;
BigDecimal n = BigDecimal.ONE;
// 2. run
for (int i = 1; i < mc.getPrecision(); i++) { // 정밀도까지만 반복
BigDecimal term = xPowN.divide(n, mc);
if (i % 2 == 0) {
result = result.subtract(term);
} else {
result = result.add(term);
}
xPowN = xPowN.multiply(x);
n = n.add(BigDecimal.ONE);
}
// 3. return
return result;
}
// BigDecimal에 대한 지수 계산
public static BigDecimal exp(BigDecimal value, MathContext mc) {
// 1. prepare
BigDecimal result = BigDecimal.ONE;
BigDecimal factorial = BigDecimal.ONE;
BigDecimal valuePowN = value;
// 2. run
for (int i = 1; i < mc.getPrecision(); i++) {
factorial = factorial.multiply(BigDecimal.valueOf(i));
result = result.add(valuePowN.divide(factorial, mc));
valuePowN = valuePowN.multiply(value);
}
// 3. return
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment