Обратные тригонометрические функции возвращают неправильные значения градусов в калькуляторе KotlinAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Обратные тригонометрические функции возвращают неправильные значения градусов в калькуляторе Kotlin

Сообщение Anonymous »

1) Неправильные выходные данные для режима степени:
  • asin(0.55) должен возвращать примерно 33,367 > градусов, но в настоящее время он возвращает 0,550.
  • acos(0,55) должен возвращать примерно 56,632 градусов, но в настоящее время он возвращает 89,449.
  • atan(0,55) должен возвращать примерно 28,810 градусов, но в настоящее время он возвращает 0,502.
2) Пределы проверки не применяются правильно в градуированном режиме:
  • Проверка входных данных (validateInverseTrigArgument) проверяет только то, что аргументы находятся в диапазоне [-1, 1], который подходит для радиан, но не применим к градусам.
    />
Это код, который является частью класса Evaluator:

Код: Выделить всё

    fun setRadianMode(isRadian: Boolean) {
isRadianMode = isRadian
}

fun isInRadianMode(): Boolean = isRadianMode

// Validate arguments for inverse trig functions
private fun validateInverseTrigArgument(func: String, argument: String): Boolean {
return try {
val value = symbols.eval(argument)
when (func) {
"asin", "acos" -> value in -1.0..1.0
else -> true
}
} catch (e: Exception) {
false  // If evaluation fails, consider it invalid
}
}

private fun convertTrigFunctions(expression: String): String {
val trigFunctions = listOf("sin", "cos", "tan", "cot")
val inverseTrigFunctions = listOf("asin", "acos", "atan", "acot")
var modifiedExpression = expression

// First handle regular trig functions
for (func in trigFunctions) {
val regex = "$func\\(".toRegex()
val matches = regex.findAll(modifiedExpression)

for (match in matches.toList().reversed()) {
val startIndex = match.range.last + 1
val endIndex = try {
findMatchingParenthesis(modifiedExpression, startIndex)
} catch (e: IllegalArgumentException) {
// If no closing parenthesis, treat end of expression as the closing point
modifiedExpression.length
}

val argument = modifiedExpression.substring(startIndex, endIndex)

val convertedArgument = if (!isRadianMode) {
"$func($argument * $PI / 180)"
} else {
"$func($argument)"
}

modifiedExpression = modifiedExpression.replaceRange(match.range.first, endIndex, convertedArgument)
}
}

// Then handle inverse trig functions separately
for (func in inverseTrigFunctions) {
val regex = "$func\\(".toRegex()
val matches = regex.findAll(modifiedExpression)

for (match in matches.toList().reversed()) {
val startIndex = match.range.last + 1
val endIndex = try {
findMatchingParenthesis(modifiedExpression, startIndex)
} catch (e: IllegalArgumentException) {
modifiedExpression.length
}

val argument = modifiedExpression.substring(startIndex, endIndex)

// Convert output of inverse trig function to degrees if in degree mode
val convertedArgument = if (!isRadianMode) {
"($func($argument) * 180 / $PI)"
} else {
"$func($argument)"
}

modifiedExpression = modifiedExpression.replaceRange(match.range.first, endIndex, convertedArgument)
}
}

return modifiedExpression
}
Я использую Javia Arity/Arithmetic для оценки выражений:
https://github.com/preda/arithmetic
Я попробовал это с математической библиотекой Java, но безуспешно

Код: Выделить всё

private fun evaluateInverseTrigFunction(func: String, argument: Double): Double {
val result = when (func) {
"asin" ->  Math.asin(argument)
"acos" -> Math.acos(argument)
"atan" -> Math.atan(argument)
else -> throw IllegalArgumentException("Invalid function: $func")
}

// Convert to degrees if not in radian mode
return if (!isRadianMode) result * 180 / Math.PI else result
}

private fun convertTrigFunctions(expression: String): String {
val trigFunctions = listOf("sin", "cos", "tan", "cot")
val inverseTrigFunctions = listOf("asin", "acos", "atan", "acot")
var modifiedExpression = expression

// Handle regular trig functions as before
for (func in trigFunctions) {
val regex = "$func\\(".toRegex()
val matches = regex.findAll(modifiedExpression)

for (match in matches.toList().reversed()) {
val startIndex = match.range.last + 1
val endIndex = try {
findMatchingParenthesis(modifiedExpression, startIndex)
} catch (e: IllegalArgumentException) {
modifiedExpression.length
}

val argument = modifiedExpression.substring(startIndex, endIndex)

val convertedArgument = if (!isRadianMode) {
"$func($argument * $PI / 180)"
} else {
"$func($argument)"
}

modifiedExpression = modifiedExpression.replaceRange(match.range.first, endIndex, convertedArgument)
}
}

// Handle inverse trig functions
for (func in inverseTrigFunctions) {
val regex = "$func\\(([^)]+)\\)".toRegex() // Match function argument inside parentheses
val matches = regex.findAll(modifiedExpression)

for (match in matches.toList().reversed()) {
val argumentStr = match.groupValues[1]

// Evaluate the argument expression as a Double
val argument = symbols.eval(argumentStr)

// Get result from evaluateInverseTrigFunction
val result = evaluateInverseTrigFunction(func, argument)

// Replace original function call with the computed result
modifiedExpression = modifiedExpression.replaceRange(match.range, result.toString())
}
}

return modifiedExpression
}

Обратные триггерные функции: когда ConvertTrigFunctions обнаруживает обратную триггерную функцию (например, asin, acos, atan):
  • Он извлекает аргумент и оценивает его как Double.
  • Он вызывает функцию AssessmentInverseTrigFunction, которая вычисляет результат и применяет преобразование степени, если isRadianMode имеет значение false.
  • Он заменяет исходный вызов функции в выражении вычисленным результатом.


Подробнее здесь: https://stackoverflow.com/questions/791 ... in-calcula
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»