Hallo to everyone.
My problem is to have the upper 4 Byte result of a multiply. For example:
unsigned int a=1000000000;//only example value unsigned int b=10000000000; unsigned int c;
the result of a*b = 0x8AC7230489E80000 How to get the upper 4 Bytes: 0x8AC72304 How to get the lower 4 Bytes: 0x89E80000
Can anybody help? I have to programm a super-fast-interrupt-routine for an microcontroller, there is not enough time for floating point.
You'd want one of the long long integer types then.
Hello,
long long may be a way, but i only need a 32-bit result, the upper 4 byte or the lower 4 byte. Maybee someone has a programm-example :-)
Regards
So extract the MSLong or LSLong of the 64-bit result. Shifting and masking, or unions work on long longs too.
union U64_ { unsigned long long ull; unsigned long ul[2]; }; unsigned long multiplier; unsigned long multiplicand; union U64_ product; unsigned long product_msl; unsigned long product_lsl; product.ull = (unsigned long long)multplicand * multiplier; product_msl = product.ul[1]; /* Assuming little-endian */ product_lsl = product.ul[0]; /* Assuming little-endian */
Quickly typed, not tested :-(
s/multplicand/multiplicand/
Hi, i tried several version of something like
unsigned int a=3162277661; unsigned int b=3162277660; unsigned int c; c=((a*b)>>32)&0xFFFFFFFF;
but i get wrong result or ARM COMPILER V2.40c, ADIDEMO\LONG_LONG_7.C: '>>': out of range shift factor has been truncated *** WARNING C200 IN LINE 16 OF ADIDEMO\LONG_LONG_7.C: '>>': out of range shift factor has been truncated
Regarding the shift operator:
"If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined."
but i get wrong result or
No, the result is not wrong, what you're doing is wrong. You're expecting the compiler to automatically expand the result to 64 bits, which it won't do.
Either you do it in assembly (ARM has very nice multiply instructions that can calculate the upper part, the lower part, or all 64 bits of a 32 bit * 32 bit multiplication), or you tell the compiler that it needs to use a 64 bit integer datatype. I wouldn't expect it to come up with optimal (super-fast) code however.
Define them as long long int (unsigned int if you desire)
long long int a; long long int b; long long int c;
int lower32; int upper32;
c = a * b;
lower32 = *((u32 *) &c); upper32 = *(((u32 *) &c) + 1); // little endian assumed
Don't worry the the last assignments look ugly. The compiler will easily optimize this to a direct 32-bit fetch of the value.
Hello, this is perfect but very slow code...
long long int a; long long int b; long long int c; int lower32; int upper32; c = a * b; lower32 = *((u32 *) &c); upper32 = *(((u32 *) &c) + 1); // little endian assumed
i had to replace u32 by unsigned int :-)
Another side effect: Writing
a=3162277660;// = 0XBC7C871C
gives the result a=0XFFFFFFFFBC7C871C
a=0xBC7C871C;// = 3162277660
gives the result a=0X00000000BC7C871C
View all questions in Keil forum