Assigning unsigned long to unsigned long long

Discussion in 'C Programming' started by George Marsaglia, Jul 8, 2003.

  1. The essence of a multiply-with-carry RNG is to have
    declarations in the RNG proc, such as

    unsigned long mwc( ){
    static unsigned long x = 123456789, c = 362436;
    unsigned long long t, a = 916905990LL;
    then reatedly form the 64-bit t = a*x+c, after which
    the new carry c is the top 32,
    and the new x (output), is the bottom 32 bits of t:
    t = a*x+c; c = t>>32; return x=t ;

    Some compilers may give a warning for
    assigning an unsigned long to an unsigned long long.
    If so, would casting,
    x=(unsigned long),
    or chopping,
    supress such warnings?
    Would some compilers balk at the assignment
    x=t; ?

    Warnings aside, in machines for which
    unsigned longs are 32 bits and
    unsigned long longs are 64,
    would the three versions
    x = t;
    x = (unsigned long) t;
    x = t&0xffffffff;
    all produce the required result: the bottom 32-bits of t?

    Is the assembler code likely to differ?

    I use gcc via djgpp in DOS, and x = t; works as expected,
    with no warnings when compiled with the -Wall option.

    George Marsaglia
    George Marsaglia, Jul 8, 2003
    1. Advertisements

  2. George Marsaglia

    Eric Sosman Guest

    Compilers can issue whatever diagnostics they feel
    like: "suspicious" conversions, comparisons of unsigned
    integers to negative numbers, or spellnig errors in your
    comments. There is no particular language construct that
    is guaranteed to shut up all compilers all the time.

    That said, the cast is more likely than the mask to
    quiet a compiler's squeaky wheels. The masking operation
    produces the result you desire, but the type will still
    be u.l.l. -- and a compiler that likes to complain about
    type demotions is still likely to do so, not realizing
    that in the case at hand no damage can occur. (True story:
    a certain compiler once complained about `float f = 0.0;'
    on the grounds that demotion from `double' to `float' might
    lose precision; I had to rewrite as `float f = 0.0f;' to
    get it to shut its stupid mouth ...). Of course, even with
    the cast the compiler may still bitch about the phase of
    the moon or something.
    Some might. They've got to accept and execute the code
    (absent any other problems), but they're free to whinge.
    A cast may or may not shut 'em up.
    Yes. The first two differ only in that the conversion
    is implicit in the first and explicit in the second; the
    exact same conversion occurs anyhow. The third develops
    the value in u.l.l. form and then demotes it to u.l. without
    further change. All three assign the same value to `x'.
    Yes. No. Maybe. And that's definite! At a guess, the
    mask version might be different from the other two -- but
    it's even in the realm of possibility that three entirely
    different instruction sequences might be generated.

    I'd suggest using -W as well as -Wall -- I don't know
    off-hand whether that would elicit additional diagnostics
    for the case you mention, but it's occasionally saved me
    from my own blunders. I've always been fond of encouraging
    the compilers/linkers/assemblers/whatever to give me all
    the constructive criticism they're capable of ...

    Eric Sosman, Jul 8, 2003
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.