I am using a legacy database with mysql. I am working stuff through in the console and it tells me... @price = Price.find(:first, :conditions => ["stockid = ? AND typeabbrev = ?", @test, "WH"]).price => #<Price price: #<BigDecimal:b7a7341c,''0.115E1'',8(12)>> So I need to coerce this into a float... I added to app/controllers/application_controller.rb (at the very bottom of the file)... # Provides extension to Numerics to provide subject decimal places class Float def to_fl(digits) sprintf("%.#{digits}f",self) end end which used to work fine for me in Rails 1.2.6...but in the 2.3.2 console...>> @price.to_i=> 1>> @price.to_fl(2)NoMethodError: undefined method `to_fl'' for #<BigDecimal:b794c0fc,''0.115E1'',8(12)> from (irb):30 from :0 How do I get the float value of ''big decimal'' ? Craig -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
Craig White wrote: [...]> NoMethodError: undefined method `to_fl'' for > #<BigDecimal:b794c0fc,''0.115E1'',8(12)> > from (irb):30 > from :0 > > How do I get the float value of ''big decimal'' ? >Perhaps you should have checked the class documentation for BigDecimal (part of the Ruby standard library). If I remember correctly, BigDecimal#to_f will do what you want. to_f is the standard name for such methods; to_fl is idiosyncratic, and will cause problems if the consumers of your API expect to_f. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org> Craig-- Posted via http://www.ruby-forum.com/.
On Wed, 2009-06-03 at 07:07 +0200, Marnen Laibow-Koser wrote:> Craig White wrote: > [...] > > NoMethodError: undefined method `to_fl'' for > > #<BigDecimal:b794c0fc,''0.115E1'',8(12)> > > from (irb):30 > > from :0 > > > > How do I get the float value of ''big decimal'' ? > > > > Perhaps you should have checked the class documentation for BigDecimal > (part of the Ruby standard library). If I remember correctly, > BigDecimal#to_f will do what you want. > > to_f is the standard name for such methods; to_fl is idiosyncratic, and > will cause problems if the consumers of your API expect to_f.---- yeah, I''m sort of stuck in a rails 1.2.x time warp and am struggling with a bunch of the changes in 2.3.x - thus, it wasn''t really the big decimal thing of mysql that was the problem. I forgot about to_f because frankly, I never used it. I primarily am concerned with view code here so I had just stuck that code to extend the Float class (which worked so well in 1.2.x)... class Float def to_fl(digits) sprintf("%.#{digits}f",self) end end and I could get a fixed number of digits whenever I wanted. Apparently this is like a very ineffective way to go about things in 2.3.x and to_f gives me whatever decimal places it believes are significant so I''m sort of trying to figure out how to locate the magic genie again. Craig -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
2009/6/3 Craig White <craigwhite-BQ75lA0ptkhBDgjK7y7TUQ@public.gmane.org>:> ... > I forgot about to_f because frankly, I never used it. I primarily am > concerned with view code here so I had just stuck that code to extend > the Float class (which worked so well in 1.2.x)... > > class Float > def to_fl(digits) > sprintf("%.#{digits}f",self) > end > end > > and I could get a fixed number of digits whenever I wanted. Apparently > this is like a very ineffective way to go about things in 2.3.x and to_f > gives me whatever decimal places it believes are significant so I''m sort > of trying to figure out how to locate the magic genie again. > > Craig >I am not sure whether you still have a problem. It is not strictly correct to say that to_f gives me whatever decimal places it believes are significant. A float will always contain as many digits as it can hold. Is the problem that you wish to display it to a certain number of digits? If so then you can use sprintf. Alternatively of course there is the question of whether you need to convert it to a float in the first place. Can you just keep it as BigDecimal? Colin
The problem is that you''re defining this method (to_fl) on Float, while AR is returning you a BigDecimal. Have you tried defining the method in the correct class? You don''t appear to really want the "float value"; for large numbers, it will lose a lot of precision (and thus the advantage of storing in a :decimal column). --Matt Jones On Jun 3, 1:53 am, Craig White <craigwh...-BQ75lA0ptkhBDgjK7y7TUQ@public.gmane.org> wrote:> yeah, I''m sort of stuck in a rails 1.2.x time warp and am struggling > with a bunch of the changes in 2.3.x - thus, it wasn''t really the big > decimal thing of mysql that was the problem. > > I forgot about to_f because frankly, I never used it. I primarily am > concerned with view code here so I had just stuck that code to extend > the Float class (which worked so well in 1.2.x)... > > class Float > def to_fl(digits) > sprintf("%.#{digits}f",self) > end > end > > and I could get a fixed number of digits whenever I wanted. Apparently > this is like a very ineffective way to go about things in 2.3.x and to_f > gives me whatever decimal places it believes are significant so I''m sort > of trying to figure out how to locate the magic genie again. > > Craig > > -- > This message has been scanned for viruses and > dangerous content by MailScanner, and is > believed to be clean.
Thanks - I see said the blind man... all I had to do was to first convert big decimal to float and then the sprint function worked. @price.to_f.to_fl(2) and I get what I wanted in the view...something displayed to 2 decimal places. The value is already stored with big_decimal precision...I just didn''t know how to format it in a view, which turned out to be trickier than if I just a float value. Craig On Wed, 2009-06-03 at 06:59 -0700, Matt Jones wrote:> > The problem is that you''re defining this method (to_fl) on Float, > while AR is returning you a BigDecimal. Have you tried defining the > method in the correct class? > > You don''t appear to really want the "float value"; for large numbers, > it will lose a lot of precision (and thus the advantage of storing in > a :decimal column). > > --Matt Jones > > > On Jun 3, 1:53 am, Craig White <craigwh...-BQ75lA0ptkhBDgjK7y7TUQ@public.gmane.org> wrote: > > yeah, I''m sort of stuck in a rails 1.2.x time warp and am struggling > > with a bunch of the changes in 2.3.x - thus, it wasn''t really the big > > decimal thing of mysql that was the problem. > > > > I forgot about to_f because frankly, I never used it. I primarily am > > concerned with view code here so I had just stuck that code to extend > > the Float class (which worked so well in 1.2.x)... > > > > class Float > > def to_fl(digits) > > sprintf("%.#{digits}f",self) > > end > > end > > > > and I could get a fixed number of digits whenever I wanted. Apparently > > this is like a very ineffective way to go about things in 2.3.x and to_f > > gives me whatever decimal places it believes are significant so I''m sort > > of trying to figure out how to locate the magic genie again. > > > > Craig-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
Craig White wrote:> Thanks - I see said the blind man... > > all I had to do was to first convert big decimal to float and then the > sprint function worked. > > @price.to_f.to_fl(2) and I get what I wanted in the view...Your Float#to_fl method is unnecessary and has semantics that will confuse experienced Ruby programmers. Try @price.round(2).to_f. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.
On Wed, 2009-06-03 at 19:36 +0200, Marnen Laibow-Koser wrote:> Craig White wrote: > > Thanks - I see said the blind man... > > > > all I had to do was to first convert big decimal to float and then the > > sprint function worked. > > > > @price.to_f.to_fl(2) and I get what I wanted in the view... > > Your Float#to_fl method is unnecessary and has semantics that will > confuse experienced Ruby programmers. Try @price.round(2).to_f.---- well, the round(2) function will return 1.5 if that is the stored value in big decimal which was unacceptable but I didn''t try @price.round(2).to_f but I wonder which is faster/slower. In reality, though, it tossed an error... undefined method `round'' for #<Price:0xb6e1bf20> which I think is back to my original problem of having a big decimal, that must be converted to a float before it can be rounded. Craig -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
Craig White wrote: [...]> ---- > well, the round(2) function will return 1.5 if that is the stored value > in big decimal which was unacceptableHuh? I don''t understand what you''re saying.> but I didn''t try > @price.round(2).to_f but I wonder which is faster/slower. > > In reality, though, it tossed an error...Again, I don''t understand. Did you try it or not?> > undefined method `round'' for #<Price:0xb6e1bf20> > > which I think is back to my original problem of having a big decimal, > that must be converted to a float before it can be rounded.No. BigDecimal#round should work as I just explained -- at least it does on my system. Are you sure @price is actually holding a BigDecimal?> > Craig >Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.
On Wed, 2009-06-03 at 23:49 +0200, Marnen Laibow-Koser wrote:> Craig White wrote: > [...] > > ---- > > well, the round(2) function will return 1.5 if that is the stored value > > in big decimal which was unacceptable > > Huh? I don''t understand what you''re saying. > > > but I didn''t try > > @price.round(2).to_f but I wonder which is faster/slower. > > > > In reality, though, it tossed an error... > > Again, I don''t understand. Did you try it or not? > > > > > undefined method `round'' for #<Price:0xb6e1bf20> > > > > which I think is back to my original problem of having a big decimal, > > that must be converted to a float before it can be rounded. > > No. BigDecimal#round should work as I just explained -- at least it > does on my system. Are you sure @price is actually holding a > BigDecimal?---- console session... _>> @price = Price.find(:first, :conditions => ["stockid = ?", "F34/CW/ES"]) => #<Price stockid: "F34/CW/ES", typeabbrev: "RE", currabrev: "USD", debtorno: " ", price: #<BigDecimal:b7dc83ec,''0.15E1'',8(12)>, branchcode: " "> _>> @price.price => #<BigDecimal:b7dacaac,''0.15E1'',8(12)> _>> @price.price.round(2) => #<BigDecimal:b7d9a4b0,''0.15E1'',8(16)> _>> @price.price.round(2).to_f => 1.5 _>> @price.price.round(2).to_fl(2) NoMethodError: undefined method `to_fl'' for #<BigDecimal:b7ee9f64,''0.15E1'',8(16)> from (irb):8 _>> @price.price.round(2).to_f.to_fl(2) => "1.50" _>> @price.price.to_f.to_fl(2) => "1.50" _>> @price.price.to_f.round(2) => 1.5 Craig -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
On Jun 3, 2009, at 7:12 PM, Craig White wrote:> On Wed, 2009-06-03 at 23:49 +0200, Marnen Laibow-Koser wrote: >> Craig White wrote: >> [...] >>> ---- >>> well, the round(2) function will return 1.5 if that is the stored >>> value >>> in big decimal which was unacceptable >> >> Huh? I don''t understand what you''re saying. >> >>> but I didn''t try >>> @price.round(2).to_f but I wonder which is faster/slower. >>> >>> In reality, though, it tossed an error... >> >> Again, I don''t understand. Did you try it or not? >> >>> >>> undefined method `round'' for #<Price:0xb6e1bf20> >>> >>> which I think is back to my original problem of having a big >>> decimal, >>> that must be converted to a float before it can be rounded. >> >> No. BigDecimal#round should work as I just explained -- at least it >> does on my system. Are you sure @price is actually holding a >> BigDecimal? > ---- > console session... > > _>> @price = Price.find(:first, :conditions => ["stockid = ?", > "F34/CW/ES"]) > => #<Price stockid: "F34/CW/ES", typeabbrev: "RE", currabrev: "USD", > debtorno: " ", price: #<BigDecimal:b7dc83ec,''0.15E1'',8(12)>, > branchcode: > " "> > _>> @price.price > => #<BigDecimal:b7dacaac,''0.15E1'',8(12)> > _>> @price.price.round(2) > => #<BigDecimal:b7d9a4b0,''0.15E1'',8(16)> > _>> @price.price.round(2).to_f > => 1.5 > _>> @price.price.round(2).to_fl(2) > NoMethodError: undefined method `to_fl'' for > #<BigDecimal:b7ee9f64,''0.15E1'',8(16)> > from (irb):8 > _>> @price.price.round(2).to_f.to_fl(2) > => "1.50" > _>> @price.price.to_f.to_fl(2) > => "1.50" > _>> @price.price.to_f.round(2) > => 1.5 > > CraigI think you two are talking past each other a bit. Marnen is describing BigDecimal correctly: irb> require ''bigdecimal'' => true irb> x = BigDecimal.new("1.50") => #<BigDecimal:8569c,''0.15E1'',8(8)> irb> x.to_s => "0.15E1" irb> x.round(2) => #<BigDecimal:802b4,''0.15E1'',8(16)> irb> x.round(2).to_f => 1.5 irb> "%.2f"%[x.round(2)] => "1.50" irb> x = BigDecimal.new("1.5431") => #<BigDecimal:6b0d0,''0.15431E1'',8(12)> irb> x.round(2) => #<BigDecimal:6845c,''0.154E1'',8(16)> irb> x.round(2).to_f => 1.54 irb> "%.2f"%[x.round(2)] => "1.54" However, Craig, you seem to want a formatted output for your Price model where the #price attribute happens to be a BigDecimal. class Price def formatted "%.2f"%[self.price.round(2)] end end Then you should have: @price = Price.find(:first, :conditions => ["stockid = ?","F34/CW/ ES"]) @price.formatted => "1.50" You might also want to roll your own helper similar to number_to_currency -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org