didi/DoKit · error · IllegalArgumentException

precision shouldn't be less than zero!

Error message

precision shouldn't be less than zero!

What it means

ConvertUtils.byte2FitMemorySize(long byteSize, int precision) formats a byte count into a human-readable B/KB/MB/GB string and requires precision >= 0 because precision is interpolated directly into a '%.<precision>f' format string. A negative value would produce an invalid format specifier, so it is rejected up front with IllegalArgumentException.

Source

Thrown at Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/ConvertUtils.java:471

     * @return fit size of memory
     */
    @SuppressLint("DefaultLocale")
    public static String byte2FitMemorySize(final long byteSize) {
        return byte2FitMemorySize(byteSize, 3);
    }

    /**
     * Size of byte to fit size of memory.
     * <p>to three decimal places</p>
     *
     * @param byteSize  Size of byte.
     * @param precision The precision
     * @return fit size of memory
     */
    @SuppressLint("DefaultLocale")
    public static String byte2FitMemorySize(final long byteSize, int precision) {
        if (precision < 0) {
            throw new IllegalArgumentException("precision shouldn't be less than zero!");
        }
        if (byteSize < 0) {
            throw new IllegalArgumentException("byteSize shouldn't be less than zero!");
        } else if (byteSize < MemoryConstants.KB) {
            return String.format("%." + precision + "fB", (double) byteSize);
        } else if (byteSize < MemoryConstants.MB) {
            return String.format("%." + precision + "fKB", (double) byteSize / MemoryConstants.KB);
        } else if (byteSize < MemoryConstants.GB) {
            return String.format("%." + precision + "fMB", (double) byteSize / MemoryConstants.MB);
        } else {
            return String.format("%." + precision + "fGB", (double) byteSize / MemoryConstants.GB);
        }
    }

    /**
     * Time span in unit to milliseconds.
     *
     * @param timeSpan The time span.

View on GitHub (pinned to 626827cddb)

Solutions

  1. Pass a valid precision; the common library default is 3.
  2. Sanitize external input: precision = Math.max(0, precision) or reject with your own validation error.
  3. Use the single-argument overload byte2FitMemorySize(byteSize) which internally uses a fixed valid precision.

Example fix

// before
String s = ConvertUtils.byte2FitMemorySize(Runtime.getRuntime().totalMemory(), -1); // throws

// after
String s = ConvertUtils.byte2FitMemorySize(Runtime.getRuntime().totalMemory(), 3);
Defensive patterns

Strategy: validation

Validate before calling

int safePrecision = Math.max(0, precision);
String s = ConvertUtils.byte2FitMemorySize(byteSize, safePrecision);

Prevention

When it happens

Trigger: Passing a negative precision, most commonly a constant or parsed value: byte2FitMemorySize(bytes, -1); reading precision from config/user input without validation; using -1 as a 'default' sentinel.

Common situations: Config files or intent extras supplying -1 to mean 'unspecified'; copying the 3-precision signature but defaulting the parameter to -1; arithmetic like precision = requested - actual that can dip below zero.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/cdeee500f2f0fe5b. Report an issue: GitHub.