Неправильный результат для побитовой операции r << 24, почему? - PullRequest
2 голосов
/ 24 марта 2020

У меня есть перечисление:

public enum STAR_TYPE {
    FAST(255, 255, 255),
    NORMAL(190, 190, 190),
    SLOW(120, 120, 120);

    private int color;

    private STAR_TYPE(int r, int g, int b) {
        int R = r << 24;
        int G = g << 16;
        int B = b << 8;
        color = R | G | B | 0xff;
    }

    public static STAR_TYPE getRandomType() {
        return values()[MathUtils.random(0, values().length - 1)];
    }

    public int getColor() {
        return color;
    }
}

Я хочу преобразовать значение RGBA в целое число, где прозрачность всегда равна 255. Я использую побитовые операции для этой цели. Но r << 24 не работает. Это возвращает неправильные результаты. </p>

Для 255 r << 24 должен возвращать 4278190080, но он возвращает -16777216. </p>

Для 190 r << 24 должен возвращать 3187671040, но он возвращает -1107296256. </p>

Только для 120 r << 24 возвращает правильный результат 2013265920. </p>

Я обнаружил, что рассчитанные значения являются десятичными знаками от дополнения со знаком 2. Приятно знать, но я никогда не просил об этом. Я хочу иметь положительную ценность. Как я могу получить нужные значения? Я в замешательстве.

1 Ответ

3 голосов
/ 24 марта 2020

Вы неверно истолковываете тот факт, что это отрицательное значение как существенное.

Вы упаковываете четыре 8-битных значения в 32-битное значение:

RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA

Если старший бит устанавливается крайний левый бит R (т. е. ваше значение R составляет не менее 128), соответствующее 32-разрядное значение типа int отрицательно.

Но это ничего не значит, на самом деле, в условия целочисленного значения. В некотором смысле вы злоупотребляете типом данных int, используя его для хранения четырех 8-битных значений. Просто так получается, что некоторые из получающихся 32-битных значений также используются для представления отрицательных чисел.

...