работы со строками, а также рассмотрели методы pack
и unpack
с точки зрения полезности для манипулирования Unicode-строками.
Наконец, мы довольно подробно остановились на справочниках сообщений. Мы поняли, для чего они нужны, как их создавать и поддерживать.
Детально рассмотрев вопрос о строках и регулярных выражениях, вернемся на главную дорогу. Глава 5 посвящена численному анализу в языке Ruby.
Глава 5. Численные методы
Дважды [члены Парламента] задавали мне вопрос: «А скажите, мистер Бэббидж, если вы заложите в эту машину неверные числа, то получите правильный результат?» Не могу даже представить себе, насколько извращенно должен мыслить человек, задающий такие вопросы.
Числа — самый первичный тип данных, естественный для любого компьютера. Придется сильно постараться, чтобы найти такую область знания, в которой нет места числам. Будь вы бухгалтером или конструктором воздухоплавательных аппаратов, без чисел вам не обойтись. В этой главе мы обсудим различные способы обработки, преобразования и анализа числовых данных.
Как и всякий современный язык, Ruby прекрасно умеет работать с любыми числами — как целыми, так и с плавающей точкой. В нем есть полный набор ожидаемых математических операторов и функций, а вместе с тем и кое-какие приятные сюрпризы: классы Bignum
, BigDecimal
и Rational
.
Помимо средств для манипуляции числами, имеющихся в системной и стандартной библиотеках, мы рассмотрим более специфические темы (тригонометрия, математический анализ и статистика). Примеры приведены не только для справки, но и как образцы кода на языке Ruby, иллюстрирующие принципы, изложенные в других частях книги.
5.1. Представление чисел в языке Ruby
Если вы знакомы с любым другим языком программирования, то представление чисел в Ruby не вызовет у вас никакого удивления. Объект класса Fixnum
может представлять число со знаком или без знака:
237 # Число без знака (положительное).
+237 # То же, что и выше.
-237 # Отрицательное число.
Если число длинное, то между любыми цифрами можно вставлять знак подчеркивания. Это сделано исключительно для удобства, назначении константы никак не сказывается. Обычно подчерки вставляются в те же места, где бухгалтеры вставляют пробелы:
1048576 # Число в обычной записи.
1_048_576 # То же самое значение.
Целые числа можно представлять и в других системах счисления (по основанию 2, 8 и 16). Для этого в начале ставятся префиксы 0b
, 0
и 0х
соответственно.
0b10010110 # Двоичное.
0b1211 # Ошибка!
01234 # Восьмеричное (основание 8).
01823 # Ошибка!
0xdeadbeef # Шестнадцатеричное (основание 16) .
0xDEADBEEF # То же самое.
0xdeadpork # Ошибка!
В числах с плавающей точкой десятичная точка должна присутствовать, а показатель степени, возможно со знаком, необязателен:
3.14 # Число пи, округленное до сотых.
-0.628 # -2*pi, поделенное на 10, округленное до тысячных.
6.02е23 # Число Авогадро.
6.626068е-34 # Постоянная Планка.
В классе Float
есть константы, определяющие минимальные и максимальные значения чисел с плавающей точкой. Они машиннозависимы. Вот некоторые наиболее важные:
Float::MIN # 2.2250738585072е-308 (на конкретной машине)
Float::МАХ # 1.79769313486232е+308
Float::EPSILON # 2.22044604925031е-16
5.2. Основные операции над числами
Обычные операции сложения, вычитания, умножения и деления в Ruby, как и во всех распространенных языках программирования, обозначаются операторами +
, -
, *
, /
. Операторы в большинстве своем реализованы в виде методов (и потому могут быть переопределены).
Возведение в степень обозначается оператором **
, как в языках BASIC и FORTRAN. Эта операция подчиняется обычным математическим правилам.
а = 64**2 # 4096
b = 64**0.5 # 8.0
с = 64**0 # 1
d = 64**-1 # 0.015625
При делении одного целого числа на другое дробная часть результата отбрасывается. Это не ошибка, так и задумано. Если вы хотите получить результат с плавающей точкой, позаботьтесь о том, чтобы хотя бы один из операндов был числом c плавающей точкой.
3 / 3 # 3
5 / 3 # 1
3 / 4 # 0
3.0 / 4 # 0.75
3 / 4.0 # 0.75
3.0 / 4.0 # 0.75
Если вы работаете с переменными и сомневаетесь относительно их типа, воспользуйтесь приведением типа к Float
или методом to_f
:
z = x.to_f / у z = Float(x) / y
См. также раздел 5.17 «Поразрядные операции над числами».
5.3. Округление чисел с плавающей точкой