Piccolo con problema con il tipo float

M

Matteo Mancini

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
 
M

Matteo Mancini

I'm sorry, I've posted in the wrong place, could someone delete this
post?
 
A

Austin Ziegler

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
 
J

Jano Svitok

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top