Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8349637

Integer.numberOfLeadingZeros outputs incorrectly in certain cases

XMLWordPrintable

    • b25
    • 19
    • b13
    • generic
    • generic

        ADDITIONAL SYSTEM INFORMATION :
        Windows 11 [Version 10.0.26100.2894]
        JDK 21.0.6, 23.0.2, 24-ea+35, 25-ea+8

        A DESCRIPTION OF THE PROBLEM :
        Use numberOfLeadingZeros inside a short loop.
        Use arrays for input, output, or both.
        Access arrays sequentially.
        Do not use branching statements such as if statements within the loop.
        A certain number of loops (hundreds of thousands of times?).
        Under these conditions, it may return a number that is 1 less at the boundary where the value changes.
        Could the Intrinsic of Integer.numberOfLeadingZeros be causing the problem?

        0x01FFFFFF: expected=7, actual=6
        0x03FFFFFE-0x03FFFFFF: expected=6, actual=5
        0x07FFFFFC-0x07FFFFFF: expected=5, actual=4
        0x0FFFFFF8-0x0FFFFFFF: expected=4, actual=3
        0x1FFFFFF0-0x1FFFFFFF: expected=3, actual=2
        0x3FFFFFE0-0x3FFFFFFF: expected=2, actual=1

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        var out = new int[0x2000004];
        for (int i = 0; i < out.length; i++)
        out[i] = Integer.numberOfLeadingZeros(i);
        System.out.println(out[0x1FFFFFF]);


        ---------- BEGIN SOURCE ----------
        public class Main {
        public static void main(String[] args) {
        arrayOutput(0x01000000, 0x02000004);
        arrayOutput(0x03000000, 0x04000004);
        arrayOutput(0x07000000, 0x08000004);
        arrayOutput(0x0F000000, 0x10000004);
        arrayOutput(0x1F000000, 0x20000004);
        arrayOutput(0x3F000000, 0x40000004);
        System.out.println();

        for (int loop = 0; loop < 5; loop++) {
        arrayInput(0x200000);
        }
        }

        static void arrayOutput(int from, int to) {
        var output = new int[to - from];
        for (int i = from; i < to; i++) {
        output[i - from] = Integer.numberOfLeadingZeros(i);
        }

        for (int i = from; i < to; i++) {
        int nlz = Integer.numberOfLeadingZeros(i);
        if (nlz != output[i - from]) {
        System.out.printf("0x%08X: expected=%d actual=%d%n", i, nlz, output[i - from]);
        }
        }
        }

        static void arrayInput(int size) {
        int expected = 0;
        for (int i = 0; i < size; i++)
        expected += Integer.numberOfLeadingZeros(-1 >>> i);

        var input = new int[size];
        java.util.Arrays.setAll(input, i -> -1 >>> i);
        int actual = 0;
        for (int i = 0; i < size; i++)
        actual += Integer.numberOfLeadingZeros(input[i]);

        System.out.printf("expected=%d, actual=%d%n", expected, actual);
        }
        }
        ---------- END SOURCE ----------

          1. Main.java
            1 kB
          2. Reduced.java
            0.8 kB

              jkarthikeyan Jasmine Karthikeyan
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              21 Start watching this issue

                Created:
                Updated:
                Resolved: