[EMAIL PROTECTED] wrote:
Jed Brown comments the answer of -
-- Roman Leshchinskiy who answers my question concerning the replacement
of floating-point numbers:
> First, when I see the advice "use something else", I always ask
"what",
> and I get an answer very, very rarely... Well? What do you propose?
For Haskell, Rational seems like a good choice. The fact that the
standard requires defaulting to Double is quite unfortunate and
inconsistent, IMO; the default should be Rational. Float and Double
shouldn't even be in scope without an explicit import. There really
is no good reason to use them unless you are
writing a binding to existing libraries or really need the performance.
Here Jed Brown says:
Until you need to evaluate a transcendental function.
...
It would be killing, wouldn't it?...
Yes, it would. I was talking about average programs, though, which (I
suspect) don't do numerics and really only need fractions. If you do
numerics, by all means use a data type that supports numerics well. But
even here, and especially in a functional language, IEEE floating point
usually isn't the best choice unless you really need the performance.
You seem to be after a type that can be used to represent non-integer
numbers in next to all problem domains. I don't think such a type
exists. So, as usual, one has to choose a data structure suited to the
problem at hand. IMO, standard floating point is not a good choice for
most problem domains so Float and Double shouldn't be used by default.
Whether Rational is a good default is certainly debatable.
For all practical purposes, the semantics of (==) is not well defined
for floating point numbers. That's one of the first things I used to
teach my students about floats: *never* compare them for equality. So
in my view, your example doesn't fail, it's undefined. That Haskell
provides (==) for floats is unfortunate.
I disagree, on practical basis. Floating-point numbers are very well
defined, we know how the mantissa is represented. If the numbers are
normalized, as they should, plenty of low-level iterative algorithms
may use the equality - after some operation - to check that the machine-
precision convergence has been obtained.
If you are absolutely sure that for every possible precision and for
every sequence of operations that compilers will generate from your code
your algorithm will actually converge to a particular binary
representation and not flip-flop on the last bit of the mantissa, for
instance, and if you do not care about the actual precision of your
algorithm (i.e., you want as much as possible of it) then yes, you might
get away with using exact equality. Of course, you'll have to protect
that part of your code by a sufficient number of warnings since you are
using a highly unsafe operation in a very carefully controlled context.
I'm not sure the trouble is really worth it. Anyway, in my view, such an
unsafe operation shouldn't be in scope by default and definitely
shouldn't be called (==). It's really quite like unsafePerformIO.
On the contrary, the verification that the absolute value between two
terms is less than some threshold, may be arbitrary or dubious.
Only if you use an inappropriate theshold. Choosing thresholds and
precision is an important part of numeric programming and should be done
with great care.
Roman
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe