Bug - Arredondamento de Valores - "Resolvido"

Olá a todos,

Favor, alguém mais pode fazer um teste e dizer se realmente é um bug, ou está acontecendo somente comigo aqui.

Campo do tipo Float (Decimal). Ao inserir um valor no formato:

11.111,11 >> 11.111,10
11.111,12 >> 11.111,10
11.111,13 >> 11.111,10
11.111,14 >> 11.111,10

Ele está aredondado o ultimo centavo, e acaba roubando 0,01 ou até 4 centavo(s).

Qual o banco ?

Ola Regis,
Fiz o teste no banco postgres utilizando um campo do tipo character varying e no sc do tipo decimal com 2 casas decimais e nao arredondou.
ficando assim no banco
sc banco
11.111,12 >11111.12

Fiz o teste no banco mysql utilizando um campo do tipo float e no sc do tipo decimal com 2 casas decimais e nao arredondou.
sc banco
11.111,12 >11111.12

Atenciosamente Arquimedes

Eu utilizo no banco Decimal(12,2) MySql, e não da esse problema.

No postgres sem problemas tb !

Não sei mais o que fazer, o trem aqui arredonda…

Ninguém está com o mesmo problema ?

Vou gravar um vídeo mostrando pra vcs!

Preciso resolver isso, meu cliente está pegando no meu pé.

Link:

http://www.gestorcustom.com.br/bug/arredondamento/

www.isub.com.br/test_script

coloquei a aplicação zipada neste link com o .sql - caso queira visualizar

mas se achar mais facil pode testar ai, em vez de “FLOAT” use “DOUBLE”.

  1. Para cálculos monetários no mysql considere o seguinte:

Decimal ou Numeric => precisão para cálculos matemáticos.
Float e Double => Trabalham com arredondamento e aproximação.

Campos tipo: FLOAT, REAL e DOUBLE PRECISION são campos com dados numéricos aproximados.
Enquanto campos tipo NUMERIC, DECIMAL, INTEGER, e SMALLINT são campos de de dados numéricos exatos.
Para valores monetários devem ser usados NUMERIC E DECIMAL para prever com exatidão os valores monetários.

Do manual do mysql ( http://dev.mysql.com/doc/refman/5.7/en/numeric-types.html ):

"MySQL suporta todos os tipos numéricos da ANSI/ISO SQL92. Estes tipos incluem o tipos de dados numéricos exatos (NUMERIC, DECIMAL, INTEGER, e SMALLINT), assim como o tipos de dados numéricos aproximados (FLOAT, REAL, e DOUBLE PRECISION). A palavra-chave INT é um sinônimo para INTEGER, e a palavra-chave DEC é um sinônimo para DECIMAL.

Os tipos NUMERIC e DECIMAL são implementados como o mesmo tipo pelo MySQL, como permitido pelo padrão SQL92. Eles são usados por valores para os quais é importante preservar a exatidão como, por exemplo, dados monetários. Quando é declarado um campo de algum desses tipos a precisão e a escala podem ser (e normalmente é) especificadas; por exemplo:

salario DECIMAL(5,2)"

No caso do tipo FLOAT a mesma parte do manual diz:

"O tipo FLOAT é usado para representar tipos de dados numéricos aproximados. O padrão SQL-92 permite uma especificação opcional da precisão (mas não da faixa do expoente) em bits, após a a palavra FLOAT e entre parenteses. A implementação MySQL também suporta esta especificação opcional de precisão. Quando FLOAT é usada para uma tipo de coluna sem especificação de precisão, MySQL utiliza quatro bytes para armazenar os valores. Uma sintaxe variante também é suportada, com dois numeros entre parenteses após a palavra FLOAT. Com esta opção, o primeiro número continua a representar a quantidade de bytes necessária para armazenar o valor, e o segundo número especifica o número de dígitos a serem armazenados e mostrados após o ponto decimal (como com DECIMAL e NUMERIC). Quando é pedido ao MySQL para armazenar um número em uma coluna com mais digitos decimais após o ponto decimal que o especificado para esta coluna, o valor é arredondado eliminando os digitos extras quando armazenado."

Uma coisa que não vi você fazer é determinar a precisão do seu campo tipo FLOAT.

Meu conselho é usar no lugar do campo FLOAT o DECIMAL ou NUMERIC com precisão 2 ou 4 conforme o caso.
Por exemplo, as bombas de gasolina trabalham com precisão 4.

  1. Para cálculos monetários no PHP considere usar a biblioteca BCMATH ( BCMath Funções Matemáticas de Precisão Arbitrária ) .
    No manual do php http://www.php.net/manual/pt_BR/book.bc.php
    Não vou explicar porque usar a bcmath, mas deixo um link com a explicação:
    http://bordim.net.br/programacao/php-e-o-ponto-flutuante/

Espero ter ajudado.

buhlerax, Obrigado pelo esclarecimento…

Valeu a todos,

Realmente é a utilização do float, “Resolvido”

Mudei para Decimal(12,2)

Cada resposta do Alexandre é uma aula.

Um abraço, professor.
Cuidado com o frio de Ctba.

Valeu.
Quando o frio chegar tomarei cuidado.
heheheeh