views:

81

answers:

4

I'm making an application which is listening to prices being updated regularly, but occasionally my data source throws me something like "1.79769313486232e+308". The numbers that get sent will never by really big numbers (eg. "179769313486232e+308"), but as with the example above, they come with a lot of precision.

I'd be happy to drop everything after the first couple of decimal places, and end up with something like "1.798", but the following code isn't working for me:

irb(main):001:0> s = '1.79769313486232e+308'
=> "1.79769313486232e+308"
irb(main):002:0> ("%.3f" % s).to_f
(irb):2: warning: Float 1.79769313486232e+30... out of range
=> 0.0

Any graceful ways to handle these kind of numbers in Ruby?

+2  A: 

I think BigDecimal from the standard library will work for this.

Jordan
+1  A: 

That's right at the top of the range of "doubles". In Python for example it's converted to the special float called "inf".

The graceful way to handle this one might be to treat it as infinity

gnibbler
But it's not infinity. It's less than $2.
Dukeh
@Dukeh, no it's exponential notation. Approximately 179769313 followed by 300 zeros. It's a pretty big number
gnibbler
A: 

you could strip out extra decimals using regexp

 >> s =~ /\.\d\d\d(\d+)/
 >> s.gsub($1, '')
 => "1.797e+308"
rogerdpack
+7  A: 

You need to find out from your data source what those really big numbers mean. The price isn't actually 1.797e+308, but it probably also isn't 1.797. How you deal with those numbers depends entirely on what value you should be interpreting them as.

Update: I'm not sure you understand what this number means. 1.79769313486232e+308 is 1.79769313486232 times ten to the 308th power. It's a number with more than 300 digits to the left of the decimal point. This isn't a price, it's a mistake. It's the upper limit of what double-precision floating point can represent.

In other words, you're getting the equivalent of 0xFFFFFFFF or something like that, but interpreted as a floating point number.

Ned Batchelder
Again, this is a price. I don't really care about it beyond 2 or 3 decimal places - in practical terms this additional precision is useless.
Dukeh
I've added to my answer.
Ned Batchelder