Чтобы получить реальную точность и масштаб результата (@val1/@val2), я бы выполнил этот скрипт T-SQL
DECLARE @val1 NUMERIC(38,16);
DECLARE @val2 NUMERIC(38,16);
SET @val1 = 0.01;
SET @val2 = 0.0074464347;
SELECT @val1/@val2
,SQL_VARIANT_PROPERTY(@val1/@val2, 'BaseType') [BaseType]
,SQL_VARIANT_PROPERTY(@val1/@val2, 'Precision') [Precision]
,SQL_VARIANT_PROPERTY(@val1/@val2, 'Scale') [Scale]
И результаты будут:
(No column name) BaseType Precision Scale
1.342924 numeric 38 6
Таким образом, точность результата равна 38, а масштаб результата равен 6. В MSDN есть некоторые подробности относительно точности и масштаба арифметических операций. Эту информацию можно найти здесь: Точность, масштаб и длина (Transact-SQL)< /а>:
Operation = e1 / e2
Result precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
Result scale * = max(6, s1 + p2 + 1)
Используя эти формулы, мы можем написать следующий скрипт T-SQL
, чтобы получить теоретическую точность и масштаб результата (@val1/@val2):
SELECT @p1 = 38 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val1, 'Precision'))
,@s1 = 16 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val1, 'Scale'))
,@p2 = 38 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val2, 'Precision'))
,@s2 = 16 --or CONVERT(INT, SQL_VARIANT_PROPERTY(@val2, 'Scale'));
--SELECT @p1 [@p1], @s1 [@s1], @p2 [@p2], @s2 [@s2];
SELECT @p_result = @p1 - @s1 + @s2 + CASE
WHEN 6 >= @s1 + @p2 + 1 THEN 6
WHEN 6 < @s1 + @p2 + 1 THEN @s1 + @p2 + 1
END
,@s_result = CASE
WHEN 6 >= @s1 + @p2 + 1 THEN 6
WHEN 6 < @s1 + @p2 + 1 THEN @s1 + @p2 + 1
END;
SELECT @p_result [@p_result], @s_result [@s_result];
Результат:
@p_result @s_result
93 55
Итак, для этой арифметической операции (@val1/@val2) в theory
точность и масштаб равны 93
и 55
, но реальная точность и масштаб равны 38
и 6
. Реальная точность равна 38, поскольку "точность результата и масштаб имеют абсолютный максимум 38".
Относительно реальной шкалы результатов (6) MSDN неясно: "Когда точность результата превышает 38, соответствующая шкала уменьшается, чтобы предотвратить усечение целой части результата" эм>.
Чтобы увидеть, как «соответствующая шкала уменьшается», я выполнил приведенные выше тесты (сценарий 1 для реальной точности и масштаба и сценарий 2 для теоретической точности и масштаба), используя значения NUMERIC
, имеющие одинаковую шкалу (16), но разные шкалы (от 16 до 38). ). Результаты этих испытаний таковы:
/*
Result prec. Result scale (T=theoretical value, R=real value)
T-R T-R --@val1 and @val2 data type
49-38 33-22 --NUMERIC(16, 16)
51-38 34-21 --NUMERIC(17, 16)
53-38 35-20 --NUMERIC(18, 16)
55-38 36-19 --NUMERIC(19, 16)
...
61-38 39-16 --NUMERIC(22, 16) -- <-- data type for [real] result scale 16
...
77-38 47-8 --NUMERIC(30, 16)
79-38 48-7 --NUMERIC(31, 16)
81-38 49-6 --NUMERIC(32, 16)
83-38 50-6 --NUMERIC(33, 16)
85-38 51-6 --NUMERIC(34, 16)
...
93-38 55-6 --NUMERIC(38, 16)
*/
Изучение этих результатов:
1.Я вижу арифметическую прогрессию по шкале реального результата: от 22 до 6, шаг -1.
2. Кроме того, если шкала для @val1 и @val2 постоянна (NUMERIC(...,16)
), то существует обратная корреляция между точностью @val1 и @val2 (от 16 до 32) и шкалой [реального] результата (от 16 до 6).
3. Если точность @val1 и @val2 равна 32 или выше (NUMERIC(32->38,16)
), [реальная] шкала результата всегда равна 6 => это ваш случай.
4. Если требуется большая [реальная] шкала результатов (более 6), вам нужно использовать более низкую точность для @val1 и @val2: NUMERIC(22, 16)
:
SELECT
CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) [CONVERT(NUMERIC(22,16)]
,SQL_VARIANT_PROPERTY( CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) , 'BaseType') [BaseType]
,SQL_VARIANT_PROPERTY( CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) , 'Precision') [Precision]
,SQL_VARIANT_PROPERTY( CONVERT(NUMERIC(22,16),@val1) / CONVERT(NUMERIC(22,16),@val2) , 'Scale') [Scale]
CONVERT(NUMERIC(22,16) BaseType Precision Scale
---------------------- -------- --------- -----
1.3429245542165299 numeric 38 16
person
Bogdan Sahlean
schedule
27.10.2011
1.3429245542165000
- person sll   schedule 27.10.2011select @theanswer = CAST(0.01 as numeric(38,16)) / CAST(0.0074464347 AS numeric(38,16))
- person sll   schedule 27.10.2011