Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / округление / 25 сообщений из 31, страница 1 из 2
06.10.2020, 15:13
    #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
06.10.2020, 15:30
    #40005776
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
округление
Имя пользователяпочему функция округления возвращает не то значение, которое я ожидаю..

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

а) Округляй (и вообще вычисляй) в своём приложении, не грузи сервер левой работой.
б) То же самое, но в UDR.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
06.10.2020, 15:50
    #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
06.10.2020, 16:27
    #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
06.10.2020, 16:48
    #40005863
Имя пользователя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
округление
Спасибо всем за оперативные ответы!
да, действительно, у меня 1 диалект.
в приложении округлять не могу, мне надо результат этого запроса скормить отчету.
UDR сейчас срочно изучать, чтоб написать свою функцию round тоже нецелесообразно..
в общем, как-то печально.. не знаю, что делать.. (
...
Рейтинг: 0 / 0
06.10.2020, 16:50
    #40005865
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
округление
hvlad
Дело в диалекте:
Ну дело в double, просто в 1-м диалекте, видимо, значение как double воспринимается, а в 3-м - нет.

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

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

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


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

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


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

Вы могли бы добавить микрокопейку перед округлением. Для 64-битного числа с плавающей запятой (double) это решит вашу проблему. Для float, микрокопейка может потеряться в короткой мантиссе.
...
Рейтинг: 0 / 0
06.10.2020, 18:45
    #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
06.10.2020, 23:11
    #40005976
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
округление
Имя пользователя

сейчас осознаю, что это значит
Это значит, что double число
9659.675 только выглядит так на экране, а внутрях может оказаться
9659.6749999999...
...
Рейтинг: 0 / 0
06.10.2020, 23:15
    #40005978
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
округление
НеофитSQL
Вы могли бы добавить микрокопейку перед округлением
Да, так правильней, наверно.
Добавлять эпсилон, допустимый для данной задачи и точности типа.
...
Рейтинг: 0 / 0
07.10.2020, 08:53
    #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
07.10.2020, 08:55
    #40006018
Имя пользователя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
округление
Ivan_Pisarevsky
Еще проверить наличие УДФ, round может быть переопределена.

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


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