Урок Ruby №9: «Если бы я был мультимиллиардером…»

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

Мы с вами разобрались с тем, что в Ruby есть целые и вещественные числа. Однако часто в скриптах приходится высчитывать просто колоссальные величины. Если бы вы программировали на других языках, то наверняка бы ломали голову над типом, в котором нужно хранить такие данные. К счастью, в Ruby все значительно проще.

Помните, я в уроке 7 говорил о том, что в Ruby есть класс BigNum?Именно он и предназначен для хранения подобных величин. Как вы уже привыкли, интерпретатор автоматически распознает, какой тип данных использовать для вашей переменной и автоматически приводит FixNum к Bignum. Ради интереса попробуйте выполнить такой код:


type1=1000000

type2=type1**3

puts type1.class #выведется на экран Fixnum

puts type2.class #выведется на экран Bignum

Кстати, описанный прием годится для определения типа данных. Это еще нам пригодится в программировании в RoR. Как видите, для этого нужно всего лишь вызвать метод class у объекта. Как я и говорил, привыкайте мыслить категориями объектно-ориентированного программирования.

Тем не менее, если с целыми числами все достаточно просто, то вот с дробями уже нет. Вспомните любую периодическую дробь – количество знаков после запятой там просто поражает воображение. Конечно, можно округлить дробь, но как быть, если мы хотим использовать все это безумное количество цифр?

Использовать класс Float нерационально, так как он уже внесет погрешность. К счастью, в Ruby есть для этих целей классы BigDecimal и Rational. Сейчас мы рассмотрим их применение.

BigDecimal позволяет нам высчитывать большие дроби с адекватной скоростью. Этот класс не предназначен для операций с периодической дробью, однако во всех остальных случаях он актуален.

Интересно, что этот объект инициализируется строкой, хотя на деле является массивом цифр. Благодаря этому достигается произвольная точность. К счастью для программиста, можно не вникать в эти детали. Тем не менее, для эффективного использования языка важно понимать, что у него под капотом.

К сожалению, в Ruby при сравнении вещественных чисел возникает казус, что при сравнении двух вроде бы одинаковых с виду дробей, одну из которых мы получили при расчете, язык посчитает, что они совершенно разные. Подробнее об этом вы можете прочитать в уроке 9. Это чревато логическими ошибками. Чтобы этого избежать, как раз и используют класс BigDecimal.

Для использования класса BigDecimal нужно подключить библиотеку bigdecimal. В Ruby библиотеки подключаются ключевым словом require. Посмотрите на такой код:


require ‘bigdecimal’ #подключаем библиотеку bigdecimal

a=BigDecimal (“3.2”)

b= BigDecimal (“2.0”)

c= BigDecimal (“1.2”)

if (a-b)==c then

puts “Все верно”

else

puts “Числа не равны”

end

Запустите скрипт и посмотрите на результат. На экран выведется «Все верно». Ради интереса, напишите такой же скрипт, только без BigDecimal. Результат вас несколько удивит.

Как я уже и говорил, библиотеку BigDecimal нужно подключить, что я и сделал в первой строчке. Без нее код бы не работал. В операторах присваивания я явным образом привел нашу дробь к типу BigDecimal. Если бы я этого не сделал, вы бы получили результатом скрипта фразу «Числа не равны».

Это очень простой пример пользы от BigDecimal, однако часто возникают ошибки как раз из-за этой особенности Ruby. Ну и напоследок хотелось бы подчеркнуть, что все три переменные из этого скрипта теперь стали объектами класса BigDecimal, а это означает, что они могут использовать его много численные методы методы.

Более подробно об этом вы можете почитать во встроенной документации по Ruby. В конце-концов, мы не будем с вами программировать сложные программы для расчетов. Единственное, что хотелось бы добавить – библиотека bigdecimal имеет ряд подбиблиотек. Это и подбиблиотека bigdecimal /math, bigdecimal /jacobian и т.д. Эти подбиблиотеки позволяют делать включают удобные модули с различными методами, которые сильно упрощают жизнь разработчику.

