我在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,我将会有问题)
答案 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数据类型。
答案 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类型更有效
- 不精确的计算