diff --git a/app/src/main/java/com/darkempire78/opencalculator/Calculator.kt b/app/src/main/java/com/darkempire78/opencalculator/Calculator.kt index 047f06d7..84d8cf3d 100644 --- a/app/src/main/java/com/darkempire78/opencalculator/Calculator.kt +++ b/app/src/main/java/com/darkempire78/opencalculator/Calculator.kt @@ -4,6 +4,7 @@ import java.math.BigInteger import kotlin.math.* import java.math.BigDecimal +import java.math.MathContext import java.math.RoundingMode import kotlin.math.ln import kotlin.math.pow @@ -283,7 +284,9 @@ class Calculator( } if (eat('^'.code)) { - val powNumber = parseFactor().toInt() + val exponent = parseFactor() + val intPart = exponent.toInt() + val decimalPart = exponent.subtract(BigDecimal(intPart)) // if the number is null if (x == BigDecimal.ZERO) { @@ -291,12 +294,18 @@ class Calculator( x = BigDecimal.ZERO } else { - if (powNumber >= 10000) { + if (exponent >= BigDecimal(10000)) { is_infinity = true x = BigDecimal.ZERO } else { - if (powNumber > 0) { - x = x.pow(powNumber) + if (exponent > BigDecimal.ZERO) { + + // To support bigdecimal exponent (e.g: 3.5) + x = x.pow(intPart, MathContext.DECIMAL64) + .multiply(BigDecimal.valueOf( + x.toDouble().pow(decimalPart.toDouble()) + )) + // To fix sqrt(2)^2 = 2 val decimal = x.toInt() @@ -306,7 +315,18 @@ class Calculator( } } else { - x = BigDecimal.ONE.divide(x.pow(-powNumber)) // To support negative factor + // To support negative factor + x = x.pow(-intPart, MathContext.DECIMAL64) + .multiply(BigDecimal.valueOf( + x.toDouble().pow(decimalPart.toDouble()) + )) + + x = try { + BigDecimal.ONE.divide(x) + } catch (e: ArithmeticException) { + // if the result is a non-terminating decimal expansion + x.divide(x, numberPrecision, RoundingMode.HALF_DOWN) + } } } diff --git a/app/src/test/java/com/darkempire78/opencalculator/ExpressionUnitTest.kt b/app/src/test/java/com/darkempire78/opencalculator/ExpressionUnitTest.kt index d183748a..14266943 100644 --- a/app/src/test/java/com/darkempire78/opencalculator/ExpressionUnitTest.kt +++ b/app/src/test/java/com/darkempire78/opencalculator/ExpressionUnitTest.kt @@ -54,6 +54,12 @@ class ExpressionUnitTest { result = calculate("5^-5", false).toDouble() assertEquals(0.00032, result, 0.0) + + result = calculate("2^3.5", false).toDouble() + assertEquals(11.31370849898476, result, 0.0000001) + + result = calculate("2^-3.5", false).toDouble() + assertEquals(0.08838834764, result, 0.0000001) } @Test