Subject: Re: [boost] New Boost.XInt Library, request preliminary review
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-04-02 21:56:25
Chad Nelson wrote:
> On 04/02/2010 03:43 PM, Jeffrey Lee Hellrung, Jr. wrote:
>>>> Don't forget (assuming a single unsigned 0):
>>>> x / 0 => NaN
>>> Eh? I thought we'd decided that anything divided by zero, other than
>>> zero itself, was infinity (or negative infinity, if x is negative)?
>> Of course you can define whatever arithmetic you like, but I think it
>> makes more sense for products and quotients of like signs being
>> positive, of opposite signs being negative, and anything involving
>> (unsigned) zero giving either (unsigned) zero or NaN.
> You've completely lost me. Zero doesn't have a sign, so anything divided
> by zero would have to take its sign from 'x'.
Like I said, you can define whatever arithmetic you want. I prefer to
extend the semantics that floats have, where x/+0 = +infinity and x/-0 =
-infinity (if x > 0). If you have a single unsigned 0, it is the
identification of the +0 and -0 float-counterparts, so x/0 should be
NaN, since it *could* be either +infinity or -infinity in floats.
(However, if you allow signed 0s, then you don't have this problem.)
>>>> What are the arguments against a signed zero?
>>> That there's no need for it in an integer library.
>>> As such, there's no real need for it in XInt.
>> I was looking more for objections based purely on logical
>> inconsistencies. Can you think of any?
> Several. To begin with, would there be different values for positive
> zero, negative zero, and "true" zero? If not, zero would have to be
> assumed to be positive zero, and that's a slight logical inconsistency
> right there.
Let's just assume that if someone constructs "zero" directly, it's +0.
Although I'm betting it doesn't make any difference.
You seem to really want some kind of one-to-one identification between
integers and xint::integer objects, but I implore you to step back a
moment and relax that requirement. Your implementation naturally
suggests two representations of zero, and I'm arguing to keep those
distinct representations available for derived/wrapper classes, and for
simplicity of implementation. I have yet to see where this makes a
difference in the core interface or complicates the internal implementation.
> And if all two or three zero types evaluated the same, how would you
> detect a positive zero or a negative zero? The sign() function wouldn't
> do it; it's spec'd to return zero for zeros, and it would break a lot of
> things in the code if that were changed. Comparison functions would see
> them as the same too. You'd have to add a special function just to
> detect the sign on a zero.
Yes, sign() should return (the int) 0 for either +0 or -0, and yes,
you'd have to add one single itty-bitty function to get whether the
underlying zero had a + or - sign. That doesn't sound very difficult or
surprising. float +0 and -0 behave the same way.
> To make a sensible signed-zero value work, I'd have to make up portions
> of the math, or adopt them from floating-point stuff even though that
> doesn't make sense here.
I don't know what you mean here. Isn't the arithmetic involving zeros
fairly straightforward, signed or not?
> It gets very messy and arbitrary, and I'd
> rather avoid it.
Well, one of my questions was, phrased another way: *Does* it *really*
get messy and arbitrary? Does it really make a difference if your
zeroed mantissa has a + or - sign in front of it, implementation-wise?
Maybe I'm thinking a bit naively, but if you add an integer to +0, any
sane implementation will give the same result if you instead added -0,
except if the result itself was +/-0 (in which case, it doesn't make any
difference). And certainly, interface-wise, other than that special
"sign-of-zero" function, it makes no difference whether, underneath,
your zero has a + or - sign.
>>>> Is it possible to simply be agnostic to the sign bit when the
>>>> mantissa is 0?
>>> Isn't that the same as saying that -0 is identical to +0?
>> If you don't have any infinities or NaNs to worry about, yes! For this
>> case, I'm just suggesting you may not have to normalize zeros if -0
>> behaves exactly the same as +0. But it still may be useful to
>> distinguish between them for libraries built on top of the core
>> implementation. An arbitrary-precision floating point type may make a
>> distinction between +0 and -0, and it would be convenient if the
>> underlying integer core allowed this distinction naturally. [...]
> That's about the only argument that had any chance of swaying me. :-)
>> What do you think?
> That I still don't see any way to cleanly and logically implement it.
Maybe you already have and just haven't realized it ;)
> The aforementioned arbitrary-precision floating point package will just
> have to handle that itself, maybe by making an extremely small but
> non-zero value and calling it negative zero.
*That* seems "messy and arbitrary" ;)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk