File: common\biginit.c
1 /* biginit.c - C routines for bignumbers */
2
3 /*
4 Note: This is NOT the biginit.c file that come the standard BigNum library,
5 but is a customized version specific to Fractint. The biggest difference
6 is in the allocations of memory for the big numbers.
7 */
8
9 #include <string.h>
10 #include <malloc.h>
11 /* see Fractint.c for a description of the "include" hierarchy */
12 #include "port.h"
13 #include "prototyp.h"
14 #include "fractype.h"
15
16 /* appears to me that avoiding the start of extraseg is unnecessary. If
17 correct, later we can eliminate ENDVID here. */
18 #ifdef ENDVID
19 #undef ENDVID
20 #endif
21 #define ENDVID 0
22
23 /* globals */
24 #ifdef BIG_BASED
25 _segment bignum_seg;
26 #endif
27 int bnstep, bnlength, intlength, rlength, padding, shiftfactor, decimals;
28 int bflength, rbflength, bfdecimals;
29
30 /* used internally by bignum.c routines */
31 static bn_t bnroot=BIG_NULL;
32 static bn_t stack_ptr; /* memory allocator base after global variables */
33 bn_t bntmp1, bntmp2, bntmp3, bntmp4, bntmp5, bntmp6; /* rlength */
34 bn_t bntmpcpy1, bntmpcpy2; /* bnlength */
35
36 /* used by other routines */
37 bn_t bnxmin, bnxmax, bnymin, bnymax, bnx3rd, bny3rd; /* bnlength */
38 bn_t bnxdel, bnydel, bnxdel2, bnydel2, bnclosenuff; /* bnlength */
39 bn_t bntmpsqrx, bntmpsqry, bntmp; /* rlength */
40 _BNCMPLX bnold, /* bnnew, */ bnparm, bnsaved; /* bnlength */
41 _BNCMPLX bnnew; /* rlength */
42 bn_t bn_pi; /* TAKES NO SPACE */
43
44 bf_t bftmp1, bftmp2, bftmp3, bftmp4, bftmp5, bftmp6; /* rbflength+2 */
45 bf_t bftmpcpy1, bftmpcpy2; /* rbflength+2 */
46 bf_t bfxdel, bfydel, bfxdel2, bfydel2, bfclosenuff; /* rbflength+2 */
47 bf_t bftmpsqrx, bftmpsqry; /* rbflength+2 */
48 _BFCMPLX /* bfold, bfnew, */ bfparm, bfsaved; /* bflength+2 */
49 _BFCMPLX bfold, bfnew; /* rbflength+2 */
50 bf_t bf_pi; /* TAKES NO SPACE */
51 bf_t big_pi; /* bflength+2 */
52
53 /* for testing only */
54
55 /* used by other routines */
56 bf_t bfxmin, bfxmax, bfymin, bfymax, bfx3rd, bfy3rd; /* bflength+2 */
57 bf_t bfsxmin, bfsxmax, bfsymin, bfsymax, bfsx3rd, bfsy3rd;/* bflength+2 */
58 bf_t bfparms[10]; /* (bflength+2)*10 */
59 bf_t bftmp;
60
61 bf_t bf10tmp; /* dec+4 */
62
63 #define LOG10_256 2.4082399653118
64 #define LOG_256 5.5451774444795
65
66 static int save_bf_vars(void);
67 static int restore_bf_vars(void);
68
69 /*********************************************************************/
70 /* given bnlength, calc_lengths will calculate all the other lengths */
71 void calc_lengths(void)
72 {
73 #if 0
82 #else
83 bnstep = 4; /* use 4 in all cases */
84 #endif
85
86 if (bnlength % bnstep != 0)
87 bnlength = (bnlength / bnstep + 1) * bnstep;
88 if (bnlength == bnstep)
89 padding = bnlength;
90 else
91 padding = 2*bnstep;
92 rlength = bnlength + padding;
93
94 /* This shiftfactor assumes non-full multiplications will be performed.*/
95 /* Change to bnlength-intlength for full multiplications. */
96 shiftfactor = padding - intlength;
97
98 bflength = bnlength+bnstep; /* one extra step for added precision */
99 rbflength = bflength + padding;
100 bfdecimals = (int)((bflength-2)*LOG10_256);
101 }
102
103 /************************************************************************/
104 /* intended only to be called from init_bf_dec() or init_bf_length(). */
105 /* initialize bignumber global variables */
106
107 long maxptr = 0;
108 long startstack = 0;
109 long maxstack = 0;
110 int bf_save_len = 0;
111
112 /* ??? for some strange reason, msc 7.0 hangs here without this pragma. ??? */
113 #ifndef XFRACT
114 #pragma optimize( "", off )
115 #endif
116 static void init_bf_2(void)
117 {
118 int i;
119 long ptr;
120 save_bf_vars(); /* copy corners values for conversion */
121
122 calc_lengths();
123
124 /* allocate all the memory at once within the same segment (DOS) */
125 #if defined(BIG_FAR) || defined(BIG_ANSI_C)
127 #else /* BASED or NEAR */
128 bnroot = (bf_t)ENDVID; /* ENDVID is to avoid videotable */
129 #endif
130 #ifdef BIG_BASED
131 bignum_seg = (_segment)extraseg;
132 #endif
133 /* at present time one call would suffice, but this logic allows
134 multiple kinds of alternate math eg long double */
135 if((i = find_alternate_math(fractype, BIGNUM)) > -1)
136 bf_math = alternatemath[i].math;
137 else if((i = find_alternate_math(fractype, BIGFLT)) > -1)
138 bf_math = alternatemath[i].math;
139 else
140 bf_math = 1; /* maybe called from cmdfiles.c and fractype not set */
141
142 floatflag=1;
143
144 /* Now split up the memory among the pointers */
145 /* internal pointers */
146 ptr = 0;
147 bntmp1 = bnroot+ptr; ptr += rlength;
148 bntmp2 = bnroot+ptr; ptr += rlength;
149 bntmp3 = bnroot+ptr; ptr += rlength;
150 bntmp4 = bnroot+ptr; ptr += rlength;
151 bntmp5 = bnroot+ptr; ptr += rlength;
152 bntmp6 = bnroot+ptr; ptr += rlength;
153
154 bftmp1 = bnroot+ptr; ptr += rbflength+2;
155 bftmp2 = bnroot+ptr; ptr += rbflength+2;
156 bftmp3 = bnroot+ptr; ptr += rbflength+2;
157 bftmp4 = bnroot+ptr; ptr += rbflength+2;
158 bftmp5 = bnroot+ptr; ptr += rbflength+2;
159 bftmp6 = bnroot+ptr; ptr += rbflength+2;
160
161 bftmpcpy1 = bnroot+ptr; ptr += (rbflength+2)*2;
162 bftmpcpy2 = bnroot+ptr; ptr += (rbflength+2)*2;
163
164 bntmpcpy1 = bnroot+ptr; ptr += (rlength*2);
165 bntmpcpy2 = bnroot+ptr; ptr += (rlength*2);
166
167 if (bf_math == BIGNUM)
168 {
169 bnxmin = bnroot+ptr; ptr += bnlength;
170 bnxmax = bnroot+ptr; ptr += bnlength;
171 bnymin = bnroot+ptr; ptr += bnlength;
172 bnymax = bnroot+ptr; ptr += bnlength;
173 bnx3rd = bnroot+ptr; ptr += bnlength;
174 bny3rd = bnroot+ptr; ptr += bnlength;
175 bnxdel = bnroot+ptr; ptr += bnlength;
176 bnydel = bnroot+ptr; ptr += bnlength;
177 bnxdel2 = bnroot+ptr; ptr += bnlength;
178 bnydel2 = bnroot+ptr; ptr += bnlength;
179 bnold.x = bnroot+ptr; ptr += rlength;
180 bnold.y = bnroot+ptr; ptr += rlength;
181 bnnew.x = bnroot+ptr; ptr += rlength;
182 bnnew.y = bnroot+ptr; ptr += rlength;
183 bnsaved.x = bnroot+ptr; ptr += bnlength;
184 bnsaved.y = bnroot+ptr; ptr += bnlength;
185 bnclosenuff= bnroot+ptr; ptr += bnlength;
186 bnparm.x = bnroot+ptr; ptr += bnlength;
187 bnparm.y = bnroot+ptr; ptr += bnlength;
188 bntmpsqrx = bnroot+ptr; ptr += rlength;
189 bntmpsqry = bnroot+ptr; ptr += rlength;
190 bntmp = bnroot+ptr; ptr += rlength;
191 }
192 if (bf_math == BIGFLT)
193 {
194 bfxdel = bnroot+ptr; ptr += bflength+2;
195 bfydel = bnroot+ptr; ptr += bflength+2;
196 bfxdel2 = bnroot+ptr; ptr += bflength+2;
197 bfydel2 = bnroot+ptr; ptr += bflength+2;
198 bfold.x = bnroot+ptr; ptr += rbflength+2;
199 bfold.y = bnroot+ptr; ptr += rbflength+2;
200 bfnew.x = bnroot+ptr; ptr += rbflength+2;
201 bfnew.y = bnroot+ptr; ptr += rbflength+2;
202 bfsaved.x = bnroot+ptr; ptr += bflength+2;
203 bfsaved.y = bnroot+ptr; ptr += bflength+2;
204 bfclosenuff= bnroot+ptr; ptr += bflength+2;
205 bfparm.x = bnroot+ptr; ptr += bflength+2;
206 bfparm.y = bnroot+ptr; ptr += bflength+2;
207 bftmpsqrx = bnroot+ptr; ptr += rbflength+2;
208 bftmpsqry = bnroot+ptr; ptr += rbflength+2;
209 big_pi = bnroot+ptr; ptr += bflength+2;
210 bftmp = bnroot+ptr; ptr += rbflength+2;
211 }
212 bf10tmp = bnroot+ptr; ptr += bfdecimals+4;
213
214 /* ptr needs to be 16-bit aligned on some systems */
215 ptr = (ptr+1)&~1;
216
217 stack_ptr = bnroot + ptr;
218 startstack = ptr;
219
220 /* max stack offset from bnroot */
221 maxstack = (long)0x10000l-(bflength+2)*22-ENDVID;
222
223 /* sanity check */
224 /* leave room for NUMVARS variables allocated from stack */
225 /* also leave room for the safe area at top of segment */
226 if(ptr + NUMVARS*(bflength+2) > maxstack)
227 {
228 char msg[80];
229 char nmsg[80];
230 static FCODE fmsg[] = {"Requested precision of %d too high, aborting"};
231 far_strcpy(nmsg,fmsg);
232 sprintf(msg,nmsg,decimals);
233 stopmsg(0,msg);
234 goodbye();
235 }
236
237 /* room for 6 corners + 6 save corners + 10 params at top of extraseg */
238 /* this area is safe - use for variables that are used outside fractal*/
239 /* generation - e.g. zoom box variables */
240 ptr = maxstack;
241 bfxmin = bnroot+ptr; ptr += bflength+2;
242 bfxmax = bnroot+ptr; ptr += bflength+2;
243 bfymin = bnroot+ptr; ptr += bflength+2;
244 bfymax = bnroot+ptr; ptr += bflength+2;
245 bfx3rd = bnroot+ptr; ptr += bflength+2;
246 bfy3rd = bnroot+ptr; ptr += bflength+2;
247 for(i=0;i<10;i++)
248 {
249 bfparms[i] = bnroot+ptr; ptr += bflength+2;
250 }
251 bfsxmin = bnroot+ptr; ptr += bflength+2;
252 bfsxmax = bnroot+ptr; ptr += bflength+2;
253 bfsymin = bnroot+ptr; ptr += bflength+2;
254 bfsymax = bnroot+ptr; ptr += bflength+2;
255 bfsx3rd = bnroot+ptr; ptr += bflength+2;
256 bfsy3rd = bnroot+ptr; ptr += bflength+2;
257 /* end safe vars */
258
259 /* good citizens initialize variables */
260 if(bf_save_len) /* leave save area */
261 far_memset(bnroot+(bf_save_len+2)*22,0,(unsigned)(startstack-(bf_save_len+2)*22));
262 else /* first time through - nothing saved */
263 {
264 /* high variables */
265 far_memset(bnroot+maxstack,0,(bflength+2)*22);
266 /* low variables */
267 far_memset(bnroot,0,(unsigned)startstack);
268 }
269
270 restore_bf_vars();
271
272 /* Initialize the value of pi. Needed for trig functions. */
273 /* init_big_pi(); */
274 /* call to init_big_pi() has been moved to fractal setup routine */
275 /* so as to use only when necessary. */
276
277 }
278
279
280 /**********************************************************/
281 /* save current corners and parameters to start of bnroot */
282 /* to preserve values across calls to init_bf() */
283 static int save_bf_vars(void)
284 {
285 int ret;
286 unsigned int mem;
287 if(bnroot != BIG_NULL)
288 {
289 mem = (bflength+2)*22; /* 6 corners + 6 save corners + 10 params */
290 bf_save_len = bflength;
291 far_memcpy(bnroot,bfxmin,mem);
292 /* scrub old high area */
293 far_memset(bfxmin,0,mem);
294 ret = 0;
295 }
296 else
297 {
298 bf_save_len = 0;
299 ret = -1;
300 }
301 return(ret);
302 }
303
304 /************************************************************************/
305 /* copy current corners and parameters from save location */
306 static int restore_bf_vars(void)
307 {
308 bf_t ptr;
309 int i;
310 if(bf_save_len == 0)
311 return(-1);
312 ptr = bnroot;
313 convert_bf(bfxmin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
314 convert_bf(bfxmax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
315 convert_bf(bfymin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
316 convert_bf(bfymax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
317 convert_bf(bfx3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
318 convert_bf(bfy3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
319 for(i=0;i<10;i++)
320 {
321 convert_bf(bfparms[i],ptr,bflength,bf_save_len);
322 ptr += bf_save_len+2;
323 }
324 convert_bf(bfsxmin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
325 convert_bf(bfsxmax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
326 convert_bf(bfsymin,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
327 convert_bf(bfsymax,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
328 convert_bf(bfsx3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
329 convert_bf(bfsy3rd,ptr,bflength,bf_save_len); ptr += bf_save_len+2;
330
331 /* scrub save area */
332 far_memset(bnroot,0,(bf_save_len+2)*22);
333 return(0);
334 }
335
336 /*******************************************/
337 /* free corners and parameters save memory */
338 void free_bf_vars()
339 {
340 bf_save_len = bf_math = 0;
341 bnstep=bnlength=intlength=rlength=padding=shiftfactor=decimals=0;
342 bflength=rbflength=bfdecimals=0;
343 }
344
345 #ifndef XFRACT
346 #pragma optimize( "", on )
347 #endif
348
349 /************************************************************************/
350 /* Memory allocator routines start here. */
351 /************************************************************************/
352 /* Allocates a bn_t variable on stack */
353 bn_t alloc_stack(size_t size)
354 {
355 long stack_addr;
356 if(bf_math == 0)
357 {
358 static FCODE msg[] = {"alloc_stack called with bf_math==0"};
359 stopmsg(0,msg);
360 return(0);
361 }
362 stack_addr = (long)(stack_ptr-bnroot)+size; /* +ENDVID, part of bnroot */
363
364 if(stack_addr > maxstack)
365 {
366 static FCODE msg[] = {"Aborting, Out of Bignum Stack Space"};
367 stopmsg(0,msg);
368 goodbye();
369 }
370 /* keep track of max ptr */
371 if(stack_addr > maxptr)
372 maxptr = stack_addr;
373 stack_ptr += size; /* increment stack pointer */
374 return(stack_ptr - size);
375 }
376
377 /************************************************************************/
378 /* Returns stack pointer offset so it can be saved. */
379 int save_stack(void)
380 {
381 return(stack_ptr - bnroot);
382 }
383
384 /************************************************************************/
385 /* Restores stack pointer, effectively freeing local variables */
386 /* allocated since save_stack() */
387 void restore_stack(int old_offset)
388 {
389 stack_ptr = bnroot+old_offset;
390 }
391
392 /************************************************************************/
393 /* Memory allocator routines end here. */
394 /************************************************************************/
395
396 /************************************************************************/
397 /* initialize bignumber global variables */
398 /* dec = decimal places after decimal point */
399 /* intl = bytes for integer part (1, 2, or 4) */
400
401 void init_bf_dec(int dec)
402 {
403 if(bfdigits)
404 decimals=bfdigits; /* blindly force */
405 else
406 decimals = dec;
407 if(bailout > 10) /* arbitrary value */
408 /* using 2 doesn't gain much and requires another test */
409 intlength = 4;
410 else if (fractype == FPMANDELZPOWER || fractype == FPJULIAZPOWER)
411 intlength = 2;
412 /* the bailout tests need greater dynamic range */
413 else if(bailoutest == Real || bailoutest == Imag || bailoutest == And ||
414 bailoutest == Manr)
415 intlength = 2;
416 else
417 intlength = 1;
418 /* conservative estimate */
419 bnlength = intlength + (int)(decimals/LOG10_256) + 1; /* round up */
420 init_bf_2();
421 }
422
423 /************************************************************************/
424 /* initialize bignumber global variables */
425 /* bnl = bignumber length */
426 /* intl = bytes for integer part (1, 2, or 4) */
427 void init_bf_length(int bnl)
428 {
429 bnlength = bnl;
430
431 if(bailout > 10) /* arbitrary value */
432 /* using 2 doesn't gain much and requires another test */
433 intlength = 4;
434 else if (fractype == FPMANDELZPOWER || fractype == FPJULIAZPOWER)
435 intlength = 2;
436 /* the bailout tests need greater dynamic range */
437 else if(bailoutest == Real || bailoutest == Imag || bailoutest == And ||
438 bailoutest == Manr)
439 intlength = 2;
440 else
441 intlength = 1;
442 /* conservative estimate */
443 decimals = (int)((bnlength-intlength)*LOG10_256);
444 init_bf_2();
445 }
446
447
448 void init_big_pi(void)
449 {
450 /* What, don't you recognize the first 700 digits of pi, */
451 /* in base 256, in reverse order? */
452 int length, pi_offset;
453 static BFCODE pi_table[] = {
454 0x44, 0xD5, 0xDB, 0x69, 0x17, 0xDF, 0x2E, 0x56, 0x87, 0x1A,
455 0xA0, 0x8C, 0x6F, 0xCA, 0xBB, 0x57, 0x5C, 0x9E, 0x82, 0xDF,
456 0x00, 0x3E, 0x48, 0x7B, 0x31, 0x53, 0x60, 0x87, 0x23, 0xFD,
457 0xFA, 0xB5, 0x3D, 0x32, 0xAB, 0x52, 0x05, 0xAD, 0xC8, 0x1E,
458 0x50, 0x2F, 0x15, 0x6B, 0x61, 0xFD, 0xDF, 0x16, 0x75, 0x3C,
459 0xF8, 0x22, 0x32, 0xDB, 0xF8, 0xE9, 0xA5, 0x8E, 0xCC, 0xA3,
460 0x1F, 0xFB, 0xFE, 0x25, 0x9F, 0x67, 0x79, 0x72, 0x2C, 0x40,
461 0xC6, 0x00, 0xA1, 0xD6, 0x0A, 0x32, 0x60, 0x1A, 0xBD, 0xC0,
462 0x79, 0x55, 0xDB, 0xFB, 0xD3, 0xB9, 0x39, 0x5F, 0x0B, 0xD2,
463 0x0F, 0x74, 0xC8, 0x45, 0x57, 0xA8, 0xCB, 0xC0, 0xB3, 0x4B,
464 0x2E, 0x19, 0x07, 0x28, 0x0F, 0x66, 0xFD, 0x4A, 0x33, 0xDE,
465 0x04, 0xD0, 0xE3, 0xBE, 0x09, 0xBD, 0x5E, 0xAF, 0x44, 0x45,
466 0x81, 0xCC, 0x2C, 0x95, 0x30, 0x9B, 0x1F, 0x51, 0xFC, 0x6D,
467 0x6F, 0xEC, 0x52, 0x3B, 0xEB, 0xB2, 0x39, 0x13, 0xB5, 0x53,
468 0x6C, 0x3E, 0xAF, 0x6F, 0xFB, 0x68, 0x63, 0x24, 0x6A, 0x19,
469 0xC2, 0x9E, 0x5C, 0x5E, 0xC4, 0x60, 0x9F, 0x40, 0xB6, 0x4F,
470 0xA9, 0xC1, 0xBA, 0x06, 0xC0, 0x04, 0xBD, 0xE0, 0x6C, 0x97,
471 0x3B, 0x4C, 0x79, 0xB6, 0x1A, 0x50, 0xFE, 0xE3, 0xF7, 0xDE,
472 0xE8, 0xF6, 0xD8, 0x79, 0xD4, 0x25, 0x7B, 0x1B, 0x99, 0x80,
473 0xC9, 0x72, 0x53, 0x07, 0x9B, 0xC0, 0xF1, 0x49, 0xD3, 0xEA,
474 0x0F, 0xDB, 0x48, 0x12, 0x0A, 0xD0, 0x24, 0xD7, 0xD0, 0x37,
475 0x3D, 0x02, 0x9B, 0x42, 0x72, 0xDF, 0xFE, 0x1B, 0x06, 0x77,
476 0x3F, 0x36, 0x62, 0xAA, 0xD3, 0x4E, 0xA6, 0x6A, 0xC1, 0x56,
477 0x9F, 0x44, 0x1A, 0x40, 0x73, 0x20, 0xC1, 0x85, 0xD8, 0x75,
478 0x6F, 0xE0, 0xBE, 0x5E, 0x8B, 0x3B, 0xC3, 0xA5, 0x84, 0x7D,
479 0xB4, 0x9F, 0x6F, 0x45, 0x19, 0x86, 0xEE, 0x8C, 0x88, 0x0E,
480 0x43, 0x82, 0x3E, 0x59, 0xCA, 0x66, 0x76, 0x01, 0xAF, 0x39,
481 0x1D, 0x65, 0xF1, 0xA1, 0x98, 0x2A, 0xFB, 0x7E, 0x50, 0xF0,
482 0x3B, 0xBA, 0xE4, 0x3B, 0x7A, 0x13, 0x6C, 0x0B, 0xEF, 0x6E,
483 0xA3, 0x33, 0x51, 0xAB, 0x28, 0xA7, 0x0F, 0x96, 0x68, 0x2F,
484 0x54, 0xD8, 0xD2, 0xA0, 0x51, 0x6A, 0xF0, 0x88, 0xD3, 0xAB,
485 0x61, 0x9C, 0x0C, 0x67, 0x9A, 0x6C, 0xE9, 0xF6, 0x42, 0x68,
486 0xC6, 0x21, 0x5E, 0x9B, 0x1F, 0x9E, 0x4A, 0xF0, 0xC8, 0x69,
487 0x04, 0x20, 0x84, 0xA4, 0x82, 0x44, 0x0B, 0x2E, 0x39, 0x42,
488 0xF4, 0x83, 0xF3, 0x6F, 0x6D, 0x0F, 0xC5, 0xAC, 0x96, 0xD3,
489 0x81, 0x3E, 0x89, 0x23, 0x88, 0x1B, 0x65, 0xEB, 0x02, 0x23,
490 0x26, 0xDC, 0xB1, 0x75, 0x85, 0xE9, 0x5D, 0x5D, 0x84, 0xEF,
491 0x32, 0x80, 0xEC, 0x5D, 0x60, 0xAC, 0x7C, 0x48, 0x91, 0xA9,
492 0x21, 0xFB, 0xCC, 0x09, 0xD8, 0x61, 0x93, 0x21, 0x28, 0x66,
493 0x1B, 0xE8, 0xBF, 0xC4, 0xAF, 0xB9, 0x4B, 0x6B, 0x98, 0x48,
494 0x8F, 0x3B, 0x77, 0x86, 0x95, 0x28, 0x81, 0x53, 0x32, 0x7A,
495 0x5C, 0xCF, 0x24, 0x6C, 0x33, 0xBA, 0xD6, 0xAF, 0x1E, 0x93,
496 0x87, 0x9B, 0x16, 0x3E, 0x5C, 0xCE, 0xF6, 0x31, 0x18, 0x74,
497 0x5D, 0xC5, 0xA9, 0x2B, 0x2A, 0xBC, 0x6F, 0x63, 0x11, 0x14,
498 0xEE, 0xB3, 0x93, 0xE9, 0x72, 0x7C, 0xAF, 0x86, 0x54, 0xA1,
499 0xCE, 0xE8, 0x41, 0x11, 0x34, 0x5C, 0xCC, 0xB4, 0xB6, 0x10,
500 0xAB, 0x2A, 0x6A, 0x39, 0xCA, 0x55, 0x40, 0x14, 0xE8, 0x63,
501 0x62, 0x98, 0x48, 0x57, 0x94, 0xAB, 0x55, 0xAA, 0xF3, 0x25,
502 0x55, 0xE6, 0x60, 0x5C, 0x60, 0x55, 0xDA, 0x2F, 0xAF, 0x78,
503 0x27, 0x4B, 0x31, 0xBD, 0xC1, 0x77, 0x15, 0xD7, 0x3E, 0x8A,
504 0x1E, 0xB0, 0x8B, 0x0E, 0x9E, 0x6C, 0x0E, 0x18, 0x3A, 0x60,
505 0xB0, 0xDC, 0x79, 0x8E, 0xEF, 0x38, 0xDB, 0xB8, 0x18, 0x79,
506 0x41, 0xCA, 0xF0, 0x85, 0x60, 0x28, 0x23, 0xB0, 0xD1, 0xC5,
507 0x13, 0x60, 0xF2, 0x2A, 0x39, 0xD5, 0x30, 0x9C, 0xB5, 0x59,
508 0x5A, 0xC2, 0x1D, 0xA4, 0x54, 0x7B, 0xEE, 0x4A, 0x15, 0x82,
509 0x58, 0xCD, 0x8B, 0x71, 0x58, 0xB6, 0x8E, 0x72, 0x8F, 0x74,
510 0x95, 0x0D, 0x7E, 0x3D, 0x93, 0xF4, 0xA3, 0xFE, 0x58, 0xA4,
511 0x69, 0x4E, 0x57, 0x71, 0xD8, 0x20, 0x69, 0x63, 0x16, 0xFC,
512 0x8E, 0x85, 0xE2, 0xF2, 0x01, 0x08, 0xF7, 0x6C, 0x91, 0xB3,
513 0x47, 0x99, 0xA1, 0x24, 0x99, 0x7F, 0x2C, 0xF1, 0x45, 0x90,
514 0x7C, 0xBA, 0x96, 0x7E, 0x26, 0x6A, 0xED, 0xAF, 0xE1, 0xB8,
515 0xB7, 0xDF, 0x1A, 0xD0, 0xDB, 0x72, 0xFD, 0x2F, 0xAC, 0xB5,
516 0xDF, 0x98, 0xA6, 0x0B, 0x31, 0xD1, 0x1B, 0xFB, 0x79, 0x89,
517 0xD9, 0xD5, 0x16, 0x92, 0x17, 0x09, 0x47, 0xB5, 0xB5, 0xD5,
518 0x84, 0x3F, 0xDD, 0x50, 0x7C, 0xC9, 0xB7, 0x29, 0xAC, 0xC0,
519 0x6C, 0x0C, 0xE9, 0x34, 0xCF, 0x66, 0x54, 0xBE, 0x77, 0x13,
520 0xD0, 0x38, 0xE6, 0x21, 0x28, 0x45, 0x89, 0x6C, 0x4E, 0xEC,
521 0x98, 0xFA, 0x2E, 0x08, 0xD0, 0x31, 0x9F, 0x29, 0x22, 0x38,
522 0x09, 0xA4, 0x44, 0x73, 0x70, 0x03, 0x2E, 0x8A, 0x19, 0x13,
523 0xD3, 0x08, 0xA3, 0x85, 0x88, 0x6A, 0x3F, 0x24,
524 /* . */ 0x03, 0x00, 0x00, 0x00
525 /* <- up to intlength 4 -> */
526 /* or bf_t int length of 2 + 2 byte exp */
527 };
528
529 length = bflength+2; /* 2 byte exp */
530 pi_offset = sizeof pi_table - length;
531 _fmemcpy(big_pi, pi_table + pi_offset, length);
532
533 /* notice that bf_pi and bn_pi can share the same memory space */
534 bf_pi = big_pi;
535 bn_pi = big_pi + (bflength-2) - (bnlength-intlength);
536 return;
537 }
538