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

    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 ?
    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.
     
    csledge, Feb 10, 2007
    #1
    1. Advertising

  2. csledge

    Tim Prince Guest

    csledge wrote:
    > 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 ?
    > Also is %lld correct ?

    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
    #2
    1. Advertising

  3. csledge wrote:
    > 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 ?
    > 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.


    %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;
    }
     
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Feb 10, 2007
    #3
  4. csledge

    Tim Prince Guest

    csledge wrote:
    > 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 ?
    > 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.
    >

    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
    #4
  5. csledge

    Joe Wright Guest

    csledge wrote:
    > 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 ?
    > Also is %lld correct ?


    Yes, if you want decimal.

    > #include<stdio.h>
    >
    > long long int64( long x, int y);
    > main()


    int main(void) please..

    > {
    > printf("%lld \n",int64(0xffffffff,1));
    >

    return 0; please..
    > }
    >
    > long long int64( long x, int y)
    > {
    > return x + y;
    > }
    >
    > Ans should be 0x100000000.


    Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    will yield 0.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Feb 10, 2007
    #5
  6. Joe Wright wrote:
    > csledge wrote:
    > > {
    > > printf("%lld \n",int64(0xffffffff,1));
    > >

    > return 0; please..
    > > }
    > >
    > > long long int64( long x, int y)
    > > {
    > > return x + y;
    > > }
    > >
    > > Ans should be 0x100000000.

    >
    > Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    > will yield 0.


    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.
     
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Feb 10, 2007
    #6
  7. "csledge" <> wrote in message
    >
    > 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 ?
    > #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.
    >

    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
    #7
  8. csledge

    Flash Gordon Guest

    Harald van Dijk wrote, On 10/02/07 17:22:
    > Joe Wright wrote:
    >> csledge wrote:
    >>> {
    >>> printf("%lld \n",int64(0xffffffff,1));
    >>>

    >> return 0; please..
    >>> }
    >>>
    >>> long long int64( long x, int y)
    >>> {
    >>> return x + y;
    >>> }
    >>>
    >>> Ans should be 0x100000000.

    >> Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    >> will yield 0.

    >
    > 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.


    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
     
    Flash Gordon, Feb 10, 2007
    #8
  9. csledge

    SM Ryan Guest

    "csledge" <> wrote:
    # 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.

    Rather
    return x+y;
    which is implicitly
    return (long long)(x+y);
    do
    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 http://www.rawbw.com/~wyrmwif/
    Wow. A sailboat.
     
    SM Ryan, Feb 10, 2007
    #9
  10. Flash Gordon wrote:
    > Harald van Dijk wrote, On 10/02/07 17:22:
    > > Joe Wright wrote:
    > >> csledge wrote:
    > >>> {
    > >>> printf("%lld \n",int64(0xffffffff,1));
    > >>>
    > >> return 0; please..
    > >>> }
    > >>>
    > >>> long long int64( long x, int y)
    > >>> {
    > >>> return x + y;
    > >>> }
    > >>>
    > >>> Ans should be 0x100000000.
    > >> Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    > >> will yield 0.

    > >
    > > 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.

    >
    > 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.


    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.
     
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Feb 10, 2007
    #10
  11. Harald van Dijk wrote:
    > Flash Gordon wrote:
    > > Harald van Dijk wrote, On 10/02/07 17:22:
    > > > Joe Wright wrote:
    > > >> csledge wrote:
    > > >>> {
    > > >>> printf("%lld \n",int64(0xffffffff,1));
    > > >>>
    > > >> return 0; please..
    > > >>> }
    > > >>>
    > > >>> long long int64( long x, int y)
    > > >>> {
    > > >>> return x + y;
    > > >>> }
    > > >>>
    > > >>> Ans should be 0x100000000.
    > > >> Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    > > >> will yield 0.
    > > >
    > > > 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.

    > >
    > > 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.

    >
    > 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.


    Sorry, that was incomplete. I forgot that such a conversion is also
    allowed to raise an implementation-defined signal, but still, no
    undefined behaviour.
     
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Feb 10, 2007
    #11
  12. csledge

    Jack Klein Guest

    On Sat, 10 Feb 2007 21:12:49 +0000, Flash Gordon
    <> wrote in comp.lang.c:

    > Harald van D?k wrote, On 10/02/07 17:22:
    > > Joe Wright wrote:
    > >> csledge wrote:
    > >>> {
    > >>> printf("%lld \n",int64(0xffffffff,1));
    > >>>
    > >> return 0; please..
    > >>> }
    > >>>
    > >>> long long int64( long x, int y)
    > >>> {
    > >>> return x + y;
    > >>> }
    > >>>
    > >>> Ans should be 0x100000000.
    > >> Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    > >> will yield 0.

    > >
    > > 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.

    >
    > 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.


    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
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Feb 11, 2007
    #12
  13. csledge

    Flash Gordon Guest

    Harald van Dijk wrote, On 10/02/07 23:58:
    > Harald van Dijk wrote:
    >> Flash Gordon wrote:
    >>> Harald van Dijk wrote, On 10/02/07 17:22:
    >>>> Joe Wright wrote:
    >>>>> csledge wrote:
    >>>>>> {
    >>>>>> printf("%lld \n",int64(0xffffffff,1));
    >>>>>>
    >>>>> return 0; please..
    >>>>>> }
    >>>>>>
    >>>>>> long long int64( long x, int y)
    >>>>>> {
    >>>>>> return x + y;
    >>>>>> }
    >>>>>>
    >>>>>> Ans should be 0x100000000.
    >>>>> Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    >>>>> will yield 0.
    >>>> 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.
    >>> 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.

    >> 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.

    >
    > Sorry, that was incomplete. I forgot that such a conversion is also
    > allowed to raise an implementation-defined signal, but still, no
    > undefined behaviour.


    Still not necessarily -1 though. Think of sign-magnitude or ones
    complement machines (not that I have come across any)
    --
    Flash Gordon
     
    Flash Gordon, Feb 11, 2007
    #13
  14. Flash Gordon <> writes:
    > Harald van Dijk wrote, On 10/02/07 17:22:

    [...]
    >> 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.

    >
    > 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.


    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 (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Feb 11, 2007
    #14
  15. "Malcolm McLean" <> writes:
    > "csledge" <> wrote in message
    >> 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 ?
    >> #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.
    >>

    > 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.


    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 (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Feb 11, 2007
    #15
  16. Flash Gordon wrote:

    > Harald van D?k wrote, On 10/02/07 23:58:
    >> Harald van D?k wrote:
    >>> Flash Gordon wrote:
    >>>> Harald van D?k wrote, On 10/02/07 17:22:
    >>>>> Joe Wright wrote:
    >>>>>> csledge wrote:
    >>>>>>> {
    >>>>>>> printf("%lld \n",int64(0xffffffff,1));
    >>>>>>>
    >>>>>> return 0; please..
    >>>>>>> }
    >>>>>>>
    >>>>>>> long long int64( long x, int y)
    >>>>>>> {
    >>>>>>> return x + y;
    >>>>>>> }
    >>>>>>>
    >>>>>>> Ans should be 0x100000000.
    >>>>>> Probably not. 0xffffffff is (long)-1 on your system (trust me). -1 + 1
    >>>>>> will yield 0.
    >>>>> 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.
    >>>> 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.
    >>> 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.

    >>
    >> Sorry, that was incomplete. I forgot that such a conversion is also
    >> allowed to raise an implementation-defined signal, but still, no
    >> undefined behaviour.

    >
    > Still not necessarily -1 though. Think of sign-magnitude or ones
    > complement machines (not that I have come across any)


    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
    #16
  17. csledge

    Guest

    On Feb 10, 8:07 am, "csledge" <> wrote:
    > 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 ?
    > #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.


    Try this following:
    ----

    #include "pstdint.h" /* http://www.pobox.com/~qed/pstdint.h */

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

    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++.)

    --
    Paul Hsieh
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
     
    , Feb 11, 2007
    #17
  18. Jack Klein <> writes:
    [...]
    > 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.


    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 (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Feb 11, 2007
    #18
  19. csledge

    CBFalconer Guest

    Christopher Layne wrote:
    > Flash Gordon wrote:
    >> Harald van D?k wrote, On 10/02/07 23:58:
    >>> Harald van D?k wrote:
    >>>

    .... snip ...
    >>>
    >>>> 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.
    >>>
    >>> Sorry, that was incomplete. I forgot that such a conversion is also
    >>> allowed to raise an implementation-defined signal, but still, no
    >>> undefined behaviour.

    >>
    >> Still not necessarily -1 though. Think of sign-magnitude or ones
    >> complement machines (not that I have come across any)

    >
    > OT: This is an example of where attribution gets out of hand. To me,
    > it's the equivalent of void ******.


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

    --
    <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
    <http://www.securityfocus.com/columnists/423>

    "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
    #19
  20. CBFalconer wrote:

    > Christopher Layne wrote:
    >> OT: This is an example of where attribution gets out of hand. To me,
    >> it's the equivalent of void ******.

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


    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
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Keflavich
    Replies:
    2
    Views:
    570
  2. Michael Tan
    Replies:
    32
    Views:
    997
    Ara.T.Howard
    Jul 21, 2005
  3. PerlFAQ Server
    Replies:
    0
    Views:
    271
    PerlFAQ Server
    Feb 2, 2011
  4. wutzke

    New Code to Compute Retail Values

    wutzke, Apr 22, 2008, in forum: Javascript
    Replies:
    4
    Views:
    127
    wutzke
    Apr 23, 2008
  5. Jeff.M
    Replies:
    6
    Views:
    179
    Lasse Reichstein Nielsen
    May 4, 2009
Loading...

Share This Page