Annotation of OpenXM_contrib2/asir2000/engine/N.c, Revision 1.12
1.2 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.3 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.12 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/engine/N.c,v 1.11 2015/08/29 04:15:04 fujimoto Exp $
1.2 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include "base.h"
52:
1.11 fujimoto 53: #if (defined(_M_IX86) || defined(i386)) && !defined(__MINGW32__)
1.5 noro 54: void addn(N n1,N n2,N *nr)
1.1 noro 55: {
1.12 ! noro 56: unsigned int *m1,*m2,*mr;
! 57: unsigned int c;
! 58: N r;
! 59: int i,d1,d2;
! 60: unsigned int tmp;
! 61:
! 62: if ( !n1 )
! 63: COPY(n2,*nr);
! 64: else if ( !n2 )
! 65: COPY(n1,*nr);
! 66: else {
! 67: if ( PL(n1) > PL(n2) ) {
! 68: d1 = PL(n1); d2 = PL(n2); m1 = BD(n1); m2 = BD(n2);
! 69: } else {
! 70: d1 = PL(n2); d2 = PL(n1); m1 = BD(n2); m2 = BD(n1);
! 71: }
! 72: *nr = r = NALLOC(d1 + 1); INITRC(r); mr = BD(r);
1.1 noro 73:
1.10 ohara 74: #if defined(_M_IX86)
1.12 ! noro 75: __asm {
! 76: push esi
! 77: push edi
! 78: mov esi,m1
! 79: mov edi,m2
! 80: mov ebx,mr
! 81: mov ecx,d2
! 82: xor eax,eax
! 83: Lstart_addn:
! 84: mov eax,DWORD PTR [esi]
! 85: mov edx,DWORD PTR [edi]
! 86: adc eax,edx
! 87: mov DWORD PTR [ebx],eax
! 88: lea esi,DWORD PTR [esi+4]
! 89: lea edi,DWORD PTR [edi+4]
! 90: lea ebx,DWORD PTR [ebx+4]
! 91: dec ecx
! 92: jnz Lstart_addn
! 93: pop edi
! 94: pop esi
! 95: mov eax,0
! 96: adc eax,eax
! 97: mov c,eax
! 98: }
1.1 noro 99: #else
1.12 ! noro 100: asm volatile("\
! 101: pushl %%ebx;\
! 102: movl %1,%%esi;\
! 103: movl %2,%%edi;\
! 104: movl %3,%%ebx;\
! 105: movl %4,%%ecx;\
! 106: testl %%eax,%%eax;\
! 107: Lstart_addn:;\
! 108: movl (%%esi),%%eax;\
! 109: movl (%%edi),%%edx;\
! 110: adcl %%edx,%%eax;\
! 111: movl %%eax,(%%ebx);\
! 112: leal 4(%%esi),%%esi;\
! 113: leal 4(%%edi),%%edi;\
! 114: leal 4(%%ebx),%%ebx;\
! 115: decl %%ecx;\
! 116: jnz Lstart_addn;\
! 117: movl $0,%%eax;\
! 118: adcl %%eax,%%eax;\
! 119: movl %%eax,%0;\
! 120: popl %%ebx"\
! 121: :"=m"(c)\
! 122: :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
! 123: :"eax","ecx","edx","esi","edi");
1.1 noro 124: #endif
1.12 ! noro 125: for ( i = d2, m1 += d2, mr += d2; (i < d1) && c ; i++ ) {
! 126: tmp = *m1++ + c;
! 127: c = tmp < c ? 1 : 0;
! 128: *mr++ = tmp;
! 129: }
! 130: for ( ; i < d1; i++ )
! 131: *mr++ = *m1++;
! 132: *mr = c;
! 133: PL(r) = (c?d1+1:d1);
! 134: }
1.1 noro 135: }
136:
1.5 noro 137: int subn(N n1,N n2,N *nr)
1.1 noro 138: {
1.12 ! noro 139: N r;
! 140: unsigned int *m1,*m2,*mr,br;
! 141: unsigned int tmp,t;
! 142: int d1,d2,sgn,i;
! 143:
! 144: if ( !n1 ) {
! 145: if ( n2 ) {
! 146: COPY(n2,*nr);
! 147: return -1;
! 148: } else {
! 149: *nr = 0;
! 150: return 0;
! 151: }
! 152: } else if ( !n2 ) {
! 153: COPY(n1,*nr);
! 154: return 1;
! 155: } else {
! 156: d1 = PL(n1); d2 = PL(n2);
! 157: m1 = BD(n1); m2 = BD(n2);
! 158: if ( (d1 = PL(n1)) > (d2 = PL(n2)) )
! 159: sgn = 1;
! 160: else if ( d1 < d2 ) {
! 161: d1 = PL(n2); d2 = PL(n1);
! 162: m1 = BD(n2); m2 = BD(n1);
! 163: sgn = -1;
! 164: } else {
! 165: for ( i = d1-1; i >= 0 && m1[i] == m2[i]; i-- );
! 166: if ( i < 0 ) {
! 167: *nr = 0;
! 168: return 0;
! 169: }
! 170: d1 = d2 = i+1;
! 171: if ( m1[i] > m2[i] )
! 172: sgn = 1;
! 173: else {
! 174: m1 = BD(n2); m2 = BD(n1);
! 175: sgn = -1;
! 176: }
! 177: }
! 178: *nr = r = NALLOC(d1); INITRC(r); mr = BD(r);
1.1 noro 179:
1.10 ohara 180: #if defined(_M_IX86)
1.12 ! noro 181: __asm {
! 182: push esi
! 183: push edi
! 184: mov esi,m1
! 185: mov edi,m2
! 186: mov ebx,mr
! 187: mov ecx,d2
! 188: xor eax,eax
! 189: Lstart_subn:
! 190: mov eax,DWORD PTR [esi]
! 191: mov edx,DWORD PTR [edi]
! 192: sbb eax,edx
! 193: mov DWORD PTR [ebx],eax
! 194: lea esi,DWORD PTR [esi+4]
! 195: lea edi,DWORD PTR [edi+4]
! 196: lea ebx,DWORD PTR [ebx+4]
! 197: dec ecx
! 198: jnz Lstart_subn
! 199: pop edi
! 200: pop esi
! 201: mov eax,0
! 202: adc eax,eax
! 203: mov br,eax
! 204: }
1.1 noro 205: #else
1.12 ! noro 206: asm volatile("\
! 207: pushl %%ebx;\
! 208: movl %1,%%esi;\
! 209: movl %2,%%edi;\
! 210: movl %3,%%ebx;\
! 211: movl %4,%%ecx;\
! 212: testl %%eax,%%eax;\
! 213: Lstart_subn:;\
! 214: movl (%%esi),%%eax;\
! 215: movl (%%edi),%%edx;\
! 216: sbbl %%edx,%%eax;\
! 217: movl %%eax,(%%ebx);\
! 218: leal 4(%%esi),%%esi;\
! 219: leal 4(%%edi),%%edi;\
! 220: leal 4(%%ebx),%%ebx;\
! 221: decl %%ecx;\
! 222: jnz Lstart_subn;\
! 223: movl $0,%%eax;\
! 224: adcl %%eax,%%eax;\
! 225: movl %%eax,%0;\
! 226: popl %%ebx"\
! 227: :"=m"(br)\
! 228: :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
! 229: :"eax","ecx","edx","esi","edi");
1.1 noro 230: #endif
1.12 ! noro 231: for ( i = d2, m1 += d2, mr += d2; (i < d1) && br; i++ ) {
! 232: t = *m1++;
! 233: tmp = t - br;
! 234: br = tmp > t ? 1 : 0;
! 235: *mr++ = tmp;
! 236: }
! 237: for ( ; i < d1; i++ )
! 238: *mr++ = *m1++;
! 239: for ( i = d1-1, mr--; i >= 0 && !*mr--; i-- );
! 240: PL(r) = i + 1;
! 241: return sgn;
! 242: }
1.1 noro 243: }
244:
1.5 noro 245: void _addn(N n1,N n2,N nr)
1.1 noro 246: {
1.12 ! noro 247: unsigned int *m1,*m2,*mr;
! 248: unsigned int c;
! 249: int i,d1,d2;
! 250: unsigned int tmp;
! 251:
! 252: if ( !n1 || !PL(n1) )
! 253: dupn(n2,nr);
! 254: else if ( !n2 || !PL(n2) )
! 255: dupn(n1,nr);
! 256: else {
! 257: if ( PL(n1) > PL(n2) ) {
! 258: d1 = PL(n1); d2 = PL(n2); m1 = BD(n1); m2 = BD(n2);
! 259: } else {
! 260: d1 = PL(n2); d2 = PL(n1); m1 = BD(n2); m2 = BD(n1);
! 261: }
! 262: mr = BD(nr);
1.1 noro 263:
1.10 ohara 264: #if defined(_M_IX86)
1.12 ! noro 265: __asm {
! 266: push esi
! 267: push edi
! 268: mov esi,m1
! 269: mov edi,m2
! 270: mov ebx,mr
! 271: mov ecx,d2
! 272: xor eax,eax
! 273: Lstart__addn:
! 274: mov eax,DWORD PTR [esi]
! 275: mov edx,DWORD PTR [edi]
! 276: adc eax,edx
! 277: mov DWORD PTR [ebx],eax
! 278: lea esi,DWORD PTR [esi+4]
! 279: lea edi,DWORD PTR [edi+4]
! 280: lea ebx,DWORD PTR [ebx+4]
! 281: dec ecx
! 282: jnz Lstart__addn
! 283: pop edi
! 284: pop esi
! 285: mov eax,0
! 286: adc eax,eax
! 287: mov c,eax
! 288: }
1.1 noro 289: #else
1.12 ! noro 290: asm volatile("\
! 291: pushl %%ebx;\
! 292: movl %1,%%esi;\
! 293: movl %2,%%edi;\
! 294: movl %3,%%ebx;\
! 295: movl %4,%%ecx;\
! 296: testl %%eax,%%eax;\
! 297: Lstart__addn:;\
! 298: movl (%%esi),%%eax;\
! 299: movl (%%edi),%%edx;\
! 300: adcl %%edx,%%eax;\
! 301: movl %%eax,(%%ebx);\
! 302: leal 4(%%esi),%%esi;\
! 303: leal 4(%%edi),%%edi;\
! 304: leal 4(%%ebx),%%ebx;\
! 305: decl %%ecx;\
! 306: jnz Lstart__addn;\
! 307: movl $0,%%eax;\
! 308: adcl %%eax,%%eax;\
! 309: movl %%eax,%0;\
! 310: popl %%ebx"\
! 311: :"=m"(c)\
! 312: :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
! 313: :"eax","ecx","edx","esi","edi");
1.1 noro 314: #endif
1.12 ! noro 315: for ( i = d2, m1 += d2, mr += d2; (i < d1) && c ; i++ ) {
! 316: tmp = *m1++ + c;
! 317: c = tmp < c ? 1 : 0;
! 318: *mr++ = tmp;
! 319: }
! 320: for ( ; i < d1; i++ )
! 321: *mr++ = *m1++;
! 322: *mr = c;
! 323: PL(nr) = (c?d1+1:d1);
! 324: }
1.1 noro 325: }
326:
1.5 noro 327: int _subn(N n1,N n2,N nr)
1.1 noro 328: {
1.12 ! noro 329: unsigned int *m1,*m2,*mr,br;
! 330: unsigned int tmp,t;
! 331: int d1,d2,sgn,i;
! 332:
! 333: if ( !n1 || !PL(n1) ) {
! 334: if ( n2 && PL(n2) ) {
! 335: dupn(n2,nr);
! 336: return -1;
! 337: } else {
! 338: PL(nr) = 0;
! 339: return 0;
! 340: }
! 341: } else if ( !n2 || !PL(n2) ) {
! 342: dupn(n1,nr);
! 343: return 1;
! 344: } else {
! 345: d1 = PL(n1); d2 = PL(n2);
! 346: m1 = BD(n1); m2 = BD(n2);
! 347: if ( (d1 = PL(n1)) > (d2 = PL(n2)) )
! 348: sgn = 1;
! 349: else if ( d1 < d2 ) {
! 350: d1 = PL(n2); d2 = PL(n1);
! 351: m1 = BD(n2); m2 = BD(n1);
! 352: sgn = -1;
! 353: } else {
! 354: for ( i = d1-1; i >= 0 && m1[i] == m2[i]; i-- );
! 355: if ( i < 0 ) {
! 356: PL(nr) = 0;
! 357: return 0;
! 358: }
! 359: d1 = d2 = i+1;
! 360: if ( m1[i] > m2[i] )
! 361: sgn = 1;
! 362: else {
! 363: m1 = BD(n2); m2 = BD(n1);
! 364: sgn = -1;
! 365: }
! 366: }
! 367: mr = BD(nr);
1.1 noro 368:
1.10 ohara 369: #if defined(_M_IX86)
1.12 ! noro 370: __asm {
! 371: push esi
! 372: push edi
! 373: mov esi,m1
! 374: mov edi,m2
! 375: mov ebx,mr
! 376: mov ecx,d2
! 377: xor eax,eax
! 378: Lstart__subn:
! 379: mov eax,DWORD PTR [esi]
! 380: mov edx,DWORD PTR [edi]
! 381: sbb eax,edx
! 382: mov DWORD PTR [ebx],eax
! 383: lea esi,DWORD PTR [esi+4]
! 384: lea edi,DWORD PTR [edi+4]
! 385: lea ebx,DWORD PTR [ebx+4]
! 386: dec ecx
! 387: jnz Lstart__subn
! 388: pop edi
! 389: pop esi
! 390: mov eax,0
! 391: adc eax,eax
! 392: mov br,eax
! 393: }
1.1 noro 394: #else
1.12 ! noro 395: asm volatile("\
! 396: pushl %%ebx;\
! 397: movl %1,%%esi;\
! 398: movl %2,%%edi;\
! 399: movl %3,%%ebx;\
! 400: movl %4,%%ecx;\
! 401: testl %%eax,%%eax;\
! 402: Lstart__subn:;\
! 403: movl (%%esi),%%eax;\
! 404: movl (%%edi),%%edx;\
! 405: sbbl %%edx,%%eax;\
! 406: movl %%eax,(%%ebx);\
! 407: leal 4(%%esi),%%esi;\
! 408: leal 4(%%edi),%%edi;\
! 409: leal 4(%%ebx),%%ebx;\
! 410: decl %%ecx;\
! 411: jnz Lstart__subn;\
! 412: movl $0,%%eax;\
! 413: adcl %%eax,%%eax;\
! 414: movl %%eax,%0;\
! 415: popl %%ebx"\
! 416: :"=m"(br)\
! 417: :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
! 418: :"eax","ecx","edx","esi","edi");
1.1 noro 419: #endif
1.12 ! noro 420: for ( i = d2, m1 += d2, mr += d2; (i < d1) && br; i++ ) {
! 421: t = *m1++;
! 422: tmp = t - br;
! 423: br = tmp > t ? 1 : 0;
! 424: *mr++ = tmp;
! 425: }
! 426: for ( ; i < d1; i++ )
! 427: *mr++ = *m1++;
! 428: for ( i = d1-1, mr--; i >= 0 && !*mr--; i-- );
! 429: PL(nr) = i + 1;
! 430: return sgn;
! 431: }
1.1 noro 432: }
433: #else
434:
1.5 noro 435: void addn(N n1,N n2,N *nr)
1.1 noro 436: {
1.12 ! noro 437: unsigned int *m1,*m2,*mr,i,c;
! 438: N r;
! 439: int d1,d2;
! 440: unsigned int tmp;
! 441:
! 442: if ( !n1 )
! 443: COPY(n2,*nr);
! 444: else if ( !n2 )
! 445: COPY(n1,*nr);
! 446: else {
! 447: if ( PL(n1) > PL(n2) ) {
! 448: d1 = PL(n1); d2 = PL(n2); m1 = BD(n1); m2 = BD(n2);
! 449: } else {
! 450: d1 = PL(n2); d2 = PL(n1); m1 = BD(n2); m2 = BD(n1);
! 451: }
! 452: *nr = r = NALLOC(d1 + 1); INITRC(r);
! 453: for ( i = 0, c = 0, mr = BD(r); i < d2; i++, m1++, m2++, mr++ ) {
! 454: tmp = *m1 + *m2;
! 455: if ( tmp < *m1 ) {
! 456: tmp += c;
! 457: c = 1;
! 458: } else {
! 459: tmp += c;
! 460: c = tmp < c ? 1 : 0;
! 461: }
! 462: *mr = tmp;
! 463: }
! 464: for ( ; (i < d1) && c ; i++, m1++, mr++ ) {
! 465: tmp = *m1 + c;
! 466: c = tmp < c ? 1 : 0;
! 467: *mr = tmp;
! 468: }
! 469: for ( ; i < d1; i++ )
! 470: *mr++ = *m1++;
! 471: *mr = c;
! 472: PL(r) = (c?d1+1:d1);
! 473: }
1.1 noro 474: }
475:
1.5 noro 476: int subn(N n1,N n2,N *nr)
1.1 noro 477: {
1.12 ! noro 478: N r;
! 479: unsigned int *m1,*m2,*mr,i,br;
! 480: L tmp;
! 481: int d1,d2,nz,sgn;
! 482:
! 483: if ( !n1 ) {
! 484: if ( n2 ) {
! 485: COPY(n2,*nr);
! 486: return -1;
! 487: } else {
! 488: *nr = 0;
! 489: return 0;
! 490: }
! 491: } else if ( !n2 ) {
! 492: COPY(n1,*nr);
! 493: return 1;
! 494: } else {
! 495: switch ( cmpn(n1,n2) ) {
! 496: case 1:
! 497: d1 = PL(n1); d2 = PL(n2); m1 = BD(n1); m2 = BD(n2);
! 498: sgn = 1; break;
! 499: case -1:
! 500: d1 = PL(n2); d2 = PL(n1); m1 = BD(n2); m2 = BD(n1);
! 501: sgn = -1; break;
! 502: case 0:
! 503: default:
! 504: *nr = 0; return ( 0 ); break;
! 505: }
! 506: *nr = r = NALLOC(d1); INITRC(r);
! 507: for ( i = 0, br = 0, nz = -1, mr = BD(r);
! 508: i < d2; i++ ) {
! 509: if ( (tmp = (L)*m1++ - (L)*m2++ - (L)br) && ( tmp > -LBASE ) )
! 510: nz = i;
! 511: if ( tmp < 0 ) {
! 512: br = 1; *mr++ = (unsigned int)(tmp + LBASE);
! 513: } else {
! 514: br = 0; *mr++ = (unsigned int)tmp;
! 515: }
! 516: }
! 517: for ( ; (i < d1) && br; i++ ) {
! 518: if ( (tmp = (L)*m1++ - (L)br) && ( tmp > -LBASE ) )
! 519: nz = i;
! 520: if ( tmp < 0 ) {
! 521: br = 1; *mr++ = (unsigned int)(tmp + LBASE);
! 522: } else {
! 523: br = 0; *mr++ = (unsigned int)tmp;
! 524: }
! 525: }
! 526: for ( ; i < d1; i++ )
! 527: if ( *mr++ = *m1++ )
! 528: nz = i;
! 529: PL(r) = nz + 1;
! 530: return sgn;
! 531: }
1.1 noro 532: }
533:
1.5 noro 534: void _addn(N n1,N n2,N nr)
1.1 noro 535: {
1.12 ! noro 536: unsigned int *m1,*m2,*mr,i,c;
! 537: int d1,d2;
! 538: unsigned int tmp;
! 539:
! 540: if ( !n1 || !PL(n1) )
! 541: dupn(n2,nr);
! 542: else if ( !n2 || !PL(n2) )
! 543: dupn(n1,nr);
! 544: else {
! 545: if ( PL(n1) > PL(n2) ) {
! 546: d1 = PL(n1); d2 = PL(n2); m1 = BD(n1); m2 = BD(n2);
! 547: } else {
! 548: d1 = PL(n2); d2 = PL(n1); m1 = BD(n2); m2 = BD(n1);
! 549: }
! 550: for ( i = 0, c = 0, mr = BD(nr); i < d2; i++, m1++, m2++, mr++ ) {
! 551: tmp = *m1 + *m2;
! 552: if ( tmp < *m1 ) {
! 553: tmp += c;
! 554: c = 1;
! 555: } else {
! 556: tmp += c;
! 557: c = tmp < c ? 1 : 0;
! 558: }
! 559: *mr = tmp;
! 560: }
! 561: for ( ; (i < d1) && c ; i++, m1++, mr++ ) {
! 562: tmp = *m1 + c;
! 563: c = tmp < c ? 1 : 0;
! 564: *mr = tmp;
! 565: }
! 566: for ( ; i < d1; i++ )
! 567: *mr++ = *m1++;
! 568: *mr = c;
! 569: PL(nr) = (c?d1+1:d1);
! 570: }
1.1 noro 571: }
572:
1.5 noro 573: int _subn(N n1,N n2,N nr)
1.1 noro 574: {
1.12 ! noro 575: N r;
! 576: unsigned int *m1,*m2,*mr,i,br;
! 577: L tmp;
! 578: int d1,d2,nz,sgn;
! 579:
! 580: if ( !n1 || !PL(n1) ) {
! 581: if ( n2 && PL(n2) ) {
! 582: dupn(n2,nr);
! 583: return -1;
! 584: } else {
! 585: PL(nr) = 0;
! 586: return 0;
! 587: }
! 588: } else if ( !n2 || !PL(n2) ) {
! 589: dupn(n1,nr);
! 590: return 1;
! 591: } else {
! 592: switch ( cmpn(n1,n2) ) {
! 593: case 1:
! 594: d1 = PL(n1); d2 = PL(n2); m1 = BD(n1); m2 = BD(n2);
! 595: sgn = 1; break;
! 596: case -1:
! 597: d1 = PL(n2); d2 = PL(n1); m1 = BD(n2); m2 = BD(n1);
! 598: sgn = -1; break;
! 599: case 0:
! 600: default:
! 601: PL(nr) = 0; return ( 0 ); break;
! 602: }
! 603: for ( i = 0, br = 0, nz = -1, mr = BD(nr);
! 604: i < d2; i++ ) {
! 605: if ( (tmp = (L)*m1++ - (L)*m2++ - (L)br) && ( tmp > -LBASE ) )
! 606: nz = i;
! 607: if ( tmp < 0 ) {
! 608: br = 1; *mr++ = (unsigned int)(tmp + LBASE);
! 609: } else {
! 610: br = 0; *mr++ = (unsigned int)tmp;
! 611: }
! 612: }
! 613: for ( ; (i < d1) && br; i++ ) {
! 614: if ( (tmp = (L)*m1++ - (L)br) && ( tmp > -LBASE ) )
! 615: nz = i;
! 616: if ( tmp < 0 ) {
! 617: br = 1; *mr++ = (unsigned int)(tmp + LBASE);
! 618: } else {
! 619: br = 0; *mr++ = (unsigned int)tmp;
! 620: }
! 621: }
! 622: for ( ; i < d1; i++ )
! 623: if ( *mr++ = *m1++ )
! 624: nz = i;
! 625: PL(nr) = nz + 1;
! 626: return sgn;
! 627: }
1.1 noro 628: }
629: #endif
630:
631: /* a2 += a1; n2 >= n1 */
632:
1.5 noro 633: void addarray_to(unsigned int *a1,int n1,unsigned int *a2,int n2)
1.1 noro 634: {
1.12 ! noro 635: int i;
! 636: unsigned int c,tmp;
1.1 noro 637:
1.12 ! noro 638: for ( i = 0, c = 0; i < n2; i++, a1++, a2++ ) {
! 639: tmp = *a1 + *a2;
! 640: if ( tmp < *a1 ) {
! 641: tmp += c;
! 642: c = 1;
! 643: } else {
! 644: tmp += c;
! 645: c = tmp < c ? 1 : 0;
! 646: }
! 647: *a2 = tmp;
! 648: }
! 649: for ( ; (i < n2) && c ; i++, a2++ ) {
! 650: tmp = *a2 + c;
! 651: c = tmp < c ? 1 : 0;
! 652: *a2 = tmp;
! 653: }
! 654: if ( i == n2 && c )
! 655: *a2 = c;
1.1 noro 656: }
657:
1.5 noro 658: void pwrn(N n,int e,N *nr)
1.1 noro 659: {
1.12 ! noro 660: N nw,nw1;
1.1 noro 661:
1.12 ! noro 662: if ( e == 1 ) {
! 663: COPY(n,*nr);
! 664: return;
! 665: }
! 666: pwrn(n,e / 2,&nw);
! 667: if ( e % 2 == 0 )
! 668: kmuln(nw,nw,nr);
! 669: else {
! 670: kmuln(nw,nw,&nw1); kmuln(nw1,n,nr); FREEN(nw1);
! 671: }
! 672: FREEN(nw);
1.1 noro 673: }
674:
1.4 murao 675:
676:
1.1 noro 677: extern int igcd_algorithm;
678:
1.4 murao 679: void gcdEuclidn(), gcdn_HMEXT();
1.7 noro 680:
681: void lcmn(N n1,N n2,N *nr)
682: {
1.12 ! noro 683: N g,t;
1.7 noro 684:
1.12 ! noro 685: gcdn(n1,n2,&g);
! 686: divsn(n1,g,&t);
! 687: muln(t,n2,nr);
1.7 noro 688: }
1.1 noro 689:
1.5 noro 690: void gcdn(N n1,N n2,N *nr)
1.1 noro 691: {
1.12 ! noro 692: if ( !igcd_algorithm )
! 693: gcdEuclidn(n1,n2,nr);
! 694: else {
! 695: gcdn_HMEXT(n1,n2,nr);
! 696: }
1.1 noro 697: }
698:
1.4 murao 699: #include "Ngcd.c"
700:
1.5 noro 701: void gcdEuclidn(N n1,N n2,N *nr)
1.1 noro 702: {
1.12 ! noro 703: N m1,m2,q,r;
! 704: unsigned int i1,i2,ir;
1.1 noro 705:
1.12 ! noro 706: if ( !n1 )
! 707: COPY(n2,*nr);
! 708: else if ( !n2 )
! 709: COPY(n1,*nr);
! 710: else {
! 711: if ( PL(n1) > PL(n2) ) {
! 712: COPY(n1,m1); COPY(n2,m2);
! 713: } else {
! 714: COPY(n1,m2); COPY(n2,m1);
! 715: }
! 716: while ( PL(m1) > 1 ) {
! 717: divn(m1,m2,&q,&r); FREEN(m1); FREEN(q);
! 718: if ( !r ) {
! 719: *nr = m2;
! 720: return;
! 721: } else {
! 722: m1 = m2; m2 = r;
! 723: }
! 724: }
! 725: for ( i1 = BD(m1)[0], i2 = BD(m2)[0]; ir = i1 % i2; i2 = ir )
! 726: i1 = i2;
! 727: if ( i2 == 1 )
! 728: COPY(ONEN,*nr);
! 729: else {
! 730: *nr = r = NALLOC(1); INITRC(r); PL(r) = 1; BD(r)[0] = i2;
! 731: }
! 732: }
1.1 noro 733: }
734:
1.5 noro 735: int cmpn(N n1,N n2)
1.1 noro 736: {
1.12 ! noro 737: int i;
! 738: unsigned int *m1,*m2;
1.1 noro 739:
1.12 ! noro 740: if ( !n1 )
! 741: if ( !n2 )
! 742: return 0;
! 743: else
! 744: return -1;
! 745: else if ( !n2 )
! 746: return 1;
! 747: else if ( PL(n1) > PL(n2) )
! 748: return 1;
! 749: else if ( PL(n1) < PL(n2) )
! 750: return -1;
! 751: else {
! 752: for ( i = PL(n1)-1, m1 = BD(n1)+i, m2 = BD(n2)+i;
! 753: i >= 0; i--, m1--, m2-- )
! 754: if ( *m1 > *m2 )
! 755: return 1;
! 756: else if ( *m1 < *m2 )
! 757: return -1;
! 758: return 0;
! 759: }
1.1 noro 760: }
761:
1.5 noro 762: void bshiftn(N n,int b,N *r)
1.1 noro 763: {
1.12 ! noro 764: int w,l,nl,i,j;
! 765: N z;
! 766: unsigned int msw;
! 767: unsigned int *p,*pz;
! 768:
! 769: if ( b == 0 ) {
! 770: COPY(n,*r); return;
! 771: }
! 772: if ( b > 0 ) { /* >> */
! 773: w = b / BSH; l = PL(n)-w;
! 774: if ( l <= 0 ) {
! 775: *r = 0; return;
! 776: }
! 777: b %= BSH; p = BD(n)+w;
! 778: if ( !b ) {
! 779: *r = z = NALLOC(l); INITRC(z); PL(z) = l;
! 780: bcopy(p,BD(z),l*sizeof(unsigned int));
! 781: return;
! 782: }
! 783: msw = p[l-1];
! 784: for ( i = BSH-1; !(msw&(((unsigned int)1)<<i)); i-- ); i++;
! 785: if ( b >= i ) {
! 786: l--;
! 787: if ( !l ) {
! 788: *r = 0; return;
! 789: }
! 790: *r = z = NALLOC(l); INITRC(z); PL(z) = l; pz = BD(z);
! 791: for ( j = 0; j < l; j++, p++ )
! 792: *pz++ = (*(p+1)<<(BSH-b))|(*p>>b);
! 793: } else {
! 794: *r = z = NALLOC(l); INITRC(z); PL(z) = l; pz = BD(z);
! 795: for ( j = 1; j < l; j++, p++ )
! 796: *pz++ = (*(p+1)<<(BSH-b))|(*p>>b);
! 797: *pz = *p>>b;
! 798: }
! 799: } else { /* << */
! 800: b = -b;
! 801: w = b / BSH; b %= BSH; l = PL(n); p = BD(n);
! 802: if ( !b ) {
! 803: nl = l+w; *r = z = NALLOC(nl); INITRC(z); PL(z) = nl;
! 804: bzero((char *)BD(z),w*sizeof(unsigned int));
! 805: bcopy(p,BD(z)+w,l*sizeof(unsigned int));
! 806: return;
! 807: }
! 808: msw = p[l-1];
! 809: for ( i = BSH-1; !(msw&(((unsigned int)1)<<i)); i-- ); i++;
! 810: if ( b + i > BSH ) {
! 811: nl = l+w+1;
! 812: *r = z = NALLOC(nl); INITRC(z); PL(z) = nl; pz = BD(z)+w;
! 813: bzero((char *)BD(z),w*sizeof(unsigned int));
! 814: *pz++ = *p++<<b;
! 815: for ( j = 1; j < l; j++, p++ )
! 816: *pz++ = (*p<<b)|(*(p-1)>>(BSH-b));
! 817: *pz = *(p-1)>>(BSH-b);
! 818: } else {
! 819: nl = l+w;
! 820: *r = z = NALLOC(nl); INITRC(z); PL(z) = nl; pz = BD(z)+w;
! 821: bzero((char *)BD(z),w*sizeof(unsigned int));
! 822: *pz++ = *p++<<b;
! 823: for ( j = 1; j < l; j++, p++ )
! 824: *pz++ = (*p<<b)|(*(p-1)>>(BSH-b));
! 825: }
! 826: }
1.1 noro 827: }
828:
829: #if 0
1.5 noro 830: void _bshiftn(N n,int b,N z)
1.1 noro 831: {
1.12 ! noro 832: int w,l,nl,i,j;
! 833: unsigned int msw;
! 834: unsigned int *p,*pz;
! 835:
! 836: if ( b == 0 ) {
! 837: copyn(n,PL(n),BD(z)); PL(z) = PL(n); return;
! 838: }
! 839: if ( b > 0 ) { /* >> */
! 840: w = b / BSH; l = PL(n)-w;
! 841: if ( l <= 0 ) {
! 842: PL(z) = 0; return;
! 843: }
! 844: b %= BSH; p = BD(n)+w;
! 845: if ( !b ) {
! 846: PL(z) = l;
! 847: bcopy(p,BD(z),l*sizeof(unsigned int));
! 848: return;
! 849: }
! 850: msw = p[l-1];
! 851: for ( i = BSH-1; !(msw&(((unsigned int)1)<<i)); i-- ); i++;
! 852: if ( b >= i ) {
! 853: l--;
! 854: if ( !l ) {
! 855: PL(z) = 0; return;
! 856: }
! 857: PL(z) = l; pz = BD(z);
! 858: for ( j = 0; j < l; j++, p++ )
! 859: *pz++ = (*(p+1)<<(BSH-b))|(*p>>b);
! 860: } else {
! 861: PL(z) = l; pz = BD(z);
! 862: for ( j = 1; j < l; j++, p++ )
! 863: *pz++ = (*(p+1)<<(BSH-b))|(*p>>b);
! 864: *pz = *p>>b;
! 865: }
! 866: } else { /* << */
! 867: b = -b;
! 868: w = b / BSH; b %= BSH; l = PL(n); p = BD(n);
! 869: if ( !b ) {
! 870: nl = l+w; PL(z) = nl;
! 871: bzero((char *)BD(z),w*sizeof(unsigned int));
! 872: bcopy(p,BD(z)+w,l*sizeof(unsigned int));
! 873: return;
! 874: }
! 875: msw = p[l-1];
! 876: for ( i = BSH-1; !(msw&(((unsigned int)1)<<i)); i-- ); i++;
! 877: if ( b + i > BSH ) {
! 878: nl = l+w+1;
! 879: PL(z) = nl; pz = BD(z)+w;
! 880: bzero((char *)BD(z),w*sizeof(unsigned int));
! 881: *pz++ = *p++<<b;
! 882: for ( j = 1; j < l; j++, p++ )
! 883: *pz++ = (*p<<b)|(*(p-1)>>(BSH-b));
! 884: *pz = *(p-1)>>(BSH-b);
! 885: } else {
! 886: nl = l+w;
! 887: PL(z) = nl; pz = BD(z)+w;
! 888: bzero((char *)BD(z),w*sizeof(unsigned int));
! 889: *pz++ = *p++<<b;
! 890: for ( j = 1; j < l; j++, p++ )
! 891: *pz++ = (*p<<b)|(*(p-1)>>(BSH-b));
! 892: }
! 893: }
1.1 noro 894: }
895: #endif
896:
1.5 noro 897: void shiftn(N n,int w,N *r)
1.1 noro 898: {
1.12 ! noro 899: int l,nl;
! 900: N z;
1.1 noro 901:
1.12 ! noro 902: if ( w == 0 )
! 903: COPY(n,*r);
! 904: else if ( w > 0 ) { /* >> */
! 905: l = PL(n)-w;
! 906: if ( l <= 0 )
! 907: *r = 0;
! 908: else {
! 909: *r = z = NALLOC(l); INITRC(z); PL(z) = l;
! 910: bcopy(BD(n)+w,BD(z),l*sizeof(unsigned int));
! 911: }
! 912: } else { /* << */
! 913: w = -w;
! 914: l = PL(n); nl = l+w;
! 915: *r = z = NALLOC(nl); INITRC(z); PL(z) = nl;
! 916: bzero((char *)BD(z),w*sizeof(unsigned int));
! 917: bcopy(BD(n),BD(z)+w,l*sizeof(unsigned int));
! 918: }
1.1 noro 919: }
920:
1.5 noro 921: void randomn(int bits,N *r)
1.1 noro 922: {
1.12 ! noro 923: int l,i;
! 924: unsigned int *tb;
! 925: N t;
! 926:
! 927: l = (bits+31)>>5; /* word length */
! 928: *r = t = NALLOC(l);
! 929: tb = BD(t);
! 930: for ( i = 0; i < l; i++ )
! 931: tb[i] = mt_genrand();
! 932: if ( bits&31 )
! 933: tb[l-1] &= (1<<(bits&31))-1;
! 934: for ( i = l-1; i >= 0 && !tb[i]; i-- );
! 935: if ( i < 0 )
! 936: *r = 0;
! 937: else
! 938: PL(t) = i+1;
1.1 noro 939: }
940:
1.5 noro 941: void freen(N n)
1.1 noro 942: {
1.12 ! noro 943: if ( n && (n != ONEN) )
! 944: free(n);
1.1 noro 945: }
946:
1.6 noro 947: /* accepts Z */
1.5 noro 948: int n_bits(N n)
1.1 noro 949: {
1.12 ! noro 950: unsigned int i,t;
! 951: int l;
1.1 noro 952:
1.12 ! noro 953: if ( !n )
! 954: return 0;
! 955: l = PL(n);
! 956: if ( l < 0 ) l = -l;
! 957: t = BD(n)[l-1];
! 958: for ( i = 0; t; t>>=1, i++);
! 959: return i + (l-1)*BSH;
1.1 noro 960: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>