numeric
、float
和 decimal
数据类型之间有什么区别,在哪些情况下应该使用哪些?
对于任何一种金融交易(例如薪金领域),首选哪一种?为什么?
仅当十进制(最多 38 位)提供的精度不足时才使用浮点或实数数据类型
近似数字数据类型(见表 3.3)不存储为许多数字指定的精确值;它们存储的值非常接近。 (技术网)
避免在 WHERE 子句搜索条件中使用浮点或实列,尤其是 = 和 <> 运算符。最好将浮点数和实数列限制为 > 或 < 比较。 (技术网)
所以通常选择 Decimal 作为您的数据类型是最好的选择,如果
你的号码可以放进去。小数精度为 10E38[~ 38 位]
Float 较小的存储空间(可能还有计算速度)对您来说并不重要
需要精确的数字行为,例如在金融应用程序中、在涉及舍入的操作中或在相等性检查中。 (技术网)
精确数字数据类型十进制和数字 - MSDN
numeric = decimal(5 到 17 字节)将映射到 .NET 中的 Decimal 两者都具有 (18, 0) 作为 SQL 服务器中的默认 (precision,scale) 参数 scale = 可以存储在右侧的最大十进制位数小数点。 money(8 byte) 和 smallmoney(4 byte) 也是精确数据类型,将映射到 .NET 中的 Decimal 并有 4 个小数点 (MSDN)
将映射到 .NET 中的 Decimal
两者都具有 (18, 0) 作为 SQL Server 中的默认 (precision,scale) 参数
scale = 可以存储在小数点右侧的最大小数位数。
money(8 byte) 和 smallmoney(4 byte) 也是精确数据类型,将映射到 .NET 中的 Decimal 并有 4 个小数点 (MSDN)
近似数值数据类型浮点数和实数 - MSDN
real(4 字节)将映射到 .NET 中的 Single 在 ISO 中 real 的同义词是 float(24)
将映射到 .NET 中的 Single
真实的 ISO 同义词是 float(24)
float(8 字节)将映射到 .NET 中的 Double
将映射到 .NET 中的 Double
https://i.stack.imgur.com/HGYoK.png
无论使用哪种处理器架构或数字的大小,所有精确的数字类型总是产生相同的结果
提供给浮点数据类型的参数定义了用于存储浮点数尾数的位数。
近似数值数据类型通常使用更少的存储空间并具有更好的速度(高达 20 倍),您还应该考虑何时将它们转换为 .NET
C#中的十进制,浮点数和双精度有什么区别
十进制与双倍速
SQL Server - .NET 数据类型映射(来自 MSDN)
主要来源:MCTS Self-Paced Training Kit (Exam 70-433): Microsoft® SQL Server® 2008 Database Development - 第 3 章 - 表、数据类型和声明性数据完整性第 1 课 - 选择数据类型(指南) - 第 93 页
MSDN 指南:Using decimal, float, and real Data
数值和小数数据类型的默认最大精度为 38。在 Transact-SQL 中,数值在功能上等同于小数数据类型。当数据值必须完全按照指定存储时,使用小数数据类型存储带小数的数字。 float 和 real 的行为遵循关于近似数值数据类型的 IEEE 754 规范。由于浮点数和实数数据类型的近似性质,当需要精确的数值行为时不要使用这些数据类型,例如在金融应用程序中、在涉及舍入的操作中或在相等性检查中。相反,请使用整数、小数、货币或 smallmoney 数据类型。避免在 WHERE 子句搜索条件中使用浮点或实列,尤其是 = 和 <> 运算符。最好将浮点数和实数列限制为 > 或 < 比较。
Scale
列中指定。
numeric
有一些优势,因为它永远不会以比您要求的更精确的方式存储:请参阅 stackoverflow.com/a/759606/626804
它们的数据类型优先级不同
Decimal 和 Numeric 在功能上是相同的,但仍然存在数据类型优先级,这在某些情况下可能至关重要。
SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')
结果数据类型是数字,因为它采用数据类型优先级。
按优先级列出的详尽数据类型列表:
numeric
。
不是一个完整的答案,而是一个有用的链接:
“我经常对十进制值进行计算。在某些情况下,在任何计算之前尽快将十进制值转换为浮点数,会产生更好的准确性。”
decimal
和 float
的下溢特性不同。十进制通过增加精度或比例来尽可能地防止下溢。但是,一旦达到十进制有效数字的限制,下溢就会消失(并且精度会丢失)。浮点数可能具有更广泛的规模,而规模限制实际上是下溢的原因。因此,浮动可以具有更好的规模。尽管如此,它仍然是一个 inexact 类型。
Float 是 Approximate-number 数据类型,这意味着并非数据类型范围内的所有值都可以精确表示。
Decimal/Numeric 是 Fixed-Precision 数据类型,这意味着数据类型范围内的所有值都可以用精度和比例精确表示。您可以使用小数来省钱。
从 Decimal 或 Numeric 转换为 float 可能会导致一些精度损失。对于 Decimal 或 Numeric 数据类型,SQL Server 将精度和小数位数的每个特定组合视为不同的数据类型。 DECIMAL(2,2) 和 DECIMAL(2,4) 是不同的数据类型。这意味着 11.22 和 11.2222 是不同的类型,但浮点数并非如此。对于 FLOAT(6) 11.22 和 11.2222 是相同的数据类型。
您还可以使用金钱数据类型来省钱。这是具有 4 位精度的本机数据类型。大多数专家更喜欢这种数据类型以节省资金。
十进制的情况
它的潜在需求是什么?
它源于这样一个事实,即计算机最终在内部以二进制格式表示数字。这不可避免地会导致舍入错误。
考虑一下:
0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")
上面的省略号 [...] 表示“无限”。如果仔细看,有一个无限重复的模式(='0011')
因此,在某些时候,计算机必须对该值进行四舍五入。这会导致由于重复使用不准确存储的数字而导致的累积错误。
假设您要存储财务金额(可能有小数部分的数字)。首先,您显然不能使用整数(整数没有小数部分)。从纯数学的角度来看,自然趋势是使用 float
。但是,在计算机中,浮点数的数字部分位于小数点之后 - “尾数” - 是有限的。这会导致舍入错误。
为了克服这个问题,计算机提供了特定的数据类型来限制计算机中十进制数的二进制舍入误差。这些是绝对应该用来表示财务金额的数据类型。这些数据类型的名称通常为 Decimal
。例如,在 C# 中就是这种情况。或者,大多数数据库中的 DECIMAL
。
十进制具有固定精度,而浮点具有可变精度。
编辑(未能阅读整个问题):Float(53)(又名 real)是 SQL Server 中的双精度(64 位)浮点数。常规浮点数是单精度(32 位)浮点数。对于许多计算,Double 是精度和简单性的良好组合。您可以使用十进制创建一个非常高精度的数字(最高 136 位),但您还必须小心定义您的精度并正确缩放,以便它可以包含所有必要位数的中间计算。
尽管该问题不包括 MONEY 数据类型,但遇到此线程的一些人可能会想使用 MONEY 数据类型进行财务计算。
请注意 MONEY 数据类型,它的精度有限。
在这个 Stackoverflow 问题的答案中有很多关于它的好信息:
Should you choose the MONEY or DECIMAL(x,y) datatypes in SQL Server?
use the float or real data types only if the precision provided by decimal is insufficient
- 我认为实数不如小数准确,那么如果小数不够,你怎么写使用实数?decimal
就可以了。这是 20 的精度。如果您需要存储介于 1e20 和 1e-20 之间的值,那么,decimal
不能 这样做。那是 40 位的精度。您永远不能将 1e20 和 1e-20 存储在同一个decimal
字段中。相反,您可以使用float
,它在内部将所有内容存储为以 2 为底的日志。这允许在一个字段中实现全范围的精度,但缺点是只有前 8 位数字是准确的。float
...” - 谁说的?这是引用还是您的意见?