Números decimais no MySQL

5,292 views
Skip to first unread message

Rodrigo

unread,
Nov 20, 2009, 2:21:31 PM11/20/09
to LISTA PHP
Alguém já precisou usar um número maior que 99999,99 no MySQL?
Preciso de mais casas após a vírgula, daí fui todo bobo colocar FLOAT
(14,13) para inserir um valor tipo: 26.7217630853994. E para minha
surpresa, ao inserir o valor pelo phpmyadmin não deu erro.

Então fui conferir o registro e tava assim: 10.0000000000000. Ou seja,
o FLOAT é limitado.

E agora?
Qual tipo de dado eu uso pra um campo desses?
DECIMAL(14,13)?

Preciso de uma variação assim:
De 0000.0000000000000 até 9999.9999999999999.

João Batista

unread,
Nov 20, 2009, 2:38:50 PM11/20/09
to list...@googlegroups.com
Rodrigo para esses valores eu uso sempre o tipo double, faça um teste com ele...


Um abraço,
Batista

2009/11/20 Rodrigo <rodrigo....@gmail.com>:

Julio Schneider

unread,
Nov 20, 2009, 2:41:20 PM11/20/09
to list...@googlegroups.com
Eu posso estar enganado, mas eu acho que pro número ficar com 2 casas antes da virgula e 13 casas depois da vírgula ele deveria ter o formato DOUBLE(15,13) e não DOUBLE(14,13) faz tempo que não uso mysql =P

Abraços!

2009/11/20 João Batista <jo.b...@gmail.com>

Rodrigo

unread,
Nov 20, 2009, 2:45:41 PM11/20/09
to LISTA PHP
O DOUBLE(15,13) e o DECIMAL(14,13) funcionaram corretamente. Agora eu
gostaria de ter certeza disso... hehe


On Nov 20, 5:41 pm, Julio Schneider <julioch...@gmail.com> wrote:
> Eu posso estar enganado, mas eu acho que pro número ficar com 2 casas antes
> da virgula e 13 casas depois da vírgula ele deveria ter o formato
> DOUBLE(15,13) e não DOUBLE(14,13) faz tempo que não uso mysql =P
>
> Abraços!
>
> 2009/11/20 João Batista <jo.bat...@gmail.com>
>
>
>
>
>
> > Rodrigo para esses valores eu uso sempre o tipo double, faça um teste com
> > ele...
>
> > Um abraço,
> > Batista
>
> > 2009/11/20 Rodrigo <rodrigo.speng...@gmail.com>:
>
> > > Alguém já precisou usar um número maior que 99999,99 no MySQL?
> > > Preciso de mais casas após a vírgula, daí fui todo bobo colocar FLOAT
> > > (14,13) para inserir um valor tipo: 26.7217630853994. E para minha
> > > surpresa, ao inserir o valor pelo phpmyadmin não deu erro.
>
> > > Então fui conferir o registro e tava assim: 10.0000000000000. Ou seja,
> > > o FLOAT é limitado.
>
> > > E agora?
> > > Qual tipo de dado eu uso pra um campo desses?
> > > DECIMAL(14,13)?
>
> > > Preciso de uma variação assim:
> > > De 0000.0000000000000 até 9999.9999999999999.- Hide quoted text -
>
> - Show quoted text -

Julio Schneider

unread,
Nov 20, 2009, 3:05:33 PM11/20/09
to list...@googlegroups.com
Eu acho que tá certo sim cara, mas faz mais testes.

Só lembre que o conjunto dentro do parenteses nesse caso significa

NUMERO_TOTAL_DE_CASAS,CASAS_DECIMAIS

Ou seja, 15,13 vão ser 2 casas e 13 decimais, entende?

Abraços

2009/11/20 Rodrigo <rodrigo....@gmail.com>

Rodrigo

unread,
Nov 20, 2009, 3:18:34 PM11/20/09
to LISTA PHP
Putz... imaginei que fosse 15 antes de vírgula e 13 depois... hehe
Eu só sabia que em FLOAT(X,Y), o X deveria ser maior que Y, mas eu não
entendia porque.

Obrigado por explicar!


Em http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html é
possível encontrar uma explicação em Inglês. Porém ela me deixa na
dúvida entre DECIMAL e DOUBLE, já que o DECIMAL fica diferente para o
MySQL 5.0.3 e superiores.

