![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Округление. [D6, IB6.x, FireBird]
IlyaA © (2002-07-25 11:15:00)Как мне вылечить след. случай. Есть у меня два поля Numeric(8,2) в разных таблицах и я при выборке вычитаю из одного сумму по другому. Так вот на приммер получаю 12-11,35=0,6498456213
IlyaA (2002-07-25 14:02:00) [1]>ALL ЗАРУЛИЛОСЬ. Сделал CAST(<выр.> as demical(8,2)) и всё заработало.
Извините, что сам не догодался. Заработался наверное!?! Было интересно почитать дискуссии. Всем спасибо!
kaif (2002-07-25 13:49:00) [2]Да, действительно.
(Alexandr © (25.07.02 13:11)
>все правильно но надо напомнить, что как интегер хранится >только в третьем диалекте.)
А диалект какой?
Я кстати, не утверждаю, что это не ошибка Firebird. Просто ошибка интерпретации типаполя в пределах полей в select и ошибка вычислений, ИМХО, разные вещи. Ошибки интерпретации типа поля в IB бывают, но они не криминальны, так как убираются использованием cast внутри текста запроса. Например:
select a - cast(sum(b) as decimal(8,2)) from...
А с точки зрения двоичной записи с фиксированной точкой, возможно, что
12-11,35==0,6498456213
совершенно верно.
AlexanderVasjuk (2002-07-25 13:32:00) [3]cast(X * 100 as integer) / 100 даст нужное тебе округление
Пальма (2002-07-25 13:29:00) [4]>kaif © (25.07.02 12:52)
>А ты пробовал результат разности привести к типу numeric(8,2),
>просто cast(... as numeric(8,2))?
Не поможет...
Alexandr (2002-07-25 13:11:00) [5]все правильно но надо напомнить, что как интегер хранится только в третьем диалекте.
kaif (2002-07-25 13:06:00) [6]2 Viewer (25.07.02 12:57)
Decimal(18,2) хранится не как double, а как Int64. То еть по размеру столько же байт, но не в виде мантиссы и порядка. По-моему так... Или я что-то не так понимаю в документации (не исключено).
Viewer (2002-07-25 12:57:00) [7]Для Decimal(18,2) IB однозначно выбирает double тип. Отсюда и погрешность минимальная.
kaif (2002-07-25 12:52:00) [8]А ты пробовал результат разности привести к типу numeric(8,2), просто cast(... as numeric(8,2))? Может, это ошибка разбора типов внутри запроса, а не ошибка вычисления. То есть IB Просто результат выдает в формате Float.
У меня суммируются около 35тыс чисел Decimal(18,2) абсолютно корректно, без погрешностей. Для того я и перешел на IB6
Praco (2002-07-25 12:17:00) [9]Только UDF
http://ib.demo.ru/DevInfo/round.htm
Viewer (2002-07-25 12:02:00) [10]Если нужна высокая точность хранения используй double
Sergey13 (2002-07-25 12:00:00) [11]Что то я ни на дибазе ни на Оракле с этой проблемой не сталкивался. Там всегда 3.14-3.14=0 а не 0.00000000х как IB. Меня как разработчика приложений мало волнует как они там хранятся, мне важно доверять результатам хранения, а в данном случае доверять им нельзя, т.к. поле нумерик(8.2) содержит "на самом деле" 0.000000х - что в принципе нонсенс.
Johnmen (2002-07-25 11:53:00) [12]>Sergey13 © (25.07.02 11:42)
Да нет никакой проблемы ! Или она надуманна !
Вещественные числа хранятся как положено в двоичном разложении.
Отсюда погрешности разрядной сетки. Зато скорость работы с ними максимальна, в отличие от др.способов хранения (напр.в виде строки в dbf).
Sergey13 (2002-07-25 11:42:00) [13]Я с этим маюсь на IB4.2, думал мигрировать на новые версии именно поэтому. Оказывается проблема не решена и в 6.х 8-( Как то странно Борланды хранят числа.
Я решил для себя проблему через UDF - просто сляпал ф-ю ROUND и применяю везде где можно или нужно. Тормознее конечно - но деваться некуда. 8-(
Johnmen (2002-07-25 11:29:00) [14]А сумма здесь 11.35 ?
Просто это ты ее видишь в соответствии с типом, а на самом деле она 11.35xxxxxxxxxx
Viewer (2002-07-25 11:25:00) [15]Попробуй перейти на тип Decimal.
Numeric и Decimal - виртуальные типы. Для конкретного случая физическое представление может быть даже smallint