рджреЛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Karatsuba рдПрд▓реНрдЧреЛрд░рд┐рдердо

рдХрд┐рд╕реА рддрд░рд╣ рдореБрдЭреЗ C ++ рдореЗрдВ рдЙрдирдХреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд▓рдВрдмреА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдЧреБрдгрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдерд╛ред 128-рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ 64-рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рджреЛ 128-рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдФрд░ рдЬрдЯрд┐рд▓рддрд╛ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╕рднреА 256 рдмрд┐рдЯреНрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 64-рдмрд┐рдЯ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЗ 4 рдЙрддреНрдкрд╛рджреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╣реИред рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ...



рдЧреБрдгрди рдХреЗ рд▓рд┐рдП, рдШрд░реЗрд▓реВ рдЧрдгрд┐рддрдЬреНрдЮ рдЕрдирд╛рддреЛрд▓реА рдПрд▓реЗрдХреНрд╕реЗрд╡рд┐рдЪ рдХрд╛рд░рддреНрд╕реБрдмрд╛ рдХреА рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдЖрдкрдХреЛ рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдЕрдкрдиреА рдЯрд┐рдкреНрдкрдгреА рджреВрдВрдЧрд╛ред рд╡рд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИред

// // Karatsuba multiplication algorithm // // +------+------+ // | x1 | x0 | // +------+------+ // * // +------+------+ // | y1 | y0 | // +------+------+ // = // +-------------+-------------+ // + | x1*y1 | x0*y0 | // +----+-+------+------+------+ // . . . // . . . // +-+------+------+ // + | x0*y1 + x1*y0 | // +-+------+------+ // 

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЯрд┐рдкреНрдкрдгреА рдпрд╣ тАЛтАЛрд╕реНрдкрд╖реНрдЯ рдХрд░рддреА рд╣реИ рдХрд┐ рдкрд░рд┐рдгрд╛рдо рдХреА рдЧрдгрдирд╛ рдХреИрд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИред
рд╡рд┐рдзрд┐ рдХрд╛ рд╕рд╛рд░ рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдирд┐рдореНрди рд╕реВрддреНрд░ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ:



T рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдХрд╛ рдкреНрд░рддреАрдХ рд╣реИ, рдХреНрд░рдорд╢рдГ T ^ 2 - рдбрдмрд▓ рдЗрдВрдбреЗрдВрдЯреЗрд╢рдиред
рдпрд╣рд╛рдБ рдХреЛрдб рд╣реИ рдЬреЛ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд░рддрд╛ рд╣реИ:

 // // Params: // T - is type of x0, x1, y0 and y1 halves // T2 - is type of x, y and half of res // template<typename T, typename T2> inline void Karatsuba_multiply(T * const x, T * const y, T2 * res) { // Define vars (depending from byte order) #define ptrRes ((T*)res) T2 & lowWord = (T2&)(ptrRes[0]); T2 & midWord = (T2&)(ptrRes[1]); T2 & highWord = (T2&)(ptrRes[2]); T & highByte = (T &)(ptrRes[3]); #undef ptrRes const T & x0 = x[0]; const T & x1 = x[1]; const T & y0 = y[0]; const T & y1 = y[1]; // Multiply action lowWord = x0 * y0; highWord = x1 * y1; T2 m1 = x0 * y1; T2 m2 = x1 * y0; midWord += m1; if (midWord < m1) highByte++; midWord += m2; if (midWord < m2) highByte++; } 

рдЯрд╛рдЗрдк T рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЖрдзрд╛ рд╣реИ, рдЯрд╛рдЗрдк x0, X1, y0, y1ред
рдЯрд╛рдЗрдк рдПрди 2 рдЖрдзреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЯрд╛рдЗрдк рдЯреА рдХрд╛ 2 рдЧреБрдирд╛ред

рд╕рдорд╛рд░реЛрд╣ рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:

 int main() { typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; u16 a = 1000; u16 b = 2000; u32 r = 0; u8 * a_ptr = (u8*)&a; u8 * b_ptr = (u8*)&b; u16 * r_ptr = (u16*)(void*)&r; Karatsuba_multiply(a_ptr, b_ptr, r_ptr); cout << r; } 

рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рд▓рд╛ рдХреЛрдб рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: codepad.org/1OTeGqhA
рдЕрд▓рдЧ-рдЕрд▓рдЧ рдмрд╛рдЗрдЯ рдСрд░реНрдбрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕рд╛рде рдХреЛрдб (LE + BE) рдпрд╣рд╛рдВ: codepad.org/f5Pxtiq1

Update1:
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ mark_ablov рдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдХреЛрдб рдореЗрдВ #undef рдХрд╛ рдЕрднрд╛рд╡ рд╣реИред
рд╕рд╣реА рдХреЛрдб: codepad.org/13U4fuTp
рд╕рд╣реА рдкреВрд░реНрдг рдХреЛрдб (LE + BE): codepad.org/kBazqo8f

UPDATE2:
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ ttim рдиреЗ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдмрд┐рд▓реНрдХреБрд▓ Karatsuba рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЪрд╛рд░ рдХреЗ рдмрдЬрд╛рдп 3 рдЧреБрдгрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХрд╛ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ред

рд╕реНрдкрд╖реНрдЯрддрд╛ рд╕реВрддреНрд░:



рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХреЗрд╡рд▓ 3 рдЙрддреНрдкрд╛рджреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
1. рдП * рдПрдХреНрд╕
2. рдм * рдп
3. (рдЯрд╛ + рдмреА) * (рдЯреАрдПрдХреНрд╕ + рд╡рд╛рдИ)

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореИрдВ рдЗрд╕ рд╕реВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рдкрд╛рдКрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ 128-рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдирд╣реАрдВ рд╣реИред рджрд░рдЕрд╕рд▓, рдореЗрд░рд╛ рдХрд╛рдо 128-рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЧреБрдгрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдерд╛ред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрдЦреНрдпрд╛ (рдЯрд╛ + рдмреА) рдФрд░ (рдЯреАрдПрдХреНрд╕ + рд╡рд╛рдИ) 128 рдмрд┐рдЯреНрд╕ рдЪреМрдбрд╝реЗ рд╣реИрдВ ...

Update3:
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ susl рдиреЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдЪрд░реНрдЪрд╛ рдЬрд╛рд░реА рд░рдЦреА рдФрд░ рджрд┐рдЦрд╛рдпрд╛ рдХрд┐ 128-рдмрд┐рдЯ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдПрдХ рдФрд░ рд╕реВрддреНрд░:



рд╕рдорд╛рд░реЛрд╣ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 // // Params: // T - is type of x0, x1, y0 and y1 halves // T2 - is type of x, y and half of res // template<typename T, typename T2> inline void Karatsuba_multiply(T * const x, T * const y, T2 * res) { // Define vars (depending from byte order) #define ptrRes ((T*)res) T2 & lowWord = (T2&)(ptrRes[0]); T2 & midWord = (T2&)(ptrRes[1]); T2 & highWord = (T2&)(ptrRes[2]); T & highByte = (T &)(ptrRes[3]); #undef ptrRes const T & x0 = x[0]; const T & x1 = x[1]; const T & y0 = y[0]; const T & y1 = y[1]; // Multiply action lowWord = x0 * y0; highWord = x1 * y1; //T2 m1 = x0 * y1; //T2 m2 = x1 * y0; T2 m = (x0+x1)*(y0+y1) - (lowWord + highWord); //midWord += m1; //if (midWord < m1) highByte++; //midWord += m2; //if (midWord < m2) highByte++; midWord += m; if (midWord < m) highByte++; } 

рд╕рд╣реА рдЙрджрд╛рд╣рд░рдг: http://codepad.org/w0INBD77
LE рдФрд░ BE рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдЙрджрд╛рд╣рд░рдг: http://codepad.org/nB9HqWt1

Source: https://habr.com/ru/post/In121950/


All Articles