Applied Energistics 2

Applied Energistics 2

160M Downloads

Power operator

Goufix opened this issue ยท 4 comments

commented

Describe the feature

Just like we have +, -, * and / operators, I would like to have an ^ operator that solves to power.

Reasons why it should be considered

I think It would be helpful to some math formulas of building shapes.

I recently figured out that AE2 supports operations, but while playing I got to create a 5x5x5 multiblock and I usually use a formula 5^3-3^3 to get the block amount, so I tried to use the power operator and figured out that it wasn't implemented.

Additional details

I'm able to PR this. I'm just openning this issue so we can discuss about it.

image

commented

Nice dude!

commented

I tought about that and managed to create some barriers to prevent overflows, also created some tests so we can ensure that no overflow is created. It looks something like this now:

I'm also working with doubles because it can handle overflows better. The caps are some limits around the overflow and error scenarios. I don't know if these numbers are the best ones, lmme know.

I've never work with large numbers before, and this code was created with AI assistance. I tried my best to keep it scoped and limit the boundries, but I'm still open to any kind of discussion about how we should handle this.

public class MathExpressionParser {
	private static final double MAX_EXPONENT_LIMIT = 307;
	// ...
	// class body
	// ...
	case '^' -> {
	    if (left.compareTo(BigDecimal.ZERO) < 0 && right.stripTrailingZeros().scale() > 0) {
	        return Optional.empty();
	    }
	
	    if (right.doubleValue() > MAX_EXPONENT_LIMIT) return Optional.empty();
	    if (left.compareTo(new BigDecimal("1E5")) > 0 && right.compareTo(new BigDecimal("10")) > 0) {
	        return Optional.empty();
	    }
	
	    double estimatedMagnitude = right.doubleValue() * Math.log10(left.abs().doubleValue());
	    if (estimatedMagnitude > MAX_EXPONENT_LIMIT) return Optional.empty();
	
	    double result = Math.pow(left.doubleValue(), right.doubleValue());
	    BigDecimal bigResult = BigDecimal.valueOf(result).stripTrailingZeros();
	
	    number.push(bigResult);
	}
commented

The reason why we didn't add it, is because it can easily lead to overflows. I suppose we could add a hard cap on the result of a power operation.

commented

Yes we can limit the amount to ~1B using log math, but the AI generated code is weird. How about:

  • Make sure that the exponent is a natural number so we can use BigDecimal.pow.
  • Check that number of digits in the integer part * exponent is <= 30.