/** * Return the greatest float that compares less than {@code f} consistently * with {@link Float#compare}. The only difference with * {@link Math#nextDown(float)} is that this method returns {@code -0f} when * the argument is {@code +0f}. */ public static float nextDown(float f) { if (Float.floatToIntBits(f) == 0) { // +0f return -0f; } return Math.nextDown(f); }
/** * Return the greatest double that compares less than {@code d} consistently * with {@link Double#compare}. The only difference with * {@link Math#nextDown(double)} is that this method returns {@code -0d} when * the argument is {@code +0d}. */ public static double nextDown(double d) { if (Double.doubleToLongBits(d) == 0L) { // +0d return -0f; } return Math.nextDown(d); }
@Override Float nextNumber(Number actual) { float number = actual.floatValue(); return Math.min(Math.nextUp(number) - number, number - Math.nextDown(number)); }
@Override Double nextNumber(Number actual) { double number = actual.doubleValue(); return Math.min(Math.nextUp(number) - number, number - Math.nextDown(number)); }
/** * Quantizes double (64 bit) latitude into 32 bits (rounding down: in the direction of -90) * @param latitude latitude value: must be within standard +/-90 coordinate bounds. * @return encoded value as a 32-bit {@code int} * @throws IllegalArgumentException if latitude is out of bounds */ public static int encodeLatitude(double latitude) { checkLatitude(latitude); // the maximum possible value cannot be encoded without overflow if (latitude == 90.0D) { latitude = Math.nextDown(latitude); } return (int) Math.floor(latitude / LAT_DECODE); }
/** * Quantizes double (64 bit) longitude into 32 bits (rounding down: in the direction of -180) * @param longitude longitude value: must be within standard +/-180 coordinate bounds. * @return encoded value as a 32-bit {@code int} * @throws IllegalArgumentException if longitude is out of bounds */ public static int encodeLongitude(double longitude) { checkLongitude(longitude); // the maximum possible value cannot be encoded without overflow if (longitude == 180.0D) { longitude = Math.nextDown(longitude); } return (int) Math.floor(longitude / LON_DECODE); }
/** * Quantizes double (64 bit) longitude into 32 bits (rounding up: in the direction of +180) * @param longitude longitude value: must be within standard +/-180 coordinate bounds. * @return encoded value as a 32-bit {@code int} * @throws IllegalArgumentException if longitude is out of bounds */ public static int encodeLongitudeCeil(double longitude) { GeoUtils.checkLongitude(longitude); // the maximum possible value cannot be encoded without overflow if (longitude == 180.0D) { longitude = Math.nextDown(longitude); } return (int) Math.ceil(longitude / LON_DECODE); }
/** * Quantizes double (64 bit) latitude into 32 bits (rounding up: in the direction of +90) * @param latitude latitude value: must be within standard +/-90 coordinate bounds. * @return encoded value as a 32-bit {@code int} * @throws IllegalArgumentException if latitude is out of bounds */ public static int encodeLatitudeCeil(double latitude) { GeoUtils.checkLatitude(latitude); // the maximum possible value cannot be encoded without overflow if (latitude == 90.0D) { latitude = Math.nextDown(latitude); } return (int) Math.ceil(latitude / LAT_DECODE); }
@GwtIncompatible("Math::nextUp is not implemented") static BigDecimal asDecimal(double number) { if (number == NEGATIVE_INFINITY) { final BigDecimal result = BigDecimal.valueOf(Math.nextUp(NEGATIVE_INFINITY)); return result.subtract(INFINITY_DISTANCE.get()); } else if (number == POSITIVE_INFINITY) { final BigDecimal result = BigDecimal.valueOf(Math.nextDown(POSITIVE_INFINITY)); return result.add(INFINITY_DISTANCE.get()); } else { return BigDecimal.valueOf(number); } } }
@ScalarOperator(SATURATED_FLOOR_CAST) @SqlType(StandardTypes.REAL) public static strictfp long saturatedFloorCastToFloat(@SqlType(StandardTypes.DOUBLE) double value) { float result; float minFloat = -1.0f * Float.MAX_VALUE; if (value <= minFloat) { result = minFloat; } else if (value >= Float.MAX_VALUE) { result = Float.MAX_VALUE; } else { result = (float) value; if (result > value) { result = Math.nextDown(result); } checkState(result <= value); } return floatToRawIntBits(result); }
@GwtIncompatible static Iterator<Double> rangeClosedBy(double from, double toInclusive, double step) { if (from == toInclusive) { return of(from); } final double toExclusive = (step > 0) ? Math.nextUp(toInclusive) : Math.nextDown(toInclusive); return rangeBy(from, toExclusive, step); }
@Test public void testCastToBigint() { assertFunction("cast(37.7E0 as bigint)", BIGINT, 38L); assertFunction("cast(-37.7E0 as bigint)", BIGINT, -38L); assertFunction("cast(17.1E0 as bigint)", BIGINT, 17L); assertFunction("cast(-17.1E0 as bigint)", BIGINT, -17L); assertFunction("cast(9.2E18 as bigint)", BIGINT, 9200000000000000000L); assertFunction("cast(-9.2E18 as bigint)", BIGINT, -9200000000000000000L); assertFunction("cast(2.21E9 as bigint)", BIGINT, 2210000000L); assertFunction("cast(-2.21E9 as bigint)", BIGINT, -2210000000L); assertFunction("cast(17.5E0 as bigint)", BIGINT, 18L); assertFunction("cast(-17.5E0 as bigint)", BIGINT, -18L); assertFunction("cast(" + Math.nextDown(0x1.0p63) + " as bigint)", BIGINT, (long) Math.nextDown(0x1.0p63)); assertInvalidFunction("cast(" + 0x1.0p63 + " as bigint)", INVALID_CAST_ARGUMENT); assertInvalidFunction("cast(" + Math.nextUp(0x1.0p63) + " as bigint)", INVALID_CAST_ARGUMENT); assertInvalidFunction("cast(" + Math.nextDown(-0x1.0p63) + " as bigint)", INVALID_CAST_ARGUMENT); assertFunction("cast(" + -0x1.0p63 + " as bigint)", BIGINT, (long) -0x1.0p63); assertFunction("cast(" + Math.nextUp(-0x1.0p63) + " as bigint)", BIGINT, (long) Math.nextUp(-0x1.0p63)); assertInvalidFunction("cast(9.3E18 as bigint)", INVALID_CAST_ARGUMENT); assertInvalidFunction("cast(-9.3E18 as bigint)", INVALID_CAST_ARGUMENT); assertInvalidFunction("cast(infinity() as bigint)", INVALID_CAST_ARGUMENT); assertInvalidFunction("cast(-infinity() as bigint)", INVALID_CAST_ARGUMENT); assertInvalidFunction("cast(nan() as bigint)", INVALID_CAST_ARGUMENT); }
@Override public Query containsQuery(String field, Object from, Object to, boolean includeFrom, boolean includeTo) { return DoubleRange.newContainsQuery(field, new double[] {includeFrom ? (Double)from : Math.nextUp((Double)from)}, new double[] {includeTo ? (Double)to : Math.nextDown((Double)to)}); } @Override
@Override public Query containsQuery(String field, Object from, Object to, boolean includeFrom, boolean includeTo) { return FloatRange.newContainsQuery(field, new float[] {includeFrom ? (Float)from : Math.nextUp((Float)from)}, new float[] {includeTo ? (Float)to : Math.nextDown((Float)to)}); } @Override
@Override public Query withinQuery(String field, Object from, Object to, boolean includeFrom, boolean includeTo) { return DoubleRange.newWithinQuery(field, new double[] {includeFrom ? (Double)from : Math.nextUp((Double)from)}, new double[] {includeTo ? (Double)to : Math.nextDown((Double)to)}); } @Override
@Override public Query intersectsQuery(String field, Object from, Object to, boolean includeFrom, boolean includeTo) { return DoubleRange.newIntersectsQuery(field, new double[] {includeFrom ? (Double)from : Math.nextUp((Double)from)}, new double[] {includeTo ? (Double)to : Math.nextDown((Double)to)}); } },
@Override public Query withinQuery(String field, Object from, Object to, boolean includeFrom, boolean includeTo) { return FloatRange.newWithinQuery(field, new float[] {includeFrom ? (Float)from : Math.nextUp((Float)from)}, new float[] {includeTo ? (Float)to : Math.nextDown((Float)to)}); } @Override
@Override public Query intersectsQuery(String field, Object from, Object to, boolean includeFrom, boolean includeTo) { return FloatRange.newIntersectsQuery(field, new float[] {includeFrom ? (Float)from : Math.nextUp((Float)from)}, new float[] {includeTo ? (Float)to : Math.nextDown((Float)to)}); } },
@Override public Query toRangeQuery(final String name, final String lower, final String upper, final boolean lowerInclusive, final boolean upperInclusive) { return DoublePoint.newRangeQuery(name, lowerInclusive ? toDouble(lower) : Math.nextUp(toDouble(lower)), upperInclusive ? toDouble(upper) : Math.nextDown(toDouble(upper))); }
@Override public Query toRangeQuery(final String name, final String lower, final String upper, final boolean lowerInclusive, final boolean upperInclusive) { return FloatPoint.newRangeQuery(name, lowerInclusive ? toFloat(lower) : Math.nextUp(toFloat(lower)), upperInclusive ? toFloat(upper) : Math.nextDown(toFloat(upper))); }