public static long divide_x_y_bsearch(long x, long y) {
        if (x < y) {
            return 0;
        }

        int power_left = 0;
        int power_right = 8 << 3;
        int power_mid = -1;
        while (power_left < power_right) {
            int tmp = power_mid;
            power_mid = power_left + ((power_right - power_left) >> 1);
            if (tmp == power_mid) {
                break;
            }
            long yshift = y << power_mid;
            if ((yshift >> power_mid) != y) {
                // yshift overflowed, use a smaller shift.
                power_right = power_mid;
                continue;
            }
            if ((y << power_mid) > x) {
                power_right = power_mid;
            } else if ((y << power_mid) < x) {
                power_left = power_mid;
            } else {
                return (1L << power_mid);
            }
        }
        long part = 1L << power_left;
        return part | divide_x_y_bsearch(x - (y << power_left), y);
    }