powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / округление
25 сообщений из 31, страница 1 из 2
округление
    #40005764
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!
Подскажите пожалуйста, почему функция округления возвращает не то значение, которое я ожидаю..
FB 2.5
поле price типа numeric(15,2).
значение = 125.
делаю запрос:
Код: sql
1.
select 77.2774*price from ...


возвращает 9659.675. это правильно. калькулятор тоже так считает.

делаю округление:
Код: sql
1.
select round(77.2774*price, 2) from ...


получаю: 9 659,670
хотя ожидаю 9659,68

думаю, мб это функция делает бухгалтерское округление и зависит от четности предыдущего знака.. проверяю:
Код: sql
1.
select round(9659.675, 2) from ...


возвращает: 9 659,680

вот еще неудачные попытки добиться правильного округления:
Код: sql
1.
2.
3.
4.
5.
select round(77.2774*round(price, 2), 2) from ...
select round(cast(77.2774 as DOUBLE PRECISION) * cast(price as DOUBLE PRECISION), 2) from
select round(cast(77.2774 as DECIMAL(18,4)) * cast(price as DECIMAL(18,2)), 2) from ...
select cast(cast(77.2774 as DECIMAL(18,4)) * cast(price as DECIMAL(18,2)) as DECIMAL(18,2)) from ...
select round(772774*ll.price / 10000, 2) from ...
...
Рейтинг: 0 / 0
округление
    #40005776
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователяпочему функция округления возвращает не то значение, которое я ожидаю..

Потому что у тебя неправильные ожидания. Round на вход получает double precision.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
округление
    #40005783
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посоветуйте, пожалуйста, как мне выйти из этой ситуации? мне хочется округлить до ближайшего целого. как это сделать?
...
Рейтинг: 0 / 0
округление
    #40005791
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя, речь про то, что 77.2774 непредставимо конечной двоичной дробью.
...
Рейтинг: 0 / 0
округление
    #40005792
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователякак это сделать?

а) Округляй (и вообще вычисляй) в своём приложении, не грузи сервер левой работой.
б) То же самое, но в UDR.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
округление
    #40005798
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя,

странно, что в трёшке не могу получить неправильный результат.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
execute block
returns (value2 numeric(15,2))

as

declare variable price numeric(15,2);

begin

price = 125 ;
for select round(77.2774 * :price, 2) from rdb$database
into :value2
do
suspend ;

end


Результат - 9659,68.
...
Рейтинг: 0 / 0
округление
    #40005838
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дело в диалекте:

1-ый диалект:
Код: plaintext
1.
2.
3.
4.
5.
SQL> select round(77.2774 * 125.00, 2) from rdb$database;

                  ROUND
=======================
      9659.670000000000

А вот 3-ий диалект
Код: plaintext
1.
2.
3.
4.
5.
SQL> select round(77.2774 * 125.00, 2) from rdb$database;

                ROUND
=====================
          9659.680000
...
Рейтинг: 0 / 0
округление
    #40005863
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо всем за оперативные ответы!
да, действительно, у меня 1 диалект.
в приложении округлять не могу, мне надо результат этого запроса скормить отчету.
UDR сейчас срочно изучать, чтоб написать свою функцию round тоже нецелесообразно..
в общем, как-то печально.. не знаю, что делать.. (
...
Рейтинг: 0 / 0
округление
    #40005865
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hvlad
Дело в диалекте:
Ну дело в double, просто в 1-м диалекте, видимо, значение как double воспринимается, а в 3-м - нет.

Для первого диалекта может помочь такой говнокод:

ROUND( ROUND( 77.2774 * 125.00, 3 ), 2 )
-----
9659.68
...
Рейтинг: 0 / 0
округление
    #40005866
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

Только это может быть неправильно логически. Но можно в первом раунде 3 заменить на 8 - результат не изменится, но уже не так критично))
...
Рейтинг: 0 / 0
округление
    #40005873
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо!
так сработало!
сейчас осознаю, что это значит, потестирую на других примерах, но, вроде, подходит такое решение!
...
Рейтинг: 0 / 0
округление
    #40005874
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
cast( *100 as int) / 100.00


Что показывает?
...
Рейтинг: 0 / 0
округление
    #40005876
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще проверить наличие УДФ, round может быть переопределена.
...
Рейтинг: 0 / 0
округление
    #40005877
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователяприложении округлять не могу, мне надо результат этого запроса скормить отчету.

