![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вещественные числа и округление [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]Потому как число с ПЛАВАЮЩЕЙ точкой. Это особенности его хранения. Хочешь точности, используй с ФИКСИРОВАННОЙ точкой.