Урок Ruby №8 «Путь статистика или как манипулировать числами в Ruby»

Из предыдущего урока вы поняли, что на Ruby легко работать с цифрами. Давайте в этом уроке пробежимся по основным методам манипуляции с числами в этом языке.

Конечно, Ruby поддерживает обыкновенные арифметические операции – сложение, вычитание, умножение и деление. Я не буду останавливаться на этом, так как здесь все делается также, как и на обычном калькуляторе.

Единственное, на что стоит обратить внимание —  в силу динамической типизации данных, часто возникает ошибка в расчетах, где используется деление. Дело в том, что Ruby слишком уж умничает в этой операции (это характерно и для многих других языков) и не всегда выдает то, что замышлял программист. А причина в этом кроется в нашей невнимательности. Запомните правило – если делятся целые числа, остаток всегда отбрасывается в Ruby. Иными словами, если вы решили разделить число 5 на 3, то результатом будет 1, а не бесконечная дробь, как вы могли ожидать. С одной стороны, с точки зрения производительности это очень удобно – процессор гораздо быстрее обрабатывает целые числа. Кроме того, часто нужно проверить в различных алгоритмах остаток от деления.

Но как быть, если вам нужен точный расчет при делении? Все очень просто – сделайте делитель или делимое (можно и то и то) дробью (вещественным числом) и частное станет дробью.


a=5.0 / 3

puts #{a}

Правило, как видите, очень простое. Однако, если вы все же сомневаетесь в типе числа, можете явно привести его к вещественному. Делается это двумя способами.

  • Используя метод to_f. Вы же помните, что в Ruby – все объекты.  И у них есть методы.  Я специально рекомендовал вам использовать NetBeans  в качестве редактора Ruby. Поэкспериментируйте на досуге, ставя точку после имени переменной. А привести переменную к вещественному типу можно так:

x=45

a=x.to_f /18 # переменная x теперь выглядит как 45.0 и теперь это число делится на 18

  • Используя функцию  Float (). Здесь все проще —  мы просто передаем функции параметр, который и нужно привести к вещественному типу:

x=45

a=Float (x) /18

Это единственное скользкое место, на которое стоило обратить внимание.

Еще одним оператором, на который стоит обратить внимание – это возведение в степень. Обозначается он как **, после этого оператора нужно указать, в какую степень возвести число.


a=3452**23 # возведем в 23 степень

Если нужно извлечь корень из числа, можете поступить аналогично. Не забывайте, что корень числа – это число в степени ½, а , значит:


a=81** 0.5 # ½ это 0.5 в десятичной дроби

В расчетах часто требуется округленное число. Не можем же мы показать клиенту, что он должен нам 533,3333333333333333 рублей, не так ли? Отбросить дробную часть мы не можем – обеднеем сами (представьте себе десят тысяч таких клиентов принесут нам убыток в 33 тысячи рублей).  Выставить ему счет в размере 534 рубля  — клиент может обидеться.  К счастью, Ruby позволяет округлить число.

Оговорюсь сразу —  так, как я сейчас вам покажу, программисты Ruby обычно не поступают. Дело в том, что нормальный (хм, рубироид? )  программист Ruby просто расширит класс Float методами с тонкой настройкой округления. Но так как мы с вами еще не прошли классы, то я опущу данный способ.

Округление вещественных чисел в Ruby делается с помощью метода round (округлить). Например:


a=34.235

b=a.round

puts #{a}

Округление произведется до целого, что не очень хорошо. Мы так и не решили нашу задачу с тем клиентом. Если нужно, чтобы округление было до нужного знака после запятой (например, когда при расчете денег, вдруг вы на Ruby on Rails смастерите магазин), используют функции  sprintf, умеющую округлять и выводить число в нужном формате и функцию eval.

Вот, как нам нужно было поступить:

 count=533,33

klient=eval (sprintf (“%8.2f”,count)) # вернет 533,33

Функция sprintf предназначена, прежде всего, для форматирования. О функция и о не в частности поговорим в других уроках. Она принимает два параметра – формат и переменную, которую нужно форматировать. Я задал функции формат вывода вещественных чисел, при котором после запятой будут выводиться  всего два знака. Можно поставить любое количество. В любом случае, это тема отдельного урока.

Повторюсь, так как я сделал – это не соответствует стилю Ruby. Когда мы изучим с вами классы,  тогда рассмотрим способ расширения функциональности класса Float своими методами.

Кстати, вы не обратили внимание на то, что я постоянно использовал переменные для того, чтобы воспользоваться методами класса? Не думайте, что это обязательно.  Можно сразу писать нужное число, правда, его нужно будет заключить в круглые скобки.


a=(34.234).round

Помимо операций арифметических, в Ruby широко используются операторы сравнения — >, <, >=, <=, !=, ==. Их применение в точности такое же, как и в математике. Однако обратите внимание на оператор сравнения ==. Если для присвоения значения используется один знак =, то для сравнения –два.

Кстати, еще одна неприятность связана со сравнением вещественных чисел (вот такие они пакостные). Дело в том, что не всегда они у вас будут совпадать. Проверьте сами:


a=1000001.0 /0.003

b=0.003*a

if b==10000001.0 then

puts “совпадение”

else

puts “несовпадение”

end

Как думаете, что выдаст Ruby на экран? Если «совпадение», то тут вы ошибаетесь. Это очень опасный момент в Ruby, который решатся перегрузкой либо самого оператора == или же пишется специальный метод сравнения. Так или иначе, вы пока к этому не готовы.

<<Предыдущий урок                                                        Следующий урок>>

Комментарии

2 комментария на “Урок Ruby №8 «Путь статистика или как манипулировать числами в Ruby»”
  1. Игорь:

    В последнем примере будет совпадение, так как в тексте программы опечатка.
    в первой строке:
    a=1000001.0 /0.003 # первое число это — 1 миллон и 1 единица
    в третьей строке:
    if b==10000001.0 then # значение переменной b сравнивается с числом 10 миллионов и 1 еденица.
    Поэтому на выходе нет соответствия — разница на порядок.
    Вот вариант правильной программы и она выдает «совпадение»:
    ——————————
    a=10000001.0/0.003
    b=0.003*a
    if b==10000001.0 then
    puts «совпадение»
    else
    puts «несовпадение»
    end

  2. Stas:

    Автор немного перемудрил с примером) На самом деле он хотел показать, что к примеру
    puts (0.4-0.3)==0.1 выдаст на экран false, хотя при всей математике, мы блин правы! =)
    P.s. Спасибо большое автору за труды, очень помогают статьи ваши!

Добавить комментарий

Внимание! Не будут добавляться комментарии в виде откровенного спама или прямого анкора на свои сайты. Все спамеры будут передаваться в базу Akismet

Подтвердите, что Вы не бот — выберите человечка с поднятой рукой: