August 27, 2003 Re: D complex vs C++ std::complex | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | [...snip...] > > Semantics: > > > > I think this guy is crazy. Bone up on Geometric Algebra; all the functionality is in the operations, not the data storage format. If C++ > is > > broken, fine, fix it. But we all know that 0 + 1i = i and 1 + 0i = 1, so > > results of operations on the two values (1 + 0i vs. 1) should be > > indistinguishable. > > They aren't with IEEE arithmetic because of the sign of 0. > > > Storage format really doesn't matter; it's all about > > what happens during the operations and how you define said operations > > (multiply, log, sqrt) and primitive values (the real numbers). > > Prof. Kahan isn't crazy, in fact, he is the prime mover behind IEEE 754 arithmetic. There really isn't anyone who knows floating point better than him. The trouble comes not from the mathematics, but from imperfections in how floating point is implemented. In dealing with complex numbers, you have > a thing called "branch cuts" which wind up relying on the sign of 0. Carrying along an extra 0 for the real part winds up getting the signs wrong. I think Kahan's point with the examples he uses (the Curmudgeon paper) is to show that you can't ignore the sign of 0 when dealing with branch cuts. See also, for example, http://www.cs.berkeley.edu/~wkahan/MathH90/S26Aug02.pdf. I haven't read C99's Annex G (the part of the C99 spec that deals with the optional support of pure imaginary types) but my impression was that pure imaginary is for efficiency and deals with things like imaginary Infs and NaNs better than general complex Inf and NaN. To quote from http://grouper.ieee.org/groups/754/meeting-minutes/01-07-18.html: Annex G specifies three imaginary types: float, double, and long double imaginary Operands not promoted to a common type domain (real, imaginary, complex) e.g. r(u + vi) = ru + rvi, not (r + 0i)(u + vi) provides natural efficiency and better treatment of special values e.g. i i = , not (1 + 0i)(0 + i)(1 + 0i)(0 + i) = NaN + NaNi Infinity properties for z nonzero and finite inf*z=inf inf*inf=inf inf/z=inf inf/0=inf z/inf=0 0/inf=0 z/0=inf |inf|=inf even for complex and imaginary z, 0s, and infinities a complex value with at least one infinite part is regarded as infinite (even if the other part is NaN) Nothing about branch cuts there, from what I can tell. Oh, and why does it say i*i is NaN+NaNi? that seems wierd. I would think ((+0)+i)*((+0)+i) = ((+0)*(+0) - 1*1) + ((+0)*1 + 1*(+0))i = ((+0)-1) + ((+0) + (+0))i = -1 + (+0)i I'd like D to include a complex math library that respects the sign of 0 in arithmetic and branch cuts but doesn't include pure imaginary in the basic language. This is what C99 does. What, by the way, is the exact arithmetic of pure imaginary type and how does it behave when combined with complex or real numbers? Is the proposal to follow C99 + Annex G? > > If there are sign issues, it's either a problem in the implementation of > the > > operations, or of the input values, or of the algorithm. I'm not sure > what > > he was trying to do but I'm pretty confident it was either the first or > the > > last of those three. Probably the first. > > In conclusion, I don't think an "imaginary" type is strictly necessary for > > correctness, nor do I believe that the implementation should favor two > such > > "axes" and ignore the plethora of other possible axes (you might think of > > these as "units" or as separate types if you wish). If you build in imaginary, pretty soon people will be asking for (or kludgily building > using > > the available language tools) "x" "y" and "z" axis types, "length" and "time" units, ad infinitum. > > It's too bad that the analysis of what exactly is going wrong isn't on his web page, but in his book. > > |
August 28, 2003 Re: D complex vs C++ std::complex | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <bhinkle4@juno.com> wrote in message news:bija5k$1aja$1@digitaldaemon.com... > [...snip...] > I think Kahan's point with the examples he uses (the Curmudgeon paper) is to > show that you can't ignore the sign of 0 when dealing with branch cuts. See > also, for example, http://www.cs.berkeley.edu/~wkahan/MathH90/S26Aug02.pdf. > I haven't read C99's Annex G (the part of the C99 spec that deals with the optional support of pure imaginary types) but my impression was that pure imaginary is for efficiency and deals with things like imaginary Infs and NaNs better than general complex Inf and NaN. > > To quote from > http://grouper.ieee.org/groups/754/meeting-minutes/01-07-18.html: > Annex G specifies three imaginary types: float, double, and long double > imaginary > Operands not promoted to a common type domain (real, imaginary, complex) > e.g. r(u + vi) = ru + rvi, not (r + 0i)(u + vi) provides natural efficiency > and better treatment of special values e.g. i i = , not (1 + 0i)(0 + i)(1 + > 0i)(0 + i) = NaN + NaNi > Infinity properties for z nonzero and finite > inf*z=inf inf*inf=inf inf/z=inf inf/0=inf > z/inf=0 0/inf=0 z/0=inf |inf|=inf > even for complex and imaginary z, 0s, and infinities a complex value with at > least one infinite part is regarded as infinite (even if the other part is > NaN) > > Nothing about branch cuts there, from what I can tell. Right, that's a different issue. > Oh, and why does it say i*i is NaN+NaNi? that seems wierd. I would think > ((+0)+i)*((+0)+i) > = ((+0)*(+0) - 1*1) + ((+0)*1 + 1*(+0))i > = ((+0)-1) + ((+0) + (+0))i > = -1 + (+0)i Something is wierd about that example, I think something was dropped from it by some font conversion. ii= ?? > I'd like D to include a complex math library that respects the sign of 0 in > arithmetic and branch cuts but doesn't include pure imaginary in the basic language. This is what C99 does. Yes, D follows C99's lead (but C99 does have a pure imaginary). > What, by the way, is the exact arithmetic of pure imaginary type and how does it behave when combined with complex or real numbers? Is the proposal to follow C99 + Annex G? Yes. The C99 numerics folks know what they're doing. |
August 29, 2003 Re: D complex vs C++ std::complex | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:bijs35$25b0$1@digitaldaemon.com... > > "Ben Hinkle" <bhinkle4@juno.com> wrote in message news:bija5k$1aja$1@digitaldaemon.com... > > [...snip...] > > I think Kahan's point with the examples he uses (the Curmudgeon paper) is > to > > show that you can't ignore the sign of 0 when dealing with branch cuts. > See > > also, for example, > http://www.cs.berkeley.edu/~wkahan/MathH90/S26Aug02.pdf. > > I haven't read C99's Annex G (the part of the C99 spec that deals with the > > optional support of pure imaginary types) but my impression was that pure > > imaginary is for efficiency and deals with things like imaginary Infs and > > NaNs better than general complex Inf and NaN. > > > > To quote from > > http://grouper.ieee.org/groups/754/meeting-minutes/01-07-18.html: > > Annex G specifies three imaginary types: float, double, and long double > > imaginary > > Operands not promoted to a common type domain (real, imaginary, complex) > > e.g. r(u + vi) = ru + rvi, not (r + 0i)(u + vi) provides natural > efficiency > > and better treatment of special values e.g. i i = , not (1 + 0i)(0 + i)(1 > + > > 0i)(0 + i) = NaN + NaNi > > Infinity properties for z nonzero and finite > > inf*z=inf inf*inf=inf inf/z=inf inf/0=inf > > z/inf=0 0/inf=0 z/0=inf |inf|=inf > > even for complex and imaginary z, 0s, and infinities a complex value with > at > > least one infinite part is regarded as infinite (even if the other part is > > NaN) > > > > Nothing about branch cuts there, from what I can tell. > > Right, that's a different issue. > > > Oh, and why does it say i*i is NaN+NaNi? that seems wierd. I would think > > ((+0)+i)*((+0)+i) > > = ((+0)*(+0) - 1*1) + ((+0)*1 + 1*(+0))i > > = ((+0)-1) + ((+0) + (+0))i > > = -1 + (+0)i > > Something is wierd about that example, I think something was dropped from it > by some font conversion. ii= ?? > > > I'd like D to include a complex math library that respects the sign of 0 > in > > arithmetic and branch cuts but doesn't include pure imaginary in the basic > > language. This is what C99 does. > > Yes, D follows C99's lead (but C99 does have a pure imaginary). From what I can tell C99 doesn't require the implementation have a pure imaginary type. Annex G is informative. > > What, by the way, is the exact arithmetic of pure imaginary type and how does it behave when combined with complex or real numbers? Is the proposal > > to follow C99 + Annex G? > > Yes. The C99 numerics folks know what they're doing. Well, there are some pitfalls with following ieee 754 is you really care about the sign of 0. See for example: http://www.concentric.net/~Ttwang/tech/javafloat.htm the section Wrong Way to Implement abs(). Also notice that since (-0) + (+0) = +0 then +0 can't be used as an "additive unit", meaning x + (+0) = x for all x. So suddenly, if you care about -0, you have to figure out all the places you might be adding 0 to expressions and make sure they are avoided (or look at them carefully). What a pain. Here's a guy who has an anti-754 rant with a few interesting points: http://www.my.netbsd.org/People/Pages/ross-essays.html Ahh, if only ieee754 had a true zero the only argument for pure imaginary would be efficiency. oh well. -Ben |
August 29, 2003 Re: D complex vs C++ std::complex | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | "Ben Hinkle" <bhinkle4@juno.com> wrote in message news:binhp0$1pe5$1@digitaldaemon.com... > > Yes. The C99 numerics folks know what they're doing. > > Well, there are some pitfalls with following ieee 754 is you really care > about the sign of 0. See for example: > http://www.concentric.net/~Ttwang/tech/javafloat.htm the section Wrong Way > to Implement abs(). Also notice that since > (-0) + (+0) = +0 > then +0 can't be used as an "additive unit", meaning x + (+0) = x for all x. > So suddenly, if you care about -0, you have to figure out all the places you > might be adding 0 to expressions and make sure they are avoided (or look at > them carefully). What a pain. > > Here's a guy who has an anti-754 rant with a few interesting points: http://www.my.netbsd.org/People/Pages/ross-essays.html > > Ahh, if only ieee754 had a true zero the only argument for pure imaginary would be efficiency. oh well. > > -Ben Those are some very interesting articles. On the other hand, the FPU hardware we're dealing with is IEEE 754, so might as well embrace it <g>. |
Copyright © 1999-2021 by the D Language Foundation