Я использую NS-3 (написанный на c ++) для имитации сетевого окружения.
Я использую его класс flowmonitor для записи показателей производительности по беспроводной связи.
Одна вещь, которую я собираю, — это разница во времени между текущей и предыдущей задержкой пакета или «дрожанием».
Чтобы получить это, я вычитаю значение времени (преобразованное в двойную переменную) из одной задержки пакета в предыдущее значение.
т.е.
0,0159051 — 0,0158002 = 0,0001049
Однако через некоторое время математика выглядит очень странно, например:
0,0159003 — 0,0158007 = 9,95972e-05
когда ответ должен быть явно 0,0000996
Чтобы уточнить дальше, я изначально использовал функцию diff, чтобы найти разницу.
template <typename T1, typename T2>
double diff(const T1& lhs, const T2& rhs)
{
std::cout << lhs << " - " << rhs << std::endl;
return lhs - rhs;
}
Но так как я обнаружил ошибку, я попробовал прямое вычитание, но я получаю ту же ошибку.
Формат с плавающей точкой использует двоичное представление мантиссы и экспоненты, он не может точно выражать каждую десятичную (десятичную) числовую дробь, и его точность ограничена, поэтому обязательно проверьте, может ли двойной формат точно представлять ваши значения. Подробнее о двойном формате здесь, в Википедии. Есть еще вопросы о точности с плавающей точкой при переполнении стека, проверьте этот и другие, связанные с этим.
Есть некоторые последствия:
(1.0+2.0)==3.0
мог бы работать, но ни один более сложный расчет с дробями не мог сравниться равным …Вещественные числа простираются от + бесконечности до — бесконечности с бесконечно малыми промежутками между числами. Это невозможно представить все действительные числа в конечном хранилище.
Чтобы обойти эту проблему, компьютер хранит величину числа (как показатель степени) и ряд значащих цифр (мантисса). Это похоже на написание числа как 1,043 X 10 ^ -5.
Поскольку хранилище не является точным, вы получите ошибки округления, и эти ошибки округления могут иногда быть существенными. Это означает, что вы не можете реально сравнить два действительных числа на компьютере. В лучшем случае можно сказать, что они лежат ближе, чем данная толерантность.
Чтобы проиллюстрировать это, возьмите 1.000, делите на 3, а затем умножьте на 3, вы должны вернуться к 1.000, но, поскольку 1.000 / 3 = от 0.333 до 3 десятичных знаков, не удивляйтесь, если результат будет 0.999. (Компьютеры используют бинарный файл (база 2), так что это может сработать иначе, но точка зрения остается неизменной)