Can we solve and close the problem of the meaning of decimal pointed leterals? To my | People wrote about toRational (0.9) == 9%10 = False | ... | Probably, the source of a `bug' is a language agreement that the | input is in decimal representation (`0.9') and its meaning is a | floating approximation in _binary_ representation. | For example, 1%5 yields a finite mantissa in decimal representation | and an infinite (periodic) mantissa for the binary representation of | toBinary(1%5) = 1B % 1001B. (a typo: this should be 101B) | Therefore applying toRational to any finite float approximation | (Double, or other) of 1%5 does not return 1%5. Lennart Augustsson <lennart@mail.augustsson.net> writes
What are you talking about? Input in decimal representation is stored as a Rational number. There is absolutely no loss of precision.
and in his next letter citates the Report:
"The floating point literal f is equivalent to fromRational (n Ratio.% d), where fromRational is a method in class Fractional and Ratio.% constructs a rational from two integers, as defined in the Ratio library. The integers n and d are chosen so that n/d = f."
By saying "input is in decimal representation (`0.9')" I meant that a number `0.9' is written by a programmer keeping in mind a decimal representation. Further, according to the citation, 0.9 --> fromRational (9%10), 0.2 --> fromRational (1%5) are stored as the values of type Fractional a => a. (1) What is this `a' for our example of toRational (fromRational (0.9)) == 9%10 ? (2) Why Haskell does not report an ambiguity error? For `a' may be Rational, Double, Float - just anything of Fractional. If we take Lennart's assertion
Input in decimal representation is stored as a Rational number. There is absolutely no loss of precision.
then it should be `a' = Rational. Then, in particular, toRational (0.d) == d%10 = True for any decimal literal d and * any other behavior is a bug. * Is this really so? Now, Hugs-98-Feb-2000, probably, decides that `a' = Double. Because it returns False for 0.9. And in this case these values are _not_ stored as the rational numbers, but convert to Double, with the precision loss caused, as I wrote initially, by truncating of the division result, like 1001B % 1010B. Who could explain, please, whether I understand correct the whole question, and answer to the questions (1), (2) ? And is `False' is a bug? Thanks in advance for the comments. ----------------- Serge Mechveliani mechvel@botik.ru
"S.D.Mechveliani" wrote:
Can we solve and close the problem of the meaning of decimal pointed leterals?
There is no problem, it's clearly specified by the report. (There is a problem with Hugs, it doesn't implement literals properly. Or has that ancient bug been fixed?)
"The floating point literal f is equivalent to fromRational (n Ratio.% d), where fromRational is a method in class Fractional and Ratio.% constructs a rational from two integers, as defined in the Ratio library. The integers n and d are chosen so that n/d = f."
By saying "input is in decimal representation (`0.9')" I meant that a number `0.9' is written by a programmer keeping in mind a decimal representation. Further, according to the citation, 0.9 --> fromRational (9%10), 0.2 --> fromRational (1%5)
are stored as the values of type Fractional a => a.
The literal itself must be stored as a Rational (i.e. `Ratio Integer'), but the result of the `fromRational L' has type `(Fractional a) => a' as you said.
(1) What is this `a' for our example of toRational (fromRational (0.9)) == 9%10 ?
It depends, see below.
(2) Why Haskell does not report an ambiguity error?
Because any ambigous type is subjected to the defaulting mechanism. If the ambigous type variable belongs to class `Num' it is defaulted according to the defaults in scope in that module. The standard default is `(Integer, Double)', so the the pick in this case is Double. So the intermediate result after fromRational is of type Double. So you will lose precision.
For `a' may be Rational, Double, Float - just anything of Fractional. If we take Lennart's assertion
Input in decimal representation is stored as a Rational number. There is absolutely no loss of precision.
then it should be `a' = Rational. Then, in particular, toRational (0.d) == d%10 = True
for any decimal literal d and * any other behavior is a bug. * Is this really so?
No, since what you wrote is equivalent to toRational (fromRational (d%10)) == d%10 and as I described it is subject to defaulting. If you do default (Integer, Rational) in your module you'll get equality. -- Lennart
Lennart:
There is no problem, [the meaning of numeric literals is] clearly specified by the report. (There is a problem with Hugs, it doesn't implement literals properly. Or has that ancient bug been fixed?)
Lennart is absolutely right, the report is quite unambiguous and there is (still) a bug in Hugs. If this bug were to be fixed (I wouldn't hold my breath), we'd promptly fall over a bunch of other infelicities in the implementation of floating point and friends. The Hugs documentation clearly states that you shouldn't use Hugs for numeric work - i.e., for work where the accuracy of non-integer arithmetic is an issue. Comments on the state of Hugs should be directed to hugs-bugs@haskell.org (and should ideally be accompanied by patches purporting to fix the problem). -- Alastair Reid
participants (3)
-
Alastair Reid -
Lennart Augustsson -
S.D.Mechveliani