Carregando ...
Desculpe, ocorreu um erro ao carregar o conteúdo.

33135RE: [mssql-l] Aproximação do flo at em comaparação do tipo doble da aplicação

Expandir mensagens
  • João Polisel
    9 de out de 2015

      Boa noite,

       

      A função POWER retorna o mesmo tipo de dado informado no primeiro argumento. Veja:

       

      declare @x float

      declare @y float

      declare @ret sql_variant

       

      set @x = 2

      set @y = 2

       

      set @ret = power(@x, @y)

      select @ret

       

      select

             SQL_VARIANT_PROPERTY(@ret, 'BaseType')

             , SQL_VARIANT_PROPERTY(@ret, 'Precision')

             , SQL_VARIANT_PROPERTY(@ret, 'Scale')

             , SQL_VARIANT_PROPERTY(@ret, 'TotalBytes')

             , SQL_VARIANT_PROPERTY(@ret, 'Collation')

             , SQL_VARIANT_PROPERTY(@ret, 'MaxLenght')

       

      BaseType deve informar float e Precision deve ser igual a 53. Um tipo float(53) é o sinônimo para double precision.

       

      Entretanto o tipo float representa um número aproximado e essa é a definição do tipo J portanto arredondamentos e diferenças podem ocorrer e são características desse tipo.

       

      Para evitar esse inconveniente você pode usar um tipo exato, como decimal (ou numeric). Que tal 30 casas decimais?

       

      declare @x decimal(38,30)

      declare @y float

      declare @ret sql_variant

       

      set @x = 2

      set @y = 2

       

      set @ret = power(@x, @y)

      select @ret

       

      select

             SQL_VARIANT_PROPERTY(@ret, 'BaseType')

             , SQL_VARIANT_PROPERTY(@ret, 'Precision')

             , SQL_VARIANT_PROPERTY(@ret, 'Scale')

             , SQL_VARIANT_PROPERTY(@ret, 'TotalBytes')

             , SQL_VARIANT_PROPERTY(@ret, 'Collation')

             , SQL_VARIANT_PROPERTY(@ret, 'MaxLenght')

       

      OBS.: Usei nos exemplos o tipo sql_variant apenas para demonstrar o que a função POWER() retorna. Em situações normais você deve atribuir o resultado a uma variável ou campo utilizando um tipo não variável.

       

      Se ainda assim não acertar mão no seu script, por favor mande os valores usados para o cálculo.

       

      Como observação adicional, a boa prática de arquitetura recomenda que você não faça cálculos no SQL Server, e sim na aplicação. Sabemos que em certos casos pode ser mais conveniente, ou até mesmo inevitável fazer os cálculos no banco de dados, então aqui vai uma dica: SQL CLR pode ser muito mais rápido em vários cenários. Quando a sua tarefa envolver uma lógica complexa (vários loops, IFs, etc) considere o uso do SQL CLR.

       

      http://blogs.msdn.com/b/sqlclrperf/archive/2007/03/08/scalar-functions.aspx

       

      []s

       

      João Polisel

       

       

      From: mssql-l@... [mailto:mssql-l@yahoogrupos.com.br]
      Sent: Wednesday, October 7, 2015 10:50 AM
      To: mssql-l@...
      Subject: [mssql-l] Aproximação do float em comaparação do tipo doble da aplicação

       

       

      Senhores,

       

      Estou convertendo uma aplicação para procedure a aplicação é powerbuilder e um dos cálculos que está sendo feito utilizar potência ao utilizar a potência o sql convert automaticamente o valor calculado para float o problema é que a precisão do campo float é de 15 casas decimais e a doble é 18.

      Alguém já enfrentou este problema pois esta dando umas diferenças de 1 centavo na 15ª casa decimal, tipo o valor correto é 83,24738293819038475 e esta dando 83,24738293819038474.

       

       

       

    • Mostrar todas as 3 mensagens neste tópico