Piccolo con problema con il tipo float

Discussion in 'Ruby' started by Matteo Mancini, Oct 8, 2007.

  1. Ho iniziato da poco a programmare in ruby, e stavo facendo un piccolo
    programma che, dato un sistema di disequazioni, trova i punti comuni a
    queste, impostando un problema di programmazione lineare.
    Viene chiesto in input prima il numero di disequazioni (vincoli) e
    quindi i parametri in questo modo:
    ax+by+c>=0
    prima il coefficiente di x, quindi quello di y, il termine noto, e
    infine un quarto parametro da impostare ad 1 o a -1 per il segno della
    disequazione.
    Ho provato il seguente sistema:
    0.9x+1.5y<=45
    x+y<=36
    x>=10
    y>=0
    Quindi inserisco da input:
    4 | 0.9 | 1.5 | 45 | -1 | 1 | 1 | 36 | -1 | 1 | 0 | 10 | 1 | 0 | 1 | 0 |
    1
    I punti in comune calcolati a mano sono:
    (10,0) (36,0) (15,21) (10,24)
    E qui sorge il problema: il programma mi scarta il punto (15,21) alla
    prima disequazione (provate a mano, la verifica!) e la fatidica somma
    0.9*0.15+1.5*21-45 ridà nientepocodimenoche 7.105427357601e-015!!!
    Fatta numericamente dà 0, eppure il programma sputa fuori questo
    risultato!
    Sono ore che ci combatto, datemi una mano vi prego!
    Grazie in anticipo!


    Il file principale è allegato, seguono le due piccole classi che ho
    implementato:

    point.rb

    class Point
    attr_reader :x, :y
    def initialize (x,y)
    @x=x
    @y=y
    end
    end

    diseq.rb

    require 'myrbs\point'

    class Diseq < Point
    attr_reader :t,:s
    def initialize (x,y,t,s)
    super(x,y)
    @t=t
    @s=s
    end
    def solve(a,b)
    c=x*a+y*b-t
    puts c
    if(c*s>=0)
    o=1
    else
    o=0
    end
    o
    end
    end

    Attachments:
    http://www.ruby-forum.com/attachment/603/area.rb

    --
    Posted via http://www.ruby-forum.com/.
    Matteo Mancini, Oct 8, 2007
    #1
    1. Advertising

  2. Matteo Mancini, Oct 8, 2007
    #2
    1. Advertising

  3. On 10/8/07, Matteo Mancini <> wrote:
    > I'm sorry, I've posted in the wrong place, could someone delete this
    > post?


    Nope. ruby-talk.com is a two-way mirroring solution for a mailing list.

    -austin
    --
    Austin Ziegler * * http://www.halostatue.ca/
    * * http://www.halostatue.ca/feed/
    *
    Austin Ziegler, Oct 8, 2007
    #3
  4. Matteo Mancini

    Jano Svitok Guest

    On 10/8/07, Matteo Mancini <> wrote:
    > Ho iniziato da poco a programmare in ruby, e stavo facendo un piccolo
    > programma che, dato un sistema di disequazioni, trova i punti comuni a
    > queste, impostando un problema di programmazione lineare.
    > Viene chiesto in input prima il numero di disequazioni (vincoli) e
    > quindi i parametri in questo modo:
    > ax+by+c>=3D0
    > prima il coefficiente di x, quindi quello di y, il termine noto, e
    > infine un quarto parametro da impostare ad 1 o a -1 per il segno della
    > disequazione.
    > Ho provato il seguente sistema:
    > 0.9x+1.5y<=3D45
    > x+y<=3D36
    > x>=3D10
    > y>=3D0
    > Quindi inserisco da input:
    > 4 | 0.9 | 1.5 | 45 | -1 | 1 | 1 | 36 | -1 | 1 | 0 | 10 | 1 | 0 | 1 | 0 |
    > 1
    > I punti in comune calcolati a mano sono:
    > (10,0) (36,0) (15,21) (10,24)
    > E qui sorge il problema: il programma mi scarta il punto (15,21) alla
    > prima disequazione (provate a mano, la verifica!) e la fatidica somma
    > 0.9*0.15+1.5*21-45 rid=E0 nientepocodimenoche 7.105427357601e-015!!!
    > Fatta numericamente d=E0 0, eppure il programma sputa fuori questo
    > risultato!
    > Sono ore che ci combatto, datemi una mano vi prego!
    > Grazie in anticipo!
    >
    >
    > Il file principale =E8 allegato, seguono le due piccole classi che ho
    > implementato:
    >
    > point.rb
    >
    > class Point
    > attr_reader :x, :y
    > def initialize (x,y)
    > @x=3Dx
    > @y=3Dy
    > end
    > end
    >
    > diseq.rb
    >
    > require 'myrbs\point'
    >
    > class Diseq < Point
    > attr_reader :t,:s
    > def initialize (x,y,t,s)
    > super(x,y)
    > @t=3Dt
    > @s=3Ds
    > end
    > def solve(a,b)
    > c=3Dx*a+y*b-t
    > puts c
    > if(c*s>=3D0)
    > o=3D1
    > else
    > o=3D0
    > end
    > o
    > end
    > end


    Hi,

    your problem is that floats are not exact. They have limited
    precision, and some numbers (especially irrational and with periodic
    fractional part) cannot be stored as floats precisely.
    Imagine using decimal notation with max 5 digits: 1/3 =3D 0.33333 or
    0.33334. therefore 3 * 1/3 =3D 3 * 0.33333 =3D 0.99999 that is 0.00001
    less that expected result. Floats are the same except they use binary
    notation and more digits.

    One way to avoid it is using BigDecimal instead of floats, although
    they are much slower.
    Sometimes it's possible to live with the small differences.

    Notice that in test/unit, they are checking float results to be within
    specified tolerance (assert_in_delta).

    (My Italian is sufficient to understand your post, but not to reply ;-)

    Jano
    Jano Svitok, Oct 8, 2007
    #4
    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. Jose Joaquin de Haro

    Problema con archivos dbx

    Jose Joaquin de Haro, Jan 28, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    1,571
    Lionel LASKE
    Jan 28, 2005
  2. Fabio Cirillo

    problema con vb net e system.net.socket

    Fabio Cirillo, Mar 29, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    652
    Fabio Cirillo
    Mar 29, 2005
  3. Replies:
    1
    Views:
    630
  4. bd
    Replies:
    0
    Views:
    624
  5. Carsten Fuchs
    Replies:
    45
    Views:
    1,540
    James Kanze
    Oct 8, 2009
Loading...

Share This Page