Страница 1 из 2

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

Добавлено: 04 дек 2006, 14:53
Dedal
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

почему так ?

Добавлено: 04 дек 2006, 15:09
kdv
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

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

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

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

Добавлено: 04 дек 2006, 16:00
kdv
Или это так принципиально для Вас ???
это принципиально для проекта Firebird.

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

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

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

Добавлено: 04 дек 2006, 20:10
Merlin
Да ты уж сам колись, дядюшка Ау, блин :)

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

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

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

Добавлено: 05 дек 2006, 21:18
kdv
произвел тест. 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.

Добавлено: 05 дек 2006, 21:29
kdv
кстати, я повторил свой тест с 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

то есть, при четырех знаках баг исправили, а при пяти - появился новый глюк.

Добавлено: 05 дек 2006, 21:34
Merlin
От же ж настырный...

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

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 с вытекающими отсюда потерями точности при вычислениях.

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

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

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

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

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

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

338.87
338.87

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

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

Добавлено: 05 дек 2006, 22:30
Merlin
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, вестимо. Если сумлеваешься насчёт параметров - щас перехреначу на переменные с присвоениями констант в теле, пажди минутку.

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

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