SQL Server中数字,浮点数和小数之间的差异

pri*_*kar 299 sql sql-server types

我在谷歌搜索过,还访问了十进制和数字以及SQL Server Helper,以收集数字,浮点数和十进制数据类型之间的差异,并找出应该在哪种情况下使用哪一个.

对于任何类型的金融交易(例如薪资领域),哪一个是首选的,为什么?

Ima*_*idi 454

仅当十进制(最多38位)提供的精度不足时才使用floatreal数据类型

  • 近似数值数据类型不存储为许多数字指定的确切值; 它们存储了非常接近的值.(Technet)

  • 避免在WHERE子句搜索条件中使用float或real列,尤其是=和<>运算符(Technet)

所以一般来说,如果您的数字可以适合,则十进制提供精度为[10E38~38位],而Float的较小存储空间(可能速度)并不重要,处理异常行为和近似数字类型的问题不是可以接受,一般使用十进制.

更有用的信息

  • numeric = decimal(5到17个字节)(精确数值数据类型)
    • 将映射到.​​NET中的Decimal
    • 两者都有(18,0)作为SQL Server中的默认(精度,缩放)参数
    • scale =可以存储在小数点右侧的最大小数位数.
    • 请注意,钱(8字节)和smallmoney(4字节)也是精确的并映射到十进制在.NET中有4个小数点(MSDN)
    • 十进制和数字(Transact-SQL) - MSDN
  • 实数(4字节)(近似 数值数据类型)
  • float(8字节)(近似 数值数据类型)
    • 将映射到.​​NET中的Double
  • 无论使用何种处理器体系结构或数字的大小,所有精确数字类型始终产生相同的结果
  • 提供给float数据类型的参数定义用于存储浮点数尾数的位数.
  • 近似数字数据类型通常使用较少的存储空间并具有更好的速度(最多20倍),您还应该考虑它们何时在.NET中转换

精确的数字数据类型 近似数字数据类型

主要来源: MCTS Self-Paced Training Kit(考试70-433):Microsoft®SQLServer®2008数据库开发 - 第3章 - 表,数据类型和声明性数据完整性第1课 - 选择数据类型(指南) - 第93页

  • `只有当十进制提供的精度不足时才使用浮点数或实数数据类型 - 我认为实数比十进制更准确,那么如果小数不足,你怎么写使用实数? (16认同)
  • @BornToCode这里的"精度"是指您想要存储的值的宽度.如果你需要存储1e10和1e-10之间的值,那么`decimal`就可以了.这是20的精度.如果你需要在1e20和1e-20之间存储值,那么,`decimal`*不能*那样做.这是40位数的精度.你不能将1e20和1e-20存储在同一个`decimal`字段中.相反,你可以使用`float`,它在内部存储所有内容作为基数2的日志.这允许在一个字段中具有完整的精度范围,缺点是只有前8位数字是准确的. (10认同)
  • real不太准确所以不建议除非存储大于小数(> 10e38)的大数字或空间考虑因素.我猜这里引用的精度意味着可能的值和幅度而不是精度 (7认同)

kmo*_*ote 24

MSDN指南:使用decimal,float和real数据

数字和十进制数据类型的默认最大精度为38.在Transact-SQL中,numeric在功能上等效于十进制数据类型.当数据值必须严格按照指定存储时,使用十进制数据类型存储带小数的数字.

float和real的行为遵循IEEE 754规范对近似数值数据类型的要求.由于float和实际数据类型的近似性质,当需要精确的数字行为时,不要使用这些数据类型,例如在财务应用程序,涉及舍入的操作或相等检查中.而是使用整数,小数,金钱或小数据数据类型.避免在WHERE子句搜索条件中使用float或real列,尤其是=和<>运算符.最好将浮点数和实数列限制为>或<比较.


A-K*_*A-K 13

不是一个完整的答案,而是一个有用的链接:

"我经常对十进制值进行计算.在某些情况下,在进行任何计算之前,将十进制值投射到ASAP,会产生更好的准确性."

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/12/20/for-better-precision-cast-decimals-before-calculations.aspx

  • 这没有道理。所有其他带有来源的答案都说数字或十进制数据类型是准确的,而浮点或实数类型是非常近似的。由于精度较低,因此我可以理解,将浮标转换为浮点数可能会加快计算速度,但不能提高精度。 (2认同)
  • 所有数字数据类型都可能出现溢出和下溢.溢出是一个显式错误,但是,下溢是静默的."decimal"和"float"的下溢特征是*不同*.十进制通过提高精度或比例来尽可能地防止下溢.但是,一旦达到十进制有效位数的限制,下溢就会保持沉默(并且精度会丢失).Float具有更广泛的规模范围,并且它的规模限制实际上是导致下溢的原因.因此,浮动可以具有更好的规模.尽管如此,它仍然是一种*不精确的*类型. (2认同)

Ste*_*han 11

它们的数据类型优先级不同

十进制数字功能上是相同的,但仍然存在数据类型优先级,这在某些情况下可能是至关重要的.

SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')
Run Code Online (Sandbox Code Playgroud)

生成的数据类型是数字,因为它采用数据类型优先级.

按优先级排列的详尽数据类型列表:

参考链接


Bri*_*ter 7

Decimal具有固定的精度,而float具有可变的精度.

编辑(无法读取整个问题):Float(53)(又名真实)是SQL Server中的双精度(32位)浮点数.Regular Float是单精度浮点数.对于大量计算,Double是精确和简单的良好组合.您可以使用十进制创建一个非常高精度的数字 - 最多136位 - 但您还必须注意正确定义精度和比例,以便它可以包含所有中间计算到必要的位数.


Som*_*luk 6

Float是 Approximate-number 数据类型,这意味着并非数据类型范围内的所有值都可以精确表示。

Decimal/Numeric是 Fixed-Precision 数据类型,这意味着数据类型范围内的所有值都可以精确地表示为精度和小数位数。您可以使用十进制来省钱。

从 Decimal 或 Numeric 转换为浮点数可能会导致一些精度损失。对于小数或数字数据类型,SQL Server 将精度和小数位数的每个特定组合视为不同的数据类型。DECIMAL(2,2) 和 DECIMAL(2,4) 是不同的数据类型。这意味着 11.22 和 11.2222 是不同的类型,尽管浮点数不是这种情况。对于 FLOAT(6) 11.22 和 11.2222 是相同的数据类型。

你也可以用数据类型来省钱。这是具有 4 位货币精度的本机数据类型。大多数专家更喜欢这种数据类型以节省资金。

参考 1 2 3


Var*_*mus 5

十进制的情况

它的潜在需求是什么?

它源于这样一个事实:最终,计算机在内部以二进制格式表示数字。这不可避免地导致四舍五入错误。

考虑一下:

0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")
Run Code Online (Sandbox Code Playgroud)

上面的省略号 [...] 表示“无限”。仔细看,有一个无限重复的图案(='0011')

因此,在某些时候,计算机必须舍入该值。这会导致由于重复使用不准确存储的数字而导致的累积错误。

假设您要存储财务金额(可能有小数部分的数字)。首先,您显然不能使用整数(整数没有小数部分)。从纯数学的角度来看,自然的趋势是使用float. 但是,在计算机中,浮点数具有位于小数点后的数字部分 - “尾数” - 有限。这会导致舍入错误。

为了克服这个问题,计算机提供了特定的数据类型来限制计算机中十进制数的二进制舍入误差。这些是绝对应该用于表示财务金额的数据类型。这些数据类型通常以Decimal. 例如,在 C# 中就是这种情况。或者,DECIMAL在大多数数据库中。