Как делать побитовые операции с огромными двоичными столбцами - PullRequest
1 голос
/ 01 мая 2019

У меня есть поле в таблице MySQL, которое называется "палитра". Он действует как шестнадцатеричный код rgb, но вместо 3-х цветов у меня 12, поэтому длина этого двоичного поля равна 24, если я не считаю 2 символа для «0x». Проблема в том, что я не могу выполнять побитовые операции над ними, как если бы программа считала их слишком большими.

Я хочу сделать что-то вокруг этих строк (я сделаю это меньше, чтобы было легче понять): 0x123456 & 0x00FF00 в mysql и получу 0x003400. Но, похоже, это не работает, так как это не то значение, которое я получаю.

Я ожидаю получить точное значение, но большую часть времени я получаю 0 (даже когда явно есть значение) или противоположное 0 (когда гекс заполнен только "F").

1 Ответ

0 голосов
/ 01 мая 2019

Если единственная проблема заключается в том, что вы не можете работать с длинными шестнадцатеричными строками, вы можете реализовать свой SP для этого.

DELIMITER $$

CREATE FUNCTION `bfunc`(
    `op` VARCHAR(3),
    `v1` VARCHAR(26) CHARSET latin1,
    `v2` VARCHAR(26) CHARSET latin1
)
RETURNS varchar(26) CHARSET latin1
DETERMINISTIC
BEGIN
    SET @r = '';
    SET @r1 = REVERSE(TRIM(LEADING '0x' FROM v1));
    SET @l1 = LENGTH(@r1);

    SET @r2 = REVERSE(TRIM(LEADING '0x' FROM v2));
    SET @l2 = LENGTH(@r2);

    SET @l = IF(@l1 > @l2, @l1, @l2);
    SET @i = 1;
    WHILE @i < @l DO
        SET @c1 = SUBSTR(@r1, @i, 1);
        SET @c2 = SUBSTR(@r2, @i, 1);
        SET @b1 = CONV(IF(@c1 = '', 0, @c1), 16, 10);
        SET @b2 = CONV(IF(@c2 = '', 0, @c2), 16, 10);
        SET @b = '';
        CASE op
            WHEN 'AND' THEN SET @b = @b1 & @b2;
            WHEN 'OR'  THEN SET @b = @b1 | @b2;
            WHEN 'XOR' THEN SET @b = @b1 ^ @b2;
        END CASE;

        SET @r = CONCAT(@r, HEX(@b));

        SET @i = @i + 1;
    END WHILE;

    RETURN REVERSE(@r);
END
$$

DELIMITER ;
SELECT bfunc('AND', '0x123456000000000000000000', '0x00FF00000000000000000000')

=> 03400000000000000000000

Конечно, для производстваокружение, вам нужно будет оптимизировать его и выполнять побитовую математику не на основе «на символ», а, например, на «8 символов»

...