Precisão da Divisão Decimal T-SQL

Alguém sabe por que, usando o SQL Server 2005

SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999) 

me dá 11,74438969709659,

mas quando eu aumento as casas decimais no denominador para 15, recebo uma resposta menos precisa:

 SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999) 

dá-me 11,74438969

Para multiplicação, simplesmente adicionamos o número de casas decimais em cada argumento (usando caneta e papel) para calcular os pontos de saída.

Mas a divisão apenas explode sua cabeça. Eu vou me deitar agora.

Em termos SQL, é exatamente como esperado.

 --Precision = p1 - s1 + s2 + max(6, s1 + p2 + 1) --Scale = max(6, s1 + p2 + 1) --Scale = 15 + 38 + 1 = 54 --Precision = 30 - 15 + 9 + 54 = 72 --Max P = 38, P & S are linked, so (72,54) -> (38,20) --So, we have 38,20 output (but we don use 20 dp for this sum) = 11.74438969709659 SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999) --Scale = 15 + 38 + 1 = 54 --Precision = 30 - 15 + 15 + 54 = 84 --Max P = 38, P & S are linked, so (84,54) -> (38,8) --So, we have 38,8 output = 11.74438969 SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999) 

Você pode fazer a mesma matemática se seguir esta regra também, se você tratar cada par de números como

  • 146804871.212533000000000 e 12499999.999900000
  • 146804871.212533000000000 e 12499999.999900000000000

Em poucas palavras, use DECIMAL (25,13) e você ficará bem com todos os cálculos – você obterá precisão como declarado: 12 dígitos antes do ponto decimal e 13 dígitos decimais depois. A regra é: p + s deve ser igual a 38 e você estará no lado seguro! Por que é isso? Por causa da implementação muito ruim da aritmética no SQL Server! Até que consertem, sigam essa regra.

Eu observei que, se você converter o valor divisor em float, ele fornecerá a resposta correta, ou seja:

 select 49/30 (result = 1) 

se tornaria:

 select 49/cast(30 as float) (result = 1.63333333333333) 

Nós estávamos confusos sobre a transição mágica,

A P & S está vinculada, então:

  1. (72,54) -> (38,29)

  2. (84,54) -> (38,8)

Assumindo (38,29) é um erro de digitação e deve ser (38,20) , o seguinte é a matemática:

  1. Eu. 72-38 = 34, ii. 54 – 34 = 20

  2. Eu. 84 – 58 = 46, ii. 54 – 46 = 8

E este é o raciocínio:

Eu. Precisão de saída menor precisão máxima são os dígitos que vamos descartar.

ii. Então a escala de saída menos o que vamos jogar nos dá … dígitos restantes na escala de saída.

Espero que isso ajude alguém tentando entender isso.

Converta a expressão não os argumentos.

 select CONVERT(DECIMAL(38,36),146804871.212533 / 12499999.9999) 

SELECIONE COL1 * 1.0 / COL2

Pode ajudar