проблема округления
проблема округления
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
почему так ?
база 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 раз.
почему RC4, скажи на милость?firebird 2.0 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
я тоже в недоумении, честное слово.
ну ладно, у меня IBE, хотя таких приколов я раньше не видел. но у него-то процедура.
тьфу, у него ж еще и 1-ый диалект.
собственно, я не знаю, в отношении вычислений в процедуре там баг или нет, но в диалекте 1 были какие-то бяки с перемножением как минимум целых чисел, да и вообще, не родной он начиная с IB6.
тьфу, у него ж еще и 1-ый диалект.
собственно, я не знаю, в отношении вычислений в процедуре там баг или нет, но в диалекте 1 были какие-то бяки с перемножением как минимум целых чисел, да и вообще, не родной он начиная с IB6.
В отладчике, штоль? Там и не такое бывает...kdv писал(а):ну ладно, у меня IBE, хотя таких приколов я раньше не видел. но у него-то процедура.
Нетkdv писал(а): тьфу, у него ж еще и 1-ый диалект.
собственно, я не знаю, в отношении вычислений в процедуре там баг или нет,
Я попрошу птичку нашу не обижать (С) Чё-т тебе примерещилось, бывает Бяки там были с арифметикой над строками. Давно.kdv писал(а): но в диалекте 1 были какие-то бяки с перемножением как минимум целых чисел, да и вообще, не родной он начиная с IB6.
Этот глюк на старой базе, которую через b/r я перевел с 1.5.3 на 2.0.
База работала уже 2 года. Раньше все было ок. Но под второй птичкой вот такие глюки.
Глюки повторяються не только в ХП, но и в IBE. Только глюк присутствует, если есть все те операнды, что я перечислил. Если убрать хотябы один SMALINT операнд - то все считаеться как надо.
База работала уже 2 года. Раньше все было ок. Но под второй птичкой вот такие глюки.
Глюки повторяються не только в ХП, но и в IBE. Только глюк присутствует, если есть все те операнды, что я перечислил. Если убрать хотябы один SMALINT операнд - то все считаеться как надо.
произвел тест. FB 1.5.3
в диалектах 1 и 3 выдает одно и то же:
338.87
338.87
как видим, это ни с одним твоим результатом даже не совпадает. что-то там у тебя не то с типами данных. Или, возможно, вначале был один тип данных, а потом ты его поменял, и данные остались в прежнем формате, откуда и лезут глюки.
p.s. сделал идентичный тест в FB 2.0 RC4, в диалекте 1. Перекомпилировал процедуру. подсоединился повторно. Результат тот же самый - 338.87.
Код: Выделить всё
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
338.87
338.87
как видим, это ни с одним твоим результатом даже не совпадает. что-то там у тебя не то с типами данных. Или, возможно, вначале был один тип данных, а потом ты его поменял, и данные остались в прежнем формате, откуда и лезут глюки.
p.s. сделал идентичный тест в FB 2.0 RC4, в диалекте 1. Перекомпилировал процедуру. подсоединился повторно. Результат тот же самый - 338.87.
кстати, я повторил свой тест с 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
то есть, при четырех знаках баг исправили, а при пяти - появился новый глюк.
Кстати. Скачал 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 раз.
От же ж настырный...
НЕФИГ СМОТРЕТЬ РЕЗУЛЬТАТЫ В ОТЛАДЧИКЕ ЭКСПЕРТА. ТАМ ДРУГИЕ ТИПЫ ДАННЫХ, не FB-шные, а дельфёвые, это же эмулятор. А если вопрос в том, почему от перестановки сомножителей вообще меняется результат, то курить мысль о том, что Numeric (9,2) - это внутри Integer с вытекающими отсюда потерями точности при вычислениях.
Код: Выделить всё
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
гм, это ты кому? Я этот отдладчик если и запускал, то последний раз года четыре назад, и то чтобы в какой-то отладчиковый баг тыкнуть.НЕФИГ СМОТРЕТЬ РЕЗУЛЬТАТЫ В ОТЛАДЧИКЕ ЭКСПЕРТА. ТАМ ДРУГИЕ ТИПЫ ДАННЫХ
Солнечным. В пражском дютифри пришлось бехеровкой сувенирной затариваться. Все на подарки пошло.Ндя... Чем балуисси? Гленфеддишем али Курвуазьём?
я хренею. ну хошь я тебе в третьем диалекте то же самое из ISQL дам?TEMP
======================
338.87
339.36
Database: d:\firebird\examples\employee.fdb
SQL> select * from nm;
TEMP
=====================
338.87
338.87
И то же самое у меня ISQL и в 1-ом диалекте выдает.
У тебя-то что за хрень???
Кстати, да, твой вариант с входными параметрами дает разницу. Мой - нет. Что в первом что в 3-ем диалекте. Пора подмогу звать, нечистое дело...У тебя-то что за хрень???
Правда, я подозреваю что твой вариант имеет проблемы с преобразованием входных значений в параметры. Но тогда непонятно, почему мой вариант разницу не дает.
ФСЕМ, БЛИН!!! Главным образом вопрошающему, конечно.kdv писал(а):гм, это ты кому?НЕФИГ СМОТРЕТЬ РЕЗУЛЬТАТЫ В ОТЛАДЧИКЕ ЭКСПЕРТА. ТАМ ДРУГИЕ ТИПЫ ДАННЫХ
А я всегда говорил, что 3-й от лукавогоkdv писал(а): я хренею. ну хошь я тебе в третьем диалекте то же самое из ISQL дам?
Database: d:\firebird\examples\employee.fdb
SQL> select * from nm;
TEMP
=====================
338.87
338.87
А вот это по меншей мере странно... Поди не на ту базу таки натравил, под Солнечный-тоkdv писал(а): И то же самое у меня ISQL и в 1-ом диалекте выдает.
А то ты не знаешь WISQL, вестимо. Если сумлеваешься насчёт параметров - щас перехреначу на переменные с присвоениями констант в теле, пажди минутку.kdv писал(а): У тебя-то что за хрень???