how to compute 64 bit result from 2 32 bit values

Discussion in 'C Programming' started by csledge, Feb 10, 2007.

  1. csledge

    csledge Guest

    I am trying to compute a 64 bit result from 2 32 bit
    registers, How do I get the carry into the higher word ?
    Also is %lld correct ?

    long long int64( long x, int y);
    printf("%lld \n",int64(0xffffffff,1));


    long long int64( long x, int y)
    return x + y;

    Ans should be 0x100000000.
    csledge, Feb 10, 2007
    1. Advertisements

  2. csledge

    Tim Prince Guest

    You won't get an answer this way from Standard C. Write your test
    in C, compile with your favorite option to generate asm, and see how
    it's done on your platform.
    Tim Prince, Feb 10, 2007
    1. Advertisements

  3. csledge

    Guest Guest

    %lld is the correct format specifier for printing a long long value.
    To force an addition of two narrower types to be done in long long
    arithmetic, add a cast:

    long long int64( long x, int y)
    return (long long) x + y;
    Guest, Feb 10, 2007
  4. csledge

    Tim Prince Guest

    How about
    return (long long)x + y;

    in case you are running a target where (long long) is bigger than (long) ?

    and the required #include ?

    I was a little confused by your function name and lack of std headers,
    which seems reminiscent of some common extensions.
    Tim Prince, Feb 10, 2007
  5. csledge

    Joe Wright Guest

    Yes, if you want decimal.
    int main(void) please..
    Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    will yield 0.
    Joe Wright, Feb 10, 2007
  6. csledge

    Guest Guest

    Good catch. Just one addition for clarification: (long) 0xffffffff is
    (long) -1 on the OP's system. 0xffffffff is always positive; it can
    only become negative when it is converted.
    Guest, Feb 10, 2007
  7. Easy in assembly, very hard to do efficiently in C as there is no carry. You
    can of course manipulate the bits yourself using the primary school
    algorithms for multiplication, but it is slow and fiddly.

    Unsigned addition is a bit easier, you have a carry if the result is less
    than either of the operands. Signed addition generates undefined behaviour
    on overflow, so you've got lots of complications.
    Malcolm McLean, Feb 10, 2007
  8. csledge

    Flash Gordon Guest

    Harald van Dijk wrote, On 10/02/07 17:22:
    I thought that converting a number out of range for a given signed type
    to that signed type invoked undefined behaviour, so (long)0xffffffff is
    undefined behaviour if long is 32 bits.
    Flash Gordon, Feb 10, 2007
  9. csledge

    SM Ryan Guest

    # Hi,
    # I am trying to compute a 64 bit result from 2 32 bit
    # registers, How do I get the carry into the higher word ?

    Cast the operands not the operation.

    return x+y;
    which is implicitly
    return (long long)(x+y);
    return (long long)x + (long long)y;

    Whether it's using 32 bit registers or 64 is not my concern.
    Whether it's using long or long long semantics is.

    # Also is %lld correct ?
    # #include<stdio.h>
    # long long int64( long x, int y);
    # main()
    # {
    # printf("%lld \n",int64(0xffffffff,1));
    # }
    # long long int64( long x, int y)
    # {
    # return x + y;
    # }
    # Ans should be 0x100000000.
    # Thanks
    # Sledge.
    SM Ryan, Feb 10, 2007
  10. csledge

    Guest Guest

    The result of converting 0xffffffff to signed long, assuming it is out
    of range, is implementation-defined. The behaviour is undefined for
    overflow during signed arithmetic, but not during a conversion.
    Guest, Feb 10, 2007
  11. csledge

    Guest Guest

    Sorry, that was incomplete. I forgot that such a conversion is also
    allowed to raise an implementation-defined signal, but still, no
    undefined behaviour.
    Guest, Feb 10, 2007
  12. csledge

    Jack Klein Guest

    No, prior to C99 assigning an integer value outside the range of a
    signed integer type produced an implementation-defined result.

    C99 add the alternate possibility that an implementation-defined
    signal might be raised. If this new option was based on experience
    with some particular platform, no one on the standard committee has
    admitted knowing about it, as far as I know.

    But integer assignment from an out-of-range integer value is not and
    has never been undefined. Assigning an out-of-range value to a signed
    or unsigned integer type from a floating point type is and always has
    been undefined.
    Jack Klein, Feb 11, 2007
  13. csledge

    Flash Gordon Guest

    Harald van Dijk wrote, On 10/02/07 23:58:
    Still not necessarily -1 though. Think of sign-magnitude or ones
    complement machines (not that I have come across any)
    Flash Gordon, Feb 11, 2007
  14. No, conversion to a signed type that can't hold the result yields an
    implementation-defined result or (new in C99) raises an
    implementation-defined signal. An overflowing arithmetic operation,
    on the other hand, invokes undefined behavior.
    Keith Thompson, Feb 11, 2007
  15. That kind of thing is not necessary in this case; if the compiler
    supports long long, then it supports 64-bit (or more) arithmetic
    directly. Just convert one operand to long long; the other will be
    converted implicitly, and the addition will be done in type long long.

    That's assuming that the OP was asking about addition. He asked how
    to "compute a 64 bit result from 2 32 bit registers"; he didn't
    actually say he wanted the result to be the sum.
    Keith Thompson, Feb 11, 2007
  16. OT: This is an example of where attribution gets out of hand. To me,
    it's the equivalent of void ******.
    Christopher Layne, Feb 11, 2007
  17. csledge

    websnarf Guest

    Try this following:

    #include "pstdint.h" /* */

    int64_t int64 (long x, int y);
    printf("%" PRINTF_INT64_MODIFIER "d \n", int64 (0xffffffff,

    int64_t int64 (long x, int y)
    return ((int64_t)x) + ((int64_t)y);


    This is pretty widely portable, it includes all C99 implementations,
    as well as many implementations of previous popular C compilers.
    Basically %lld and "long long" are non-portable (though they exist in
    C99 and some compilers like the gnu C compiler, they are not supported
    by, for example, Microsoft Visual C++.)
    websnarf, Feb 11, 2007
  18. It would be an unusual implementation on which it's possible to have
    an integer value that's out of range for any floating-point type.
    FLT_MAX is at least 1E+37, which can be represented as an integer in
    123 bits (124 bits if it's signed). It's certainly *possible* that a
    float-to-integer conversion might overflow, but it's not likely on
    realistic implementations.
    Keith Thompson, Feb 11, 2007
  19. csledge

    CBFalconer Guest

    I see nothing out of hand. However, the previous showed grevious
    signs of 'failure to snip'.


    "A man who is right every time is not likely to do very much."
    -- Francis Crick, co-discover of DNA
    "There is nothing more amazing than stupidity in action."
    -- Thomas Matthews
    CBFalconer, Feb 11, 2007
  20. And yet, I know one of the pedants would call me on that while I was replying
    to it. Unfortunately, I left it in there to specifically show what I was
    referring to - hence at the time I didn't feel they were unsnippable.

    It is out of hand and I think you're just being ridiculous about it.
    Christopher Layne, Feb 11, 2007
    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.