BigDecimal все же не удобен для работы с бесконечными дробями в силу своей погрешности при округлении. Поэтому в Ruby имеется класс Rational. В справочной документации об этом классе очень хорошо написано, поэтому я не буду дублировать ее. Тем не менее, вам важно знать, как пользоваться этим классом.

Учтите, что экземплярами этого класса должны быть только рациональные числа (частное от деления двух целых чисел). С иррациональными числами его использовать нельзя.

Для создания объекта Rational используется одноименный метод, в который мы передаем в качестве параметром делитель и делимое через запятую:


r=Rational (1,2) # r равно 0.5

r1=Rational (1,3) #0.333333333333…

r2=Rational (4,2) #2.0, тоже рациональное число

Не вздумайте передавать вторым параметром 0! Это ошибка. Важно понять, что метод Rational возвращает объекту частное от деления и поэтому для него характерно то же самое, что и для арифметических правил.

А теперь давайте применим наши знания на практике. Вспомните пример из предыдущего урока:


a=1000001.0 /0.003

b=0.003*a

if b==10000001.0 then

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

else

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

end

Ruby выдавал нам «несовпадение». А вот теперь смотрите как можно сделать «совпадение»


a=Rational (1000001,1) / Rational (3,1000)

b=Rational (3,1000) *x

if b==10000001.0 then

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

else

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

end

Запустите скрипт на исполнение и посмотрите на результат. Теперь все работает как нужно.

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


По просьбам читателей, я сделал электронные версии книги по своим урокам. Кроме того, в качестве бонуса в архив помещен редактор кода с подсветкой ruby. Скачать архив вы можете здесь или здесь

Комментарии

