Annotation of OpenXM_contrib/gmp/tests/devel/tst-addsub.c, Revision 1.1.1.1
1.1 ohara 1: /* Copyright 1996, 2001 Free Software Foundation, Inc.
2:
3: This file is part of the GNU MP Library.
4:
5: The GNU MP Library is free software; you can redistribute it and/or modify
6: it under the terms of the GNU Lesser General Public License as published by
7: the Free Software Foundation; either version 2.1 of the License, or (at your
8: option) any later version.
9:
10: The GNU MP Library is distributed in the hope that it will be useful, but
11: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13: License for more details.
14:
15: You should have received a copy of the GNU Lesser General Public License
16: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
17: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18: MA 02111-1307, USA.
19: */
20:
21: #include <stdio.h>
22: #include <stdlib.h>
23: #include "gmp.h"
24: #include "gmp-impl.h"
25:
26: #define ADD 1
27: #define SUB 2
28:
29: #ifndef METHOD
30: #define METHOD ADD
31: #endif
32:
33: #if METHOD == ADD
34: #define REFCALL refmpn_add_n
35: #define TESTCALL mpn_add_n
36: #endif
37:
38: #if METHOD == SUB
39: #define REFCALL refmpn_sub_n
40: #define TESTCALL mpn_sub_n
41: #endif
42:
43: mp_limb_t refmpn_add_n ();
44: mp_limb_t refmpn_sub_n ();
45:
46: #define SIZE 100
47:
48: main (argc, argv)
49: int argc;
50: char **argv;
51: {
52: mp_size_t alloc_size, max_size, size, i, cumul_size;
53: mp_ptr s1, s2, dx, dy;
54: int s1_align, s2_align, d_align;
55: long pass, n_passes;
56: mp_limb_t cx, cy;
57:
58: max_size = SIZE;
59: n_passes = 1000000;
60:
61: argc--; argv++;
62: if (argc)
63: {
64: max_size = atol (*argv);
65: argc--; argv++;
66: }
67:
68: alloc_size = max_size + 32;
69: s1 = malloc (alloc_size * BYTES_PER_MP_LIMB);
70: s2 = malloc (alloc_size * BYTES_PER_MP_LIMB);
71: dx = malloc (alloc_size * BYTES_PER_MP_LIMB);
72: dy = malloc (alloc_size * BYTES_PER_MP_LIMB);
73:
74: cumul_size = 0;
75: for (pass = 0; pass < n_passes; pass++)
76: {
77: cumul_size += size;
78: if (cumul_size >= 1000000)
79: {
80: cumul_size -= 1000000;
81: printf ("%d ", pass); fflush (stdout);
82: }
83: s1_align = random () % 32;
84: s2_align = random () % 32;
85: d_align = random () % 32;
86:
87: size = random () % max_size + 1;
88:
89: mpn_random2 (s1 + s1_align, size);
90: mpn_random2 (s2 + s2_align, size);
91:
92: for (i = 0; i < alloc_size; i++)
93: dx[i] = dy[i] = i + 0x9876500;
94:
95: cx = TESTCALL (dx + d_align, s1 + s1_align, s2 + s2_align, size);
96: cy = REFCALL (dy + d_align, s1 + s1_align, s2 + s2_align, size);
97:
98: if (cx != cy || mpn_cmp (dx, dy, alloc_size) != 0)
99: abort ();
100: }
101:
102: printf ("%d passes OK\n", n_passes);
103: exit (0);
104: }
105:
106: mp_limb_t
107: #if __STDC__
108: refmpn_add_n (mp_ptr res_ptr,
109: mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
110: #else
111: refmpn_add_n (res_ptr, s1_ptr, s2_ptr, size)
112: register mp_ptr res_ptr;
113: register mp_srcptr s1_ptr;
114: register mp_srcptr s2_ptr;
115: mp_size_t size;
116: #endif
117: {
118: register mp_limb_t x, y, cy;
119: register mp_size_t j;
120:
121: /* The loop counter and index J goes from -SIZE to -1. This way
122: the loop becomes faster. */
123: j = -size;
124:
125: /* Offset the base pointers to compensate for the negative indices. */
126: s1_ptr -= j;
127: s2_ptr -= j;
128: res_ptr -= j;
129:
130: cy = 0;
131: do
132: {
133: y = s2_ptr[j];
134: x = s1_ptr[j];
135: y += cy; /* add previous carry to one addend */
136: cy = (y < cy); /* get out carry from that addition */
137: y = x + y; /* add other addend */
138: cy = (y < x) + cy; /* get out carry from that add, combine */
139: res_ptr[j] = y;
140: }
141: while (++j != 0);
142:
143: return cy;
144: }
145:
146: mp_limb_t
147: #if __STDC__
148: refmpn_sub_n (mp_ptr res_ptr,
149: mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
150: #else
151: refmpn_sub_n (res_ptr, s1_ptr, s2_ptr, size)
152: register mp_ptr res_ptr;
153: register mp_srcptr s1_ptr;
154: register mp_srcptr s2_ptr;
155: mp_size_t size;
156: #endif
157: {
158: register mp_limb_t x, y, cy;
159: register mp_size_t j;
160:
161: /* The loop counter and index J goes from -SIZE to -1. This way
162: the loop becomes faster. */
163: j = -size;
164:
165: /* Offset the base pointers to compensate for the negative indices. */
166: s1_ptr -= j;
167: s2_ptr -= j;
168: res_ptr -= j;
169:
170: cy = 0;
171: do
172: {
173: y = s2_ptr[j];
174: x = s1_ptr[j];
175: y += cy; /* add previous carry to subtrahend */
176: cy = (y < cy); /* get out carry from that addition */
177: y = x - y; /* main subtract */
178: cy = (y > x) + cy; /* get out carry from the subtract, combine */
179: res_ptr[j] = y;
180: }
181: while (++j != 0);
182:
183: return cy;
184: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>