Advertisement
r57shell

Karatsuba test

Apr 10th, 2014
567
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.79 KB | None | 0 0
  1. // author: r57shell@uralweb.ru
  2. #include <cstdio>
  3.  
  4. // standard add carry flag calculation
  5. bool add_c(int a, int b)
  6. {
  7.     if ((unsigned int)a > 0xF || (unsigned int)b > 0xF)
  8.         printf("Assertation failed!\n");
  9.     int r = a + b;
  10.     return ((a&0x8)&b)|(((~r)&0x8)&b)|(((~r)&0x8)&a);
  11. }
  12.  
  13. // if you don't belive to previous function, use this
  14. bool add_c1(int a, int b)
  15. {
  16.     if ((unsigned int)a > 0xF || (unsigned int)b > 0xF)
  17.         printf("Assertation failed!\n");
  18.     int r = a + b;
  19.     return r>0xF;
  20. }
  21.  
  22. // simple signed 4.4 fixed point multiplication
  23. int mul(int a, int b)
  24. {
  25.     if ((unsigned int)a > 0xFF || (unsigned int)b > 0xFF)
  26.         printf("Assertation failed!\n");
  27.     return (((int)(char)a*(int)(char)b)>>4)&0xFF;
  28. }
  29.  
  30. // karatsuba test signed 4.4 fixed point multiplication
  31. int mul2(int a, int b)
  32. {
  33.     if ((unsigned int)a > 0xFF || (unsigned int)b > 0xFF)
  34.         printf("Assertation failed!\n");
  35.     int s=1;
  36.     if ((char)a < 0)
  37.     {
  38.         s *= -1;
  39.         a = -(char)a;
  40.     }
  41.     if ((char)b < 0)
  42.     {
  43.         s *= -1;
  44.         b = -(char)b;
  45.     }
  46.     if ((unsigned int)a > 0xFF || (unsigned int)b > 0xFF)
  47.         printf("Assertation failed!\n");
  48.     int z1 = ((a&0xF)*(b&0xF))&0xFF; //mul low
  49.     int z3 = ((a>>4)*(b>>4))&0xFF; // mul high
  50.     int x = ((a>>4)-(a&0xF))*((b>>4)-(b&0xF))&0xFF; // mul :S
  51.     int y = (z1-x)&0xFF;
  52.     int z2 = (y+z3)&0xFF; // z2 now calculated
  53.     int r1 = ((z1>>4)+z2&0xF); // sum low part
  54.     int c = add_c((z1>>4),z2&0xF)?1:0; // check carry
  55.     int r2 = ((z2>>4)+(z3&0xF)+c)&0xF; // sum high part
  56.     int r = (r1)|(r2<<4); // combine result
  57.     if (s == -1) // sign invert
  58.         r = ((~r)+((z1)&0xF?0:1))&0xFF;
  59.     return r; // hurray!
  60. }
  61.  
  62. int main()
  63. {
  64.     for (int a=0; a<0x100; ++a)
  65.         for (int b=0; b<0x100; ++b)
  66.         {
  67.             if (mul(a,b) != mul2(a,b))
  68.                 printf("mul(%02X,%02X)=%02X!=%02X=mul2(%02X,%02X)\n",a,b,mul(a,b),mul2(a,b),a,b);
  69.         }
  70.     return 0;
  71. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement