public static double floatToDoubleUpper(float f){
  if (Float.isNaN(f)) {
    return Double.NaN;
  }
  if (Float.isInfinite(f)) {
    if (f > 0) {
      return Double.POSITIVE_INFINITY;
    }
 else {
      return Double.longBitsToDouble(0xc7efffffffffffffL);
    }
  }
  long bits=Double.doubleToRawLongBits((double)f);
  if ((bits & 0x8000000000000000L) == 0) {
    if (bits == 0L) {
      return Double.longBitsToDouble(0x3690000000000000L);
    }
    if (f == Float.MIN_VALUE) {
      return Double.longBitsToDouble(0x36a7ffffffffffffL);
    }
    if (Float.MIN_NORMAL > f && f >= Double.MIN_NORMAL) {
      final long bits2=Double.doubleToRawLongBits((double)Math.nextUp(f));
      bits=(bits >>> 1) + (bits2 >>> 1) - 1L;
    }
 else {
      bits+=0xfffffffL;
    }
    return Double.longBitsToDouble(bits);
  }
 else {
    if (bits == 0x8000000000000000L) {
      return -0.0d;
    }
    if (f == -Float.MIN_VALUE) {
      return Double.longBitsToDouble(0xb690000000000001L);
    }
    if (-Float.MIN_NORMAL < f && f <= -Double.MIN_NORMAL) {
      final long bits2=Double.doubleToRawLongBits((double)Math.nextUp(f));
      bits=(bits >>> 1) + (bits2 >>> 1) + 1L;
    }
 else {
      bits-=0xfffffffL;
    }
    return Double.longBitsToDouble(bits);
  }
}

public static double floatToDoubleUpper ( float f ) { if ( Float . isNaN ( f ) ) { return Double . NaN ; } if ( Float . isInfinite ( f ) ) { if ( f > 0 ) { return Double . POSITIVE_INFINITY ; } else { return Double . longBitsToDouble ( 0xc7efffffffffffffL ) ; } } long bits = Double . doubleToRawLongBits ( ( double ) f ) ; if ( ( bits & 0x8000000000000000L ) == 0 ) { if ( bits == 0L ) { return Double . longBitsToDouble ( 0x3690000000000000L ) ; } if ( f == Float . MIN_VALUE ) { return Double . longBitsToDouble ( 0x36a7ffffffffffffL ) ; } if ( Float . MIN_NORMAL > f && f >= Double . MIN_NORMAL ) { final long bits2 = Double . doubleToRawLongBits ( ( double ) Math . nextUp ( f ) ) ; bits = ( bits > > > 1 ) + ( bits2 > > > 1 ) - 1L ; } else { bits += 0xfffffffL ; } return Double . longBitsToDouble ( bits ) ; } else { if ( bits == 0x8000000000000000L ) { return - 0.0d ; } if ( f == - Float . MIN_VALUE ) { return Double . longBitsToDouble ( 0xb690000000000001L ) ; } if ( - Float . MIN_NORMAL < f && f <= - Double . MIN_NORMAL ) { final long bits2 = Double . doubleToRawLongBits ( ( double ) Math . nextUp ( f ) ) ; bits = ( bits > > > 1 ) + ( bits2 > > > 1 ) + 1L ; } else { bits -= 0xfffffffL ; } return Double . longBitsToDouble ( bits ) ; } }
return the largest double that rounds down to this float . note : probably not always correct - subnormal values are quite tricky . so some of the bounds might not be tight .
