Я делал некоторые домашние проблемы из своего учебника и имел несколько вопросов о округлении/точности с плавающей точкой для определенных арифметических операций.Сложение/умножение с плавающей запятой/Подразделение
Если я отлиты двойников из междунар так:
int x = random();
double dx = (double) x;
И скажем переменные у, г, ду и дг в том же формате.
Тогда бы такие операции, как:
(dx + dy) + dz == dx + (dy + dz)
(dx * dy) * dz == dx * (dy * dz)
ассоциативными? Я знаю, что если у нас есть дробные представления, то это не будет ассоциативно, потому что некоторая точность будет потеряна из-за округления в зависимости от того, какие операнды добавляют/умножают друг друга. Однако, поскольку они выбрасываются из ints, я чувствую, что точность не будет проблемой и что они могут быть ассоциативными?
И, наконец, учебник я использую не объясняет FP разделение вообще так мне было интересно, если это утверждение верно, или, по крайней мере, просто как с плавающей точкой подразделение работает в целом:
dx/dx == dz/dz
I посмотрел это онлайн, и я читал в некоторых областях, таких как операция, как 3/3, может дать 0,999 ... 9, но не было достаточной информации, чтобы объяснить, как это произошло, или если это будет отличаться от других операций деления.
Хороший компилятор должен распознать dx/dx и фактически не выдавать инструкции разделения. –
Вы можете точно представить любое значение до 2^53 + 1 как двойное. Кроме того, вы сталкиваетесь с ошибками округления, даже для целочисленных типов. http://stackoverflow.com/a/1848762/141172 –
, вы, возможно, помните, что из ваших школьных дней число, разделенное само по себе, равно 1, поэтому сравнение «может» работать. Однако, как правило, число с плавающей запятой никогда не должно сравниваться с использованием «==» вместо этого, получить абсолютные значения, получить разницу, проверить, чтобы разница была меньше, чем какая-то трехосадка – user3629249