Oracle Floats vs Number

Я вижу противоречивые ссылки в Документация оракулов. Есть ли разница между хранением десятичных дробей в типах FLOAT и NUMBER в базе данных?

Как я помню из C и др., Float имеет ограничения точности, которых нет у int. Например, для чисел с плавающей точкой 0,1 (база 10) приблизительно равно 0,110011001100110011001101 (база 2), что примерно равно 0,100000001490116119384765625 (база 10). Однако для int 5 (база 10) равно 101 (база 2).

Вот почему следующее не завершится должным образом на C:

float i;
i = 0;
for (i=0; i != 10; )
{
    i += 0.1
}

Однако я вижу в другом месте документации Oracle, что FLOAT был определен как НОМЕР. И, насколько я понимаю, реализация Oracle типа NUMBER не сталкивается с той же проблемой, что и float в C.

Итак, какова здесь настоящая история? Oracle отклонился от нормы того, что я ожидаю, с float / FLOATs?

(Я уверен, что это большая разница в том, для чего я буду их использовать, но я знаю, что у меня возникнут вопросы, если 0,1 * 10 превратится в 1,0000000000000000001)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
17
0
64 768
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Число Oracle на самом деле представляет собой десятичное представление с плавающей запятой (base-10) ... Float - это просто псевдоним для Number и делает то же самое.

если вам нужны двоичные (base-2) числа с плавающей запятой, вам нужно использовать типы данных Oracle BINARY_FLOAT или BINARY_DOUBLE.

текст ссылки

Ответ принят как подходящий

Oracle BINARY_FLOAT хранит данные внутри, используя представление с плавающей запятой IEEE 754, как это делают C и многие другие языки. Когда вы извлекаете их из базы данных и обычно сохраняете их в типе данных IEEE 754 на главном языке, он может скопировать значение без его преобразования.

В то время как тип данных Oracle FLOAT является синонимом типа данных ANSI SQL NUMERIC, который в Oracle называется NUMBER. Это точный числовой, масштабированный десятичный тип данных, который не имеет поведения округления, как в IEEE 754. Но если вы извлечете эти значения из базы данных и поместите их в число с плавающей запятой C или Java, вы можете потерять точность на этом этапе.

Oracle BINARY_FLOAT и BINARY_DOUBLE в основном эквивалентны стандарту IEEE 754, но определенно не хранятся внутри в стандартном представлении IEEE 754.

Например, BINARY_DOUBLE занимает 9 байтов памяти по сравнению с IEEE 8. Также двойное плавающее число -3.0 представлено как 3F-F7-FF-FF-FF-FF-FF-FF, которое, если вы используете настоящий IEEE, будет C0- 08-00-00-00-00-00-00. Обратите внимание, что бит 63 равен 0 в представлении Oracle, в то время как он равен 1 в IEEE (если 's' является битом знака, согласно IEEE, знак числа равен (-1) ^ s). См. Очень хорошие калькуляторы IEEE 754 на http://babbage.cs.qc.cuny.edu/IEEE-754/

Вы можете легко найти это, если у вас есть столбец BINARY__DOUBLE BD в таблице T с запросом:

select BD,DUMP(BD) from T

Теперь все это хорошо и интересно (возможно), но когда кто-то работает на C и получает числовое значение от Oracle (путем привязки переменной к числовому столбцу любого типа), обычно результат получается в реальном IEEE double как есть поддерживается C. Теперь это значение подвержено всем обычным неточностям IEEE.

Если кто-то хочет выполнять точную арифметику, это можно сделать либо на PL / SQL, либо с помощью специальных библиотек C для точной арифметики.

Собственное объяснение Oracle их числовых типов данных см .: http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/datatype.htm#i16209

Ответ Билла о Oracle FLOAT верен только для поздней версии (скажем, 11i), в Oracle 8i в документе говорится:

You can specify floating-point numbers with the form discussed in "NUMBER Datatype". Oracle also supports the ANSI datatype FLOAT. You can specify this datatype using one of these syntactic forms:

FLOAT specifies a floating-point number with decimal precision 38, or binary precision 126. FLOAT(b) specifies a floating-point number with binary precision b. The precision b can range from 1 to 126. To convert from binary to decimal precision, multiply b by 0.30103. To convert from decimal to binary precision, multiply the decimal precision by 3.32193. The maximum of 126 digits of binary precision is roughly equivalent to 38 digits of decimal precision.

Это звучит как четырехкратная точность (двоичная точность 126). Если я не ошибаюсь, IEEE754 требует только b = 2, p = 24 для одинарной точности и p = 53 для двойной точности. Различия между 8i и 11i вызвали большую путаницу, когда я изучал план преобразования между Oracle и PostgreSQL.

Как и PLS_INTEGER, упомянутый ранее, типы BINARY_FLOAT и BINARY_DOUBLE в Oracle 10g используют машинную арифметику и требуют меньше места для хранения, что делает их более эффективными, чем тип NUMBER.

  • ТОЛЬКО BINARY_FLOAT и BINARY_DOUBLE поддерживают значения NAN

-неточные расчеты

Другие вопросы по теме