18

我在Oracles 文档中看到相互冲突的引用。小数如何存储在 FLOAT 和数据库中的 NUMBER 类型之间有什么区别吗?

正如我从 C 等人中回忆的那样,浮点数具有 int 没有的精度限制。Rg,对于“浮点数”,0.1(以 10 为底)近似为 0.110011001100110011001101(以 2 为底),大致等于 0.100000001490116119384765625(以 10 为底)。然而,对于 'int's,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 是否偏离了我对浮点数/浮点数的预期?

(我敢肯定,对于我将使用它们的用途而言,这是一场巨大的飓风,但我知道如果 0.1*10 等于 1.00000000000000001,我会有疑问)

4

5 回答 5

29

OracleBINARY_FLOAT使用 IEEE 754 浮点表示在内部存储数据,就像 C 和许多其他语言一样。当您从数据库中获取它们,并且通常将它们存储在宿主语言中的 IEEE 754 数据类型中时,它能够在不转换值的情况下复制值。

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

于 2008-12-01T22:53:23.167 回答
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。请注意,位 63 在 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 double 的结果。由 C 支持。现在这个值受制于所有常见的 IEEE 不准确之处。

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

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

于 2009-04-30T16:14:29.217 回答
3

Oracle 的 Number 实际上是 Decimal(以 10 为底)浮点表示... Float 只是 Number 的别名,做的事情完全相同。

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

链接文本

于 2008-12-01T22:46:00.233 回答
2

比尔关于 Oracle 的 FLOAT 的回答只对 Oracle 8i 中的最新版本(比如 11i)是正确的,该文件说:

您可以使用“NUMBER 数据类型”中讨论的形式指定浮点数。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。当我研究 Oracle 和 PostgreSQL 之间的转换计划时,8i 和 11i 之间的差异引起了很多混乱。

于 2012-05-11T14:25:32.777 回答
2

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

  • 只有 BINARY_FLOAT 和 BINARY_DOUBLE 支持 NAN 值

-不精确的计算

于 2015-08-07T06:01:51.463 回答