Округление непоследовательно после математики с плавающей запятой

Возьмем следующий пример (с надуманными числами):

double a = 9.0, b = 2.0;
double c = a / b;
int d = RoundAndCastToInt(c);

В нескольких прогонах значение d не совпадает. Вот два надуманных способа выполнения математики:

Выполнение 1:

9.0 / 2.0 == 4.49999...

Раундандкасттоинт(4.49999...) == 4

Выполнение 2:

9.0 / 2.0 == 4.5

Раундандкасттоинт (4.5) == 5

Я хочу получить одно и то же значение последовательно в разных исполнениях и на разных машинах. В приведенном выше примере результат 4 или 5 подходит, если он всегда 4 или всегда 5.


person ubc_ben    schedule 29.05.2019    source источник
comment
Каковы ваши входы? Каков ваш ожидаемый результат? Что делают функции Convert()?   -  person Tom    schedule 29.05.2019
comment
В примере кода две переменные a и b не инициализируются. Или, если они действительно инициализируются, не могли бы вы показать реальный код.   -  person Mr Lister    schedule 29.05.2019
comment
Помогает ли это?   -  person Paul Sanders    schedule 29.05.2019
comment
Я сильно отредактировал ваш вопрос, потому что кажется, что многие пользователи были сбиты с толку. Я попытался переформулировать вашу проблему по-другому. Если я ошибаюсь в отношении вашей проблемы или вам не нравятся мои изменения, отмените их.   -  person Weak to Enuma Elish    schedule 29.05.2019
comment
Честно говоря, я не знаю, почему это закрылось. Вопрос содержал желаемое/фактическое поведение еще до того, как я его отредактировал. Convert было легко понять из контекста. Я тоже не могу найти хороший ответ на этот вопрос. Насколько я могу судить, это хороший вопрос.   -  person Weak to Enuma Elish    schedule 29.05.2019
comment
Спасибо за реструктуризацию моего вопроса. Ваше понимание правильное. Фоном является интеграционный/регрессионный тест, в котором мы запускаем два двоичных файла, созданных из разных версий репозитория. Мы получаем неожиданный diff из-за такой проблемы.   -  person ubc_ben    schedule 30.05.2019
comment
@ubc_ben Но без конкретных примеров эта проблема не воспроизводима. Пример в редактировании всегда дает ровно 4,5, если вы не можете указать ситуацию, в которой это не так.   -  person Mr Lister    schedule 30.05.2019


Ответы (1)


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

#include <stdio.h>
#include <math.h>

int main(int argc, char * argv[]) {
  float i = 5.3 / 4.7;
  float j = 5.3 / 4.7;

  printf("i %f \n", round(i * 10000.0) / 10000.0);
  printf("j %f \n", round(j * 10000.0) / 10000.0);


  return 0;
}
person Quan Shi    schedule 29.05.2019
comment
О... вам нужно только целое число. Тогда раунд - это все, что вам нужно... для c... для С++, я думаю, std::round() - это то, что вам нужно, как говорили другие. - person Quan Shi; 29.05.2019
comment
Это ответ C, а не C++ - person KPCT; 29.05.2019