Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
temp2 = temp.round # -48Иногда бывает нужно округлить не до целого, а до заданного числа знаков после запятой. В таком случае можно воспользоваться функциями
sprintfevalpi = 3.1415926535pi6 = eval(sprintf("%8.6f",pi)) # 3.141593pi5 = eval(sprintf("%8.5f",pi)) # 3.14159pi4 = eval(sprintf("%8.4f",pi)) # 3.1416Это не слишком красиво. Поэтому инкапсулируем оба вызова функций в метод, который добавим в класс
Floatclass Float def roundf(places) temp = self.to_s.length sprintf("%#{temp}.#{places}f",self).to_f endendИногда требуется округлять до целого по-другому. Традиционное округление
n+0.5n+0.5n+1n0.5Floatround2class Float def round2 whole = self.floor fraction = self — whole if fraction == 0.5 if (whole % 2) == 0 whole else whole+1 end else self.round end endenda = (33.4).round2 # 33b = (33.5).round2 # 34с = (33.6).round2 # 34d = (34.4).round2 # 34e = (34.5).round2 # 34f = (34.6).round2 # 35Видно, что
round2roundНу а если мы хотим округлять до заданного числа знаков после запятой, но при этом использовать метод «округления до четного»? Тогда нужно добавить в класс
Floatroundf2class Float # Определение round2 такое же, как и выше. def roundf2(places) shift = 10**places (self * shift).round2 / shift.to_f endenda = 6.125b = 6.135x = a.roundf2(a) #6.12y = b.roundf2(b) #6.13У методов
roundfroundf25.4. Сравнение чисел с плавающей точкой
Печально, но факт: в компьютере числа с плавающей точкой представляются неточно. В идеальном мире следующий код напечатал бы «да», но на всех машинах где мы его запускали, печатается «нет»:
x = 1000001.0/0.003y = 0.003*xif y == 1000001.0 puts "да"else puts "нет"endОбъясняется это тем, что для хранения числа с плавающей точкой выделено конечное число битов, а с помощью любого, сколь угодно большого, но конечного числа битов нельзя представить периодическую десятичную дробь с бесконечным числом знаков после запятой.
Из-за этой неустранимой неточности при сравнении чисел с плавающей точкой мы можем оказаться в ситуации (продемонстрированной выше), когда с практической точки зрения два числа равны, но аппаратура упрямо считает их различными.
Ниже показан простой способ выполнения сравнения с «поправкой», когда числа считаются равными, если отличаются не более чем на величину, задаваемую программистом:
class Float EPSILON = 1e-6 # 0.000001 def == (x) (self-x).abs < EPSILON endendx = 1000001.0/0.003y = 0.003*xif y == 1.0 # Пользуемся новым оператором ==. puts "да" # Теперь печатается "да".else puts "нет"endВ зависимости от ситуации может понадобиться задавать разные погрешности. Для этого определим в классе
Floatequals?equal?eql?
