[Haskell-cafe] Set of reals...?

Glynn Clements glynn at gclements.plus.com
Wed Oct 27 09:33:39 EDT 2004


Stijn De Saeger wrote:

> Thanks for the explanation, at first it seemed like enumFromThenTo
> would indeed give me the functionality I am looking for. But then all
> of GHCi started acting weird while playing around... this is a
> copy-paste transcript from the terminal.
> 
> *S3> 0.5 `elem` [0.0,0.1..1.0]
> True
> *S3> 0.8 `elem` [0.6,0.7..1.0]
> False
> *S3> 0.8 `elem` [0.6,0.7..1.0]
> False
> *S3> [0.6,0.7..0.9]
> [0.6,0.7,0.7999999999999999,0.8999999999999999]
> *S3> 
> 
> ????????

Floating point has limited precision, and uses binary rather than
decimal, so you can't exactly represent multiples of 1/10 as
floating-point values. Internally, the elements of the list would
actually be out by a relative error of ~2e-16 for double-precision,
~1e-7 for single precision, but the code which converts to decimal
representation for printing rounds it.

However, Haskell does support rationals:

	Prelude> [6/10 :: Rational,7/10..9/10]
	[3 % 5,7 % 10,4 % 5,9 % 10]
	Prelude> 4/5 `elem` [6/10 :: Rational,7/10..9/10]
	True

> in your reply you wrote :
> > However, you can't specify infinitesimally small steps, nor increment
> > according to the resolution of the floating point type (at least, not
> > using the enumeration syntax; you *could* do it manually using integer
> > enumerations and encodeFloat, but that wouldn't be particularly
> > practical).
> 
> Is this what you were referring to? i wouldn't say 0.1 is an
> infinitesimal small step.

No; you could realistically use much smaller steps than that. My point
was that you can't realistically use sufficiently small steps that
values won't "fall through the cracks":

	Prelude> 0.61 `elem` [0.6,0.7..0.9]
	False

Whilst you could, without too much effort, enumerate a range of
floating-point values such that all intermediate values were included,
the resulting list would be massive. Single precision floating-point
uses a 24-bit mantissa, so an exhaustive iteration of the range
[0.5..1.0] would have 2^24+1 elements.

-- 
Glynn Clements <glynn at gclements.plus.com>


More information about the Haskell-Cafe mailing list