проблема округления

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Dedal
Сообщения: 26
Зарегистрирован: 11 янв 2006, 13:35

проблема округления

Сообщение Dedal » 04 дек 2006, 14:53

firebird 2.0 RC4
база 1 диалект
есть хранимая процедура из такими переменными:

temp - Numeric(15,2)
M3 - Numeric(9,2)
STO - Smallint
days - Smallint
hours - Smallint
PROC_STO - Numeric(9,2)
PRICE_K - Numeric(9,5)

при таком выражении:
temp=:STO*:days*:hours*:M3*:PROC_STO*:PRICE_K
получаю результат:
338.00=1*31*8*1.22*1.11666*1.00
а при таком:
temp=:STO*:days*:hours*:M3*:PRICE_K*:PROC_STO
резудьтат:
337.86=1*31*8*1.22*1.00*1.11666

почему так ?
Последний раз редактировалось Dedal 04 дек 2006, 16:42, всего редактировалось 1 раз.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 04 дек 2006, 15:09

firebird 2.0 RC4
почему RC4, скажи на милость?

целочисленная математика описана тут:
http://www.ibphoenix.com/main.nfs?a=ibp ... act_num_fs

правда, что-то и я вижу, что в FB 1.5.3
select 1.00*1.11666 from rdb$database
возвращает
1.0000000
а в cast as varchar(30) - как положено, нормальное "число".

Кстати
select cast(1.11666*1.00 as numeric(15,4)) from rdb$database
1.1167

select cast(1.11666*1.00 as numeric(15,5)) from rdb$database
1.00000

я тоже в недоумении, честное слово.

Dedal
Сообщения: 26
Зарегистрирован: 11 янв 2006, 13:35

Сообщение Dedal » 04 дек 2006, 15:53

почему RC4, скажи на милость?
Идет интенсивное проектирование базы данных, как только появитса свободная минута сразу закачаю и переставлю на финальную версию.
Или это так принципиально для Вас ???

За ссылку спасибо, может чтото там найду.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 04 дек 2006, 16:00

Или это так принципиально для Вас ???
это принципиально для проекта Firebird.

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 04 дек 2006, 19:48

kdv писал(а):правда, что-то и я вижу, что в FB 1.5.3
select 1.00*1.11666 from rdb$database
возвращает
1.0000000
Не вижу такого ни с 1.5.3, ни с 2.0, ни в 1-ом диалекте, ни в 3-м

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 04 дек 2006, 20:03

Не вижу такого ни с 1.5.3, ни с 2.0, ни в 1-ом диалекте, ни в 3-м
ф чем проверяишь? :D

hvlad
Разработчик Firebird
Сообщения: 1244
Зарегистрирован: 21 мар 2005, 10:48

Сообщение hvlad » 04 дек 2006, 20:07

kdv писал(а):
Не вижу такого ни с 1.5.3, ни с 2.0, ни в 1-ом диалекте, ни в 3-м
ф чем проверяишь? :D
В IBE вестимо :)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 04 дек 2006, 20:10

Да ты уж сам колись, дядюшка Ау, блин :)

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 04 дек 2006, 20:47

ну ладно, у меня IBE, хотя таких приколов я раньше не видел. но у него-то процедура.
тьфу, у него ж еще и 1-ый диалект.
собственно, я не знаю, в отношении вычислений в процедуре там баг или нет, но в диалекте 1 были какие-то бяки с перемножением как минимум целых чисел, да и вообще, не родной он начиная с IB6.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 04 дек 2006, 20:51

kdv писал(а):ну ладно, у меня IBE, хотя таких приколов я раньше не видел. но у него-то процедура.
В отладчике, штоль? Там и не такое бывает...
kdv писал(а): тьфу, у него ж еще и 1-ый диалект.
собственно, я не знаю, в отношении вычислений в процедуре там баг или нет,
Нет
kdv писал(а): но в диалекте 1 были какие-то бяки с перемножением как минимум целых чисел, да и вообще, не родной он начиная с IB6.
Я попрошу птичку нашу не обижать (С) :) Чё-т тебе примерещилось, бывает :) Бяки там были с арифметикой над строками. Давно.

Dedal
Сообщения: 26
Зарегистрирован: 11 янв 2006, 13:35

Сообщение Dedal » 05 дек 2006, 20:55

Этот глюк на старой базе, которую через b/r я перевел с 1.5.3 на 2.0.
База работала уже 2 года. Раньше все было ок. Но под второй птичкой вот такие глюки.
Глюки повторяються не только в ХП, но и в IBE. Только глюк присутствует, если есть все те операнды, что я перечислил. Если убрать хотябы один SMALINT операнд - то все считаеться как надо.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 дек 2006, 21:18

произвел тест. FB 1.5.3

Код: Выделить всё

create procedure nm
returns
(temp numeric(15,2))
as
declare variable m3 numeric(9,2);
declare variable sto smallint;
declare variable days smallint;
declare variable hours smallint;
declare variable proc_sto numeric(9,2);
declare variable price_k numeric(9,2);
begin
  sto=1;
  days=31;
  hours=8;
  m3=1.22;
  proc_sto=1.11666;
  price_k=1.00;
  temp = sto*days*hours*m3*proc_sto*price_k;
  suspend;
  temp = sto*days*hours*m3*price_k*proc_sto;
  suspend;
end
в диалектах 1 и 3 выдает одно и то же:
338.87
338.87

как видим, это ни с одним твоим результатом даже не совпадает. что-то там у тебя не то с типами данных. Или, возможно, вначале был один тип данных, а потом ты его поменял, и данные остались в прежнем формате, откуда и лезут глюки.

p.s. сделал идентичный тест в FB 2.0 RC4, в диалекте 1. Перекомпилировал процедуру. подсоединился повторно. Результат тот же самый - 338.87.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 дек 2006, 21:29