Nesse meu caso (MySQL 5), devo usar: DOUBLE(18,13) ou DECIMAL(18,13)
para representar um número de 0.0000000000000 até 99999.9999999999999.
É isso?

Obrigado!


On Nov 20, 6:05 pm, Julio Schneider <julioch...@gmail.com> wrote:
> Eu acho que tá certo sim cara, mas faz mais testes.
>
> Só lembre que o conjunto dentro do parenteses nesse caso significa
>
> NUMERO_TOTAL_DE_CASAS,CASAS_DECIMAIS
>
> Ou seja, 15,13 vão ser 2 casas e 13 decimais, entende?
>
> Abraços
>
> 2009/11/20 Rodrigo <rodrigo.speng...@gmail.com>
> > > - Show quoted text -- Hide quoted text -

Julio Schneider

unread,
Nov 20, 2009, 3:23:35 PM11/20/09
to list...@googlegroups.com
Sempre as ordi =)

2009/11/20 Rodrigo <rodrigo....@gmail.com>

Rodrigo

unread,
Nov 20, 2009, 3:26:48 PM11/20/09
to LISTA PHP
Fiz mais testes e usei o limite que mencionei anteriormente
(99999.9999999999999).

Quando usei esse limite aconteceu o seguinte:
DOUBLE(18,13) = Arredondou para 10000.0000000000000
DECIMAL(18,13) = Manteve o valor 99999.9999999999999

Portanto, o mais preciso seria usar DECIMAL(18,13).

Julio Schneider

unread,
Nov 20, 2009, 3:30:45 PM11/20/09
to list...@googlegroups.com
Nesse link aqui http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html

lá pro fim vc vai ver uma explicação dizendo que o DECIMAL deve ser usado quando vc precisa de precisão em números absurdamente grandes =)

2009/11/20 Rodrigo <rodrigo....@gmail.com>

Rodrigo

unread,
Nov 20, 2009, 3:43:23 PM11/20/09
to LISTA PHP
Talvez seja o meu caso...

Pra explicar melhor, preciso dividir um valor monetário (Ex.: R$
106700,00) em várias partes/cotas (Ex.: 3993).
Essa divisão gera o valor: R$ 26,7217630853994 que será o Valor por
Cota.

Esse valor por cota é armazenado no BD e utilizo posteriormente para
calcular a contribuição de cada integrante do grupo.
Ou seja, se eu tenho 50 cotas, vou ter que pagar aproximadamente R$
1336,09.
Se eu usar um valor truncado ou arredondado (R$ 26,72), o valor total
será de R$ 1336,00.

Ou seja, em apenas 1 integrante do grupo a diferença foi de R$ 0,09.
Agora imagine 1000 integrantes com cotas diferentes.

Eu fiz um teste antes, sem usar 13 como máximo de casas após a vírgula
e houve casos em que o valor dava R$ 300 a mais ou a menos na soma de
todos os integrantes.

E como estou mexendo com dinheiro dos outros, o ideal é não fazer
cálculos errados.

Será que estou "apelando" demais ao usar o DECIMAL?


On Nov 20, 6:30 pm, Julio Schneider <julioch...@gmail.com> wrote:
> Nesse link aquihttp://dev.mysql.com/doc/refman/5.0/en/numeric-types.html
>
> lá pro fim vc vai ver uma explicação dizendo que o DECIMAL deve ser usado
> quando vc precisa de precisão em números absurdamente grandes =)
>
> 2009/11/20 Rodrigo <rodrigo.speng...@gmail.com>
>
>
>
>
>
> > Fiz mais testes e usei o limite que mencionei anteriormente
> > (99999.9999999999999).
>
> > Quando usei esse limite aconteceu o seguinte:
> > DOUBLE(18,13) = Arredondou para 10000.0000000000000
> > DECIMAL(18,13) = Manteve o valor 99999.9999999999999
>
> > Portanto, o mais preciso seria usar DECIMAL(18,13).
>
> > On Nov 20, 6:18 pm, Rodrigo <rodrigo.speng...@gmail.com> wrote:
> > > Putz... imaginei que fosse 15 antes de vírgula e 13 depois... hehe
> > > Eu só sabia que em FLOAT(X,Y), o X deveria ser maior que Y, mas eu não
> > > entendia porque.
>
> > > Obrigado por explicar!
>
> > > Emhttp://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.htmlé<http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html%C3%A9>

