任何人都可以在MsSQL中尝试这个:
select floor(4.7000000000000000000000000000000000000)+0.5
我得到这个结果:5(!!)但应该是4.5!?
或者再试一次:
select floor(4.70 * 0.25000 * 0.2440 * 5.6325 * 3.0542 * 2.345 * 2.35 * 3.253 )+0.5
结果是89 !!但应该是:88.5?!
这是一个问题吗?或者有解释吗?
(与CEILING
相同的问题)
谢谢大家!
答案 0 :(得分:2)
根据FLOOR
的文档:
-- Syntax for SQL Server, Azure SQL Data Warehouse, Parallel Data Warehouse
FLOOR ( numeric_expression )
返回类型
返回与
numeric_expression
相同的类型。
问题在于它不是真的。它保留了基本类型,但如果是decimal
类型,则比例缩小为0:
SELECT
SQL_VARIANT_PROPERTY(4.00, 'precision') AS [precision]
SQL_VARIANT_PROPERTY(4.00, 'scale') AS scale,
结果:精度3,比例2.
SELECT
SQL_VARIANT_PROPERTY(FLOOR(4.00), 'precision') AS [precision],
SQL_VARIANT_PROPERTY(FLOOR(4.00), 'scale') AS scale
结果:精度3,比例0.一旦decimal
达到最大精度,这就成了问题:
SELECT
SQL_VARIANT_PROPERTY(4.7000000000000000000000000000000000000, 'precision') AS [precision]
SQL_VARIANT_PROPERTY(4.7000000000000000000000000000000000000, 'scale') AS scale,
精度38,比例37.但FLOOR
将其转换为精度38,比例0和
SELECT CONVERT(DECIMAL(38, 0), 4) + 0.5
根据{{3}},结果为5
:此结果应为decimal(40, 1)
,但由于超出了最大精度,因此缩放比例以保留尽可能多的数字在期间的前面,再次给我们decimal(38, 0)
:5
。
相反,这没有问题:
SELECT 4.0000000000000000000000000000000000000 + 0.5
结果是DECIMAL(38, 37)
,可以完全保留4.5000000000000000000000000000000000000
。
道德:要注意FLOOR
(和CEILING
)的这种消除尺度的方面,并在必要时降低精度,以免因溢出而缩小比例:
SELECT CONVERT(DECIMAL(3, 0), FLOOR(4.70 * 0.25000 * 0.2440 * 5.6325 * 3.0542 * 2.345 * 2.35 * 3.253)) + 0.5
收益率88.5
。