гистограмма — вопрос округления C ++

Я пытаюсь создать гистограмму с помощью GSL. У меня возникает проблема, когда я пытаюсь добавить к гистограмме значение деления 1470/100.
Это приводит к 14.69999999 и при добавлении к гистограмме округляется до нижнего бина.
Мой вопрос, как я могу сделать 1470/100 результат в 14,7, а не 14,69999?
Спасибо

Редактировать:

int minRange = 14;
double val;val = minRange + j*0.05;gsl_histogram_increment(hist, val);

Когда значение val добавляется к гистограмме, оно считается 14,65 вместо 14,7. (в этом случае j = 14).

Я решил проблему, добавив 1e-6 к val. Спасибо вам за помощь

0

Решение

Это проблема точности с плавающей запятой. Хороший способ решить эту проблему — установить точки гистограммы рядом с целыми значениями, например, 15 - e где e порядка 10-6.

3

Другие решения

Да,

Добавление 1e-6 обычно работает, но в целом вы должны быть более осторожны при обрезании float.

Этот блог объясните все проблемы, с которыми вы можете столкнуться, если хотите округлить числа с плавающей точкой (а также подводные камни наивных решений). Также предлагается следующая более надежная реализация «добавления 1e-6»

 float myround(float f)
{
if (f >= 0x1.0p23) return f;
return (float) (unsigned int) (f + 0.49999997f);
}

Вы можете проверить, что myround (0.49999997) = 0 и myround (0.49999999) = 1.

Поэтому я бы сначала прочитал этот блог, прежде чем назвать этот вопрос полностью решенным!

Другой момент заключается в том, что в c ++ 11 появилась новая функция std :: round, которая возвращает ближайшее целое число, поэтому вы также можете реализовать округление путем сравнения std::abs(x - std::round(x)) < epsilon, где epsilon ваша цель. Опять же, это наивная реализация, которая не так надежна, как myround (которую нужно адаптировать для удвоения).

0

По вопросам рекламы [email protected]