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

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

Жанры

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

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

Магия чистых душ 3

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Магия чистых душ 3

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Барон обходит правила

Ренгач Евгений
14. Закон сильного
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Барон обходит правила

Советник 2

Шмаков Алексей Семенович
7. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Советник 2

Мы – Гордые часть 8

Машуков Тимур
8. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Мы – Гордые часть 8

Ты - наша

Зайцева Мария
1. Наша
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Ты - наша

Вперед в прошлое 9

Ратманов Денис
9. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 9

Противостояние

Гаевский Михаил
2. Стратег
Фантастика:
боевая фантастика
космическая фантастика
5.25
рейтинг книги
Противостояние

Адвокат Империи 4

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

Третий Генерал: Том VII

Зот Бакалавр
6. Третий Генерал
Фантастика:
городское фэнтези
аниме
сказочная фантастика
попаданцы
5.00
рейтинг книги
Третий Генерал: Том VII

Барон запрещает правила

Ренгач Евгений
9. Закон сильного
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Барон запрещает правила

Бастард Императора. Том 6

Орлов Андрей Юрьевич
6. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 6

Неудержимый. Книга II

Боярский Андрей
2. Неудержимый
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга II

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

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