Code Comments
Programming Forum and web based access to our favorite programming groups.Ray Dillinger <bear@sonic.net> writes: > > That is, um, interesting and unexpected. For one number to > have two contradictory exactness values is very strange. I agree that R5RS did not expect that. There are two reasons why I did it that way: 1. My language Kogut implements complex numbers as pairs of real numbers. It's dynamically typed, and complex numbers are "honestly" implemented in it rather than using low-level C-defined type, so it's natural to allow any real types as parts. Specialization of + for complex numbers uses dispatched + for its parts. If I was to force same exactness types as both parts (i.e. if an integer or rational part was to be coerced to a float whenever the other part is a float), it would bring two divantages: a) more work b) less accurate results for no real benefit. 2. I couldn't decide whether to provide a function which converts two real numbers to a complex number, or to let programmers write a+b*I. Finally I allowed both. But in order for a+b*I to yield correct signs with -0.0, b*I must be distinguished from 0.0+b*I (because x + 0.0 is not the same as x when x is -0.0). C99 distinguishes them statically, with an imaginary type. William Kahan in the article I mentioned previously tries to explain that this distinction is useful for some numeric algorithms. It's hard to read, because he complains a lot without telling what exactly he complains about, technically, and what he would propose instead, but I believe I got this fact right. He also says that a float added to a complex should not be implemented by coercing the float to a complex first, in order to not change the imaginary part if it was -0.0, but Kogut already did that without problems. So I considered introducing imaginary type, which would be dynamically dispatched. Then I realized that if exact 0 was treated appropriately in mixed arithmetic with floats (such that for example x + 0 is x when x is a float), then a regular complex number with exact 0 as its real part would serve as the imaginary type, without having to implement its arithmetic specially. > You will find that R5RS forbids very little. It is "compatible" > with almost any correct (and, indeed, many incorrect) way of > handling numbers. This thread has been pointed out to me: http://www.google.pl/groups?threadm...40aubrey.jaffer It seems that R5RS is a bit incompatible with IEEE floating point arithmetic. For example IEEE says that (= nan nan) is #f; Scheme defines eqv? for numbers in terms of = and exactness; it says that eq implies eqv; everybody expects (eq? x x) to be #t without checking what x is. This is a contradiction of separate standards taken together. I think the best way of breaking the contradiction would be to divorce eqv? from =. The spirit of eqv? is that it tells whether two objects are interchangeable when the amount of sharing of immutable objects is not taken into account. I think I will explicitly break R5RS in my implementation, as it's already broken wrt. equality of nan. The R5RS definition of eqv? in terms of = did not expect some corner cases: -0.0, nan, and complex numbers with mixed exactness. Changing eqv? to conform to the idea above fixes all these cases at once. I will do this: (eqv? 0.0 -0.0) => #f (eqv? nan nan) => #t (eqv? 2+3.0i 2.0+3i) => #f even though = is different: (= 0.0 -0.0) => #t (= nan nan) => #f (= 2+3.0i 2.0+3i) => #t and document it as a non-compliance with R5RS. Printing representation of infinities and nan is a separate issue discussed in that thread. I will tackle it later. For anybody wanting to flame me: I did not invent -0.0 and nan, I only want to support them in the way IEEE and many languages and hardware processors do. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.