import java.util.Random;

public class Reproduce {
    public static int SIZE = 10_000;
    static Random RANDOM = new Random(42);

    private static void init(float[] a) {
        for (int i = 0; i < SIZE; i++) {
            a[i] = switch(RANDOM.nextInt() % 20) {
                case 0  -> Float.NaN;
                case 1  -> 0;
                case 2  -> 1;
                case 3  -> Float.POSITIVE_INFINITY;
                case 4  -> Float.NEGATIVE_INFINITY;
                case 5  -> Float.MAX_VALUE;
                case 6  -> Float.MIN_VALUE;
                case 7, 8, 9 -> RANDOM.nextFloat();
                default -> Float.intBitsToFloat(RANDOM.nextInt());
            };
        }
    }

    private static void init(int[] a) {
        for (int i = 0; i < SIZE; i++) {
            a[i] = RANDOM.nextInt();
        }
    }

    public static void main(String[] args) {
        int[] a = new int[SIZE];
        int[] b = new int[SIZE];

        float[] c = new float[SIZE];
        float[] d = new float[SIZE];

        float[] gold1 = new float[SIZE];
        float[] gold2 = new float[SIZE];

        float[] res1 = new float[SIZE];
        float[] res2 = new float[SIZE];

        init(a);
        init(b);
        init(c);
        init(d);

        // run in interpreter to get gold.
        testCMoveUIGTforF(a, b, c, d, gold1, gold2);

        for (int k = 0; k < 10_000; k++) {
            testCMoveUIGTforF(a, b, c, d, res1, res2);
            for (int i = 0; i < SIZE; i++) {
                if (Float.floatToIntBits(res1[i]) != Float.floatToIntBits(gold1[i]) ||
                    Float.floatToIntBits(res2[i]) != Float.floatToIntBits(gold2[i])) {
                    System.out.println("Wrong result at: " + i);
                    System.out.println("1: " + res1[i] + " vs " + gold1[i]);
                    System.out.println("2: " + res2[i] + " vs " + gold2[i]);
                    throw new RuntimeException("wrong result");
                }
            }
        }
    }

    private static void testCMoveUIGTforF(int[] a, int[] b, float[] c, float[] d, float[] r, float[] r2) {
        for (int i = 0; i < a.length; i++) {
            float cc = c[i];
            float dd = d[i];
            r2[i] = cc + dd;
            r[i] = Integer.compareUnsigned(a[i], b[i]) > 0 ? cc : dd;
        }
    }
}
