SQL Server Float 数据类型计算与小数

发布于 2024-12-20 03:08:19 字数 665 浏览 4 评论 0原文

在下面的查询中,

declare @a float(23)
declare @b float(23)
declare @c float(53)
set @a = 123456789012.1234
set @b = 1234567.12345678
set @c = @a * @b
select @c

select LTRIM(STR((@c),32,12))

declare @x  decimal(16,4)
declare @y decimal(16,8)
declare @z decimal (32,12)

set @x = 123456789012.1234
set @y = 1234567.12345678
set @z = @x * @y
select @z

我得到的答案是

1.52415693411713E+17
152415693411713020.000000000000
152415692881907790.143935926652

从上面的答案中,第三个答案是正确的。这就是为什么浮点数据类型被称为近似数字数据类型的原因

还是我做了一些根本错误的事情。

顺便说一句,这是由于我在遗留系统中遇到的一个问题,其中我必须使用浮点作为存储数据类型,同时在计算时不应该损失精度。

请提出替代方案或解释。

In the following query

declare @a float(23)
declare @b float(23)
declare @c float(53)
set @a = 123456789012.1234
set @b = 1234567.12345678
set @c = @a * @b
select @c

select LTRIM(STR((@c),32,12))

declare @x  decimal(16,4)
declare @y decimal(16,8)
declare @z decimal (32,12)

set @x = 123456789012.1234
set @y = 1234567.12345678
set @z = @x * @y
select @z

I get answers as

1.52415693411713E+17
152415693411713020.000000000000
152415692881907790.143935926652

From the above answers the third answer is the correct one. Is this the reason why float data type is called Approximate Numeric Data Type

Or am I doing something fundamentally wrong.

BTW this is due to a problem I have with legacy system wherein I have to use float as storage data type, at the same time in there should not be loss of precision while calculation.

Please suggest alternatives, or an explanation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

月亮是我掰弯的 2024-12-27 03:08:19

浮点数仅精确到 15 位有效数字(在 SQL Server 中)。

1.52415693411713 E+17 对此进行了演示,其中 1.52415693411713(15 位数字)与您所能得到的一样准确。 152415693411713STR 后的最终 020...ma​​de up浮点分辨率

为了保持精度,不要使用 float。就是这么简单。如果您想要计算,请转换为十进制,但如果您转换回浮点数,则限制为 15 位数字,

请参阅"每个计算机科学家应该了解的浮点运算知识"

Float is accurate to 15 significant figures only (in SQL Server).

This is demonstrated by 1.52415693411713 E+17 where 1.52415693411713 (15 digits) is as accurate as you'll get. The final 020... after 152415693411713 with STR is made up is the resolution of floating point

To keep precision, don't use float. It is that simple. CAST to decimal if you want for calculation, but if you CAST back to float you are limited to 15 digits

See "What Every Computer Scientist Should Know About Floating-Point Arithmetic"

美人迟暮 2024-12-27 03:08:19

最后一个答案

152415692881907790.143935926652

是提供最多 12 位小数的缩放比例,因为您已相应地声明了 @z。

declare @z decimal (32,12)

此声明中的第二个参数是比例,设置为 12。

有关此内容的更多信息,请访问 http://msdn.microsoft.com/en-us/library/ms187746.aspx

The last answer

152415692881907790.143935926652

is providing scale up to 12 decimal places because you have declared @z accordingly.

declare @z decimal (32,12)

The second parameter in this declaration is scale which is set to 12.

More on the this can be found at http://msdn.microsoft.com/en-us/library/ms187746.aspx

简单 2024-12-27 03:08:19

问题不在于 float 数据类型。
问题在于使用 float(23)。
该数据类型可容纳 8 位有效数字,而不是 float(53) 那样的 15 位。
这正是输出中正确数字的数量。

2 个 float(23) 数字的计算是以 float(23) 精度完成的,然后才转换为 float(53),这绝对无用且具有误导性。

修复@a和@b的初始声明,问题就会消失。

Problem not with float Data type.
Problem is with using float(23).
This data type has a capacity of holding 8 significant digits, not 15 as float(53).
And that's exactly how many correct digits you've got in the output.

Calculation of 2 float(23) numbers is done with float(23) precision, and only afterwards converted to float(53), which is absolutely useless and misleading.

Fix the initial declarations of @a and @b and the problem will disappear.

哆啦不做梦 2024-12-27 03:08:19

始终检查实际分配给变量的值是多少:

declare @a float(23)
declare @b float(23)
declare @c float(23)

set @a = 123456789012.1234
set @b = 1234567.12345678
SET @c = @a * @b 

select @a, @b, @c

GO 

declare @a float
declare @b float
declare @c float

set @a = 123456789012.1234
set @b = 1234567.12345678
SET @c = @a * @b 

select @a, @b, @c

GO 

The outputs of the SELECTs:

1.234568E+11    1234567     1.524157E+17

123456789012.123    1234567.12345678    1.52415692881908E+17

PS 第二级(乘法、除法)和小数值上的运算使用浮点计算,因此它们不可能比 FLOAT 值上的相同运算更精确,假设两种类型使用相同的深度级别。

Always check what is the value to have actually assigned to a variable:

declare @a float(23)
declare @b float(23)
declare @c float(23)

set @a = 123456789012.1234
set @b = 1234567.12345678
SET @c = @a * @b 

select @a, @b, @c

GO 

declare @a float
declare @b float
declare @c float

set @a = 123456789012.1234
set @b = 1234567.12345678
SET @c = @a * @b 

select @a, @b, @c

GO 

The outputs of the SELECTs:

1.234568E+11    1234567     1.524157E+17

123456789012.123    1234567.12345678    1.52415692881908E+17

P.S. Operations of 2nd level (multiplication, division) and upper on decimal values use float point computing, so they cannot be any more precise than same operations on FLOAT values, assuming the same level of depth used for both types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文