#ruby-on-rails #ruby #numbers
#ruby-on-rails #ruby #числа
Вопрос:
У меня есть модель обзора, которая допускает систему оценки продуктов «1-10». В моем представлении формы, вот как я сделал поле, чтобы отобразить выпадающий список 1-10…
<%= f.select :rating, options_for_select((0..10).to_a, @review.rating) %>
Работает отлично, но команда теперь хочет иметь .5 десятичных чисел для рейтинговой системы, чтобы что-то могло быть оценено в 7.5, 8.0, 8.5 и т.д.
Однако это ставит меня в тупик … как я могу изменить приведенный выше код и выполнить итерацию по набору чисел и увеличивать его на .5 каждый раз в Ruby? (Примечание: Да, я уже преобразовал свой столбец рейтинга из целого числа в число с плавающей точкой.)
Ответ №1:
Вы можете определить приращение следующим образом
(0..10).step(0.5)
Комментарии:
1. Вот и все, так просто. Большое вам спасибо. Проверю это как ответ, как только SO позволит мне.
2. На самом деле это так просто, но я сталкиваюсь с проблемой, поскольку, когда я делаю (1 .. 2). шаг (0.1), я получил ответ как [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9000000000000001, 2.0]. Почему я получаю это 1.9000000000000001???
3. @SwapnilChincholkar — Я опубликовал новый ответ, который должен решить эту проблему
Ответ №2:
Ответ, помеченный как правильный, не является точным. Он страдает от ошибок точности с плавающей запятой — вы можете прочитать об этой распространенной проблеме информатики здесь: https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
Чтобы точно увеличить этот диапазон, вы должны передать функции step значение BigDecimal вместо значения Ruby float по умолчанию:
require 'bigdecimal'
require 'bigdecimal/util'
(0..10).step(0.5.to_d)
Комментарии:
1.Вам также понадобится следующий код, иначе to_d не будет работать
require 'bigdecimal'
require 'bigdecimal/util'
2.Да, это лучший ответ, спасибо zarazan. Также используйте to_d в диапазоне, например
(0.5.to_d..0.8.to_d).step(0.02.to_d).collect {|t| t.to_s} => ["0.5", "0.52", "0.54", "0.56", "0.58", "0.6", "0.62", "0.64", "0.66", "0.68", "0.7", "0.72", "0.74", "0.76", "0.78", "0.8"]
(0.5..0.8).step(0.02.to_d).collect {|t| t.to_s} => ["0.5", "0.52", "0.54", "0.56", "0.58", "0.6", "0.62", "0.64", "0.66", "0.6799999999999999", "0.7", "0.72", "0.74", "0.76", "0.78", "0.8"]