docs: public static double floatToDoubleLower(float f) {
      if(Float.isNaN(f)) {
        return Double.NaN;
      }
      if(Float.isInfinite(f)) {
        return f < 0 ? Double.NEGATIVE_INFINITY : Double.longBitsToDouble(0x47efffffffffffffL);
      }
      long bits = Double.doubleToRawLongBits((double) f);
      if((bits & 0x8000000000000000L) == 0) { // Positive
        if(bits == 0L) {
          return +0.0d;
        }
        if(f == Float.MIN_VALUE) {
          // bits -= 0xf_ffff_ffff_ffffl;
          return Double.longBitsToDouble(0x3690000000000001L);
        }
        if(Float.MIN_NORMAL > f /* && f >= Double.MIN_NORMAL */) {
          // The most tricky case:
          // a denormalized float, but a normalized double
          final long bits2 = Double.doubleToRawLongBits((double) -Math.nextUp(-f));
          bits = (bits >>> 1) + (bits2 >>> 1) + 1L; // + (0xfff_ffffL << 18);
        }
        else {
          bits -= 0xfffffffL; // 28 extra bits
        }
        return Double.longBitsToDouble(bits);
      }
      else {
        if(bits == 0x8000000000000000L) {
          return Double.longBitsToDouble(0xb690000000000000L);
        }
        if(f == -Float.MIN_VALUE) {
          // bits += 0x7_ffff_ffff_ffffl;
          return Double.longBitsToDouble(0xb6a7ffffffffffffL);
        }
        if(-Float.MIN_NORMAL < f /* && f <= -Double.MIN_NORMAL */) {
          // The most tricky case:
          // a denormalized float, but a normalized double
          final long bits2 = Double.doubleToRawLongBits((double) -Math.nextUp(-f));
          bits = (bits >>> 1) + (bits2 >>> 1) - 1L;
        }
        else {
          bits += 0xfffffffL; // 28 extra bits
        }
        return Double.longBitsToDouble(bits);
      }
    }