我在Oracles文档中看到了相互矛盾的引用.FLOAT中的小数与数据库中的NUMBER类型之间的存储方式有何不同?
正如我从C等人那里回忆的那样,浮点数具有int没有的精度限制.Rg,对于'浮点数,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 }
但是我在Oracle文档的其他地方看到FLOAT已被定义为NUMBER.据我所知,Oracle的NUMBER类型的实现并没有遇到与C的浮点相同的问题.
那么,这里的真实故事是什么?Oracle是否偏离了我对浮动/ FLOATs的期望?
(我确信这对于我将要使用它们的方式来说是一个惊人的屁股,但我知道如果0.1*10出现在1.00000000000000001,我将会有问题)
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.请注意,位表示在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