Oracle Floats vs Number

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

Как я помню из C, et al, у float есть ограничения точности, которых нет у int. R.g., For 'float's, 0.1 (Base 10) приближается к 0,110011001100110011001101 (основа 2), что составляет примерно 0,100000001490116119384765625 (основание 10). Однако для "int" 5 (Base 10) составляет ровно 101 (Base 2).

Вот почему следующее условие не будет прекращено, как ожидалось, в C:

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

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

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

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

Ответ 1

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

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

Ответ 2

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/

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

выберите BD, DUMP (BD) из 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

Ответ 3

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

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

текст ссылки

Ответ 4

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

Вы можете указать числа с плавающей запятой в форме, описанной в "NUMBER Datatype". Oracle также поддерживает тип данных ANSI типа FLOAT. Вы может указывать этот тип данных с использованием одной из этих синтаксических форм:

FLOAT указывает число с плавающей запятой с десятичной точностью 38 или двоичная точность 126. FLOAT (b) указывает число с плавающей запятой с бинарная точность b. Точность b может варьироваться от 1 до 126. Для конвертировать из двоичной в десятичную, умножить b на 0.30103. к преобразовать из десятичной в двоичную точность, умножить десятичную на 3.32193. Максимум 126 цифр бинарной точности примерно эквивалентно 38 цифрам десятичной точности.

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

Ответ 5

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

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

- неточные вычисления