Может дело в том, что 123.345 он понимает как 123.3449999999999 и делает потом Trunc?
Как нормально округлить число? Писать свою функцию с использованием Round?
Hello, mlecter!
You wrote on Wed, 15 Sep 2004 13:57:07 GMT:
m> Делаю
m> SetRoundMode(rmNearest); m> RoundTo(123.345, -2)
m> Получаю
m> 123.34
m> причем, если передаю 1.245, то выдает 1.25
m> Может дело в том, что 123.345 он понимает как 123.3449999999999 и m> делает потом Trunc? m> Как нормально округлить число? Писать свою функцию с использованием m> Round?
Ого-го... Вот это да! Глюк у RoundTo на таких маленьких числах!
Помогло изменение функции RoundTo:
function RoundTo(const AValue: Extended {было Double}; const ADigit: TRoundToRange): Extended; {было Double}
var
LFactor: Extended; {было Double}
begin
LFactor := IntPower(10, ADigit);
Result := Round(AValue / LFactor) * LFactor;
end;
После изменений 1.245 стало округлять правильно — до 1.24 %)
Hello, mlecter!
You wrote on Wed, 15 Sep 2004 14:37:23 GMT:
m> Проблема в RoundMode m> Если даже стоит rmNearest округление происходит банковским методом. m> Можно ли округлять не банковским методом?
Можно!
Ручками. Но зачем?
Здравствуйте, mlecter, Вы писали:
M>Доброго времени суток! M>Есть такая проблема: M>Делаю
M>SetRoundMode(rmNearest); M>RoundTo(123.345, -2)
M>Получаю
M>123.34
M>причем, если передаю 1.245, то выдает 1.25
M>Может дело в том, что 123.345 он понимает как 123.3449999999999 и делает потом Trunc? M>Как нормально округлить число? Писать свою функцию с использованием Round?
Здравствуйте, AMogil, Вы писали:
AM>Здравствуйте, mlecter, Вы писали:
M>>Доброго времени суток! M>>Есть такая проблема: M>>Делаю
M>>SetRoundMode(rmNearest); M>>RoundTo(123.345, -2)
M>>Получаю
M>>123.34
M>>причем, если передаю 1.245, то выдает 1.25
M>>Может дело в том, что 123.345 он понимает как 123.3449999999999 и делает потом Trunc? M>>Как нормально округлить число? Писать свою функцию с использованием Round?
AM>SimpleRoundTo?
AM>Алексей.
Она округляет до большего, т.е. для положительных чисел все делает как мы привыкли.
Здравствуйте, mlecter, Вы писали:
M>Здравствуйте, AMogil, Вы писали:
AM>>>Алексей.
AM>>Она округляет до большего, т.е. для положительных чисел все делает как мы привыкли.
AM>>Алексей.
M>Не до большего, а до ближайшего четного. M>1.345 -> 1.34 M>1.355 -> 1.36
M>"Мы" так не привыкли
SimpleRoundTo uses asymmetric arithmetic rounding to determine how to round values that are exactly midway between the two values that have the desired number of significant digits. This method always rounds to the larger value.
Здравствуйте, AMogil, Вы писали:
AM>Здравствуйте, mlecter, Вы писали:
M>>Здравствуйте, AMogil, Вы писали:
AM>>>>Алексей.
AM>>>Она округляет до большего, т.е. для положительных чисел все делает как мы привыкли.
AM>>>Алексей.
M>>Не до большего, а до ближайшего четного. M>>1.345 -> 1.34 M>>1.355 -> 1.36
M>>"Мы" так не привыкли
AM>Пример из справки Delphi
AM>Expression Value
AM>SimpleRoundTo(1234567, 3) 1234000 AM>SimpleRoundTo(1.234, -2) 1.23 !!!!!!! AM>SimpleRoundTo(1.235, -2) 1.24 AM>SimpleRoundTo(-1.235, -2) -1.23
AM>И техт:
AM>SimpleRoundTo uses asymmetric arithmetic rounding to determine how to round values that are exactly midway between the two values that have the desired number of significant digits. This method always rounds to the larger value.
AM>>Пример из справки Delphi
AM>>Expression Value
AM>>SimpleRoundTo(1234567, 3) 1234000 AM>>SimpleRoundTo(1.234, -2) 1.23 !!!!!!! AM>>SimpleRoundTo(1.235, -2) 1.24 AM>>SimpleRoundTo(-1.235, -2) -1.23
AM>>И техт:
AM>>SimpleRoundTo uses asymmetric arithmetic rounding to determine how to round values that are exactly midway between the two values that have the desired number of significant digits. This method always rounds to the larger value.
AM>Попробуйте
AM>SetRoundMode(rmDown);
Спасибо, заработало
Хотя странно, SimpleRoundTo вроде не должен использовать RoundMode
function SimpleRoundTo(const AValue: Double; const ADigit: TRoundToRange = -2): Double;
var
LFactor: Double;
begin
LFactor := IntPower(10, ADigit);
Result := Trunc((AValue / LFactor) + 0.5) * LFactor;
end;
Здравствуйте, mlecter, Вы писали:
M>Здравствуйте, AMogil, Вы писали:
AM>>>Пример из справки Delphi
AM>>>Expression Value
AM>>>SimpleRoundTo(1234567, 3) 1234000 AM>>>SimpleRoundTo(1.234, -2) 1.23 !!!!!!! AM>>>SimpleRoundTo(1.235, -2) 1.24 AM>>>SimpleRoundTo(-1.235, -2) -1.23
AM>>>И техт:
AM>>>SimpleRoundTo uses asymmetric arithmetic rounding to determine how to round values that are exactly midway between the two values that have the desired number of significant digits. This method always rounds to the larger value.
AM>>Попробуйте
AM>>SetRoundMode(rmDown);
M>Спасибо, заработало M>Хотя странно, SimpleRoundTo вроде не должен использовать RoundMode
Тем более, что после того как я сделаю SetRoundMode(rmDown), RoundTo начинает все округлять (естественно) вниз, в то время как SimpleRoundTo начинает округлять нормально. Получается путанница...
Здравствуйте, Diouzshev, Вы писали:
m>> Проблема в RoundMode m>> Если даже стоит rmNearest округление происходит банковским методом. m>> Можно ли округлять не банковским методом? D>Можно!
В семерке есть функия
SimpleRoundTo function
Rounds a floating-point value to a specified digit or power of ten using asymmetric arithmetic rounding.