未验证 提交 2ce7b3dc 编写于 作者: C Clint Wylie 提交者: GitHub

bitwise math function expressions (#10605)

* expressions: adding bitwise expressions

* double handling and vectorization

* move conversion to Evals

* revert unintended changes

* less magic, split convert functions, fix parser for funny exponent doubles

* fix spelling exceptions list

* more spelling

* fix grammar, add more test, fix docs

* fix docs
Co-authored-by: NMax Kaplan <max@maxkaplan.me>
上级 a46d561b
......@@ -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 | ~ [\'\\])* '\'';
......
......@@ -312,6 +312,40 @@ public interface Function
}
}
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<Expr> args)
{
return ExprType.LONG;
}
@Override
public boolean canVectorize(Expr.InputBindingInspector inspector, List<Expr> 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 interface Function
}
}
class BitwiseComplement extends UnivariateMathFunction
{
@Override
public String name()
{
return "bitwiseComplement";
}
@Nullable
@Override
public ExprType getOutputType(Expr.InputBindingInspector inspector, List<Expr> args)
{
return ExprType.LONG;
}
@Override
protected ExprEval eval(long param)
{
return ExprEval.of(~param);
}
@Override
public <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> 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<Expr> 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 <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> 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<Expr> 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 <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> 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 <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> 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 <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> 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 <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> 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 <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> 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 <T> ExprVectorProcessor<T> asVectorProcessor(Expr.VectorInputBindingInspector inspector, List<Expr> args)
{
return VectorMathProcessors.bitwiseXor(inspector, args.get(0), args.get(1));
}
}
class Cbrt extends DoubleUnivariateMathFunction
{
@Override
......
......@@ -1968,7 +1968,406 @@ public class VectorMathProcessors
);
}
public static <T> ExprVectorProcessor<T> 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 <T> ExprVectorProcessor<T> 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<T>) processor;
}
public static <T> ExprVectorProcessor<T> 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<T>) processor;
}
public static <T> ExprVectorProcessor<T> 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 <T> ExprVectorProcessor<T> 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 <T> ExprVectorProcessor<T> 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 <T> ExprVectorProcessor<T> 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 <T> ExprVectorProcessor<T> 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()
{
......
......@@ -519,6 +519,41 @@ public class FunctionTest extends InitializedNullHandlingTest
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());
......
......@@ -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 class ParserTest extends InitializedNullHandlingTest
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 class ParserTest extends InitializedNullHandlingTest
);
}
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)
{
......
......@@ -137,7 +137,10 @@ public class VectorExprSanityTest extends InitializedNullHandlingTest
"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 class VectorExprSanityTest extends InitializedNullHandlingTest
"min",
"nextAfter",
"scalb",
"pow"
"pow",
"bitwiseAnd",
"bitwiseOr",
"bitwiseXor",
"bitwiseShiftLeft",
"bitwiseShiftRight"
};
final String[] templates = new String[]{
"%s(d1, d2)",
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册