Julio Schneider

unread,
Nov 20, 2009, 3:45:24 PM11/20/09
to list...@googlegroups.com
Tá certíssimo. Lembro de uma professora de matemática que eu tinha na quinta série que me falou "toda vez que você arredonda um número, você comete um erro" ou seja, essa porra aí se for double sempre vai acabar te "traindo" e te dando centavos pra mais ou pra menos e vai sobrar pra vc heehhe

=)

2009/11/20 Rodrigo <rodrigo....@gmail.com>

Rodrigo

unread,
Nov 20, 2009, 3:56:49 PM11/20/09
to LISTA PHP
Valeu pela força!

Vou implementar dessa forma para evitar problemas no futuro.

On Nov 20, 6:45 pm, Julio Schneider <julioch...@gmail.com> wrote:
> Tá certíssimo. Lembro de uma professora de matemática que eu tinha na quinta
> série que me falou "toda vez que você arredonda um número, você comete um
> erro" ou seja, essa porra aí se for double sempre vai acabar te "traindo" e
> te dando centavos pra mais ou pra menos e vai sobrar pra vc heehhe
>
> =)
>
> 2009/11/20 Rodrigo <rodrigo.speng...@gmail.com>

Jean

unread,
Nov 20, 2009, 2:27:11 PM11/20/09
to list...@googlegroups.com
Peor q nao sei mas ja testou double? ou real?

2009/11/20 Rodrigo <rodrigo....@gmail.com>:
--
[]´s Jean a.k.a Suissa

Tecnólogo em Análise de Sistemas - UTF-PR
131

www.twitter.com/suissacorp

Tiago Natel de Moura

unread,
Nov 20, 2009, 3:51:15 PM11/20/09
to list...@googlegroups.com
>Tá certíssimo. Lembro de uma professora de matemática que eu tinha na quinta série que me falou "toda vez que você arredonda um número, você comete um erro"

Sua professora estava errada ! Depende do número e de como ele foi obtido.
Operações sobre dados experimentais, por exemplo, tornam-se erradas se voce "não" arredondar. :)

:)

Tiago Natel de Moura
http://blog.tiagomoura-design.com.br



Achetez un nouveau PC et bénéficiez de Windows 7 dès sa sortie ! En savoir plus

Tiago Natel de Moura

unread,
Nov 20, 2009, 3:59:47 PM11/20/09
to list...@googlegroups.com
Sobre o arredondamento de monetário. Voce não pode obter mais casas decimais do que a menor unidade monetária, ou seja, no nosso caso o centavo.

Você não pode obter divisões e obter 0.1 centavos, etc quando ocorrer isso (somente quando acontecer isso) vc deve arredondar da meneira correta.
Não precisa usar um tipo de dado absurdamente grande, isso é errado pois com isso vai perder ou ganhar dinheiro.

Até mais.
Gratuit : Hotmail plus rapide avec Internet Explorer 8 ! Cliquez ici !

Rodrigo

unread,
Nov 20, 2009, 6:05:02 PM11/20/09
to LISTA PHP
Olá Tiago!

Não tiro sua razão quanto a valor monetário, porém o valor do montante
deve ser rateado de forma muito justa. Ou seja, nenhum integrante deve
ser beneficiado ou prejudicado por um arredondamento logo na segunda
casa após a vírgula.

Resolvi usar uma quantidade de 13 casas, pois creio que seja o mais
justo possível para esse sistema, já que no final das contas, o valor
de diferença não passa de R$ 1,00 entre todos os integrantes.

Um caso comum de cobrança usando mais de 2 casas após a vírgula, é o
Combustível.

É só fazer a conta!
Exemplo:
R$ 2,59 * 50 litros = R$ 129,50
R$ 2,599 * 50 litros = R$ 129,95
R$ 2,60 * 50 litros = R$ 130,00

Os postos de gasolina utilizam R$ 2,599 para dar uma falsa impressão
de R$ 2,59, enquanto faturam quase R$ 0,01 por litro.
Para o nosso carro, quase não importa se é R$ 2,599, pois vai deixar
de voltar apenas R$ 0,45 no troco, porém se colocarmos 200 carros por
dia nos 30 dias do mês já dá R$ 2700,00.

