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

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

Жанры

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

str = sprintf ("%5.1f",x) # "345.7"

Наконец, в классе

String
есть метод
%
, решающий ту же задачу. Слева от знака
%
должна стоять форматная строка, а справа — единственный аргумент (или массив значений), результатом является строка.

# Порядок вызова: 'формат % значение'

str = "%5.1f" % x # "345.7"

str = "%6.2f, %05d" % [x,i] # "345.68, 00123"

5.6. Вставка разделителей при форматировании чисел

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

def commas(x)

str = x.to_s.reverse

str.gsub!(/([0-9]{3})/,"\\1,")

str.gsub(/,$/,"").reverse

end

puts commas(123) # "123"

puts commas(1234) # "1,234"

puts commas(12345) # "12,435"

puts commas(123456) # "123,456"

puts commas(1234567) # "1,234,567"

5.7. Работа с очень большими числами

Управлять массами все равно что управлять немногими: дело в частях и в числе.

Сунь-Цзы [9]

При необходимости Ruby позволяет работать с произвольно большими целыми числами. Переход от

Fixnum
к
Bignum
производится автоматически, прозрачно для программиста. В следующем разделе результат оказывается настолько большим, что преобразуется из объекта
Fixnum
в
Bignum
:

9

Трактат «Искусство войны».

num1 = 1000000 # Один миллион (10**6)

num2 = num1*num1 # Один триллион (10**12)

puts num1 # 1000000

puts num1.class # Fixnum

puts num2 # 1000000000000

puts num2.class # Bignum

Размер

Fixnum
зависит от машинной архитектуры. Вычисления с объектами
Bignum
ограничены только объемом памяти и быстродействием процессора. Конечно, они потребляют больше памяти и выполняются несколько медленнее, тем не менее операции над очень большими целыми (сотни знаков) реальны.

5.8. Использование класса BigDecimal

Стандартная библиотека

bigdecimal
позволяет работать с дробями, имеющими много значащих цифр. Число хранится как массив цифр, а не преобразуется в двоичное представление. Тем самым достижима произвольная точность, естественно, ценой замедления работы.

Чтобы оценить преимущества, рассмотрим следующий простой фрагмент кода, в котором используются числа с плавающей точкой:

if (3.2 - 2.0) == 1.2

 puts "равны"

else

 puts "не равны" # Печатается "не равны"!

end

В подобной ситуации на помощь приходит класс

BigDecimal
. Однако в случае бесконечных периодических дробей проблема остается. Другой подход обсуждается в разделе 5.9 «Работа с рациональными числами».

Объект

BigDecimal
инициализируется строкой. (Объекта типа
Float
было бы недостаточно, поскольку погрешность вкралась бы еще до начала конструирования
BigDecimal
.) Метод
BigDecimal
эквивалентен
BigDecimal.new
; это еще один особый случай, когда имя метода начинается с прописной буквы. Поддерживаются обычные математические операции, например
+
и
*
. Отметим, что метод
to_s
может принимать в качестве параметра форматную строку. Дополнительную информацию вы найдете на сайте ruby-doc.org.

require 'bigdecimal'

x = BigDecimal("3.2")

y = BigDecimal("2.0")

z = BigDecimal("1.2")

if (x - y) == z

 puts "равны" # Печатается "равны"!

else

 puts "не равны"

end

а = x*y*z

a.to_s # "0.768Е1" (по умолчанию: научная нотация)

a.to_s("F") # "7.68" (обычная запись)

Если необходимо, можно задать число значащих цифр. Метод

precs
возвращает эту информацию в виде массива, содержащего два числа: количество использованных байтов и максимальное число значащих цифр.

x = BigDecimal ("1.234",10)

y = BigDecimal("1.234",15)

x.precs # [8, 16]

y.precs # [8, 20]

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

BigDecimal
пытается оптимизировать использование внутренней памяти). У обычных операций (сложение, вычитание, умножение и деление) есть варианты принимающие в качестве дополнительного параметра число значащих цифр. Если результат содержит больше значащих цифр, чем указано, производится округление до заданного числа знаков.

a = BigDecimal("1.23456")

b = BigDecimal("2.45678")

# В комментариях "BigDecimal:objectid" опущено.

c = a+b # <'0.369134Е1\12(20)>

c2 = a.add(b,4) # <'0.3691Е1',8(20)>

d = a-b # <'-0.122222E1',12(20)>

d2 = a.sub(b,4) # <'-0.1222E1',8(20)>

e = a*b # <'0.30330423168E1\16(36)>

e2 = a.mult(b,4) # <'0.3033E1',8(36)>

f = a/b # <'0.502511417383729922907221E0',24(32)>

f2 = a.div(b,4) # <'0.5025E0',4(16)>

В классе

BigDecimal
определено и много других функций, например
floor
,
abs
и т.д. Как и следовало ожидать, имеются операторы
%
и
**
, а также операторы сравнения, к примеру
<
. Оператор
==
не умеет округлять свои операнды — эта обязанность возлагается на программиста.

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

Черный Маг Императора 12

Герда Александр
12. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 12

Император Пограничья 10

Астахов Евгений Евгеньевич
10. Император Пограничья
Фантастика:
городское фэнтези
аниме
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 10

Мастер...

Чащин Валерий
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Мастер...

Гранит науки. Том 2

Зот Бакалавр
2. Героями не становятся, ими умирают
Фантастика:
фэнтези
5.00
рейтинг книги
Гранит науки. Том 2

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение

Тактик

Земляной Андрей Борисович
2. Офицер
Фантастика:
альтернативная история
7.70
рейтинг книги
Тактик

Ст. сержант. Назад в СССР. Книга 5

Гаусс Максим
5. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ст. сержант. Назад в СССР. Книга 5

Рассвет русского царства. Книга 2

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

Надуй щеки! Том 2

Вишневский Сергей Викторович
2. Чеболь за партой
Фантастика:
попаданцы
дорама
фантастика: прочее
5.00
рейтинг книги
Надуй щеки! Том 2

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

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

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

Воин

Бубела Олег Николаевич
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Воин

Неправильный лекарь. Том 4

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

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI