Boost logo

Boost :

From: Jeffrey C. Jacobs (darklord_at_[hidden])
Date: 2002-09-24 16:30:04


(Hope I'm not out of line bringing this back up)

Just some thoughts on the 64,000-millibit question.

First off, I think we should keep in mind that "long long" is very likely to
be added to the standard, but almost certainly will be added in such a way
that it is not necessairily 64 bits. Specifically, I'd expect the rules to
be rewritten:

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <=
sizeof(long long).

Granted, most of the time this will be implemented as:
1, 2, 4, 4, 8 (with char being 8 bits)

It is POSSIBLE an implementation could define:
1, 2, 4, 4, 4

Or even!
1, 1, 1, 1, 1

Not to mention the DEC alpha [and likely many future compilers] would
typically use:
1, 4?, 8, 8, 16

[As an asside, anyone remember the __int128 MS supported on their DEC Alpha
compiler...?]

The int_t template works well with this "implementation" detail and IMHO
should stick with the abstraction layed out by the standard. If "long long"
(Boost type def BOOST_HAS_LONG_LONG) is supported then long long should
(neigh MUST IMHO) be included in integer.hpp.

Stephen already suggested how this might be done (assuming you insert it
into the sequence) and I agree with this but would recommend using "long
long" only and #if defined(BOOST_HAS_LONG_LONG).

However, ironically I have veired away to the main point of this discussion
AFAICT: __int64. __int64 is a whole other can of worms IMHO from what
integer.hpp may be used for. Or more to the point, it BETTER serves the
same purpose as the int_t template. Yes, you could use the typedef for
int64_t (baring the problems inherent in protocol -- and again I vote: if it
ain't native, it ain't supported) but, well, let me give you an example of
how I would use int_t<n>:

template <typename T>
inline const T add_with_carry(const T lhs, const T rhs, T &carry)
{
    // Note, since T should always be Unsigned Integral,
    // sign_traits<T>::unsigned should technically be the parameter types
    // See thread on sign_traits<> elsewhere for detail.
    typedef uint_t<numeric_limits<T>::digits + 1>::fast big_t;

    big_t r_(big_t(lhs) + _big_t(rhs) + big_t(carry));
    return detail::split_big_t(r_, carry);
}
//...
namespace detail
{
    template <typename T>
    inline const T split_big_t(const uint_t<numeric_limits<T>::digits *
2>::fast r_, T &carry)
    {
        // Note, digits * 2 because of multiplication (explain later)
        // May be repeat of function of other library
        // Low "Word" is Result, High "Word" is Carry
        carry = r_>>numeric_limits<T>::digits;
        return r_ & integer_traits<T>::const_max;
    }
}

(This code is part of a library I am working on; probably redundant but if
it shapes up as I hope and someone does not beat me to it, I will propose it
here later. Sadly, INTERNALLY the compiler is already computing lhs+rhs and
setting a carry bit (flag) on x86 that is inaccessible at the C++ level so I
have this nasty, round-about way of obtaining it. But then *I* would
suggest something like:

#if defined(INTEL_MS_COMPILER)
    __asm
    //...
#elif defined(COMPILER_xxx)
    //...
#else
    // Above code
#endif

But if I wrote it that way I know I'd be flame-roasted big-time!)

The point being, what I want from an int_t<> is a way to go from integral
type T to some type big_t large enough to store "add with carry" (or
multiply with carry) the same way my platform does.

To me, the easiest way to do this is to have a separate MS-implimentation of
int_t and the int_least_helper that uses ALL the sized MS types:

__int8
__int16
__int32
__int64
__int128 [on DEC Alpha]

[then don't bother with numeric_limits?] since we know __int8 is 8 bits on
all platforms supporting __int8 (MS) -- that's why it's called __int8 after
all. :) But actually HOW to support the MS extensions I want to ignore for
now and get back to my chief concern: is sizeof(long long) ==, < or >
sizeof(__int64).

Clearly it could be ANY of those relations, and although not any time in the
forseeable future, it is possible sizeof(int) > sizeof(__int64). In fact,
there is no "true" comparison between __int<n> and the intrinsic types any
more than we can guarentee that sizeof(wchar_t) <= sizeof(short) [although
IIRC sizeof(wchar_t) <= sizeof(long)].

IMHO __int<n> of MS is a different class of relations from long, long long,
int, ... and should be handled separately. At the same time, it should be
handled s.t. the sample code need not care if it is using __int64 or long
long or even long.

Hope that's clear...?

Jeffrey.

"Neal D. Becker" <nbecker_at_[hidden]> wrote in message
news:x88sn3iuhux.fsf_at_rpppc1.md.hns.com...
> I wish boost::int_t would support long long. Now it is restricted to
> long. Is there any good reason for this restriction?
> _______________________________________________
> Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk