Во многих местах в интернете алгоритм представления числа в троичной симметричной системе счисления указан не вполне корректно. Цифра может иметь отрицательное значение, что и приводит к сложности в корректировке обычного алгоритма, основанного на последовательном делении на основание системы счисления. Постарался восполнить этот пробел.
Главная идея в том, что при получении 2 в остатке от деления на 3, его необходимо представить как две троичные цифры +1•3¹ -1. -1 — это искомая младшая цифра, а +1•3¹ — добавка к исходному числу. Так как для получения следующей цифры исходное значение предварительно нужно разделить на 3, то корректировку числа можно провести уже после деления, но соответственно на 1, а не 3. Таким образом корректировку можно свести к увеличению частного на остаток, поделенный на 2.
MODULE BalancedTernary; IMPORT Variant;
PROCEDURE From*(v: INTEGER; VAR str: ARRAY OF CHAR);
VAR i, k, t: INTEGER; digits: ARRAY 4 OF CHAR; c: CHAR;
BEGIN
IF v >= 0 THEN
digits := "0+-"
ELSE
v := -v;
digits := "0-+"
END;
i := 0;
REPEAT
t := v MOD 3;
IF Variant.One THEN
v := v DIV 3;
IF t = 2 THEN INC(v) END
ELSE
v := v DIV 3 + t DIV 2
END;
str[i] := digits[t];
INC(i)
UNTIL v = 0;
str[i] := 0X;
DEC(i); k := 0;
WHILE i > k DO
c := str[k]; str[k] := str[i]; str[i] := c;
INC(k); DEC(i)
END
END From;
END BalancedTernary.
Код в песочнице.
Примечательно, что и ChatGPT испытывает сложности с созданием алгоритма печати. Передача пояснительного абзаца позволяет ему создать правильный код.
Комментариев нет:
Отправить комментарий