Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Димчанский, Вы писали:
Д>>Здравствуйте, Кодт, Вы писали:
К>>>К>>>double round(double x, double accuracy)
К>>>{
К>>> assert(accuracy > 0);
К>>> return floor(x / accuracy + 0.5) * accuracy;
К>>>}
К>>>
Д>>Я бы переписал код так:
Д>>Д>>double round(double x, double accuracy)
Д>>{
Д>> assert(accuracy > 0);
Д>> if(x<0)
Д>> return ceil(x / accuracy - 0.5) * accuracy;
Д>> return floor(x / accuracy + 0.5) * accuracy;
Д>>}
Д>>
Д>>Так как в противном случае возникает неопределенность:
Д>>round(-1.5, 1.0) = -1.0 (должно бы получиться -2.0)
Д>>в то время как
Д>>round(1.5, 1.0) = 2.0
Д>>В MatLab round работает "одинаково" как для отрицательных чисел, так и для положительных.
J>неправильно работает
J>по определению операции округления, действительное число округляется до целого х, если оно попадает в [x-0.5, x+0.5), независимо от знака.
а то, что ты написал, это
sign(x) * round(abs(x))
Здравствуйте, orangy, Вы писали:
O>O>template<typename T> int round(T value) { return int(value + 0.5); }
O>
Здесь есть один тонкий момент, оператор преобразования (int)value,
будет реализован как загрузка value в регистр сопроцессора,
и выгрузка его в память как целое значение.
При выгрузке регистра его значение может быть преобразовано в целое
различными способами (в большую строну, меньшую или округление),
это будет зависеть от состояния флагов сопроцессора.
Вообщем, нет гарантии, что (int) все время будет возвращаеть ближайщее целое снизу.
И потом, я не видел, чтобы стандарт C++ явно указывал на то
как должен работать оператор (int).
Здравствуйте, _Vladimir_, Вы писали:
_V_>Здравствуйте, orangy, Вы писали:
O>>O>>template<typename T> int round(T value) { return int(value + 0.5); }
O>>
_V_>Здесь есть один тонкий момент, оператор преобразования (int)value,
_V_>будет реализован как загрузка value в регистр сопроцессора,
_V_>и выгрузка его в память как целое значение.
_V_>При выгрузке регистра его значение может быть преобразовано в целое
_V_>различными способами (в большую строну, меньшую или округление),
_V_>это будет зависеть от состояния флагов сопроцессора.
_V_>Вообщем, нет гарантии, что (int) все время будет возвращаеть ближайщее целое снизу.
_V_>И потом, я не видел, чтобы стандарт C++ явно указывал на то
_V_>как должен работать оператор (int).
[conv.fpint] 4.9 Floating-integral conversions
1 An rvalue of a floating point type can be converted to an rvalue of an integer type. The conversion truncates; that is, the fractional part is discarded.
так что по умолчанию происходит sign(x)*floor(abs(x))
Здравствуйте, jazzer, Вы писали:
Д>>В MatLab round работает "одинаково" как для отрицательных чисел, так и для положительных.
J>неправильно работает
J>по определению операции округления, действительное число округляется до целого х, если оно попадает в [x-0.5, x+0.5), независимо от знака.
Что-то я старею. Действительно такое определение округления?
J>а то, что ты написал, это
J>sign(x) * round(abs(x))
Я-то, наивный, думал, что такой раунд — стандарт, раз даже в MatLab он так работает.
... << Rsdn@Home 1.1.4 beta 1 >>