Возникла проблема округления в процедуре FIREBIRD 5. В таблице есть поле типа FLOAT. Имеет значения от 1.00 до 1.60 через 0.1. Процедура возвращает нехорошие значения. Т.е. не соответствуют значениям посчитаным вручную. Прошел под IBEXPERT в отладке. Вместо 1.00 увидел 1.0139 для этого поля после чтения из таблицы... Где я не прав? Хотя по документации: Тип данных FLOAT по умолчанию представляет собой 32-битный тип с плавающей запятой одинарной точности с приблизительной точностью 7 десятичных знаков после десятичной точки (24 двоичных знака). Числа типа FLOAT находятся в диапазоне от 1.175 x 10-38 до 3.402 x 1038.
Ты путаешь точность отдельно взятого числа и точность серии расчётов пачки таких чисел. Переходи на точные числа, раз у тебя шаг фиксированный.
SD писал(а) Mon, 23 February 2026 15:22 Ты путаешь точность отдельно взятого числа и точность серии расчётов пачки таких чисел. Переходи на точные числа, раз у тебя шаг фиксированный. Вы меня, наверное, не поняли.... я Записал в поле FLOAT 1.100 Почему я на чтении получаю этот результат? Еще раз повторяю - на ЧТЕНИи. И через ibexpert....
Ты путаешь точность отдельно взятого числа и точность серии расчётов пачки таких чисел. Я не путаю... Я нашел поле типа FLOAT которое мне возвращает для меня очень удивительное значение... И дальше летит к какой то матери все мои расчеты и округления....
Потому что это FLOAT. Он так устроен. Он так работает. Никогда не используй его. Ну или жалуйся Хвастунову: SQL> create table fl (f float); SQL> insert into fl values(1.100); SQL> select * from fl; F ============== 1.1000000
Влазит, конечно. Но я склоняюсь к тому, что это ошибка самой БД. И именно при select в процедуре, а может и функциях. Объявление принимающей переменной (например NUMERIC(15,3)) для поля FLOAT - ничего не меняет. Просто отсекаются лишние цифирьки. Ошибка составляет 1-2%. Это недопустимо. И, наверняка, ее нужно исправлять...
"А может быть корова... А может бегемот." (с) "Воспроизводимый пример есть?" (с) Вон у меня выше в скрипте никакие лишние циферки не появляются.
Если Вы прочитаете первое мое сообщение - я просил помощи... А вместо помощи - хамство... У меня select на таблицу с FLOAT возвращает такие-же красивые результаты... А в процедуре - имею другой результат... Буду пытаться сделать воспроизводимый пример. Оригинальный Select просто собирает данные с энного количества таблиц... P.S. Select генериться в процедуре и выполняется через execute statement...
Процедура секретная? Без кода все эти утверждения о баге бла-бла-бла. Ну и numeric(15,3) в первом диалекте таки хранится как double precision, а не float. А если это не первый диалект, тогда вообще не понимаю ваше упорство с float. Уж если без чисел с плавающей запятой не обойтись, то используйте хотя бы double precision
bsa1959 писал(а) Tue, 24 February 2026 14:35 Если Вы прочитаете первое мое сообщение - я просил помощи... А если Вы перечитаете моё первое сообщение, то там написано полное описание корня проблемы и её решение. bsa1959 писал(а) Tue, 24 February 2026 14:35 Оригинальный Select просто собирает данные с энного количества таблиц... То есть, как и было мною сказано: большое количество неточных чисел складываются вместе с помощью кучи арифметики и как результат - изначальная приближённость FLOAT дорастает до третьего знака после запятой.
Просто напомню, что стандартный способ улучшить точность сложения ряда вещественных чисел с большой разницей порядков (мантиссы) - складывать от меньших к бОльшим. В PSQL это будет курсор для select с order by.
bsa1959 писал(а) Mon, 23 February 2026 08:46 Прошел под IBEXPERT в отладке. Вместо 1.00 увидел 1.0139 для этого поля после чтения из таблицы... Где я не прав? Без примера не сказать. Плюс это может быть и глюк в отладчике. Сделайте сохранение промежуточных результатов в какую-нибудь временную таблицу, так вернее будет.
ggreggory писал(а) Wed, 25 February 2026 22:48 bsa1959 писал(а) Mon, 23 February 2026 08:46 Прошел под IBEXPERT в отладке. Вместо 1.00 увидел 1.0139 для этого поля после чтения из таблицы... Где я не прав? Без примера не сказать. Плюс это может быть и глюк в отладчике. Сделайте сохранение промежуточных результатов в какую-нибудь временную таблицу, так вернее будет. Очень хотелось бы - глюк в отладчике... Но в production имею такие-же цифры... Из-за этого - так задергался.... С++Builder 37, FIBPlusVersion:integer = 7; FIBPlusBuild:integer = 632; FIBPlusBuildDate = '17.02.2014'; FIBCustomBuild:integer = 3171; Firebird WI-V6.3.3.1683 Firebird 5.0 Client library version 5.0.1.1469 Может эта информация позволит Вам вывести меня на чистую воду?
Для тех, кто в школе или институте прогулял уроки понятия "точность": У вас есть число с точностью ±0.5е-7. Вы складываете тысячу таких чисел и получаете результат с точностью ±0.5е-4. На ста тысячах это уже даст искомое расхождение во втором знаке после запятой. Ещё хуже ситуация с умножением, где отклонение не складывается, а возводится в степень.
bsa1959 писал(а) Thu, 26 February 2026 18:49 Может эта информация позволит Вам вывести меня на чистую воду? Это вообще никак не поможет. Выкладывайте воспроизводимый пример.
Да хотя бы min/max значения приведите. Что там такое космическое складываете? P.S. Помню старый совет - не хранить суммы в рублях.копейках, а переводить в копейки и хранить все в INT. С учетом BIGINT/INT128 в FB5 - в такое поле можно много чего запихнуть.
https://www.ibase.ru/round/ К сожалению, великолепные 2 статьи на delphikingdom про точность и округление вещественных чисел уже потеряны. Хотя, их можно найти в инете, скопированными. "Загадки округления" и "Неочевидные особенности вещественных чисел"
https://web.archive.org/web/20100114105218/http://delphiking dom.com/asp/viewitem.asp?catalogid=374