/** * Start building an instance which maps {@code x = x1} to {@code y = y1}. Both arguments must be * finite. Call either {@link LinearTransformationBuilder#and} or {@link * LinearTransformationBuilder#withSlope} on the returned object to finish building the instance. */ public static LinearTransformationBuilder mapping(double x1, double y1) { checkArgument(isFinite(x1) && isFinite(y1)); return new LinearTransformationBuilder(x1, y1); }
static long getSignificand(double d) { checkArgument(isFinite(d), "not a normal value"); int exponent = getExponent(d); long bits = doubleToRawLongBits(d); bits &= SIGNIFICAND_MASK; return (exponent == MIN_EXPONENT - 1) ? bits << 1 : bits | IMPLICIT_BIT; }
/** * Builds an instance representing a horizontal transformation with a constant value of {@code y}. * (The inverse of this will be a vertical transformation.) */ public static LinearTransformation horizontal(double y) { checkArgument(isFinite(y)); double slope = 0.0; return new RegularLinearTransformation(slope, y); }
/** * Builds an instance representing a vertical transformation with a constant value of {@code x}. * (The inverse of this will be a horizontal transformation.) */ public static LinearTransformation vertical(double x) { checkArgument(isFinite(x)); return new VerticalLinearTransformation(x); }
/** * Finish building an instance which also maps {@code x = x2} to {@code y = y2}. These values * must not both be identical to the values given in the first mapping. If only the {@code x} * values are identical, the transformation is vertical. If only the {@code y} values are * identical, the transformation is horizontal (i.e. the slope is zero). */ public LinearTransformation and(double x2, double y2) { checkArgument(isFinite(x2) && isFinite(y2)); if (x2 == x1) { checkArgument(y2 != y1); return new VerticalLinearTransformation(x1); } else { return withSlope((y2 - y1) / (x2 - x1)); } }
/** * Start building an instance which maps {@code x = x1} to {@code y = y1}. Both arguments must be * finite. Call either {@link LinearTransformationBuilder#and} or {@link * LinearTransformationBuilder#withSlope} on the returned object to finish building the instance. */ public static LinearTransformationBuilder mapping(double x1, double y1) { checkArgument(isFinite(x1) && isFinite(y1)); return new LinearTransformationBuilder(x1, y1); }
@GwtIncompatible // com.google.common.math.DoubleUtils @CanIgnoreReturnValue private static double checkFinite(double argument) { checkArgument(isFinite(argument)); return argument; }
/** * Finish building an instance with the given slope, i.e. the rate of change of {@code y} with * respect to {@code x}. The slope must not be {@code NaN}. It may be infinite, in which case * the transformation is vertical. (If it is zero, the transformation is horizontal.) */ public LinearTransformation withSlope(double slope) { checkArgument(!Double.isNaN(slope)); if (isFinite(slope)) { double yIntercept = y1 - x1 * slope; return new RegularLinearTransformation(slope, yIntercept); } else { return new VerticalLinearTransformation(x1); } } }
/** * Builds an instance representing a horizontal transformation with a constant value of {@code y}. * (The inverse of this will be a vertical transformation.) */ public static LinearTransformation horizontal(double y) { checkArgument(isFinite(y)); double slope = 0.0; return new RegularLinearTransformation(slope, y); }
/** * Builds an instance representing a vertical transformation with a constant value of {@code x}. * (The inverse of this will be a horizontal transformation.) */ public static LinearTransformation vertical(double x) { checkArgument(isFinite(x)); return new VerticalLinearTransformation(x); }
static long getSignificand(double d) { checkArgument(isFinite(d), "not a normal value"); int exponent = getExponent(d); long bits = doubleToRawLongBits(d); bits &= SIGNIFICAND_MASK; return (exponent == MIN_EXPONENT - 1) ? bits << 1 : bits | IMPLICIT_BIT; }
/** * Returns {@code true} if {@code x} is exactly equal to {@code 2^k} for some finite integer * {@code k}. */ @GwtIncompatible // com.google.common.math.DoubleUtils public static boolean isPowerOfTwo(double x) { if (x > 0.0 && isFinite(x)) { long significand = getSignificand(x); return (significand & (significand - 1)) == 0; } return false; }
/** * Finish building an instance which also maps {@code x = x2} to {@code y = y2}. These values * must not both be identical to the values given in the first mapping. If only the {@code x} * values are identical, the transformation is vertical. If only the {@code y} values are * identical, the transformation is horizontal (i.e. the slope is zero). */ public LinearTransformation and(double x2, double y2) { checkArgument(isFinite(x2) && isFinite(y2)); if (x2 == x1) { checkArgument(y2 != y1); return new VerticalLinearTransformation(x1); } else { return withSlope((y2 - y1) / (x2 - x1)); } }
/** * Builds an instance representing a vertical transformation with a constant value of {@code x}. * (The inverse of this will be a horizontal transformation.) */ public static LinearTransformation vertical(double x) { checkArgument(isFinite(x)); return new VerticalLinearTransformation(x); }
/** * Returns {@code true} if {@code x} represents a mathematical integer. * * <p>This is equivalent to, but not necessarily implemented as, the expression {@code * !Double.isNaN(x) && !Double.isInfinite(x) && x == Math.rint(x)}. */ @GwtIncompatible // java.lang.Math.getExponent, com.google.common.math.DoubleUtils public static boolean isMathematicalInteger(double x) { return isFinite(x) && (x == 0.0 || SIGNIFICAND_BITS - Long.numberOfTrailingZeros(getSignificand(x)) <= getExponent(x)); }
@GwtIncompatible // com.google.common.math.DoubleUtils @CanIgnoreReturnValue private static double checkFinite(double argument) { checkArgument(isFinite(argument)); return argument; }
/** * Finish building an instance with the given slope, i.e. the rate of change of {@code y} with * respect to {@code x}. The slope must not be {@code NaN}. It may be infinite, in which case * the transformation is vertical. (If it is zero, the transformation is horizontal.) */ public LinearTransformation withSlope(double slope) { checkArgument(!Double.isNaN(slope)); if (isFinite(slope)) { double yIntercept = y1 - x1 * slope; return new RegularLinearTransformation(slope, yIntercept); } else { return new VerticalLinearTransformation(x1); } } }
/** * Returns {@code true} if {@code x} is exactly equal to {@code 2^k} for some finite integer * {@code k}. */ @GwtIncompatible // com.google.common.math.DoubleUtils public static boolean isPowerOfTwo(double x) { if (x > 0.0 && isFinite(x)) { long significand = getSignificand(x); return (significand & (significand - 1)) == 0; } return false; }
/** * Returns {@code true} if {@code x} represents a mathematical integer. * * <p>This is equivalent to, but not necessarily implemented as, the expression {@code * !Double.isNaN(x) && !Double.isInfinite(x) && x == Math.rint(x)}. */ @GwtIncompatible // java.lang.Math.getExponent, com.google.common.math.DoubleUtils public static boolean isMathematicalInteger(double x) { return isFinite(x) && (x == 0.0 || SIGNIFICAND_BITS - Long.numberOfTrailingZeros(getSignificand(x)) <= getExponent(x)); }
/** * Returns {@code true} if {@code x} is exactly equal to {@code 2^k} for some finite integer * {@code k}. */ @GwtIncompatible // com.google.common.math.DoubleUtils public static boolean isPowerOfTwo(double x) { if (x > 0.0 && isFinite(x)) { long significand = getSignificand(x); return (significand & (significand - 1)) == 0; } return false; }