21 коммент. на “Урок Ruby №9: «Если бы я был мультимиллиардером…»”
  1. Ленар:

    А где же продолжение уроков?(

  2. Вячеслав "VeGA" Головлев:

    Увы, уроки по Ruby я тоже забросил в силу низкой популярности. Уроки по программированию писать очень трудно, так как нужно написать такой текст, чтобы читатель смог дочитать его до конца и не закрыл страницу (чем пренебрегают авторы технических книг). А что на выхлопе? Очень мизерный просмотр этих самых уроков и, в основном, спам в комментариях (спамеры очень любят первый урок этой серии).
    Человек так устроен, что хочет видеть востребованность своего труда. Я же не видел этого. Поэтому написание уроков по Ruby, равно как и по C++ отложено до лучших времен, когда я увижу их реальную востребованность.

  3. Алексей:

    Кому надо, тот читает и благодарит. Не надо думать что никто не читает.

    • Вячеслав "VeGA" Головлев:

      Читать — да, может быть, читают и чему то учатся. Благодарить — не дождешься. Мне даже один гоблин написал, что я»козлиная рожа, отнимающая у него массу времени на изучение галимых уроков», а он мог это время потратить на Одноклассники.
      Конечно, глупо все это утрировать, но ряд неприятных осадков остается. Ведь уроки по Ruby я лишь затеял из добрых побуждений, так как внятных уроков просто нет в сети. В итоге я получил то, что имею.
      По большому счету, львиная доля моих «посетителей» идут на этот блог, что своровать контент. Причем, часто они раздосадованы тем фактом, что я бросил писать.
      Вообще, я уже решил для себя — 9 июня домену исполнится год. Я его продам в более умелые руки. Пусть вешает рекламой с сомнительным контентом, заражает вирусами. Мне уже это безразлично.
      Кстати, по моим задумкам, только базовых уроков по Ruby должно быть около 75. Еще примерно столько же по фрэймворку On Rails. Так что можете прикинуть, сколько времени нужно на написание.

      • Дмитрий:

        Очень жаль, что перестали писать. Действительно очень хорошо написано и познавательно, спасибо и за это.

  4. Андрей:

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

  5. Денис:

    Вячеслав, Ваши уроки — лучшие из русскоязычных. Понятно, что низкая посещаемость демотивирует Вас, но для многих — Ваши уроки единственные понятные и доступные. Со временем посещаемость увеличится, а начинающим будут рекомендовать ИМЕННО Ваши уроки. Продолжайте писать. Всех благ.

  6. Илья:

    Поддерживаю тех кто хочет продолжения! Захотелось выучить рельсы и понять почему же все их так пиарят и расхваливают. Читал ваши уроки, но до рельс так и дело и не дошло, обидно получается) Кстати, у вас и вправду хорошо выходит, читается легко. Так что советую продолжить серию, хорошее и полезное начинание!

  7. Артем:

    Очень приятным языком описываете все, спасибо большое. Жаль, что забросили, но хотя бы энтузиазма добавили, а дальше можно и скучными книгами заняться (и практикой, разумеется).

  8. admin:

    Всем спасибо за подобные комментарии!
    Сейчас у меня появится чуточку больше времени, которое я посвящу дописанию всех начатых уроков, так как все таки это изначально задумывался как образовательный ресурс.
    Правда, я постарел на год и вряд ли уже смогу писать в том стиле, что и раньше, но постараюсь Так что ждите продолжения.

  9. Антон:

    Ждем продолжения!!!

  10. Kan:

    Блииииииииииин!!! мне дали 7 дней на изучение руби, я нашел наконец-то нормальный самоучитель; а оказывается продолжения нет….мда….Добавлю, что уроки очень хорошие, редко такие найдешь….

  11. Никита:

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

    • admin:

      Так, а кто вам давал права их опубликовывать без моего разрешения? Или интеллектуальное право уже не катит?
      Уроки чисто мои авторские и только я могу ими распоряжаться.
      В общем, для тех читателей, которые недовольны, что уроки так и не дописаны, могу сказать -благодарите вот таких Никит, которые тупо воруют материал и все.

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

      Я не отношусь к тем авторам, которые «любой ценой» будут загонять на свой ресурс пользователей, которые уже завтра и хрен сюда зайдут.

  12. Рустям:

    Скажите, вышла ли ваша книга по Ruby и как она называется?

  13. Виталик:

    мда.. жаль что это все. Толковые уроки.

  14. Марина:

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

    • admin:

      Знаете, Вы бросаете в лицо мне какие-то обвинения в том, что я не дописал уроки. Да, бросил писать. И что? Мне то что? Есть книги, которые можно нахаляву даже скачать, причем тут мои уроки? Я и не претендовал на академическую полноту этих уроков. Вы прочли их, отлично, импульс я дал. Вы даже не удосужились посмотреть обо мне на блоге, хотя бы как меня звать. Но легко обвиняете в том, что я бросил писать. Эгоизм как раз не с моей стороны. В конце-концов, этого блога вообще могло не быть, или я бы его или продал или вообще ликвидировал. И что?! Это мое дело и мое право.
      Я долго думал, отвечать или нет на эту белиберду. Но решил все же ответить. Уроки я перевожу в новый формат. Они будут более свежими по материалам, но и будут теперь в виде мобильной версии с подпиской.
      Равно как и здесь теперь часть уроков будет бесплатной, так сказать, демонстрационной, а остальная будет платной по подписке. Они не будут стоить там миллионы денег, нет. Но с учетом аудитории людей, что заходит ко мне, даже тридцать рублей с носа за допуск к закрытой части даст и мне финансовый стимул дописывать уроки и улучшать их, даст новую жизнь блогу и т.д. И цену проезда на городском транспорте в один конец. Я не думаю, что это слишком высокая цена. Если да, то разговаривать больше не о чем. Я тоже человек и у меня собственные желания и потребности.

      • Игорь:

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

        Удачи Вам и творческих успехов.

        • admin:

          Спасибо за поддержку, правда, почитав некоторые Ваши комментарии по поводу исправления моих мелких недоработок, даже теперь сомневаюсь в правильности своих уроков

  15. Александр:

    Почтеннейший!
    В Ваших уроках содержится информация, а это — самое главное, чтобы начать движение.
    Как говорили «древние» учителя по программированию: пользователи выбирают свой язык программирования исходя из содержания той книги, которую они смогли понять.
    А дальше — могут быть любые формы донесения материала.
    На Ваш выбор.
    Успехов!
    Создайте свою «могучую кучку»!

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

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

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