mirror of
https://github.com/SimpleMobileTools/Simple-Calculator.git
synced 2025-02-20 13:30:44 +01:00
rely on objecthunter:exp4j at calculating formulas
This commit is contained in:
parent
7b82f163a8
commit
6e27c97323
@ -59,6 +59,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.simplemobiletools:commons:5.31.25'
|
implementation 'com.simplemobiletools:commons:5.31.25'
|
||||||
implementation 'me.grantland:autofittextview:0.2.1'
|
implementation 'me.grantland:autofittextview:0.2.1'
|
||||||
|
implementation 'net.objecthunter:exp4j:0.4.8'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
testImplementation 'org.robolectric:robolectric:4.2'
|
testImplementation 'org.robolectric:robolectric:4.2'
|
||||||
|
@ -2,14 +2,13 @@ package com.simplemobiletools.calculator.helpers
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.simplemobiletools.calculator.R
|
import com.simplemobiletools.calculator.R
|
||||||
import com.simplemobiletools.calculator.operation.OperationFactory
|
|
||||||
import com.simplemobiletools.calculator.operation.PercentOperation
|
import com.simplemobiletools.calculator.operation.PercentOperation
|
||||||
import com.simplemobiletools.commons.extensions.areDigitsOnly
|
import com.simplemobiletools.commons.extensions.areDigitsOnly
|
||||||
import com.simplemobiletools.commons.extensions.toast
|
import com.simplemobiletools.commons.extensions.toast
|
||||||
|
import net.objecthunter.exp4j.ExpressionBuilder
|
||||||
|
|
||||||
class CalculatorImpl(calculator: Calculator, val context: Context) {
|
class CalculatorImpl(calculator: Calculator, val context: Context) {
|
||||||
var displayedNumber: String? = null
|
var displayedNumber: String? = null
|
||||||
var displayedFormula: String? = null
|
|
||||||
var lastKey: String? = null
|
var lastKey: String? = null
|
||||||
private var inputDisplayedFormula = "0"
|
private var inputDisplayedFormula = "0"
|
||||||
private var callback: Calculator? = calculator
|
private var callback: Calculator? = calculator
|
||||||
@ -20,7 +19,7 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
private var secondValue = 0.0
|
private var secondValue = 0.0
|
||||||
private var lastOperation = ""
|
private var lastOperation = ""
|
||||||
private val operations = listOf("+", "-", "*", "/", "^", "%", "√")
|
private val operations = listOf("+", "-", "*", "/", "^", "%", "√")
|
||||||
private val operationsRegex = "[+,-,*,/,^,%,√]".toRegex()
|
private val operationsRegex = "[-+*/^%√]".toPattern()
|
||||||
private var moreOperationsInRaw = false
|
private var moreOperationsInRaw = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -42,7 +41,6 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
resetValue = false
|
resetValue = false
|
||||||
lastOperation = ""
|
lastOperation = ""
|
||||||
displayedNumber = ""
|
displayedNumber = ""
|
||||||
displayedFormula = ""
|
|
||||||
isFirstOperation = true
|
isFirstOperation = true
|
||||||
lastKey = ""
|
lastKey = ""
|
||||||
}
|
}
|
||||||
@ -53,8 +51,8 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setFormula(value: String) {
|
private fun setFormula(value: String) {
|
||||||
callback!!.setFormula(value, context)
|
/*callback!!.setFormula(value, context)
|
||||||
displayedFormula = value
|
displayedFormula = value*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateFormula() {
|
private fun updateFormula() {
|
||||||
@ -90,8 +88,6 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun formatString(str: String): String {
|
private fun formatString(str: String): String {
|
||||||
// if the number contains a decimal, do not try removing the leading zero anymore, nor add group separator
|
|
||||||
// it would prevent writing values like 1.02
|
|
||||||
if (str.contains(".")) {
|
if (str.contains(".")) {
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
@ -129,11 +125,30 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
baseValue = 1.0
|
baseValue = 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
val operation = OperationFactory.forId(lastOperation, baseValue, secondValue)
|
if (lastKey != EQUALS) {
|
||||||
if (operation != null) {
|
val valueToCheck = if (inputDisplayedFormula.startsWith("-")) {
|
||||||
|
inputDisplayedFormula.substring(1)
|
||||||
|
} else {
|
||||||
|
inputDisplayedFormula
|
||||||
|
}
|
||||||
|
|
||||||
|
val parts = valueToCheck.split(operationsRegex).filter { it.trim().isNotEmpty() }
|
||||||
|
baseValue = parts.first().replace(",", "").toDouble()
|
||||||
|
if (inputDisplayedFormula.startsWith("-")) {
|
||||||
|
baseValue *= -1
|
||||||
|
}
|
||||||
|
|
||||||
|
secondValue = parts.getOrNull(1)?.replace(",", "")?.toDouble() ?: secondValue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastOperation != "") {
|
||||||
try {
|
try {
|
||||||
updateResult(operation.getResult())
|
val expression = "${baseValue.format()}${getSign(lastOperation)}${secondValue.format()}".replace("√", "sqrt")
|
||||||
inputDisplayedFormula = displayedNumber ?: ""
|
val result = ExpressionBuilder(expression.replace(",", "")).build().evaluate()
|
||||||
|
updateResult(result)
|
||||||
|
baseValue = result
|
||||||
|
inputDisplayedFormula = result.format()
|
||||||
|
callback!!.setFormula(expression.replace("sqrt", "√"), context)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(R.string.unknown_error_occurred)
|
context.toast(R.string.unknown_error_occurred)
|
||||||
}
|
}
|
||||||
@ -174,12 +189,12 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastKey == DIGIT && lastOperation != "" && operation == PERCENT) {
|
/*if (lastKey == DIGIT && lastOperation != "" && operation == PERCENT) {
|
||||||
val tempOperation = lastOperation
|
val tempOperation = lastOperation
|
||||||
handlePercent()
|
handlePercent()
|
||||||
lastKey = tempOperation
|
lastKey = tempOperation
|
||||||
lastOperation = tempOperation
|
lastOperation = tempOperation
|
||||||
} else if (lastKey == DIGIT) {
|
} else */if (lastKey == DIGIT) {
|
||||||
handleResult()
|
handleResult()
|
||||||
if (inputDisplayedFormula.last() != '+' &&
|
if (inputDisplayedFormula.last() != '+' &&
|
||||||
inputDisplayedFormula.last() != '-' &&
|
inputDisplayedFormula.last() != '-' &&
|
||||||
@ -240,7 +255,7 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
fun handleReset() {
|
fun handleReset() {
|
||||||
resetValues()
|
resetValues()
|
||||||
setValue("0")
|
setValue("0")
|
||||||
setFormula("")
|
callback!!.setFormula("", context)
|
||||||
inputDisplayedFormula = ""
|
inputDisplayedFormula = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +286,7 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
val value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
val value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
||||||
if (!value.contains(".")) {
|
if (!value.contains(".")) {
|
||||||
when {
|
when {
|
||||||
value == "0" && !valueToCheck.contains(operationsRegex) -> inputDisplayedFormula = "0."
|
value == "0" && !valueToCheck.contains(operationsRegex.toRegex()) -> inputDisplayedFormula = "0."
|
||||||
value == "" -> inputDisplayedFormula += "0."
|
value == "" -> inputDisplayedFormula += "0."
|
||||||
else -> inputDisplayedFormula += "."
|
else -> inputDisplayedFormula += "."
|
||||||
}
|
}
|
||||||
@ -296,8 +311,14 @@ class CalculatorImpl(calculator: Calculator, val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun zeroClicked() {
|
private fun zeroClicked() {
|
||||||
val value = getSecondValue().toString()
|
val valueToCheck = if (inputDisplayedFormula.startsWith("-")) {
|
||||||
if (value != "0") {
|
inputDisplayedFormula.substring(1)
|
||||||
|
} else {
|
||||||
|
inputDisplayedFormula
|
||||||
|
}
|
||||||
|
|
||||||
|
val value = valueToCheck.substring(valueToCheck.indexOfAny(operations) + 1)
|
||||||
|
if (value != "0.0" || value.contains(".")) {
|
||||||
addDigit(0)
|
addDigit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,6 @@ class MainActivityTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkFormula(desired: String) {
|
private fun checkFormula(desired: String) {
|
||||||
assertEquals(desired, activity.calc.displayedFormula)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calcResult(baseValue: BigDecimal, operation: String, secondValue: BigDecimal): String? {
|
private fun calcResult(baseValue: BigDecimal, operation: String, secondValue: BigDecimal): String? {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user