#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2011
    Location
    Ľubeľa (SK)
    Posts
    1
    Rep Power
    0

    Rounding error? (absolute beginner)


    Hi there,

    First of all: I'm an absolute beginner in Ruby, so please don't shoot me if I'm asking stupid questions...

    Here's the problem:

    Code:
    print("Length: ")
    s = gets()
    length = s.to_f
    print("Width: ")
    s = gets()
    width = s.to_f
    surface = length * width
    puts("Surface = #{length} x #{width} = #{surface}")
    When running this code, it asks for Length and Width as expected, but when I type the values 4.9 and 5.9 it gives 28.910000000000004 as result.
    The values 3.9 and 3.9 give 15.20999999999999 as result.
    Those results are not what I expected them to be...
    What do I need to do to avoid these rounding-errors?

    Greetings, and thanks!
    J.
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2010
    Posts
    7
    Rep Power
    0
    That is very strange... I have no idea (I'm new also) but think it's damn weird Ruby would do that.

    I also think it's neat how I used a completely different code to do the same thing you did. Even though our codes look so very different, they do the same thing! Well... I think it's neat anyway

    Code:
    puts 'Length:'
    length = gets.chomp
    puts 'Width:'
    width = gets.chomp
    surface = (length.to_f * width.to_f)
    puts surface
  4. #3
  5. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Location
    Norcross, GA (again)
    Posts
    1,805
    Rep Power
    1570
    Actually, this is to be expected when using floating-point arithmetic, and is not specific to Ruby; it will occur in any language using IEEE754 floating-point numbers.

    Because the FP numbers are actually in base 2 rather than base 10, they cannot accurately represent certain decimal fractions - what in base 10 may be an exact fraction could be a repeating fraction in base 2, and vis versa. The best solution is to use BigDecimal numbers instead of floats:

    Code:
    require "bigdecimal"
    
    print("Length: ")
    s = gets()
    length = BigDecimal.new(s)
    print("Width: ")
    s = gets()
    width = BigDecimal.new(s)
    surface = length * width
    puts("Surface =  #{length.to_s('F')} x #{width.to_s('F')} = #{surface.to_s('F')}")
    Now, BigDecimal has some quirks of it's own - by default, the string representation returned by to_s() is in exponential notation, for example - but it does provide exact decimal fractions.
    Last edited by Schol-R-LEA; January 16th, 2012 at 02:05 PM.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in Short Understanding the C/C++ Preprocessor
    Taming Python A Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov

IMN logo majestic logo threadwatch logo seochat tools logo