Search code examples
javaconditional-operator

Simplify expression with ternary operator


Can the following code be shortened/simplified without introducing a division?

a, b, c and y are arbitrary integer values:

int x = 0;
if (y > 0) {
    x = c < y * a ? 1 : c < y * b ? 2 : 4;
}
if (y < 0) {
    x = c > y * a ? 1 : c > y * b ? 2 : 4;
}

Solution

  • I would use a method. Not necessarily simpler but more efficient.

    • first check to see if y == 0.
    • then check if y < 0 and return the value.
    • else return the remaining result.
    public static int evaluate(int a, int b, int c, int y) {
        if (y == 0) {
            return 0;
        }
        if (y > 0) {
            return c < y * a ? 1 : c < y * b ? 2 : 4;
        } 
        return  c > y * a ? 1 : c > y * b ? 2 : 4;
    }
    

    Updated

    Simple timing tests such as this are not usually reliable to check one implementation against another. But this should reasonably show that:

    • your other method also seems to work
    • that after 10 million iterations of not only comparing the two results but generating random numbers to do the test, simplifications will probably not improve much in terms of computing time.
    
    Random r = new Random();
    long start = System.nanoTime();
    for (int i = 0; i < 10_000_000; i++) {
        int y = r.nextInt(-1000, 1000);
        int a = r.nextInt(-1000, 1000);
        int b = r.nextInt(-1000, 1000);
        int c = r.nextInt(-1000, 1000);
        int x = 0;
        int y1 = y;
        int c1 = c;
        if (y < 0) {
            y = -y;
            c = -c;
        }
        if (y != 0) {
            x = c < y * a ? 1 : c < y * b ? 2 : 4;
        }
    
        int x1 = evaluate(a, b, c1, y1);
        if (x != x1) {
            System.out.printf("Oops! a = %d, b = %d, c1 = %d, y1 = %d%n", a, b, c1, y1);
        }
    }
    

    prints something like the following on my Windows i7

    0.635331 (or 635 ms)