Главная Обратная связь

Дисциплины:






Поразрядные операции над числами



Иногда требуется работать с двоичным представлением объекта Fixnum. На прикладном уровне такая необходимость возникает нечасто, но все-таки возникает.

Ruby обладает всеми средствами для таких операций. Для удобства числовые константы можно записывать в двоичном, восьмеричном или шестнадцатеричном виде. Поразрядным операциям И, ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ и НЕ соответствуют операторы &, |, ^ и ~.

x = 0377 # Восьмеричное (десятичное 255)

y = 0b00100110 # Двоичное (десятичное 38)

z = 0xBEEF # Шестнадцатеричное (десятичное 48879)

 

а = x | z # 48895 (поразрядное ИЛИ)

b = x & z # 239 (поразрядное И)

с = x ^ z # 48656 (поразрядное ИСКЛЮЧАЮЩЕЕ ИЛИ)

d = ~ y # -39 (отрицание или дополнение до 1)

Метод экземпляра size позволяет узнать размер слова для той машины, на которой исполняется программа.

size # Для конкретной машины возвращает 4.

Имеются операторы сдвига влево и вправо (<< и >>соответственно). Это логические операторы сдвига, они не затрагивают знаковый бит (хотя оператор >> распространяет его).

x = 8

y = -8

 

а = x >> 2 # 2

b = y >> 2 # -2

с = x << 2 # 32

d = y << 2 # -32

Конечно, если сдвиг настолько велик, что дает нулевое значение, то знаковый бит теряется, поскольку -0 и 0 — одно и то же.

Квадратные скобки позволяют трактовать числа как битовые массивы. Бит с номером 0 всегда является младшим, вне зависимости от порядка битов в конкретной машинной архитектуре.

x = 5 # То же, что 0b0101

а = x[0] # 1

b = x[1] # 0

с = x[2] # 1

d = x[3] # 0

# И так далее # 0

Присваивать новые значения отдельным битам с помощью такой нотации невозможно (поскольку Fixnum хранится как непосредственное значение, а не как ссылка на объект). Но можно имитировать это действие путем сдвига 1 влево на нужное число позиций с последующим выполнением операции ИЛИ или И.

# Выполнить присваивание x[3] = 1 нельзя,

# но можно поступить так:

x |= (1<<3)

# Выполнить присваивание x[4] = 0 нельзя,

# но можно поступить так:

x &= ~(1<<4)

Преобразование системы счисления

Ясно, что любое целое число можно представить в любой системе счисления, поскольку хранятся эти числа в двоичном виде. Мы знаем, что Ruby умеет работать c целыми константами, записанными в любой из четырех наиболее популярных систем. Следовательно, разговор о преобразовании системы счисления может вестись только применительно к числам, записанным в виде строк.

Вопрос о преобразовании строки в целое рассмотрен в разделе 2.24. Для преобразования числа в строку проще всего воспользоваться методом to_s, которому можно еще передать основание системы счисления. По умолчанию оно равно 10, но в принципе может быть любым вплоть до 36 (когда задействованы все буквы латинского алфавита).



237.to_s(2) # "11101101"

237.to_s(5) # "1422"

237.to_s(8) # "355"

237.to_s # "237"

237.to_s(16) # "ed"

237.to_s(30) # "7r"

Другой способ — обратиться к методу % класса String:

hex = "%x" % 1234 # "4d2"

oct = "%о" % 1234 # "2322"

bin = "%b" % 1234 # "10011010010"

Метод sprintf тоже годится:

str = sprintf(str,"Nietzsche is %x\n",57005)

# str теперь равно: "Nietzsche is dead\n"

Если нужно сразу же вывести преобразованное в строку значение, то подойдет и метод printf.





sdamzavas.net - 2019 год. Все права принадлежат их авторам! В случае нарушение авторского права, обращайтесь по форме обратной связи...