Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вещественные числа и округление [D7]


Juice ©   (2007-01-26 13:36:00) 

Помогите пожалуйста понять следующую проблему. В ячейку грида вносим число - 1.005. В AfterPost нужно округлять вносимую в эту колонку величину до копеек методом арифметического округления и присвоить результат переменной.

Округление на 1,005 постоянно выдавало 1 (пробовал как на стандартной SimpleRoundTo так и на сторонней DecimalRoundExt). Провел єксперимент:


 x, y : Extended;
begin
x := DataSet.FieldByName('PriceEval').Value;
 y := DataSet.FieldByName('PriceEval').AsFloat;
 if (DataSet.FieldByName('PriceEval').Value) < 1.005 then ShowMessage('Value<1.005');
 if (DataSet.FieldByName('PriceEval').Value) > 1.005 then ShowMessage('Value>1.005');
 if (DataSet.FieldByName('PriceEval').Value) = 1.005 then ShowMessage('Value=1.005');

 if (DataSet.FieldByName('PriceEval').AsFloat) < 1.005 then ShowMessage('AsFloat<1.005');
 if (DataSet.FieldByName('PriceEval').AsFloat) > 1.005 then ShowMessage('AsFloat>1.005');
 if (DataSet.FieldByName('PriceEval').AsFloat) = 1.005 then ShowMessage('AsFloat=1.005');

 if x < 1.005 then ShowMessage('x<1.005');
 if x > 1.005 then ShowMessage('x>1.005');
 if x = 1.005 then ShowMessage('x=1.005');

 if y < 1.005 then ShowMessage('y<1.005');
 if y > 1.005 then ShowMessage('y>1.005');
 if y = 1.005 then ShowMessage('y=1.005');


Результат :

Value=1.005
АsFloat<1.005
x<1.005
y<1.005


Вопрос: почему "Value =" а "AsFloat<" ???

И еще :
z := DataSet.FieldByName('PriceEval').Value;
x < 1.005 = true
т.е. в результате даже присвоения переменной меняется значение, но почему? Ведь z по типу extended, самый широкий ?


Juice   (2007-01-26 18:16:00) [1]


> Float - это число, а не деньги. В нем нет копеек.
> Еще раз: используй фиксированный формат, а не пытайся заниматься
> проктологией.

Я согласен на все сто, я и сам в финансовых вычислениях currency использую. Просто для себя хотелось разобраться, причину такого поведения я для себя уяснил, число не выражается конечной двоичной дробью и отсюда все проблемы. Интересно таки как же округлять числа с плавающей точкой ? Вот FloatToStr к примеру все правильно показывает, значит умеет правильно округлять.


> странно, и в примере вот тоже написано
> RoundTo(1.235, -2) 1.24
>
> и так и есть.
> А
> RoundTo(1.005, -2) 1

Это банковское округление


Vlad Oshin   (2007-01-26 16:02:00) [2]

странно, и в примере вот тоже написано
RoundTo(1.235, -2) 1.24

и так и есть.
А
RoundTo(1.005, -2) 1

правда, можно решить используя бесконечно малую :)
RoundTo(1.0050000000000001, -2) 1

SetRoundMode или тут поковырять, может и есть что


Desdechado   (2007-01-26 15:28:00) [3]

> А как решить простую практическую задачу - правильно округлить float-значение до копеек ?
Float - это число, а не деньги. В нем нет копеек.
Еще раз: используй фиксированный формат, а не пытайся заниматься проктологией.


Juice   (2007-01-26 14:17:00) [4]


> Прочти и раскрась
> http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1217

Спасибо, но читал уже и не раз, то что стандартные лагают знаю из собственного опыта. Но вот проблема, повторюсь, как правильно округлить float-значение ? Рекомендуемая автором той статьи DecimalRoundExt(n, 2, drHalfUp) by John Herbsterтоже дает 1. ???


icWasya   (2007-01-26 14:07:00) [5]

Прочти и раскрась
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1217


Juice   (2007-01-26 14:05:00) [6]


> Потому как число с ПЛАВАЮЩЕЙ точкой. Это особенности его
> хранения. Хочешь точности, используй с ФИКСИРОВАННОЙ точкой.
>

Это понятно, меня эта особенность и интересовала.
А как решить простую практическую задачу - правильно округлить float-значение до копеек ?


Desdechado   (2007-01-26 14:00:00) [7]

Потому как число с ПЛАВАЮЩЕЙ точкой. Это особенности его хранения. Хочешь точности, используй с ФИКСИРОВАННОЙ точкой.


Наверх

Титульная страница Поиск, карта сайта Написать письмо