Также доступны методы минимума, максимума, счета, суммы.

аюсь рассчитать среднюю чистую цену товара. В моей модели продукта есть: total_sold и: total_net_revenue. Прямое деление в методе, кажется, всегда приводит к 0. Я прибег к использованию BigDecimal, как я полагал, что это было проблемой ... но с моей последней итерацией кода ниже, я все равно получаю ноль, когда ответ приходит к десятичная дробь

def avg_price
  BigDecimal(total_sold.to_s) / (BigDecimal(total_net_revenue.to_s) / 100)
end  

Чистый доход в центах, поэтому я делю на 100. Кто-то может указать, что я делаю неправильно или должен делать?

 Ryan Bigg19 янв. 2011 г., 06:17
ПочемуBigDecimal? не было быto_f на конец этих значений хватит?

Ответы на вопрос(5)

100 предметов / $ 150 = .667 предметов за доллар

против

$ 150/100 штук = $ 1,50 за штуку

Второе: Как и в других языках, вам нужно сделать так, чтобы одно из чисел в уравнении было десятичным, чтобы результат также был представлен как единое целое. Поскольку ваш доход представляет собой целое число, это означает, что все три значения были целыми числами, что означает, что в результате вы получили целое число. Чтобы получить десятичное число, приведите один из них как число с плавающей запятой.

Другими словами, чтобы получить то, что вам нужно, сделайте это:

price_per_item = (total_net_revenue.to_f / 100) / total_sold

исла с плавающей точкой (числа с десятичными числами), чтобы математические вычисления приводили к плавающему числу вместо целого числа.

Так что в целом это работает так:

some_integer.to_f / some_other_integer.to_f  # returns a float

Кроме того, если вы используете Rails и ваши хранилища данных в конкретной модели, ActiveRecord имеет специальные методы, и вам не нужно рассчитывать самостоятельно.

Model.average("field_with_data")

Также доступны методы минимума, максимума, счета, суммы.

что вы делаете, называется целочисленным делением, которое отбрасывает любой остаток, так как оно не будет выражаться в целых числах, например:

1 / 3 # == 0

Как уже упоминали другие респонденты, вы можете форсировать деление с плавающей запятой. Вы должны заставить первый аргумент быть float (1 здесь), вызывая .to_f. Второй аргумент будет автоматически приведен к плавающей запятой, т.е.

1.to_f / 3 # ~ 0.3333...

Обратите внимание, что после перехода к числам с плавающей запятой результат, вообще говоря, уже не является точным. Вот почему я поставил ~ 0,333.

чные детали более сложны. Я полагаю, что в двоичной арифметике с плавающей запятой, которая является обычной в современных микропроцессорах, степени 2 все еще точны. Но целое число 3, например, больше не представляется точно, а только в пределах точности представления с плавающей запятой (обычно 1E-16 или около того для «двойной» точности).

Короче говоря, вот эмпирическое правило: если вы имеете дело с денежными значениями, где точность имеет значение (когда-либо замечалось расхождение в 1 цент в телефонном счете?), Не храните вычисленные результаты и не храните значения в плавающих точках. Вместо этого используйте целочисленные или десятичные типы данных (которые внутренне хранят строки). Вычислять результаты с плавающей запятой только для отображения и по запросу, если это возможно. Избегайте добавления больших и малых значений вместе, как только они являются плавающими, и избегайте цепных вычислений в плавающих. Переработайте свою алгебру, чтобы избежать делений до конца. Ruby также поддерживает тип данных Rational, который точно представляет дроби и может быть полезен.

Эти проблемы подпадают под науку о «распространении ошибок с плавающей точкой», где вы можете найти больше информации, если вам нужно.

 Wolfram Arnold19 янв. 2011 г., 03:33
Это то, что я нашел, работает лучше всего тоже. Есть также некоторые драгоценные камни, например драгоценный камень, который добавляет легкости этому подходу.
 Slick2319 янв. 2011 г., 03:14
Спасибо за подробное объяснение. Я обычно храню денежные значения в виде центов и вычисляю их на основе центов, чтобы избежать десятичных дробей, потому что мне нужно хранить эти значения время от времени.
Решение Вопроса
total_net_revenue / total_sold

или же

total_net_revenue / total_sold / 100.0

или же

total_net_revenue.to_f / total_sold / 100

Эти три метода дают большую точность, если вы этого хотите. Помните, что "средняя цена" - это "средняя цена / продажа. Это деньги за единицу, поэтому вы захотите выполнить деление в этом конкретном порядке.

Ваш ответ на вопрос