Отчёту можно скармливать и неокруглённый результат. Форматировать числа это его прямая работа.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
округление
    #40005879
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_Pisarevsky
Еще проверить наличие УДФ, round может быть переопределена.
Round может быть недостаточно круглой
...
Рейтинг: 0 / 0
округление
    #40005905
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery
Ivan_Pisarevsky
Еще проверить наличие УДФ, round может быть переопределена.
Round может быть недостаточно круглой
Ага, смейся, злодей. Выпиливал эти abs, round, trunc из rfunc вроде бы... оно помимо недостаточной круглости(нумерик - дабл, втихаря в третьем диалекте) еще и нолики из нуллов делало.
...
Рейтинг: 0 / 0
округление
    #40005925
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имя пользователя
Посоветуйте, пожалуйста, как мне выйти из этой ситуации? мне хочется округлить до ближайшего целого. как это сделать?


У вас параметр округления, .674999999999999..(из-за двоичного представления мантиссы), поэтому он округляется до .67

Вы могли бы добавить микрокопейку перед округлением. Для 64-битного числа с плавающей запятой (double) это решит вашу проблему. Для float, микрокопейка может потеряться в короткой мантиссе.
...
Рейтинг: 0 / 0
округление
    #40005928
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя
Посоветуйте, пожалуйста, как мне выйти из этой ситуации? мне хочется округлить до ближайшего целого. как это сделать?
Код: sql
1.
2.
3.
4.
5.
SELECT Cast(77.49 AS INTEGER),
    Cast(77.51 AS INTEGER),
    Trunc(77.49 + 0.5),
    Trunc(77.51 + 0.5)
  FROM RDB$DATABASE
...
Рейтинг: 0 / 0
округление
    #40005976
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имя пользователя

сейчас осознаю, что это значит
Это значит, что double число
9659.675 только выглядит так на экране, а внутрях может оказаться
9659.6749999999...
...
Рейтинг: 0 / 0
округление
    #40005978
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Вы могли бы добавить микрокопейку перед округлением
Да, так правильней, наверно.
Добавлять эпсилон, допустимый для данной задачи и точности типа.
...
Рейтинг: 0 / 0
округление
    #40006017
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WildSery
Код: sql
1.
cast( *100 as int) / 100.00


Что показывает?

Код: sql
1.
SELECT cast( 77.2774 * ll.price *100 as int) / 100.00 from ...


возвращает 9659,6700000000001
...
Рейтинг: 0 / 0
округление
    #40006018
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_Pisarevsky
Еще проверить наличие УДФ, round может быть переопределена.

нет. это UDF. проверил
...
Рейтинг: 0 / 0
округление
    #40006019
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Имя пользователя
Посоветуйте, пожалуйста, как мне выйти из этой ситуации? мне хочется округлить до ближайшего целого. как это сделать?


У вас параметр округления, .674999999999999..(из-за двоичного представления мантиссы), поэтому он округляется до .67

Вы могли бы добавить микрокопейку перед округлением. Для 64-битного числа с плавающей запятой (double) это решит вашу проблему. Для float, микрокопейка может потеряться в короткой мантиссе.

Код: sql
1.
select ROUND( 77.2774 * price + 0.000001, 2 ) from 

такой вариант работает, спасибо за решение!
но я не могу понять, какую долю копейки мне нужно использовать в данном случае. у меня price - это numeric(15, 2). умножая это поле на 77.2774, какой тип данных будет округлять ROUND? т.е. сколько надо прибавлять, чтоб не перевалить случайно в большую сторону? я хочу получить 4 знака после запятой после умножения, а потом округлить до 2 знаков.
...
Рейтинг: 0 / 0
округление
    #40006022
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev
Имя пользователя
Посоветуйте, пожалуйста, как мне выйти из этой ситуации? мне хочется округлить до ближайшего целого. как это сделать?
Код: sql
1.
2.
3.
4.
5.
SELECT Cast(77.49 AS INTEGER),
    Cast(77.51 AS INTEGER),
    Trunc(77.49 + 0.5),
    Trunc(77.51 + 0.5)
  FROM RDB$DATABASE


простите, не понял.. т.е. как работают данные функции я понимаю, но не усек, как мне их применить в моей ситуации
...
Рейтинг: 0 / 0
округление
    #40006025
Имя пользователя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
подводя итог, я делаю вывод: "граждане, храните деньги в сберегательной кассе целочисленных типах данных". правильный вывод?
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / округление
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]