Hi people, bug_mult_and_shift_long.c ------------------------- #include <stdio.h> // it's for public domain by J.C. Pizarro, hahahahaha int main() { long long int a,b,c; unsigned int hi_a,lo_a,hi_b,lo_b,hi_c,lo_c;
a = 10000000000L; // 10G b = 100000000L; // 100M c = a * b; hi_a = (((unsigned long)a)>>32); // <- warning? why? (>>32) hi_a = ((((unsigned long)a)>>31)>>1); // <- no warning! dirty workaround lo_a = ((((unsigned long)(a<<32))>>31)>>1); // <- warning? why? (<<32) lo_a = a; // <- no warning! hi_b = ((((unsigned long)b)>>1)>>31); lo_b = b & 0x00000000FFFFFFFFL; hi_c = ((((unsigned long)c)>>16)>>16); lo_c = c & 0x00000000FFFFFFFFL; printf("a = %ld\n",a); printf("b = %ld\n",b); printf("c = a x b = %ld\n",c); printf("high(a) = 0x%08X ; low(a) = 0x%08X\n",hi_a,lo_a); printf("high(b) = 0x%08X ; low(b) = 0x%08X\n",hi_b,lo_b); printf("high(c) = 0x%08X ; low(c) = 0x%08X\n",hi_c,lo_c); printf("why this multiply?\n"); printf("It's a bug: long x long -> { 0, unsigned int } \ instead of long x long -> long\n"); return 0; } run.sh ------ #!/bin/sh gcc bug_mult_and_shift_long.c ./a.out rm -f a.out run.log ------- Reading specs from /usr/lib/gcc/i486-slackware-linux/3.4.6/specs Configured with: ../gcc-3.4.6/configure --prefix=/usr --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-checking --with-gnu-ld --verbose --target=i486-slackware-linux --host=i486-slackware-linux Thread model: posix gcc version 3.4.6 bug_mult_and_shift_long.c: In function `main': bug_mult_and_shift_long.c:5: warning: integer constant is too large for "long" type bug_mult_and_shift_long.c:8: warning: right shift count >= width of type a = 1410065408 b = 100000000 c = a x b = -1486618624 high(a) = 0x00000000 ; low(a) = 0x540BE400 high(b) = 0x00000000 ; low(b) = 0x05F5E100 high(c) = 0x00000000 ; low(c) = 0xA7640000 why this multiply? It's a bug: long x long -> { 0, unsigned int } instead of long x long -> long Using built-in specs. Target: i686-pc-linux-gnu Configured with: ./configure --prefix=/opt/gcc413 Thread model: posix gcc version 4.1.3 20070326 (prerelease) bug_mult_and_shift_long.c: In function 'main': bug_mult_and_shift_long.c:5: warning: integer constant is too large for 'long' type bug_mult_and_shift_long.c:8: warning: right shift count >= width of type a = 1410065408 b = 100000000 c = a x b = -1486618624 high(a) = 0x00000000 ; low(a) = 0x540BE400 high(b) = 0x00000000 ; low(b) = 0x05F5E100 high(c) = 0x00000000 ; low(c) = 0xA7640000 why this multiply? It's a bug: long x long -> { 0, unsigned int } instead of long x long -> long Brief summary, there are 3 bugs: 1. Error and Warning in assignment of a long constant (with L letter) (it's not true that a = 1410065408, high(a) = 0x00000000). 2. Warning in shifts << & >> of a long variable (i don't know if there is an error). 3. Error in multiply of long variables. (it's not true that c = -1486618624). Sincerely yours, J.C. Pizarro
testing_long_GCC_march2007_2.tar.gz
Description: GNU Zip compressed data