Oracle Floats与Number

时间:2008-12-01 22:41:38

标签: oracle types numbers floating-point fixed-point

我在Oracles documentation中看到了相互矛盾的引用。 FLOAT中的小数与数据库中的NUMBER类型之间的存储方式有何不同?

我回忆起C等人,浮点数具有int没有的精度限制。 R.g.,对于'浮点数,0.1(基数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
}

但是,我看到elsewhere in Oracle's documentation已将FLOAT定义为NUMBER。据我了解,Oracle的NUMBER类型的实现与C的浮动不会遇到同样的问题。

那么,这里的真实故事是什么? Oracle是否偏离了我对浮动/ FLOATs的期望?

(我确信这对于我将要使用它们的飓风来说是一个惊人的飓风,但我知道如果0.1 * 10出现在1.00000000000000001,我将会有问题)

5 个答案:

答案 0 :(得分:25)

Oracle BINARY_FLOAT使用IEEE 754浮点表示在内部存储数据,如C和许多其他语言。当您从数据库中获取它们,并且通常将它们存储在主机语言的IEEE 754数据类型中时,它可以复制该值而无需对其进行转换。

而Oracle的FLOAT数据类型是ANSI SQL NUMERIC数据类型的同义词,在Oracle中称为NUMBER。这是一个精确的数字,一个缩放的十进制数据类型,没有IEEE 754的舍入行为。但是如果从数据库中获取这些值并将它们放入C或Java浮点数,则在此步骤中可能会丢失精度。

答案 1 :(得分:10)

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。请注意,位表示在Oracle表示中为0,而在IEEE表示中为1(如果's'是符号位,则根据IEEE,数字的符号为(-1)^ s)。在http://babbage.cs.qc.cuny.edu/IEEE-754/

上查看非常好的IEEE 754计算器

如果表T中有一个带有查询的BINARY__DOUBLE列BD,您可以轻松找到这个:

  

从T

中选择BD,DUMP(BD)

现在所有这些都很好而且有趣(可能)但是当一个人在C中工作并从Oracle获取数值(通过将变量绑定到任何类型的数字列)时,通常会在真实的IEEE中获得结果C支持的双倍。现在这个值受到所有常见IEEE不准确性的影响。

如果想要进行精确算术,可以在PL / SQL中使用,也可以使用特殊的精确算术C库。

有关Oracle对其数字数据类型的解释,请参阅:http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/datatype.htm#i16209

答案 2 :(得分:3)

Oracle的Number实际上是一个十进制(基数为10)的浮点表示... Float只是Number的别名,完全相同。

如果你想要二进制(base-2)浮点数,你需要使用Oracle的BINARY_FLOAT或BINARY_DOUBLE数据类型。

link text

答案 3 :(得分:2)

比尔关于甲骨文FLOAT的回答只适用于晚期版本(比如11i),在Oracle 8i中,文件说:

  

您可以使用中讨论的形式指定浮点数   “NUMBER数据类型”。 Oracle还支持ANSI数据类型FLOAT。您   可以使用以下语法形式之一指定此数据类型:

     

FLOAT指定具有小数精度38的浮点数,或   二进制精度126. FLOAT(b)指定一个浮点数   二进制精度b。精度b的范围为1到126. To   从二进制转换为十进制精度,将b乘以0.30103。至   从十进制转换为二进制精度,乘以小数   精度为3.32193。二进制精度的最大值为126位   大致相当于38位十进制精度。

听起来像四倍精度(126二进制精度)。如果我没有记错的话,IEEE754只要求b = 2,单精度p = 24,双精度p = 53。当我在研究Oracle和PostgreSQL之间的转换计划时,8i和11i之间的差异引起了很多混乱。

答案 4 :(得分:2)

与前面提到的PLS_INTEGER类似,Oracle 10g中的BINARY_FLOAT和BINARY_DOUBLE类型使用机器算法并且需要更少的存储空间,这两者都使它们比NUMBER类型更有效

  • 仅限BINARY_FLOAT和BINARY_DOUBLE支持NAN值

- 不精确的计算