Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
есть табличка: Код: plaintext 1. 2. 3. 4. 5. 6. 7. и если потом выполнить запрос: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. то получим странные результаты: автор16.5 -> 16; 19.5 -> 20; 22.5 -> 22 Т.е. правильно округляется через раз. от клиента это не зависит.... пробовал вместо "r1" REAL -> "r1" DOUBLE PRECISION : результат тот же :( но если в звапросе вместо поля "r1" руками написать 1.5, то все вычисляется как надо. но требуется имеено взять поле из базы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 10:59 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
банковское — округление половины (N+1 знак = 5) к ближайшему чётному. В этом случае исчезает систематическая ошибка округления при суммировании большого количества чисел. Еще тут Видимо в постгресе заложено банковское округление. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 11:11 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
Выполните запрос и подумайте о точности представления данных (float, real и т.п.) Код: plaintext Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 11:15 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
но если руками прописать 1.5 то считает по другому. это тоже нормально? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 11:17 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
adminchegно если руками прописать 1.5 то считает по другому. это тоже нормально?Ну значит то, что написано выше уже не мной. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 11:18 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
написал вот так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. результат вполне математически-верный. никаких подводных камней не будет ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 11:21 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
Думайте Код: plaintext Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 11:29 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
мдаааа.... из цикла "забавная математика" :) может открыть отдельную ветку в форуме с Postgres-овскими забавами ? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 14:19 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
Округление ROUND в Postgres не банковское, а обычное арифметическое, и реализовано правильно. В данном же случае на первый план выступает неявное приведение результата арифметической операции к типу исходных операндов. Другими словами, результат деления двух целых чисел приводится к целому. Причем приводится не округлением (ROUND), а усечением (TRUNC). Например, 100/51.0 = 1.9607843137254902 100/51 = 1 Самое противное, что этот принцип применяется не ко всему выражению в целом, а к каждой паре операндов, с начала вычисления. То есть, для 100/51*51.0 сначала вычисляется 100/51, приводится к целой единице, а потом умножается на 51.0, и получаем 51.0 100/51*51.0 = 51.0 В то же время, если один из первых двух операндов будет вещественным, то и результат их не усечется, и дельнейшие вычисления пойдут верно: 100/51.0*51 = 100.0000000000000002 Двойка за пределами значащих разрядов - неизбежное следствие погрешностей машинной арифметики, и легко убирается тем же ROUND. Поэтому, если есть желание вести вычисления с вещественными числами, лучше сразу привести все аргументы к вещественному типу, а для подавления мусора за пределами значащих цифр использовать округление ROUND. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 14:42 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
Вроде бы как все встало на свои места... но вот один вопрос остается у меня: в самом верху приведены исходные данные эксперимента и всё такое. так вот есди я беру из поля значение (1100/100*"r1",) то получается что то неправильное :( если же вместо "r1" напишу в запросе руками 1.5 - получается как надо... разжуйте плизз эту ситуацию ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 15:02 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
или в постгресе 1.5 введенное руками по умолчанию является типом numeric ? тогда получается результат округления все же сильно зависит вещественных от типов данных ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 15:05 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
Да, действительно, все зависит от того, каким типом считается 1.5 SELECT 1100/100*(1.5::numeric), 1100/100*(1.5::float), ROUND(1100/100*(1.5::numeric)), ROUND(1100/100*(1.5::float)) ; ?column? | ?column? | round | round ----------+----------+-------+------- 16.5 | 16.5 | 17 | 16 Суть в том, что 1.5 не может точно втиснуться в тип float, и в результате получается что-то вроде 16.49999999999..., округляемое до 16.0. А при выведении на экран применяется некое форматирование (не строгое округление), прячущее эти подробности, и сбивающее с толку непосвященных. То есть при приведении к numeric считает правильно. И по умолчанию 1.5 приводится к numeric (Chapter 10. Type Conversion, 10.3. Functions, Example 10-4. Rounding Function Argument Type Resolution, "...Since numeric constants with decimal points are initially assigned the type numeric..."). В общем-то все логично. Потому что: "The type numeric can store numbers with up to 1000 digits of precision and perform calculations exactly. It is especially recommended for storing monetary amounts and other quantities where exactness is required". А про это ваше там float вааще говорят (Chapter 8. Data Types, 8.1.3. Floating-Point Types): "If you require exact storage and calculations (such as for monetary amounts), use the numeric type instead". А теперь скажите, что Вы считаете, и почему выбрали float? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 16:49 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
Спасибо за разъяснения. Ужо сделал поле "r1" numeric и теперь всё пучком :) Считаю бабки :( Выбрал float ибо как то уж больно много там примудростей вокруг numeric понаписано.... засомневался как оно будет работать в прогах когда этот numeric читать из базы буду... вопщем тлевратное лияние С (ЦЕ) :) "r1" - это в реальном то написании "Reward" типа процент вознаграждения... и максимум был бы он с двумя знаками после запятой, из этих соображений казалось бы и float-а хватит... ан нет - вона какие хитрости подстерегают :) а ващще все суммы храню в копейках - целые числа однако. вот только тут при расчете процентов вещественные числа и проскакивают. Так то вроде бы и фигня полкопейки ту, полкопейки сюда.... пустячок - а неприятно :( Вот и стал разбираться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 17:01 |
|
||
|
неверное округление
|
|||
|---|---|---|---|
|
#18+
>>> и максимум был бы он с двумя знаками после запятой, из этих соображений казалось бы и float-а хватит float - это не только ограничение на количество значащих цифр, но и специфическое внутреннее представление, накладывающее свои ограничения. Какие именно? Попробуйте на бумажке выразить число 0.1 в двоичном виде, (точнее, в представлении с плавающей запятой) - и увидите. Получите бесконечный хвост, точно как при попытке записать 10/3 десятичной дробью. Разумеется, при втискивании в конкретные ячейки этот хвост приходится где-то обрезать, внося погрешность уже при присвоении значения переменной. >>> а ващще все суммы храню в копейках в numeric можно хранить и в рублях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2007, 19:20 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=34847025&tid=2004970]: |
0ms |
get settings: |
7ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
63ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
71ms |
get tp. blocked users: |
2ms |
| others: | 244ms |
| total: | 423ms |

| 0 / 0 |
