diff --git a/core/src/main/antlr4/org/apache/druid/math/expr/antlr/Expr.g4 b/core/src/main/antlr4/org/apache/druid/math/expr/antlr/Expr.g4 index db336a2d54e0..9b9eda9dfded 100644 --- a/core/src/main/antlr4/org/apache/druid/math/expr/antlr/Expr.g4 +++ b/core/src/main/antlr4/org/apache/druid/math/expr/antlr/Expr.g4 @@ -51,9 +51,12 @@ numericElement : (LONG | DOUBLE | NULL); literalElement : (STRING | LONG | DOUBLE | NULL); NULL : 'null'; +LONG : [0-9]+; +EXP: [eE] [-]? LONG; +// DOUBLE provides partial support for java double format +// see: https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#valueOf-java.lang.String- +DOUBLE : 'NaN' | 'Infinity' | (LONG '.' LONG?) | (LONG EXP) | (LONG '.' LONG? EXP); IDENTIFIER : [_$a-zA-Z][_$a-zA-Z0-9]* | '"' (ESC | ~ [\"\\])* '"'; -LONG : [0-9]+ ; -DOUBLE : [0-9]+ '.' [0-9]* ; WS : [ \t\r\n]+ -> skip ; STRING : '\'' (ESC | ~ [\'\\])* '\''; diff --git a/core/src/main/java/org/apache/druid/math/expr/Function.java b/core/src/main/java/org/apache/druid/math/expr/Function.java index 2c4ff6853749..fef0776ecff3 100644 --- a/core/src/main/java/org/apache/druid/math/expr/Function.java +++ b/core/src/main/java/org/apache/druid/math/expr/Function.java @@ -312,6 +312,40 @@ public ExprType getOutputType(Expr.InputBindingInspector inspector, List a } } + abstract class BivariateBitwiseMathFunction extends BivariateFunction + { + @Override + protected final ExprEval eval(ExprEval x, ExprEval y) + { + // this is a copy of the logic of BivariateMathFunction for string handling, which itself is a + // remix of BinaryEvalOpExprBase.eval modified so that string inputs are always null outputs + if (NullHandling.sqlCompatible() && (x.value() == null || y.value() == null)) { + return ExprEval.of(null); + } + + ExprType type = ExprTypeConversion.autoDetect(x, y); + if (type == ExprType.STRING) { + return ExprEval.of(null); + } + return eval(x.asLong(), y.asLong()); + } + + protected abstract ExprEval eval(long x, long y); + + @Nullable + @Override + public ExprType getOutputType(Expr.InputBindingInspector inspector, List args) + { + return ExprType.LONG; + } + + @Override + public boolean canVectorize(Expr.InputBindingInspector inspector, List args) + { + return inspector.areNumeric(args) && inspector.canVectorize(args); + } + } + /** * Base class for a 2 variable input {@link Function} whose first argument is a {@link ExprType#STRING} and second * argument is {@link ExprType#LONG} @@ -724,6 +758,203 @@ public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspe } } + class BitwiseComplement extends UnivariateMathFunction + { + @Override + public String name() + { + return "bitwiseComplement"; + } + + @Nullable + @Override + public ExprType getOutputType(Expr.InputBindingInspector inspector, List args) + { + return ExprType.LONG; + } + + @Override + protected ExprEval eval(long param) + { + return ExprEval.of(~param); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseComplement(inspector, args.get(0)); + } + } + + class BitwiseConvertLongBitsToDouble extends UnivariateMathFunction + { + @Override + public String name() + { + return "bitwiseConvertLongBitsToDouble"; + } + + @Nullable + @Override + public ExprType getOutputType(Expr.InputBindingInspector inspector, List args) + { + ExprType type = args.get(0).getOutputType(inspector); + if (type == null) { + return null; + } + return ExprType.DOUBLE; + } + + @Override + protected ExprEval eval(long param) + { + return ExprEval.of(Double.longBitsToDouble(param)); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseConvertLongBitsToDouble(inspector, args.get(0)); + } + } + + class BitwiseConvertDoubleToLongBits extends UnivariateMathFunction + { + @Override + public String name() + { + return "bitwiseConvertDoubleToLongBits"; + } + + @Nullable + @Override + public ExprType getOutputType(Expr.InputBindingInspector inspector, List args) + { + ExprType type = args.get(0).getOutputType(inspector); + if (type == null) { + return null; + } + return ExprType.LONG; + } + + @Override + protected ExprEval eval(double param) + { + return ExprEval.of(Double.doubleToLongBits(param)); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseConvertDoubleToLongBits(inspector, args.get(0)); + } + } + + class BitwiseAnd extends BivariateBitwiseMathFunction + { + @Override + public String name() + { + return "bitwiseAnd"; + } + + @Override + protected ExprEval eval(long x, long y) + { + return ExprEval.of(x & y); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseAnd(inspector, args.get(0), args.get(1)); + } + } + + class BitwiseOr extends BivariateBitwiseMathFunction + { + @Override + public String name() + { + return "bitwiseOr"; + } + + @Override + protected ExprEval eval(long x, long y) + { + return ExprEval.of(x | y); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseOr(inspector, args.get(0), args.get(1)); + } + } + + class BitwiseShiftLeft extends BivariateBitwiseMathFunction + { + @Override + public String name() + { + return "bitwiseShiftLeft"; + } + + @Override + protected ExprEval eval(long x, long y) + { + return ExprEval.of(x << y); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseShiftLeft(inspector, args.get(0), args.get(1)); + } + } + + class BitwiseShiftRight extends BivariateBitwiseMathFunction + { + @Override + public String name() + { + return "bitwiseShiftRight"; + } + + @Override + protected ExprEval eval(long x, long y) + { + return ExprEval.of(x >> y); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseShiftRight(inspector, args.get(0), args.get(1)); + } + } + + class BitwiseXor extends BivariateBitwiseMathFunction + { + @Override + public String name() + { + return "bitwiseXor"; + } + + @Override + protected ExprEval eval(long x, long y) + { + return ExprEval.of(x ^ y); + } + + @Override + public ExprVectorProcessor asVectorProcessor(Expr.VectorInputBindingInspector inspector, List args) + { + return VectorMathProcessors.bitwiseXor(inspector, args.get(0), args.get(1)); + } + } + class Cbrt extends DoubleUnivariateMathFunction { @Override diff --git a/core/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java b/core/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java index c1a9888466a0..0a170ac24969 100644 --- a/core/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java +++ b/core/src/main/java/org/apache/druid/math/expr/vector/VectorMathProcessors.java @@ -1968,7 +1968,406 @@ public double apply(double input) ); } + public static ExprVectorProcessor bitwiseComplement(Expr.VectorInputBindingInspector inspector, Expr arg) + { + return makeLongMathProcessor( + inspector, + arg, + () -> new LongOutLongInFunctionVectorProcessor( + arg.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long input) + { + return ~input; + } + }, + () -> new LongOutDoubleInFunctionVectorProcessor( + arg.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double input) + { + return ~((long) input); + } + } + ); + } + + public static ExprVectorProcessor bitwiseConvertDoubleToLongBits( + Expr.VectorInputBindingInspector inspector, + Expr arg + ) + { + final ExprType inputType = arg.getOutputType(inspector); + + ExprVectorProcessor processor = null; + if (inputType == ExprType.LONG) { + processor = new LongOutLongInFunctionVectorProcessor( + arg.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long input) + { + return Double.doubleToLongBits(input); + } + }; + } else if (inputType == ExprType.DOUBLE) { + processor = new LongOutDoubleInFunctionVectorProcessor( + arg.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double input) + { + return Double.doubleToLongBits(input); + } + }; + } + if (processor == null) { + throw Exprs.cannotVectorize(); + } + return (ExprVectorProcessor) processor; + } + + public static ExprVectorProcessor bitwiseConvertLongBitsToDouble( + Expr.VectorInputBindingInspector inspector, + Expr arg + ) + { + final ExprType inputType = arg.getOutputType(inspector); + + ExprVectorProcessor processor = null; + if (inputType == ExprType.LONG) { + processor = new DoubleOutLongInFunctionVectorProcessor( + arg.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public double apply(long input) + { + return Double.longBitsToDouble(input); + } + }; + } else if (inputType == ExprType.DOUBLE) { + processor = new DoubleOutDoubleInFunctionVectorProcessor( + arg.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public double apply(double input) + { + return Double.longBitsToDouble((long) input); + } + }; + } + if (processor == null) { + throw Exprs.cannotVectorize(); + } + return (ExprVectorProcessor) processor; + } + + public static ExprVectorProcessor bitwiseAnd(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + return makeLongMathProcessor( + inspector, + left, + right, + () -> new LongOutLongsInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, long right) + { + return left & right; + } + }, + () -> new LongOutLongDoubleInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, double right) + { + return left & (long) right; + } + }, + () -> new LongOutDoubleLongInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, long right) + { + return (long) left & right; + } + }, + () -> new LongOutDoublesInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, double right) + { + return (long) left & (long) right; + } + } + ); + } + public static ExprVectorProcessor bitwiseOr(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + return makeLongMathProcessor( + inspector, + left, + right, + () -> new LongOutLongsInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, long right) + { + return left | right; + } + }, + () -> new LongOutLongDoubleInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, double right) + { + return left | (long) right; + } + }, + () -> new LongOutDoubleLongInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, long right) + { + return (long) left | right; + } + }, + () -> new LongOutDoublesInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, double right) + { + return (long) left | (long) right; + } + } + ); + } + + public static ExprVectorProcessor bitwiseXor(Expr.VectorInputBindingInspector inspector, Expr left, Expr right) + { + return makeLongMathProcessor( + inspector, + left, + right, + () -> new LongOutLongsInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, long right) + { + return left ^ right; + } + }, + () -> new LongOutLongDoubleInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, double right) + { + return left ^ (long) right; + } + }, + () -> new LongOutDoubleLongInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, long right) + { + return (long) left ^ right; + } + }, + () -> new LongOutDoublesInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, double right) + { + return (long) left ^ (long) right; + } + } + ); + } + + public static ExprVectorProcessor bitwiseShiftLeft( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return makeLongMathProcessor( + inspector, + left, + right, + () -> new LongOutLongsInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, long right) + { + return left << right; + } + }, + () -> new LongOutLongDoubleInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, double right) + { + return left << (long) right; + } + }, + () -> new LongOutDoubleLongInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, long right) + { + return (long) left << right; + } + }, + () -> new LongOutDoublesInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, double right) + { + return (long) left << (long) right; + } + } + ); + } + + public static ExprVectorProcessor bitwiseShiftRight( + Expr.VectorInputBindingInspector inspector, + Expr left, + Expr right + ) + { + return makeLongMathProcessor( + inspector, + left, + right, + () -> new LongOutLongsInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, long right) + { + return left >> right; + } + }, + () -> new LongOutLongDoubleInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(long left, double right) + { + return left >> (long) right; + } + }, + () -> new LongOutDoubleLongInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, long right) + { + return (long) left >> right; + } + }, + () -> new LongOutDoublesInFunctionVectorProcessor( + left.buildVectorized(inspector), + right.buildVectorized(inspector), + inspector.getMaxVectorSize() + ) + { + @Override + public long apply(double left, double right) + { + return (long) left >> (long) right; + } + } + ); + } private VectorMathProcessors() { diff --git a/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java b/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java index 3c5c214de657..96a22840eb04 100644 --- a/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java +++ b/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java @@ -519,6 +519,41 @@ public void testLeast() assertExpr("least(1, null, 'A')", "1"); } + @Test + public void testBitwise() + { + assertExpr("bitwiseAnd(3, 1)", 1L); + assertExpr("bitwiseAnd(2, 1)", 0L); + assertExpr("bitwiseOr(3, 1)", 3L); + assertExpr("bitwiseOr(2, 1)", 3L); + assertExpr("bitwiseXor(3, 1)", 2L); + assertExpr("bitwiseXor(2, 1)", 3L); + assertExpr("bitwiseShiftLeft(2, 1)", 4L); + assertExpr("bitwiseShiftRight(2, 1)", 1L); + assertExpr("bitwiseAnd(bitwiseComplement(1), 7)", 6L); + assertExpr("bitwiseAnd('2', '1')", null); + assertExpr("bitwiseAnd(2, '1')", 0L); + + // doubles are cast + assertExpr("bitwiseOr(2.345, 1)", 3L); + assertExpr("bitwiseOr(2, 1.3)", 3L); + assertExpr("bitwiseAnd(2.345, 2.0)", 2L); + + // but can be converted to be double-like + assertExpr( + "bitwiseAnd(bitwiseConvertDoubleToLongBits(2.345), bitwiseConvertDoubleToLongBits(2.0))", + 4611686018427387904L + ); + assertExpr( + "bitwiseConvertLongBitsToDouble(bitwiseAnd(bitwiseConvertDoubleToLongBits(2.345), bitwiseConvertDoubleToLongBits(2.0)))", + 2.0 + ); + assertExpr("bitwiseConvertDoubleToLongBits(2.0)", 4611686018427387904L); + assertExpr("bitwiseConvertDoubleToLongBits(bitwiseConvertDoubleToLongBits(2.0))", 4886405595696988160L); + assertExpr("bitwiseConvertLongBitsToDouble(4611686018427387904)", 2.0); + assertExpr("bitwiseConvertLongBitsToDouble(bitwiseConvertLongBitsToDouble(4611686018427387904))", 1.0E-323); + } + private void assertExpr(final String expression, @Nullable final Object expectedResult) { final Expr expr = Parser.parse(expression, ExprMacroTable.nil()); diff --git a/core/src/test/java/org/apache/druid/math/expr/ParserTest.java b/core/src/test/java/org/apache/druid/math/expr/ParserTest.java index 1ebd71f1cc43..4fd7c13e9afc 100644 --- a/core/src/test/java/org/apache/druid/math/expr/ParserTest.java +++ b/core/src/test/java/org/apache/druid/math/expr/ParserTest.java @@ -41,6 +41,8 @@ public class ParserTest extends InitializedNullHandlingTest @Rule public ExpectedException expectedException = ExpectedException.none(); + VectorExprSanityTest.SettableVectorInputBinding emptyBinding = new VectorExprSanityTest.SettableVectorInputBinding(8); + @Test public void testSimple() { @@ -49,6 +51,32 @@ public void testSimple() Assert.assertEquals(expected, actual); } + + @Test + public void testParseConstants() + { + validateLiteral("null", ExprType.STRING, null); + validateLiteral("'hello'", ExprType.STRING, "hello"); + validateLiteral("'hello \\uD83E\\uDD18'", ExprType.STRING, "hello \uD83E\uDD18"); + validateLiteral("1", ExprType.LONG, 1L); + validateLiteral("1.", ExprType.DOUBLE, 1.0, false); + validateLiteral("1.234", ExprType.DOUBLE, 1.234); + validateLiteral("1e10", ExprType.DOUBLE, 1.0E10, false); + validateLiteral("1e-10", ExprType.DOUBLE, 1.0E-10, false); + validateLiteral("1E10", ExprType.DOUBLE, 1.0E10, false); + validateLiteral("1E-10", ExprType.DOUBLE, 1.0E-10, false); + validateLiteral("1.E10", ExprType.DOUBLE, 1.0E10, false); + validateLiteral("1.E-10", ExprType.DOUBLE, 1.0E-10, false); + validateLiteral("1.e10", ExprType.DOUBLE, 1.0E10, false); + validateLiteral("1.e-10", ExprType.DOUBLE, 1.0E-10, false); + validateLiteral("1.1e10", ExprType.DOUBLE, 1.1E10, false); + validateLiteral("1.1e-10", ExprType.DOUBLE, 1.1E-10, false); + validateLiteral("1.1E10", ExprType.DOUBLE, 1.1E10); + validateLiteral("1.1E-10", ExprType.DOUBLE, 1.1E-10); + validateLiteral("Infinity", ExprType.DOUBLE, Double.POSITIVE_INFINITY); + validateLiteral("NaN", ExprType.DOUBLE, Double.NaN); + } + @Test public void testSimpleUnaryOps1() { @@ -542,6 +570,26 @@ public void testUniquify() ); } + private void validateLiteral(String expr, ExprType type, Object expected) + { + validateLiteral(expr, type, expected, true); + } + + private void validateLiteral(String expr, ExprType type, Object expected, boolean roundTrip) + { + Expr parsed = Parser.parse(expr, ExprMacroTable.nil(), false); + Expr parsedFlat = Parser.parse(expr, ExprMacroTable.nil(), true); + Assert.assertTrue(parsed.isLiteral()); + Assert.assertTrue(parsedFlat.isLiteral()); + Assert.assertEquals(type, parsed.getOutputType(emptyBinding)); + Assert.assertEquals(type, parsedFlat.getOutputType(emptyBinding)); + Assert.assertEquals(expected, parsed.getLiteralValue()); + Assert.assertEquals(expected, parsedFlat.getLiteralValue()); + if (roundTrip) { + Assert.assertEquals(expr, parsed.stringify()); + Assert.assertEquals(expr, parsedFlat.stringify()); + } + } private void validateFlatten(String expression, String withoutFlatten, String withFlatten) { diff --git a/core/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java b/core/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java index 72bc0c89d821..8c6a46cfd382 100644 --- a/core/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java +++ b/core/src/test/java/org/apache/druid/math/expr/VectorExprSanityTest.java @@ -137,7 +137,10 @@ public void testUnivariateMathFunctions() "tanh", "toDegrees", "toRadians", - "ulp" + "ulp", + "bitwiseComplement", + "bitwiseConvertDoubleToLongBits", + "bitwiseConvertLongBitsToDouble" }; final String[] templates = new String[]{"%s(l1)", "%s(d1)", "%s(pi())"}; testFunctions(types, templates, functions); @@ -156,7 +159,12 @@ public void testBivariateMathFunctions() "min", "nextAfter", "scalb", - "pow" + "pow", + "bitwiseAnd", + "bitwiseOr", + "bitwiseXor", + "bitwiseShiftLeft", + "bitwiseShiftRight" }; final String[] templates = new String[]{ "%s(d1, d2)", diff --git a/docs/misc/math-expr.md b/docs/misc/math-expr.md index 916d9cb827f4..0e902b05bc43 100644 --- a/docs/misc/math-expr.md +++ b/docs/misc/math-expr.md @@ -115,45 +115,53 @@ See javadoc of java.lang.Math for detailed explanation for each function. |name|description| |----|-----------| -|abs|abs(x) would return the absolute value of x| -|acos|acos(x) would return the arc cosine of x| -|asin|asin(x) would return the arc sine of x| -|atan|atan(x) would return the arc tangent of x| -|atan2|atan2(y, x) would return the angle theta from the conversion of rectangular coordinates (x, y) to polar * coordinates (r, theta)| -|cbrt|cbrt(x) would return the cube root of x| -|ceil|ceil(x) would return the smallest (closest to negative infinity) double value that is greater than or equal to x and is equal to a mathematical integer| -|copysign|copysign(x) would return the first floating-point argument with the sign of the second floating-point argument| -|cos|cos(x) would return the trigonometric cosine of x| -|cosh|cosh(x) would return the hyperbolic cosine of x| -|cot|cot(x) would return the trigonometric cotangent of an angle x| +|abs|abs(x) returns the absolute value of x| +|acos|acos(x) returns the arc cosine of x| +|asin|asin(x) returns the arc sine of x| +|atan|atan(x) returns the arc tangent of x| +|bitwiseAnd|bitwiseAnd(x,y) returns the result of x & y. Double values will be implicitly cast to longs, use `bitwiseConvertDoubleToLongBits` to perform bitwise operations directly with doubles| +|bitwiseComplement|bitwiseComplement(x) returns the result of ~x. Double values will be implicitly cast to longs, use `bitwiseConvertDoubleToLongBits` to perform bitwise operations directly with doubles| +|bitwiseConvertDoubleToLongBits|bitwiseConvertDoubleToLongBits(x) converts the bits of an IEEE 754 floating-point double value to a long. If the input is not a double, it is implicitly cast to a double prior to conversion| +|bitwiseConvertLongBitsToDouble|bitwiseConvertLongBitsToDouble(x) converts a long to the IEEE 754 floating-point double specified by the bits stored in the long. If the input is not a long, it is implicitly cast to a long prior to conversion| +|bitwiseOr|bitwiseOr(x,y) returns the result of x [PIPE] y. Double values will be implicitly cast to longs, use `bitwiseConvertDoubleToLongBits` to perform bitwise operations directly with doubles| +|bitwiseShiftLeft|bitwiseShiftLeft(x,y) returns the result of x << y. Double values will be implicitly cast to longs, use `bitwiseConvertDoubleToLongBits` to perform bitwise operations directly with doubles| +|bitwiseShiftRight|bitwiseShiftRight(x,y) returns the result of x >> y. Double values will be implicitly cast to longs, use `bitwiseConvertDoubleToLongBits` to perform bitwise operations directly with doubles| +|bitwiseXor|bitwiseXor(x,y) returns the result of x ^ y. Double values will be implicitly cast to longs, use `bitwiseConvertDoubleToLongBits` to perform bitwise operations directly with doubles| +|atan2|atan2(y, x) returns the angle theta from the conversion of rectangular coordinates (x, y) to polar * coordinates (r, theta)| +|cbrt|cbrt(x) returns the cube root of x| +|ceil|ceil(x) returns the smallest (closest to negative infinity) double value that is greater than or equal to x and is equal to a mathematical integer| +|copysign|copysign(x) returns the first floating-point argument with the sign of the second floating-point argument| +|cos|cos(x) returns the trigonometric cosine of x| +|cosh|cosh(x) returns the hyperbolic cosine of x| +|cot|cot(x) returns the trigonometric cotangent of an angle x| |div|div(x,y) is integer division of x by y| -|exp|exp(x) would return Euler's number raised to the power of x| -|expm1|expm1(x) would return e^x-1| -|floor|floor(x) would return the largest (closest to positive infinity) double value that is less than or equal to x and is equal to a mathematical integer| -|getExponent|getExponent(x) would return the unbiased exponent used in the representation of x| -|hypot|hypot(x, y) would return sqrt(x^2+y^2) without intermediate overflow or underflow| -|log|log(x) would return the natural logarithm of x| -|log10|log10(x) would return the base 10 logarithm of x| -|log1p|log1p(x) would the natural logarithm of x + 1| -|max|max(x, y) would return the greater of two values| -|min|min(x, y) would return the smaller of two values| -|nextafter|nextafter(x, y) would return the floating-point number adjacent to the x in the direction of the y| -|nextUp|nextUp(x) would return the floating-point value adjacent to x in the direction of positive infinity| -|pi|pi would return the constant value of the π | -|pow|pow(x, y) would return the value of the x raised to the power of y| -|remainder|remainder(x, y) would return the remainder operation on two arguments as prescribed by the IEEE 754 standard| -|rint|rint(x) would return value that is closest in value to x and is equal to a mathematical integer| -|round|round(x, y) would return the value of the x rounded to the y decimal places. While x can be an integer or floating-point number, y must be an integer. The type of the return value is specified by that of x. y defaults to 0 if omitted. When y is negative, x is rounded on the left side of the y decimal points. If x is `NaN`, x will return 0. If x is infinity, x will be converted to the nearest finite double. | -|scalb|scalb(d, sf) would return d * 2^sf rounded as if performed by a single correctly rounded floating-point multiply to a member of the double value set| -|signum|signum(x) would return the signum function of the argument x| -|sin|sin(x) would return the trigonometric sine of an angle x| -|sinh|sinh(x) would return the hyperbolic sine of x| -|sqrt|sqrt(x) would return the correctly rounded positive square root of x| -|tan|tan(x) would return the trigonometric tangent of an angle x| -|tanh|tanh(x) would return the hyperbolic tangent of x| +|exp|exp(x) returns Euler's number raised to the power of x| +|expm1|expm1(x) returns e^x-1| +|floor|floor(x) returns the largest (closest to positive infinity) double value that is less than or equal to x and is equal to a mathematical integer| +|getExponent|getExponent(x) returns the unbiased exponent used in the representation of x| +|hypot|hypot(x, y) returns sqrt(x^2+y^2) without intermediate overflow or underflow| +|log|log(x) returns the natural logarithm of x| +|log10|log10(x) returns the base 10 logarithm of x| +|log1p|log1p(x) will the natural logarithm of x + 1| +|max|max(x, y) returns the greater of two values| +|min|min(x, y) returns the smaller of two values| +|nextafter|nextafter(x, y) returns the floating-point number adjacent to the x in the direction of the y| +|nextUp|nextUp(x) returns the floating-point value adjacent to x in the direction of positive infinity| +|pi|pi returns the constant value of the π | +|pow|pow(x, y) returns the value of the x raised to the power of y| +|remainder|remainder(x, y) returns the remainder operation on two arguments as prescribed by the IEEE 754 standard| +|rint|rint(x) returns value that is closest in value to x and is equal to a mathematical integer| +|round|round(x, y) returns the value of the x rounded to the y decimal places. While x can be an integer or floating-point number, y must be an integer. The type of the return value is specified by that of x. y defaults to 0 if omitted. When y is negative, x is rounded on the left side of the y decimal points. If x is `NaN`, x returns 0. If x is infinity, x will be converted to the nearest finite double. | +|scalb|scalb(d, sf) returns d * 2^sf rounded as if performed by a single correctly rounded floating-point multiply to a member of the double value set| +|signum|signum(x) returns the signum function of the argument x| +|sin|sin(x) returns the trigonometric sine of an angle x| +|sinh|sinh(x) returns the hyperbolic sine of x| +|sqrt|sqrt(x) returns the correctly rounded positive square root of x| +|tan|tan(x) returns the trigonometric tangent of an angle x| +|tanh|tanh(x) returns the hyperbolic tangent of x| |todegrees|todegrees(x) converts an angle measured in radians to an approximately equivalent angle measured in degrees| |toradians|toradians(x) converts an angle measured in degrees to an approximately equivalent angle measured in radians| -|ulp|ulp(x) would return the size of an ulp of the argument x| +|ulp|ulp(x) returns the size of an ulp of the argument x| ## Array functions diff --git a/website/.spelling b/website/.spelling index 4184c674101c..6f7a1ff6c1e4 100644 --- a/website/.spelling +++ b/website/.spelling @@ -1090,6 +1090,15 @@ array_to_string asin atan atan2 +bitwise +bitwiseAnd +bitwiseComplement +bitwiseConvertDoubleToLongBits +bitwiseConvertLongBitsToDouble +bitwiseOr +bitwiseShiftLeft +bitwiseShiftRight +bitwiseXor bloom_filter_test cartesian_fold cartesian_map