我开始了这个帖子SQL Server float data type understanding
以下问题部分与此有关,所以我把它带回来。
Documents和SQL Server用户说float(8 bytes)
和real(4 bytes)
数据类型仅供大致使用。我可以看到通过使用SQL Server Management Studio和一些简单的查询,如
declare @f float=0.000123456789123456789;
select @f;
其中输出变为0.000123456789123457
(自动舍入错误),因为精度设置为15
非零数字和小数点后。
我认为SQLServer Management Studio的输出是实现定义的。因为馈入系统的字节序列被转换为长位整数,然后根据用于实现系统和转换函数的语言,转换为具有相同精度的float
类型。如果主要原因恰好在这一点上,那么我认为可以修正近似问题。那就是用数据流重新编程函数以获得先前输入的精确值。
但是,我仍然希望了解您所知道的其他特定示例可能会出现其近似错误症状吗?
在我的前一个帖子中,我还有另外一个问题,即在大端和小端系统中处理浮点数和实数数据类型时的字节顺序及其转换。如果有人可以给我一些想法,那真的很棒。
我对此的看法是float
已修复little endian
,real
不是例外,因为它们仅在存储中有所不同。它们的功能完全相同。然而,急需专家对此进行确认。
答案 0 :(得分:1)
您可以将此作为示例:
DECLARE @a float = 0.00000000000000000000000000000000001
DECLARE @b float = 98749946543
DECLARE @c float = 12345679491
SELECT @a * (@b * @c) as [a(bc)], (@a * @b) * @c as [(ab)c]
--Check
IF ((SELECT @a * (@b * @c)) <> (SELECT (@a * @b) * @c))
BEGIN
SELECT 'Match!'
END
ELSE
BEGIN
SELECT 'Mismatch!'
END
这两个表达式在数学上是相同的。但浮动将失败。
就像一个证据,使用十进制相同:
DECLARE @a decimal(38,37) = 0.00000000000000000000000000000000001
DECLARE @b decimal(38,27) = 98749946543
DECLARE @c decimal(38,27) = 12345679491
SELECT @a * (@b * @c) as [a(bc)], (@a * @b) * @c as [(ab)c]
--Check
IF ((SELECT @a * (@b * @c)) <> (SELECT (@a * @b) * @c))
BEGIN
SELECT 'Match!'
END
ELSE
BEGIN
SELECT 'Mismatch!'
END