Enfim, sempre é bom usar os decimais pra ser justo, pois o
arredondamento pode prejudicar no final das contas.


On Nov 20, 6:59 pm, Tiago Natel de Moura <tiago_mo...@live.com> wrote:
> Sobre o arredondamento de monetário. Voce não pode obter mais casas decimais do que a menor unidade monetária, ou seja, no nosso caso o centavo.
>
> Você não pode obter divisões e obter 0.1 centavos, etc quando ocorrer isso (somente quando acontecer isso) vc deve arredondar da meneira correta.
> Não precisa usar um tipo de dado absurdamente grande, isso é errado pois com isso vai perder ou ganhar dinheiro.
>
> Até mais.
>
> Tiago Natel de Mourahttp://blog.tiagomoura-design.com.br
>
> _________________________________________________________________
> A la recherche de bons plans pour une rentrée pas chère ? Bing ! Trouvez !http://www.bing.com/search?q=bons+plans+rentr%C3%A9e&form=MVDE6

Tiago Natel de Moura

unread,
Nov 20, 2009, 11:22:18 PM11/20/09
to list...@googlegroups.com
Sim, postos de combustiveis usam mais de duas casas decimais após a virgula. Mas cálculos monetários sempre utilizam números reais de casas decimais fixas OU números inteiros. Tem uma grande discussão encima disto.

Sua dúvida nesta thread acho que já foi respondida né, não quero começar outra discussão sobre o padrão de cálculo monetário mas por informação acho que só existe essas duas maneiras corretas de se fazer isso:

1 - (Mais comum) Usar números reais de precisão previamente estabelecido (posto de combustivel? 3 casas. Comércio? 2 casas), aplicar todas as operações matemáticas normalmente (sem arredondamento) e no "resultado final" ignorar todas as casas maiores que 2, se for necessário arredondar. Ex.: Resultado final: R$ 1245,328244645646876764646876446876 = R$ 1245,33

2 - (Acredita-se que a mais correta, mas não muito frequente) Usar números inteiros e contar todo valor monetário como unidades fixas da menor unidade monetária da moeda (nosso caso centavo). Aplica-se todas as operações matemáticas sobre os centavos depois transforma-se para reais. Lembre-se que são unidades indivisiveis, ou seja:

R$ 10,00 divididos entre três pessoas seria:
R$ 10,00 x 100 = 1000 centavos.
Divisão inteira de 1000 por três pessoas = 333 mais resto 1, ou seja
1000 centavos por tres pessoas ficam duas pessoas com 333 e uma com 334 centavos.
Pessoal do Java tá acostumado com isso e usar até um pattern chamado "Money". Pesquise sobre design pattern Money.

Incrivel mas já vi coisas absurdas em ecommerce em PHP como: sprintf("%.2f", $valor1 / $valor2); oO

Até mais.

felipe moraes

unread,
Nov 21, 2009, 1:10:28 PM11/21/09
to list...@googlegroups.com
pelo q lembro ...

não seria ..

DECIMAL( 17, 2 )

tamanho de 17, 15 antes da virgula e 2 depois ..

??

esse FLOAT( 17,13 ) com 13 casas decimais ficou esquisito ..

felipe moraes

unread,
Nov 21, 2009, 1:15:44 PM11/21/09
to list...@googlegroups.com
hum ...

mantenha 2 casas decimais .. que é o padrão brasileiro ..

use tecnicas de arredondamento ..

onde a diferença vc coloca no ultimo pagamento .. ou logo no primeiro ...

12 parcelas de 15 e 1 de 16 ...

1 parcela de 16 e 11 de 15 ..

assim vc tiraria a diferença ..

ou faz .. arredondamento sempre para mais .. assim não terá prejuizo ..

Eduardo Kraus

unread,
Nov 22, 2009, 4:37:11 AM11/22/09
to list...@googlegroups.com
o decimal é mais é mais preciso pois salva dois inteiros separados por virgula. Já o Float salva apenas um float.

Então quando precisar de precisão, use DECIMAL.


Eduardo Kraus

Desenvolvedor
eduard...@gmail.com
blog.mxml.com.br
www.twitter.com/EduardoKraus


2009/11/20 Rodrigo <rodrigo....@gmail.com>
Reply all
Reply to author
Forward
0 new messages