float precision

Discussion in 'Ruby' started by Difei Zhao, Sep 12, 2008.

  1. Difei Zhao

    Difei Zhao Guest

    Hi all,

    Is there a direct method to get something like:

    var = sprintf("%.2f", 92.22312).to_f

    Thanks alot!

    Difei
    --
    Posted via http://www.ruby-forum.com/.
    Difei Zhao, Sep 12, 2008
    #1
    1. Advertising

  2. The round function in the float class does not provide a precision
    feature, but you can do something like:
    (100*9.23234234234532).round/100.0

    According to my benchmarks this is at least 1/3 faster than your
    approach

    Thomas
    thomas peklak, Sep 12, 2008
    #2
    1. Advertising

  3. Difei Zhao

    Difei Zhao Guest

    thomas peklak wrote:
    > The round function in the float class does not provide a precision
    > feature, but you can do something like:
    > (100*9.23234234234532).round/100.0
    >
    > According to my benchmarks this is at least 1/3 faster than your
    > approach
    >
    > Thomas


    thanks for the sharing.
    --
    Posted via http://www.ruby-forum.com/.
    Difei Zhao, Sep 12, 2008
    #3
  4. thomas peklak wrote:
    > The round function in the float class does not provide a precision
    > feature, but you can do something like:
    > (100*9.23234234234532).round/100.0
    >
    > According to my benchmarks this is at least 1/3 faster than your
    > approach
    >
    > Thomas


    Just out of curiosity, does it make any difference on benchmarks with
    Ruby using division versus multiplication? It used to be much faster to
    multiply by .01 than divide by 100. I don't know if this has changed
    with newer processors and compilers.
    Michael W. Ryder, Sep 12, 2008
    #4
  5. You are right, multiplying with 0.01 is even fast, see the benchmarks:

    require 'benchmark'

    times = 1000000
    float = 9.234234765765765764
    Benchmark.bm do |r|
    r.report('SPf :') {
    times.times do
    f1 = sprintf('%.2f' ,float).to_f
    end
    }
    r.report('*100 :') {
    times.times do
    f2 = (100 * float).round/100.0
    end
    }
    r.report('*.01 :') {
    times.times do
    f3 = (100 * float).round*0.01
    end
    }
    end

    user system total real
    SPf : 5.590000 0.050000 5.640000 ( 5.720373)
    *100 : 3.760000 0.040000 3.800000 ( 3.829771)
    *.01 : 1.770000 0.010000 1.780000 ( 1.811917)

    Thomas
    thomas peklak, Sep 13, 2008
    #5
  6. thomas peklak wrote:
    > You are right, multiplying with 0.01 is even fast, see the benchmarks:
    >


    Thanks for the information. It looks like multiplication is still twice
    as fast as division. I am sure that with today's computers this only
    matters with large numbers of operations but on a IBM PC-1 it made a lot
    of difference.


    > require 'benchmark'
    >
    > times = 1000000
    > float = 9.234234765765765764
    > Benchmark.bm do |r|
    > r.report('SPf :') {
    > times.times do
    > f1 = sprintf('%.2f' ,float).to_f
    > end
    > }
    > r.report('*100 :') {
    > times.times do
    > f2 = (100 * float).round/100.0
    > end
    > }
    > r.report('*.01 :') {
    > times.times do
    > f3 = (100 * float).round*0.01
    > end
    > }
    > end
    >
    > user system total real
    > SPf : 5.590000 0.050000 5.640000 ( 5.720373)
    > *100 : 3.760000 0.040000 3.800000 ( 3.829771)
    > *.01 : 1.770000 0.010000 1.780000 ( 1.811917)
    >
    > Thomas
    Michael W. Ryder, Sep 14, 2008
    #6
  7. 2008/9/13 thomas peklak <>:
    > You are right, multiplying with 0.01 is even fast, see the benchmarks:
    >
    > require 'benchmark'
    > user system total real
    > SPf : 5.590000 0.050000 5.640000 ( 5.720373)
    > *100 : 3.760000 0.040000 3.800000 ( 3.829771)
    > *.01 : 1.770000 0.010000 1.780000 ( 1.811917)


    It's even more efficient to calculate with the full precision and
    round only on output. :)

    Cheers

    robert


    --
    use.inject do |as, often| as.you_can - without end
    Robert Klemme, Sep 16, 2008
    #7
  8. Robert Klemme wrote in post #727777:
    > 2008/9/13 thomas peklak <>:
    >> You are right, multiplying with 0.01 is even fast, see the benchmarks:
    >>
    >> require 'benchmark'
    >> user system total real
    >> SPf : 5.590000 0.050000 5.640000 ( 5.720373)
    >> *100 : 3.760000 0.040000 3.800000 ( 3.829771)
    >> *.01 : 1.770000 0.010000 1.780000 ( 1.811917)

    >
    > It's even more efficient to calculate with the full precision and
    > round only on output. :)
    >
    > Cheers
    >
    > robert


    This doesn't seem to work for certain numbers though... is there a way
    to round this 7.17... e+25:

    puts "#{cd}\t#{(100 * thr.max).round*0.01}"

    output ..

    1000 7.17897987691824e+25
    200 3.35
    4000 0.99
    20000 0.69

    --
    Posted via http://www.ruby-forum.com/.
    Ted Flethuseo, Mar 3, 2011
    #8
  9. Difei Zhao

    Joshua S. Guest

    Not surprisingly, it's extremely quicker to convert to a string and
    match a regular expression.

    user system total real
    spf : 1.560000 0.000000 1.560000 ( 1.557252)
    *100 : 0.320000 0.000000 0.320000 ( 0.322573)
    *.01 : 0.350000 0.000000 0.350000 ( 0.343289)
    regex: 0.000000 0.000000 0.000000 ( 0.000019)

    The expression
    (^-?\d+(\.\d{1,2})?) matches all the following:

    12
    1.2
    1.234567890
    12.34567890
    123.4567890
    1234.567890
    -12
    -1.2
    -1.234567890
    -12.34567890
    -123.4567890
    -1234.567890

    -----

    require 'benchmark'

    times = 1000000
    float = 9.234234765765765764
    Benchmark.bm do |r|
    r.report('spf :') {
    times.times do
    f1 = sprintf('%.2f' ,float).to_f
    end
    }
    r.report('*100 :') {
    times.times do
    f2 = (100 * float).round/100.0
    end
    }
    r.report('*.01 :') {
    times.times do
    f3 = (100 * float).round*0.01
    end
    }
    r.report('regex:') {
    f4 = float.to_s.match(/(^-?\d+(\.\d{1,2})?)/)[1].to_f
    }
    end

    --
    Posted via http://www.ruby-forum.com/.
    Joshua S., Apr 27, 2011
    #9
  10. Joshua S. wrote in post #995421:
    > Not surprisingly, it's extremely quicker to convert to a string and
    > match a regular expression.
    >
    > user system total real
    > spf : 1.560000 0.000000 1.560000 ( 1.557252)
    > *100 : 0.320000 0.000000 0.320000 ( 0.322573)
    > *.01 : 0.350000 0.000000 0.350000 ( 0.343289)
    > regex: 0.000000 0.000000 0.000000 ( 0.000019)


    You should be suspicious of a result which indicates it's 5 orders of
    magnitude faster.

    > r.report('regex:') {
    > f4 = float.to_s.match(/(^-?\d+(\.\d{1,2})?)/)[1].to_f
    > }


    Ahem, you forgot the "times.times do...end" loop in the benchmark :)

    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, Apr 28, 2011
    #10
  11. Difei Zhao

    Joshua S. Guest

    Brian Candler wrote in post #995481:
    > Joshua S. wrote in post #995421:
    >> Not surprisingly, it's extremely quicker to convert to a string and
    >> match a regular expression.
    >>
    >> user system total real
    >> spf : 1.560000 0.000000 1.560000 ( 1.557252)
    >> *100 : 0.320000 0.000000 0.320000 ( 0.322573)
    >> *.01 : 0.350000 0.000000 0.350000 ( 0.343289)
    >> regex: 0.000000 0.000000 0.000000 ( 0.000019)

    >
    > You should be suspicious of a result which indicates it's 5 orders of
    > magnitude faster.
    >
    >> r.report('regex:') {
    >> f4 = float.to_s.match(/(^-?\d+(\.\d{1,2})?)/)[1].to_f
    >> }

    >
    > Ahem, you forgot the "times.times do...end" loop in the benchmark :)


    Wow. Yea ... scratch that.


    user system total real
    spf : 1.570000 0.000000 1.570000 ( 1.569649)
    *100 : 0.330000 0.000000 0.330000 ( 0.323864)
    *.01 : 0.340000 0.000000 0.340000 ( 0.342777)
    regex: 4.120000 0.010000 4.130000 ( 4.127264)

    --
    Posted via http://www.ruby-forum.com/.
    Joshua S., Apr 28, 2011
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thinkit
    Replies:
    2
    Views:
    293
    Thinkit
    Nov 28, 2003
  2. Thinkit
    Replies:
    8
    Views:
    510
    Thinkit
    Dec 24, 2003
  3. bd
    Replies:
    0
    Views:
    604
  4. Carsten Fuchs
    Replies:
    45
    Views:
    1,505
    James Kanze
    Oct 8, 2009
  5. Anton81

    Float precision and float equality

    Anton81, Dec 5, 2009, in forum: Python
    Replies:
    26
    Views:
    1,115
Loading...

Share This Page