2017-09-23 17:13:56 -07:00
|
|
|
package org.nwapw.abacus.plugin.standard.operator
|
2017-09-23 17:11:05 -07:00
|
|
|
|
2017-11-23 02:21:06 -08:00
|
|
|
import org.nwapw.abacus.context.PluginEvaluationContext
|
2017-09-23 17:11:05 -07:00
|
|
|
import org.nwapw.abacus.function.OperatorAssociativity
|
|
|
|
import org.nwapw.abacus.function.OperatorType
|
2017-11-14 23:03:12 -08:00
|
|
|
import org.nwapw.abacus.function.interfaces.NumberOperator
|
2017-09-23 17:11:05 -07:00
|
|
|
import org.nwapw.abacus.number.NumberInterface
|
2017-09-23 22:16:44 -07:00
|
|
|
import org.nwapw.abacus.plugin.standard.StandardPlugin.*
|
2017-09-23 17:11:05 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The power operator.
|
|
|
|
*
|
|
|
|
* This is a standard operator that brings one number to the power of the other.
|
|
|
|
*/
|
|
|
|
class OperatorCaret: NumberOperator(OperatorAssociativity.RIGHT, OperatorType.BINARY_INFIX, 2) {
|
|
|
|
|
2017-11-23 02:21:06 -08:00
|
|
|
override fun matchesParams(context: PluginEvaluationContext, params: Array<out NumberInterface>) =
|
2017-09-23 17:11:05 -07:00
|
|
|
params.size == 2
|
|
|
|
&& !(params[0].signum() == 0 && params[1].signum() == 0)
|
2017-11-03 21:41:46 -07:00
|
|
|
&& !(params[0].signum() == -1 && !params[1].isInteger())
|
2017-09-23 17:11:05 -07:00
|
|
|
|
2017-11-23 02:21:06 -08:00
|
|
|
override fun applyInternal(context: PluginEvaluationContext, params: Array<out NumberInterface>): NumberInterface {
|
2017-09-23 17:11:05 -07:00
|
|
|
val implementation = context.inheritedNumberImplementation
|
|
|
|
if (params[0].signum() == 0)
|
|
|
|
return implementation.instanceForString("0")
|
|
|
|
else if (params[1].signum() == 0)
|
|
|
|
return implementation.instanceForString("1")
|
|
|
|
//Detect integer bases:
|
2017-11-03 21:41:46 -07:00
|
|
|
if (params[0].isInteger()
|
2017-09-23 17:11:05 -07:00
|
|
|
&& FUNCTION_ABS.apply(context, params[1]) < implementation.instanceForString(Integer.toString(Integer.MAX_VALUE))
|
|
|
|
&& FUNCTION_ABS.apply(context, params[1]) >= implementation.instanceForString("1")) {
|
|
|
|
val newParams = arrayOf(params[0], params[1].fractionalPart())
|
|
|
|
return params[0].intPow(params[1].floor().intValue()) * applyInternal(context, newParams)
|
|
|
|
}
|
|
|
|
return FUNCTION_EXP.apply(context, FUNCTION_LN.apply(context, FUNCTION_ABS.apply(context, params[0])) * params[1])
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|