Advertisement
r57shell

Karatsuba test new version

Apr 10th, 2014
472
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. // standard sub carry flag calculation
  23. bool sub_c(int a, int b)
  24. {
  25.     int r = a - b;
  26.     return (((~a)&0x8)&b)|((r&0x8)&b)|((r&0x8)&(~a));
  27. }
  28.  
  29. // if you don't belive to previous function, use this
  30. bool sub_c1(int a, int b)
  31. {
  32.     if ((unsigned int)a > 0xF || (unsigned int)b > 0xF)
  33.         printf("Assertation failed!\n");
  34.     return a<b;
  35. }
  36.  
  37.  
  38. // simple signed 4.4 fixed point multiplication
  39. int mul(int a, int b)
  40. {
  41.     if ((unsigned int)a > 0xFF || (unsigned int)b > 0xFF)
  42.         printf("Assertation failed!\n");
  43.     return (((int)(char)a*(int)(char)b)>>4)&0xFF;
  44. }
  45.  
  46. // karatsuba test signed 4.4 fixed point multiplication
  47. int mul2(int a, int b)
  48. {
  49.     if ((unsigned int)a > 0xFF || (unsigned int)b > 0xFF)
  50.         printf("Assertation failed!\n");
  51.     int s=1;
  52.     if ((char)a < 0)
  53.     {
  54.         s *= -1;
  55.         a = -(char)a;
  56.     }
  57.     if ((char)b < 0)
  58.     {
  59.         s *= -1;
  60.         b = -(char)b;
  61.     }
  62.     if ((unsigned int)a > 0xFF || (unsigned int)b > 0xFF)
  63.         printf("Assertation failed!\n");
  64.     int z1 = ((a&0xF)*(b&0xF))&0xFF; //mul low
  65.     int z3 = ((a>>4)*(b>>4))&0xFF; // mul high
  66.     int z = 1;
  67.     int aa = ((a>>4)-(a&0xF))&0xF;
  68.     if (sub_c((a>>4),(a&0xF)))
  69.     {
  70.         z = -z;
  71.         aa = (-aa)&0xF;
  72.     }
  73.     int bb = ((b>>4)-(b&0xF))&0xF;
  74.     if (sub_c((b>>4),(b&0xF)))
  75.     {
  76.         z = -z;
  77.         bb = (-bb)&0xF;
  78.     }
  79.     int x = aa*bb&0xFF; // mul :S
  80.     if (z == -1)
  81.         x = (-x)&0xFF;
  82.     int y = (z1-x)&0xFF;
  83.     int z2 = (y+z3)&0xFF; // z2 now calculated
  84.     int r1 = ((z1>>4)+z2&0xF); // sum low part
  85.     int c = add_c((z1>>4),z2&0xF)?1:0; // check carry
  86.     int r2 = ((z2>>4)+(z3&0xF)+c)&0xF; // sum high part
  87.     int r = (r1)|(r2<<4); // combine result
  88.     if (s == -1) // sign invert
  89.         r = ((~r)+((z1)&0xF?0:1))&0xFF;
  90.     return r; // hurray!
  91. }
  92.  
  93. int main()
  94. {
  95.     for (int a=0; a<0x100; ++a)
  96.         for (int b=0; b<0x100; ++b)
  97.         {
  98.             if (mul(a,b) != mul2(a,b))
  99.                 printf("mul(%02X,%02X)=%02X!=%02X=mul2(%02X,%02X)\n",a,b,mul(a,b),mul2(a,b),a,b);
  100.         }
  101.     return 0;
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement