Ruby on Rails — Преобразование чисел в десятичное число для поля оценки отзыва

#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"]