recuperar dados do banco

73 views
Skip to first unread message

Daniel Vilar

unread,
Sep 17, 2012, 2:56:26 PM9/17/12
to rail...@googlegroups.com
Pessoal, estou recuperando dados do banco mas está vindo errado!
ex:
  no banco: 0.07
  retorna : 0.07000000000000001

Este erro ocorre tanto no console quanto na view!

alguns valores ele retorna correto mas outros ele traz esse lixo.

Estou usando o oracle_enhanced_adapter com oci-8.

Algum sabe o que é isto?


Att,

CARDOSO, Daniel Fernandes Vilar.
Analista de Sistemas.

Douglas Camata

unread,
Sep 17, 2012, 2:57:15 PM9/17/12
to rail...@googlegroups.com
Isso é a imprecisão da representação do float no sistema binário.

2012/9/17 Daniel Vilar <fvcd...@gmail.com>


--
Você recebeu essa mensagem porquê está inscrito no Google
Groups "rails-br".
Para enviar uma mensagem para o grupo, mande um email para rail...@googlegroups.com
Para se descadastrar, mande um e-mail para
rails-br+u...@googlegroups.com
Visite o grupo em http://groups.google.com/group/rails-br?hl=pt-BR
Leia nossa política de uso: http://goo.gl/YGgt7



--
Douglas Camata
Graduando em Ciência da Computação (UENF)

Skype: douglas_camata
-----------------------------------
Linux User #509211

Daniel Vilar

unread,
Sep 17, 2012, 3:02:58 PM9/17/12
to rail...@googlegroups.com
Blz, como resolve?




Att,

CARDOSO, Daniel Fernandes Vilar.
Analista de Sistemas.



2012/9/17 Douglas Camata <d.ca...@gmail.com>

Douglas Camata

unread,
Sep 17, 2012, 3:08:27 PM9/17/12
to rail...@googlegroups.com
Ai eu não sei. Fiz um trabalhos de cálculo numérico em Python que precisavam de precisão grande e usei o módulo "decimal" dele. Não sei se existe um equivalente em Ruby.

2012/9/17 Daniel Vilar <fvcd...@gmail.com>

Stclara

unread,
Sep 17, 2012, 3:21:22 PM9/17/12
to rail...@googlegroups.com
Salve.
Não sei que tipo de campo é e se vc precisa formatado só na view, mas para money uso:
number_to_currency(seu_campo).

Se quiser duas casas após o ponto:
format("%.2f", seu_campo).

[]'s


Stclara.

Daniel Vilar

unread,
Sep 17, 2012, 3:26:35 PM9/17/12
to rail...@googlegroups.com
O problema aparentemente é com o bigdecimal.
quando eu faço .to_f ele retorna o valor correto.

Mas essa solução não é mto DRY.




Att,

CARDOSO, Daniel Fernandes Vilar.
Analista de Sistemas.



2012/9/17 Stclara <stc...@gmail.com>

Stclara

unread,
Sep 17, 2012, 3:34:18 PM9/17/12
to rail...@googlegroups.com
Será que a formatação de precision no locale não resolve? O meu está assim (pt_BR.yml):

number:
    format:
      separator: ','
      delimiter: '.'
      precision: 2
      significant: false
      strip_insignificant_zeros: false

    currency:
      format:
        format: '%u %n'
        unit: 'R$'
        separator: ','
        delimiter: '.'
        precision: 2
        significant: false
        strip_insignificant_zeros: false

[]'s

Stclara.

Daniel Vilar

unread,
Sep 17, 2012, 3:42:51 PM9/17/12
to rail...@googlegroups.com
Está igual, não acho que seja isso.
Tem alguma imprecisão com numeros flutuantes como disse o Douglas.
Depois eu irei testar com outras versões do Ruby. Estou usando a 1.9.3-194.

De qualquer forma obrigado!

Douglas Camata

unread,
Sep 17, 2012, 3:43:56 PM9/17/12
to rail...@googlegroups.com
Daniel, a imprecisão vai existir em qualquer versão do Ruby, ela vem do hardware. Você pode, e deve, formatar os floats que for usar. 

2012/9/17 Daniel Vilar <fvcd...@gmail.com>

Stephen Eilert

unread,
Sep 17, 2012, 4:46:11 PM9/17/12
to rail...@googlegroups.com
2012/9/17 Daniel Vilar <fvcd...@gmail.com>
Blz, como resolve?


Não "resolve". Não existe representação exata em ponto-flutuante na base 2 para 0.07 (http://www.wolframalpha.com/input/?i=0.07+to+base+2)

Ou ainda:

$ irb
> printf("%.50f", 0.07)
0.07000000000000000666133814775093924254179000854492 => nil 

O problema aparentemente é com o bigdecimal.
quando eu faço .to_f ele retorna o valor correto.

Não, piorou, ele apenas está exibindo arredondado. BigDecimal consegue representar números com precisão arbitrária (não usa o hardware para isso), mas você vai ter que se assegurar que tudo está trabalhando com BigDecimal (ou equivalente, no caso do banco).

E não tente fazer coisas do tipo:

BigDecimal.new("0.07") + 0.1 => ele vai fazer cast pra float, pra depois fazer a soma. No IRB vai aparecer como 0.17, mas isso é só porque ele está arredondando/truncando o resultado pra você para duas casas decimais.

> BigDecimal.new("0.07") + 0.1
 => 0.17 

> printf("%.50f", (BigDecimal.new("0.07") + 0.1))
0.17000000000000001221245327087672194465994834899902 => nil 

Dito isso, a não ser que você esteja trabalhando com valores monetários (que não devem usar float mesmo) ou seja resultado de inúmeras operações em ponto flutuante, isso não têm importância. Formate antes de imprimir para o usuário com a precisão que você quer.

Recomendo ler um pouco mais sobre representação de números em ponto flutuante (base 2). Você vai esbarrar com problemas desse tipo de vez em quando - por exemplo, na hora de comparar 2 Floats. Ruby é bonzinho e tenta usar Float::EPSILON pra isso, mas nem sempre é o valor correto para seu caso.


-- Stephen

"Kids these days.
Whatever happened to hard work?"

       -- Joel Spolsky, The perils of javaschools

Daniel Vilar

unread,
Sep 17, 2012, 5:00:53 PM9/17/12
to rail...@googlegroups.com
Galera, obrigado pela ajuda. Deu para entender o que aconteceu. Este campo é referente a um percentual que e eu já estou contornando o problema na view.

Obrigado.




Att,

CARDOSO, Daniel Fernandes Vilar.
Analista de Sistemas.



2012/9/17 Stephen Eilert <sped...@gmail.com>
Reply all
Reply to author
Forward
0 new messages