diff --git a/docs/scarpet/language/Operators.md b/docs/scarpet/language/Operators.md index b403d4d7..00e19403 100644 --- a/docs/scarpet/language/Operators.md +++ b/docs/scarpet/language/Operators.md @@ -143,6 +143,9 @@ in the output map. Functional forms of `-` and `/` have less intuitive multi-nary interpretation, but they might be useful in some situations. `x-y-z` resolves to `difference(x, y, z)`. +`/` always produces a properly accurate result, fully reversible with `*` operator. To obtain a integer 'div' result, use +`floor(x/y)`. + Examples:
@@ -160,11 +163,15 @@ b = [100,63,100]; b+[10,0,10] => [110,63,110] ### Just Operators `%`, `^` -The modulo and exponent (power) operators work only if both operands are numbers +The modulo and exponent (power) operators work only if both operands are numbers. `%` is a proper (and useful) 'modulus' operator, +not a useless 'reminder' operator that you would expect from anything that touches Java. While typically modulus is reserved +to integer numbers, scarpet expands them to floats with as much sense as possible.pi^pi%euler => 1.124.... --9 % 4 => -1 -9 % -4 => 0 ¯\_(ツ)_/¯ Java +-9 % 4 => 3 +9 % -4 => -3 +9.1 % -4.2 => -3.5 +9.1 % 4.2 => 0.7 -3 ^ 2 => 9 -3 ^ pi => // Errordiff --git a/src/main/java/carpet/script/language/Operators.java b/src/main/java/carpet/script/language/Operators.java index f0e12bcd..6f18f456 100644 --- a/src/main/java/carpet/script/language/Operators.java +++ b/src/main/java/carpet/script/language/Operators.java @@ -80,7 +80,7 @@ public class Operators { expression.addFunctionalEquivalence("/", "quotient"); expression.addBinaryOperator("%", precedence.get("multiplication*/%"), true, (v1, v2) -> - new NumericValue(NumericValue.asNumber(v1).getDouble() % NumericValue.asNumber(v2).getDouble())); + NumericValue.asNumber(v1).mod(NumericValue.asNumber(v2))); expression.addBinaryOperator("^", precedence.get("exponent^"), false, (v1, v2) -> new NumericValue(java.lang.Math.pow(NumericValue.asNumber(v1).getDouble(), NumericValue.asNumber(v2).getDouble()))); diff --git a/src/main/java/carpet/script/value/NumericValue.java b/src/main/java/carpet/script/value/NumericValue.java index 00a506f4..27830682 100644 --- a/src/main/java/carpet/script/value/NumericValue.java +++ b/src/main/java/carpet/script/value/NumericValue.java @@ -313,4 +313,14 @@ public class NumericValue extends Value { return longValue!= null || getDouble() == (double)getLong(); } + + public Value mod(NumericValue n2) + { + if (this.longValue != null && n2.longValue != null) + return new NumericValue(Math.floorMod(longValue, n2.longValue)); + double x = value; + double y = n2.value; + if (y == 0) throw new ArithmeticException("Division by zero"); + return new NumericValue( x - Math.floor(x / y) * y); + } }