Created
May 13, 2024 17:11
-
-
Save daanta-real/e9f46b975d20e8d9bff108ffe3332d4b to your computer and use it in GitHub Desktop.
POW with 2 BigDecimal instances. yeah
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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