Информация об изменениях

Сообщение Re[5]: Вопрос на элегантность решения от 13.10.2014 17:57

Изменено 13.10.2014 17:59 watchmaker

Здравствуйте, Muxa, Вы писали:

M>В интах-то?

M>Насколько я знал такое может быть только при делении на float константу
Забавно, но вот как раз с float так не всегда получается — если вместо деления на d делать умножение на (1.0/d), то результат, как правило, отличается результата простого деления и обладает худшей точностью. Это связано с тем, что происходит лишнее округление при вычислении константы (1.0/d), ведь, как правило, это число не представимо точно. Так что обычно компиляторы вычисляют выражения с плавающей запятой практически ровно как они записаны, ведь даже внешне незначительные преобразования, вроде изменения порядка слагаемых в сумме, порой приводят к значительному изменению результата. И у компилятора недостаточно знаний о том, действительно-ли в данной формуле нужно строго соблюдать порядок операций или можно её преобразовать ради увеличения скорости. Собственно, тут всё решает программист и только он может сообщить компилятору, что (a/b) == a*(1/b) (например, путём указания соответствующих опций вроде ключа -ffast-math в gcc).
А вот с делением целого на целочисленную константу такого выбора не стоит — там всегда достигается истинный результат.
Re[5]: Вопрос на элегантность решения
Здравствуйте, Muxa, Вы писали:

M>В интах-то?

M>Насколько я знал такое может быть только при делении на float константу
Забавно, но вот как раз с float так не всегда получается — если вместо деления на d делать умножение на (1.0/d), то результат, как правило, отличается от результата простого деления и обладает худшей точностью. Это связано с тем, что происходит лишнее округление при вычислении константы (1.0/d), ведь, как правило, это число не представимо точно. Так что обычно компиляторы вычисляют выражения с плавающей запятой практически ровно как они записаны, ведь даже внешне незначительные преобразования, вроде изменения порядка слагаемых в сумме, порой приводят к значительному изменению результата. И у компилятора недостаточно знаний о том, действительно-ли в данной формуле нужно строго соблюдать порядок операций или можно её преобразовать ради увеличения скорости. Собственно, тут всё решает программист и только он может сообщить компилятору, что (a/b) == a*(1/b) (например, путём указания соответствующих опций вроде ключа -ffast-math в gcc).
А вот с делением целого на целочисленную константу такого выбора не стоит — там всегда достигается истинный результат.