how to compute 64 bit result from 2 32 bit values

C

csledge

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

Tim Prince

csledge said:
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.
 
G

Guest

csledge said:
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;
}
 
T

Tim Prince

csledge said:
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.
 
J

Joe Wright

csledge said:
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.
 
G

Guest

Joe said:
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.
 
M

Malcolm McLean

csledge said:
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.
 
F

Flash Gordon

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

SM Ryan

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

Guest

Flash said:
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.

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

Guest

Harald said:
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.
 
J

Jack Klein

Harald van D?k 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.

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

Flash Gordon

Harald van Dijk wrote, On 10/02/07 23:58:
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)
 
K

Keith Thompson

Flash Gordon said:
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.
 
K

Keith Thompson

Malcolm McLean said:
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.
 
C

Christopher Layne

Flash said:
Harald van D?k 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)

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

websnarf

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

Keith Thompson

Jack Klein said:
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.
 
C

CBFalconer

Christopher said:
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
 
C

Christopher Layne

CBFalconer said:
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.
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top