кстати, я повторил свой тест с numeric(15,4) в ISQL, нет такого глюка, как в IBE. Нормально округляет до 1.1167. Собственно, у меня IBE от 4 января 2006. Старенький уже, может в новом этот баг исправлен...

Кстати. Скачал IBE. 2006.11.26

select cast(1.11666*1.00 as numeric(15,5)) from rdb$database
1.11665

select cast(1.11666*1.00 as numeric(15,4)) from rdb$database
1.1167

то есть, при четырех знаках баг исправили, а при пяти - появился новый глюк.
Последний раз редактировалось kdv 05 дек 2006, 22:15, всего редактировалось 1 раз.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 дек 2006, 21:34

От же ж настырный...

Код: Выделить всё

Create Procedure Odna_Chort
(M3 Numeric (9,2),
 STO Smallint,
 days Smallint,
 hours Smallint,
 PROC_STO Numeric(9,2),
 PRICE_K Numeric(9,5))
Returns (Temp Numeric (15,2))
As
Begin
   temp=:STO*:days*:hours*:M3*:PROC_STO*:PRICE_K;
   Suspend;
   temp=:STO*:days*:hours*:M3*:PRICE_K*:PROC_STO;
   Suspend;
End

Firebird/linux Intel (access method), version "LI-V1.5.3.4842 Firebird 1.5"

select * from Odna_Chort(1.22,1,31,8,1.11666,1.00)

                  TEMP 
====================== 

                338.87 
                339.36 

Firebird/linux Intel (access method), version "LI-V2.0.0.12748 Firebird 2.0"

select * from Odna_Chort(1.22,1,31,8,1.11666,1.00)

                  TEMP 
====================== 

                338.87 
                339.36 

НЕФИГ СМОТРЕТЬ РЕЗУЛЬТАТЫ В ОТЛАДЧИКЕ ЭКСПЕРТА. ТАМ ДРУГИЕ ТИПЫ ДАННЫХ, не FB-шные, а дельфёвые, это же эмулятор. А если вопрос в том, почему от перестановки сомножителей вообще меняется результат, то курить мысль о том, что Numeric (9,2) - это внутри Integer с вытекающими отсюда потерями точности при вычислениях.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 дек 2006, 21:46

kdv писал(а): то есть, при четырех багах знак исправили
Ндя... Чем балуисси? Гленфеддишем али Курвуазьём? ;) У меня 2005.02.14.2. полёт нормальный. Потому и не скачиваю новые - знакомый буг луччи новых двух (С)

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 дек 2006, 22:10

НЕФИГ СМОТРЕТЬ РЕЗУЛЬТАТЫ В ОТЛАДЧИКЕ ЭКСПЕРТА. ТАМ ДРУГИЕ ТИПЫ ДАННЫХ
гм, это ты кому? Я этот отдладчик если и запускал, то последний раз года четыре назад, и то чтобы в какой-то отладчиковый баг тыкнуть.

Ндя... Чем балуисси? Гленфеддишем али Курвуазьём?
Солнечным. В пражском дютифри пришлось бехеровкой сувенирной затариваться. Все на подарки пошло.
TEMP
======================

338.87
339.36
я хренею. ну хошь я тебе в третьем диалекте то же самое из ISQL дам?

Database: d:\firebird\examples\employee.fdb
SQL> select * from nm;

TEMP
=====================

338.87
338.87

И то же самое у меня ISQL и в 1-ом диалекте выдает.
У тебя-то что за хрень???

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 дек 2006, 22:14

У тебя-то что за хрень???
Кстати, да, твой вариант с входными параметрами дает разницу. Мой - нет. Что в первом что в 3-ем диалекте. Пора подмогу звать, нечистое дело...
Правда, я подозреваю что твой вариант имеет проблемы с преобразованием входных значений в параметры. Но тогда непонятно, почему мой вариант разницу не дает.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 05 дек 2006, 22:30

kdv писал(а):
НЕФИГ СМОТРЕТЬ РЕЗУЛЬТАТЫ В ОТЛАДЧИКЕ ЭКСПЕРТА. ТАМ ДРУГИЕ ТИПЫ ДАННЫХ
гм, это ты кому?
ФСЕМ, БЛИН!!! :-D Главным образом вопрошающему, конечно.

kdv писал(а): я хренею. ну хошь я тебе в третьем диалекте то же самое из ISQL дам?

Database: d:\firebird\examples\employee.fdb
SQL> select * from nm;

TEMP
=====================

338.87
338.87
А я всегда говорил, что 3-й от лукавого :-D
kdv писал(а): И то же самое у меня ISQL и в 1-ом диалекте выдает.
А вот это по меншей мере странно... Поди не на ту базу таки натравил, под Солнечный-то ;)
kdv писал(а): У тебя-то что за хрень???
А то ты не знаешь ;) WISQL, вестимо. Если сумлеваешься насчёт параметров - щас перехреначу на переменные с присвоениями констант в теле, пажди минутку.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 06 дек 2006, 00:09

виноват. Влад мне указал на ошибку. я в процедуре price_k не тот тип дал. результат совпадает с тем что у вас в 1-м диалекте, и получается 337.86 (2 раза) в 3-ем диалекте.

Dedal
Сообщения: 26
Зарегистрирован: 11 янв 2006, 13:35

Сообщение Dedal » 06 дек 2006, 12:24

ФСЕМ, БЛИН!!! Главным образом вопрошающему, конечно.
Помоему я ниразу не писал что смотрел в отладчике. Хранимая процедура заносит даные в таблицу, там и смотрел результаты.
То же самое дает при select 31*8*1.22*1.11666*1 from rdb$database
в IBE и isql.

Ответить