Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

class MyNumberSystem

 def +(other)

if other.kind_of?(MyNumberSystem)

result = some_calculation_between_self_and_other

MyNumberSystem.new(result)

else

n1, n2 = other.coerce(self)

n1 + n2

end

 end

end

Метод

coerce
возвращает массив из двух элементов, содержащий аргумент и вызывающий объект, приведенные к совместимым типам.

В данном примере мы полагаемся на то, что приведение выполнит тип аргумента. Но если мы хотим быть законопослушными гражданами, то должны реализовать приведение в своем классе, сделав его пригодным для работы с другими типами чисел. Для этого нужно знать, с какими типами мы в состоянии работать непосредственно, и при необходимости выполнять приведение к одному из этих типов. Если мы не можем сделать это самостоятельно, то должны обратиться за помощью к родительскому классу.

def coerce(other)

 if other.kind_of?(Float)

return other, self.to_f

 elsif other.kind_of?(Integer)

return other, self.to_i

 else

super

 end

end

Разумеется, это будет работать только, если наш объект реализует методы

to_i
и
to_f
.

Метод

coerce
можно применить для реализации автоматического преобразования строк в числа, как в языке Perl:

class String

 def coerce(n)

if self['.']

[n, Float(self)]

else

[n, Integer(self)]

end

 end

end

x = 1 + "23" # 24

y = 23 * "1.23" # 28.29

Мы не настаиваем на таком решении. Но рекомендуем реализовывать

coerce
при создании любого класса для работы с числовыми данными.

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

Иногда требуется работать с двоичным представлением объекта

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)

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

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

Поделиться:
Популярные книги

Бастард Императора. Том 4

Орлов Андрей Юрьевич
4. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 4

Искатель 2

Шиленко Сергей
2. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 2

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Спасите меня, Кацураги-сан! Том 4

Аржанов Алексей
4. Токийский лекарь
Фантастика:
городское фэнтези
попаданцы
дорама
фэнтези
5.00
рейтинг книги
Спасите меня, Кацураги-сан! Том 4

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Лейб-хирург

Дроздов Анатолий Федорович
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Лейб-хирург

Гримуар темного лорда II

Грехов Тимофей
2. Гримуар темного лорда
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар темного лорда II

Мое ускорение

Иванов Дмитрий
5. Девяностые
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Мое ускорение

Старая школа рул

Ромов Дмитрий
1. Второгодка
Фантастика:
альтернативная история
6.00
рейтинг книги
Старая школа рул

Последний Паладин. Том 4

Саваровский Роман
4. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 4

Запрети любить

Джейн Анна
1. Навсегда в моем сердце
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Запрети любить

Хорунжий

Вязовский Алексей
1. Индийский поход
Фантастика:
попаданцы
альтернативная история
5.40
рейтинг книги
Хорунжий

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье