SHOW:
|
|
- or go back to the newest paste.
| 1 | // author: [email protected] | |
| 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 | - | int x = ((a>>4)-(a&0xF))*((b>>4)-(b&0xF))&0xFF; // mul :S |
| 50 | + | |
| 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 | } |