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

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

Жанры

Программирование на языке 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
и т.д. Как и следовало ожидать, имеются операторы
%
и
**
, а также операторы сравнения, к примеру
<
. Оператор
==
не умеет округлять свои операнды — эта обязанность возлагается на программиста.

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

Жена неверного ректора Полицейской академии

Удалова Юлия
Любовные романы:
любовно-фантастические романы
4.25
рейтинг книги
Жена неверного ректора Полицейской академии

Александр Агренев. Трилогия

Кулаков Алексей Иванович
Александр Агренев
Фантастика:
альтернативная история
9.17
рейтинг книги
Александр Агренев. Трилогия

Играть... в тебя

Зайцева Мария
3. Звериные повадки Симоновых
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Играть... в тебя

Аспирант

Поселягин Владимир Геннадьевич
3. Рунный маг
Фантастика:
боевая фантастика
4.50
рейтинг книги
Аспирант

Антимаг его величества. Том VI

Петров Максим Николаевич
6. Модификант
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Антимаг его величества. Том VI

Газлайтер. Том 5

Володин Григорий
5. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 5

Тринадцатый III

NikL
3. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый III

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

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

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

Вернуть невесту. Ловушка для попаданки

Ардова Алиса
1. Вернуть невесту
Любовные романы:
любовно-фантастические романы
8.49
рейтинг книги
Вернуть невесту. Ловушка для попаданки

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

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Убивать чтобы жить 6

Бор Жорж
6. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 6

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

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

Одинаковые. Том 3. Индокитай

Алмазный Петр
3. Братья Горские
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Одинаковые. Том 3. Индокитай