SHOW:
|
|
- or go back to the newest paste.
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 | - | 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 | } |