Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Dúvida sobre o tipo Decimal

Quando utilizo a variável @PRECO como um DECIMAL o resultado sai um pouco abaixo do esperado, e quando utilizo como sendo do tipo FLOAT o resultado saiu correto. Já a variável acumulativa, no meu caso eu utilizei a @FATURAMENTO, não faz diferença ser utilizada como um DECIMAL ou FLOAT, apenas a exibição final é afetada. Queria saber o por quê do resultado oscilar devido ao tipo de dado ser FLOAT ou DECIMAL.

Segue o meu código

DECLARE @ANO AS INT = 2017, @MES AS INT = 1
DECLARE @FATURAMENTO DECIMAL = 0
DECLARE @QTD INT, @PRECO FLOAT -- QUANDO UTILIZO DECIMAL O RESULTADO SAIU UM POUCO ABAIXO DO ESPERADO

DECLARE CURSOR_FATURAMENTO CURSOR FOR
SELECT INF.[QUANTIDADE], INF.[PREÇO]
FROM [ITENS NOTAS FISCAIS] INF INNER JOIN
[NOTAS FISCAIS] NF
ON INF.[NUMERO] = NF.NUMERO
WHERE YEAR(NF.[DATA]) = @ANO AND MONTH(NF.[DATA]) = @MES

OPEN CURSOR_FATURAMENTO 
FETCH NEXT FROM CURSOR_FATURAMENTO INTO @QTD, @PRECO
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @FATURAMENTO = @FATURAMENTO + (@QTD * @PRECO)
    FETCH NEXT FROM CURSOR_FATURAMENTO INTO @QTD, @PRECO
END -- WHILE

PRINT 'FATURAMENTO: ' + CONVERT(VARCHAR(MAX),@FATURAMENTO)
CLOSE CURSOR_FATURAMENTO
DEALLOCATE CURSOR_FATURAMENTO
2 respostas
solução!

Bom dia Victor,

O FLOAT normalmente possui 32 bits para representar o expoente e a mantissa, além do sinal. Dá pra representar muitos números, mas por sua natureza binária não consegue representar todos os números, então ele representa o que está mais próximo do que se deseja. Ele tem 24 dígitos de precisão e por isso é chamado de simples precisão. Muitos cálculos necessitam precisão, mas não exatidão. Então pelo computador se dar melhor com ele, use-o. Se for algo científico de cálculos pesados a performance faz muita diferença. O mesmo pode-se dizer de computação gráfica ou jogos. Haverá um arredondamento de qualquer forma, então a falta de exatidão prejudica nada.

O tipo DECIMAL tem exatidão, ele é sobre ter o número exato que se pretende. Ele indica que o número está em conformidade com o que se espera. Ele chama decimal por ter base 10 e não binária como os anteriores. Cada tecnologia o implementa de alguma forma diferente. É comum guardar a parte inteira e decimal separadamente em inteiros, ou guardar tudo junto em um inteiro e determinar uma escala, ou seja, onde o ponto flutuante está, quantas casas ele deve assumir, em geral é um inteiro dividido por 1, 10, 100, 1000, etc. Por ser decimal a performance não é das melhores, mas longe de ser uma tragédia. Em geral não é um problema por trabalhar com valor monetário e os cálculos onde ele é envolvido costumam ser simples, se comparados com científicos e CGI. Os cálculos são feitos com instruções de inteiros do processador, o que é rápido, mas precisa de vários passos de normalização do número, precisa prover algum arredondamento, muitas vezes o seu código precisa fazer alguma conta extra, então acaba ficando mais lento, mas nada crítico.

Espero ter ajudado.

Abraço!!

Muito obrigado, Stefano!