Не секрет, что в мире компьтеров нередко принято измерять величины степенями двойки, а не 10, и многие программы стремятся отображать значения в «честных» мегабайтах, терабайтах, которые больше своих десятичных аналогов. При этом есть большой недостаток: такая «честность» достигается в ущерб точности.

Я в FAR Manager нажал F3 на папке и увидел «48 М» в строке статуса. Нажал Insert и увидел точное десятичное значение «50 510 690». Ни то, ни другое меня не вполне устраивали, поэтому я думал, как бы всё же совместить «честность» с точностью.

И вот, что получилось:
Код
    Кибиричная           Десятичная        Шестнадцатеричная
1'000'000'000'        1 073 741 824                400 00000
    1'000'000'            1 048 576                  1 00000
        4'000'                4 096                     1000
        2'000'                2 048                      800
        1'001'                1 025                      401
        1'000'                1 024                      400
          999'                1 023                      3FF
          750'                  768                      300
          500'                  512                      200
          499'                  511                      1FF
          250'                  256                      100
          125'                  128                       80
           80'                   82                       52
           7A'                   81                       51
           79'                   80                       50
           63'                   64                       40
           40'                   41                       29
           3A'                   40                       28
           39'                   39                       27
           32'                   32                       20
           16'                   16                       10
           10'                   10                        A
            8'                    8                        8
            4'                    4                        4
            2'                    2                        2
            1'                    1                        1
            0'                    0                        0


Как можно видеть, эта система счисления хорошо передаёт величину. 750' — это три четверти от 1'000', а 125' — одна восьмая. И если вы видите в кибиричной системе запись 4'851'964', вы не сильно ошибётесь, если округлите на глаз это до 4,85 Миб. Для сравнения, в шестнадцатеричной системе счисления 210 вообще не является единицей с нулями.

Кибиричная система счисления — это 1024ричная система счисления и её особое представление в десятичных цифрах. «Киби» — это не прижившаяся в русском языке приставка для 1024. Кило = 1000, киби = 1024. Вот как раз хоть здесь пригодилась, потому что «1024ричная» тяжело произносить.

В кибиричной системе счисления 1024 истинных цифр, но представляются они группами по 3 цифры. Смешивать их нельзя, поэтому обязательным является разделение, например, апострофами. И в конец, чтобы отличалось от десятичной системы счисления, дописывается апостроф, что в десятичной точно не делается. Последовательностей цифр от 000 до 999, если использовать только цифры от 0 до 9, хватает только на 1000, а ещё остаётся 24. Если оставшиеся 24 равномерно вставить внутрь, они собой разрежут 1000 на 25 ровных частей по 40. На границе разрезов девятка в следующий разряд не переносится, а сначала переходит в цифру «десять» (записывается буквой A, как в шестнадцатеричной), а только потом — в следующий разряд.

Идею кибиричной системы счисления можно выразить так:
1000 = 40 * 25
1024 = (40 + 1) * 25 - 1
Совсем по-научному — было бы выразить через декартовы произведения, отношения и изоморфизмы.

Кстати, отброшенная последовательность — это 99A'. Вместо неё после 999' идёт сразу 1'000'.


Пример раскодировки:

189'094'35A' = (189 + 18/4) * 1 024 * 1 024 + (94 + 9/4) * 1 024 + (360 + 35/4) = 193 * 1 048 576 + 96 * 1 024 + 368 = 202 473 840.

Деление имеется в виду целочисленное.

В этой системе счисления можно даже производить арифметические операции. Достаточно декодировать каждую истинную цифру, остановиться на этом, а дальше производить над ними операции, как в любой другой позиционной системе счисления. Придётся брать остаток и частное от деления на 1024, но этим всё и ограничится, по модулю 1 048 576 уже необходимость не возникает. Для тех, кто учил таблицу умножения для десятичной системы счисления, а для шестнадцатеричной — не учил, то есть, практически для всех, в кибиричной системе счисления в конечном итоге научиться считать будет проще, чем в более известной шестнадцатеричной.

Числа в таком представлении я генерировал на Аде и Джаваскрипте и могу поделиться кодом на этих языках:

   Kibimal_Digits : constant array (0 .. 10) of Character := ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A');

-------------------
-- Image_Kibimal --
-------------------

function Image_Kibimal (Arg : Interfaces.Integer_64) return String is
begin
if Arg = 0 then
return "0'";
end if;

declare
Result : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.To_Unbounded_String ("'");
Sign : constant String := (if Arg < 0 then "-" else "");
Abs_Value : constant Interfaces.Integer_64 := abs Arg;
Tail : Interfaces.Integer_64 := Abs_Value / 1024;
Head : Integer := Integer (Abs_Value mod 1024);
Head_Tail : Integer := (Head - (Head + 1) / 41) / 10;
Head_Head : Integer := Head - Head_Tail * 10 - Head_Tail / 4;
begin
loop
declare
New_Chunk : constant String :=
(if Head_Tail > 0 then
Ada.Strings.Fixed.Trim (Integer'Image (Head_Tail), Ada.Strings.Left)
else
"") & Kibimal_Digits (Head_Head);
begin
if Tail = 0 then
return Sign & New_Chunk & To_String (Result);
end if;
Insert (Result, 1, ''' & Ada.Strings.Fixed."*" (3 - New_Chunk'Length, '0') & New_Chunk);
Head := Integer (Tail mod 1024);
Tail := Tail / 1024;
Head_Tail := (Head - (Head + 1) / 41) / 10;
Head_Head := Head - Head_Tail * 10 - Head_Tail / 4;
end;
end loop;
end;
end Image_Kibimal;


   function Image_Kibimal (Arg) {
var Result, Sign, Abs_Value, Tail, Head, Head_Tail, Head_Head, New_Chunk, Kibimal_Digits;
if (0 === Arg) {
return "0'";
}
Kibimal_Digits = '0123456789A';

Result = "'";
Sign = ((Arg < 0) ? "-" : "");
Abs_Value = Math.abs (Arg);
Tail = Abs_Value / 1024 | 0;
Head = Abs_Value % 1024;
Head_Tail = (Head - ((Head + 1) / 41 | 0)) / 10 | 0;
Head_Head = Head - Head_Tail * 10 - (Head_Tail / 4 | 0);
do {
New_Chunk = ((Head_Tail > 0) ? Head_Tail : "") + Kibimal_Digits.charAt (Head_Head);
if (0 === Tail) {
return Sign + New_Chunk + Result;
}
Result = "'" + "000".substring (New_Chunk.length) + New_Chunk + Result;
Head = Tail % 1024;
Tail = Tail / 1024 | 0;
Head_Tail = (Head - ((Head + 1) / 41 | 0)) / 10 | 0;
Head_Head = Head - Head_Tail * 10 - (Head_Tail / 4 | 0);
} while (true);
}


Здесь можно посмотреть, как бы могло выглядеть всё, если перейти на кибиричную систему счисления.