|
|
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Доброе утро немного пятничная тема. Запрос Код: plsql 1. на oracle выдаёт корректный ответ 0.3 На Python, Java, Perl и других языках .1 + .2 0.30000000000000004 Вопрос возникает, какая разница в механизмах расчётов в СУБД и ЯП? Как писать код на яве в оракле с оглядкой на эту проблему. Кстати, Firebird тоже корректно вычисляет Код: plsql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 05:40 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
DFilushin, вы бы ещё указали типы данных в случае с ораклом и с ЯПами.... Если в ваших ЯПах это что-то из серии флоат (float), то ничего удивительно. Флоат - это приблизительный тип. Соответственно, и результат в нем будет - тоже приблизительный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 05:57 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Щукина Анна, для питона набирал в консоли, без указания типов, он же с динам. типизацией ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 06:05 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 06:14 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Вячеслав Любомудров, здесь вы указали тип принудительно Какой механизм используется для простого "нетипизированного" вычисления? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 06:41 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
А по умолчанию NUMBER со своей точностью 39-40 знаков Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 07:15 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Вячеслав ЛюбомудровА по умолчанию NUMBER А в PL/SQL ещё и PLS_INTEGER. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 07:22 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Щукина Анна Флоат - это приблизительный тип. Соответственно, и результат в нем будет - тоже приблизительный. Это типа шутка такая была? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 12:48 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
andrey_anonymousЩукина Анна Флоат - это приблизительный тип. Соответственно, и результат в нем будет - тоже приблизительный. Это типа шутка такая была? Почему шутка? Флоат же аппаратный тип, а не программный. Из-за грубого округления в двоичной системе счисления и возникает неточность. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 12:57 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
DFilushinВопрос возникает, какая разница в механизмах расчётов в СУБД и ЯП? Как писать код на яве в оракле с оглядкой на эту проблему.У меня возникает другой вопрос - как работающий в IT человек может не знать отличий binary и decimal форматов? Про стандарт IEEE 754 не буду вспоминать уж. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 13:02 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
IMNOФлоат же аппаратный тип, а не программный. Из-за грубого округления в двоичной системе счисления и возникает неточность. Рукалицо. Не поверите - в современной вычислительной технике ВСЕ данные - двоичные, "программные" тоже. Впрочем, про IEEE 754 тут уже напомнили - несведущим рекомендовал бы ознакомиться хотя бы поверхностно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 13:16 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
в делфи тип currency подходит для денег ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 14:42 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
andreymxв делфи тип currency подходит для денег Для денег подойдет любая реализация fixed point, самая распространенная - представление в виде целого, помноженного на 10 в интересующей степени. Из плавающих - подойдет реализация с десятичным порядком, к примеру - см. decimalXX из IEEE 754—2008, он же ISO/IEC/IEEE 60559:2011. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.08.2018, 14:55 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
andrey_anonymous, С каких пор decimal с плавающей точкой? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2018, 09:03 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
HettС каких пор decimal с плавающей точкой?Decimal из sql и инженерный не одно и то же. А точке все равно, в чем плавать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2018, 11:31 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Hettandrey_anonymous, С каких пор decimal с плавающей точкой?Это уже становится не смешно. Позор какой-то, люди типа "работают" в IT и при этом не желают знать базовых стандартов данных IEEE 754 указывает следующие типы форматов с плавающей запятой: Стандарт-binary16 -binary32 -binary64 -binary128 -binary256 -decimal32 -decimal64 -decimal128 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2018, 12:27 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
DFilushinДоброе утро на oracle выдаёт корректный ответ 0.3 Давай поделим 1 на 3 в троичной системе отсчета, что получится? Получится в естественной форме записи числа 0.1 в троичной системе отсчета. Теперь поделим 1 на 3 в десятичной системе отсчета и о ужас получится 0.3333333333 ну и так далее в периоде, вах вах вах в одной системе отсчета так красиво 0.1, а в другой 0.(3) как же так? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2018, 13:52 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
До этой темы я докумал, что понимаю как хранятся числа. Перечитал IEEE754. Ещё раз перечитал. Погуглил статьи про фиксированную/плавающую запятую. Перечитал стандарт ещё несколько раз. Теперь я вообще ничего не понимаю. Вячеслав Любомудров приводил пример. Код: plsql 1. Здесь результат принудительно приводится к типу decimalXX, который из IEEE754. Откуда берётся "четвёрка": Переведём 0.1 в двоичную систему счисления: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. Дальше можно не продолжать. Результат: 0.1 = 0.000110011 Можно заметить что 0011 в периоде. То есть как и ожидалось, 0.1 в двоичную систему нормально не переводится. Нужно выбрать точность перевода. Отсюда и "четверка" в примере выше. Но почему "правильный результат" получился в этом примере? Код: plsql 1. Почему результат без "непредвиденной" дроби? Что за магия? Зашедший писал: Зашедший не знать отличий binary и decimal То есть могу предположить, что во втором примере(второй пример в моем сообщении) тип binaryXX. Тогда я вообще ничего не понимаю. Ведь binaryXX почти тоже самое что и decimalXX. У них только основание различается, то есть тоже должна быть погрешность. Короче, что происходит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2018, 17:17 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
IMNOВедь binaryXX почти тоже самое что и decimalXX. У них только основание различается, то есть тоже должна быть погрешность.Децимал - даже близко не то же самое. 0.1 с десятичным основанием переведется как 1х10^-1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2018, 18:28 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
IMNOПочему результат без "непредвиденной" дроби? Что за магия? Магия типа Number в Oracle ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2018, 23:35 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
IMNO Код: plsql 1. Здесь результат принудительно приводится к типу decimalXX, который из IEEE754.Все-таки открывай учебник по продукту с которым работаешь/разбираешься D - это не от Decimal, а от Double Есть еще F Код: plsql 1. 2. 3. 4. 5. IMNOПереведём 0.1 в двоичную систему счисления: Результат: 0.1 = 0.000110011 Можно заметить что 0011 в периоде.Ну, в общем, чем больше этих периодов, том точнее приближение, как оно укладывается в 64 Double-precision floating-point format можно посмотреть, например, тут IMNOНо почему "правильный результат" получился в этом примере? Код: plsql 1. Почему результат без "непредвиденной" дроби? Что за магия? Потому что тип NUMBER хранится не по основанию 2, а по основанию 100 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.08.2018, 04:24 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Вячеслав Любомудров как оно укладывается в 64 Double-precision floating-point format можно посмотреть, например, тут Крутая ссылка, спасибо. Вячеслав Любомудров IMNOНо почему "правильный результат" получился в этом примере? Код: plsql 1. Почему результат без "непредвиденной" дроби? Что за магия? Потому что тип NUMBER хранится не по основанию 2, а по основанию 100 Так. Получается, что в Oracle: 1. BINARY_FLOAT и BINARY_DOUBLE - это binaryXX из IEEE754 2. NUMBER - это decimalXX из IEEE754 Все три типа "программные", а не "аппаратные". Немного отступления. Что я имею ввиду, когда пишу "стандарт". Этакий чёрный ящик, у которого есть входы и выходы. Совершенно не важно, как данные хранятся внутри(программно, аппаратно или ещё как-нибудь), главное чтобы на выходе результат был такой, какой описан в стандарте. То есть binaryXX говорит, что может должна быть неточность после N-ого знака. DecimalXX говорит, что до N-ой позиции неточности быть не должно. То есть как писал andrey_anonymous, тот же decimalXX всё равно хранится как двоичный код, но результат должен выдаваться точный. То есть при использовании типа decimalXX отрабатывает алгоритм который сглаживает неточность хранения чисел в двоичном коде. Поправьте пожалуйста, если что не так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.08.2018, 11:33 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
Оракловый NUMBER не имеет никакого отношения к IEEE754 и ссылочку на его потроха тебе приведена Больше всего оно похоже на BCD ( https://ru.wikipedia.org/wiki/Двоично-десятичный_код), бывший популярен во многих финансово-ориентированных языках (Cobol, PL/1), только основание не 10, а 100 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.08.2018, 11:39 |
|
||
|
0.1 + 0.2 = 0.3
|
|||
|---|---|---|---|
|
#18+
IMNOПоправьте пожалуйста, если что не так. Поправляю. Числа с плавающей точкой хранятся как пара целых чисел. Целых, обратите внимание. Все истории про неточности - это истории про множества представимых чисел и выбор ближайшего представимого для непредставимого (правила округления). А вся разница между binary, decimal и тем же oracle number - это основание логарифма. Десятичный или двойка. Все остальное - в контексте обсуждаемой проблемы от лукавого. "стреляет" основание логарифма при нормализации. Не будь ее - не стреляло бы, но имели бы место другие спецэффекты. И еще. Разделение на "программные" и "аппаратные" в том пещерном понимании, которое тут демонстрировалось - суть фейк. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.08.2018, 13:14 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=39686022&tid=1883601]: |
0ms |
get settings: |
10ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
164ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
77ms |
get tp. blocked users: |
1ms |
| others: | 235ms |
| total: | 524ms |

| 0 / 0 |
