Velocity Reviews > how to compute 64 bit result from 2 32 bit values

# how to compute 64 bit result from 2 32 bit values

csledge
Guest
Posts: n/a

 02-10-2007
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.

Tim Prince
Guest
Posts: n/a

 02-10-2007
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

=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=
Guest
Posts: n/a

 02-10-2007
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

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

Tim Prince
Guest
Posts: n/a

 02-10-2007
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.
>

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.

Joe Wright
Guest
Posts: n/a

 02-10-2007
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()

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

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

=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=
Guest
Posts: n/a

 02-10-2007
Joe Wright wrote:
> csledge wrote:
> > {
> > printf("%lld \n",int64(0xffffffff,1));
> >

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

Malcolm McLean
Guest
Posts: n/a

 02-10-2007
"csledge" <(E-Mail Removed)> 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.

Flash Gordon
Guest
Posts: n/a

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

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

SM Ryan
Guest
Posts: n/a

 02-10-2007
"csledge" <(E-Mail Removed)> 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.

=?utf-8?B?SGFyYWxkIHZhbiBExLNr?=
Guest
Posts: n/a

 02-10-2007
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));
> >>>
> >>> }
> >>>
> >>> 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.