Piccolo con problema con il tipo float

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.90.15+1.521-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=xa+yb-t
puts c
if(c*s>=0)
o=1
else
o=0
end
o
end
end

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

On 10/8/07, Matteo M. [email protected] 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

On 10/8/07, Matteo M. [email protected] wrote:

0.9x+1.5y<=45
0.90.15+1.521-45 ridà nientepocodimenoche 7.105427357601e-015!!!

require ‘myrbs\point’
puts c
if(c*s>=0)
o=1
else
o=0
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 = 0.33333 or
0.33334. therefore 3 * 1/3 = 3 * 0.33333 = 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 :wink:

Jano