/[dtapublic]/projs/dtats/trunk/projs/2018/20180707_cgi_web_tools_aux_exe/subfunc_cfbrap.c
ViewVC logotype

Contents of /projs/dtats/trunk/projs/2018/20180707_cgi_web_tools_aux_exe/subfunc_cfbrap.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 175 - (show annotations) (download)
Mon Jul 9 00:00:34 2018 UTC (5 years, 11 months ago) by dashley
File MIME type: text/plain
File size: 25408 byte(s)
Update license (GPL->MIT) and copyright information.  Remove CVS log, which SVN does not support.
1 //$Header$
2 //********************************************************************************
3 //Copyright (c) 2003, 2018 David T. Ashley.
4 //********************************************************************************
5 //This file is part of "arith_large_cgi", a program that is designed to be
6 //invoked by a PHP script as part of serving a web page that performs
7 //calculations involving large integers. (A secondary compiled program is
8 //used because a compiled program can perform certain calculation-intensive
9 //tasks far more efficiently than a PHP script.) This program is provided by
10 //David T. Ashley (dashley@gmail.com) under the MIT License (reproduced
11 //immediately below).
12 //********************************************************************************
13 //Permission is hereby granted, free of charge, to any person obtaining a copy
14 //of this software and associated documentation files (the "Software"), to deal
15 //in the Software without restriction, including without limitation the rights
16 //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 //copies of the Software, and to permit persons to whom the Software is
18 //furnished to do so, subject to the following conditions:
19 //
20 //The above copyright notice and this permission notice shall be included in all
21 //copies or substantial portions of the Software.
22 //
23 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 //SOFTWARE.
30 //********************************************************************************
31 //
32 //This module finds the best rational approximations to a rational number
33 //subject to constraints on the numerator and denominator using continued
34 //fraction techniques. All of the algorithms employed are O(log N) so
35 //there should be no problem obtaining results for any practical problem.
36 //This module is based on a paper written by Dave Ashley and others providing
37 //best rational approximation algorithms.
38 //
39 //INPUT PARAMETERS
40 //----------------
41 //This subfunction accepts the following parameters, in order.
42 //
43 // (a) The numerator of the number whose best rational approximation is to
44 // be found (max 1000 digits).
45 //
46 // (b) The denominator of the number whose best rational approximation is to
47 // be found (max 1000 digits).
48 //
49 // (c) The largest allowable numerator of the approximations, or "0" if the numerator
50 // is unconstrained (max 1000 digits).
51 //
52 // (d) The largest allowable denominator of the approximations, or "0" if the denominator
53 // is unconstrained (max 1000 digits).
54 //
55 // (e) The number of neighbors to the left of the specified number to return (max 1000).
56 //
57 // (f) The number of neighbors to the right of the specified number to return (max 1000).
58 //
59 // (g) The number of significant figures to use in floating-point results (note that
60 // "significant figures" includes the numbers before the decimal point as well as
61 // after). The maximum value here is 1000.
62 //
63 // (h) The maximum number of CPU seconds to expend calculating (max 1000).
64 //
65 // NOTE (1): Numerator and denominator may not both be unconstrained.
66 //
67 //OUTPUT RESULTS
68 //--------------
69 //The notation below gives the outputs of the program. In some cases, [i] notation
70 //is used to indicate line numbers.
71 //
72 //[01] An overall success or failure code for the operation, as a string.
73 // Valid responses are:
74 // S : Success.
75 // FNPAR : The number of command-line parameters was wrong.
76 // FCPU : The operation failed because ran out of CPU time.
77 // FNUM : The operation failed because the numerator of the rational number whose
78 // neighbors are to be found was invalid or too large.
79 // FDEN : The operation failed because the denominator of the rational number whose
80 // neighbors are to be found was invalid or too large.
81 // FNUMMAX : The operation failed because the numerator limit was invalid or
82 // too large.
83 // FDENMAX : The operation failed because the denominator limit was invalid
84 // or too large.
85 // FLEFT : The operation failed because the number of left neighbors requested
86 // was invalid or too large.
87 // FRIGHT : The operation failed because the number of right neighbors requested
88 // was invalid or too large.
89 // FSIG : The number of significant figures specified was invalid.
90 // FCPU : The CPU time limit was invalid.
91 // FGEN : General failure code (catchall, if anything else is possible).
92 //
93 // For all failure codes, there will be no additional output if a failure code
94 // appears on the first line.
95 //[02] The total number of lines in the output from the program, including the start
96 // and ending lines.
97 //[03] The fully normalized numerator entered. This means it has been
98 // stripped of all weird characters, etc. This can be used by the
99 // PHP script to repopulate form boxes.
100 //[04] The fully normalized denominator entered.
101 //[05] The fully normalized maximum numerator entered.
102 //[06] The fully normalized maximum denominator entered.
103 //[07] The fully normalized number of left neighbors entered.
104 //[08] The fully normalized number of right neighbors entered.
105 //[09] The fully normalized number of significant figures requested.
106 //[10] The fully normalized number of CPU seconds allowed.
107 //
108 //The next section of the output contains the decimal form of the number that is to
109 //be approximated and also slightly more data about the number to be approximated.
110 //The PHP script may receive a number which is either specified as
111 //a rational number or as a decimal number, and the PHP script must convert it to a
112 //rational number so this program can process it. Depending on what the PHP script
113 //was given as input, it may not have the decimal form.
114 //
115 //[11] Decimal equivalent of number entered, avoiding scientific notation if
116 // possible but using it if necessary.
117 //[12] Scientific notation equivalent of number entered.
118 //[13] GCD of numerator and denominator of [04] and [05].
119 //[14] Numerator of reduced rational form.
120 //[15] Denominator of reduced rational form.
121 //
122 //This secion contains "pointers" to the major sections which may follow.
123 //All line numbers below are engineered so that "1" is the first line number
124 //in the output block and "0" represents the non-existence of the section.
125 //[16] Index to results section (code "NEIGHBORS").
126 //[17] Index to CF decomp of number to approximate (code "CFINPUT").
127 //[18] Index to CF decomp of reciprocal of number to approximate (code "CFINPUTRECIP").
128 //[19] Index to CF decomp of corner point (code "CFCORNER").
129 //[20] Index to CF decomp of reciprocal of corner point (code "CFCORNERRECIP").
130 //
131 //This section contains the neighbors of the number to approximate. The number of
132 //neighbors is strongly influenced by the number of neighbors specified on the
133 //CGI-BIN form. However, there may be fewer neighbors returned if 0/1 or the last
134 //formable rational number is encountered.
135 //[N+ 0] Constant "NEIGHBORS".
136 //[N+ 1] Number of neighbors to follow.
137 //[N+ 2] Subscript of first neighbor, from left to right. Subscripts are assigned so they rank
138 // the neighbors in relation to the number to approximate. "0" indicates that the number
139 // is the number to approximate, i.e. the number is present in the rectangular region of
140 // the integer lattice being considered.
141 //[N+ 3] 1 if the number is the corner point, or 0 otherwise.
142 //[N+ 4] Numerator of number, irreducible with respect to denominator.
143 //[N+ 5] Denominator of number, irreducible with respect to numerator.
144 //[N+ 6] Decimal form of neighbor, avoiding scientific notation if possible.
145 //[N+ 7] Decimal form of neighbor, using scientific notation.
146 //[N+ 8] Sign of error. Will be "-" for negative error or "+" otherwise.
147 //[N+ 9] Numerator of absolute value of error, irreducible with respect to denominator.
148 //[N+10] Denominator of absolute value of error, irreducible with respect to numerator.
149 //[N+11] Decimal form of absolute value of error, avoiding scientific notation if possible.
150 //[N+12] Decimal form of absolute value of error, using scientific notation.
151 //[N+13] Repeats at [N+2] for next neighbor, out to as many neighbors specified in
152 // [N+1]
153 //
154 //The next section of the output contains the continued fraction decomposition
155 //of the number to approximate.
156 //[N+ 0] Constant "CFINPUT".
157 //[N+ 1] Number of partial quotients to follow.
158 //[N+ 2] k, subscript of iteration (first subscript is 0).
159 //[N+ 3] dividend_k
160 //[N+ 4] divisor_k
161 //[N+ 5] a_k
162 //[N+ 6] remainder_k
163 //[N+ 7] p_k
164 //[N+ 8] q_k
165 //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
166 // quotients specified in [N+1].
167 //
168 //The next section of the output contains the continued fraction decomposition
169 //of the reciprocal of the number to approximate. If the number to approximate is 0,
170 //this entire section will be omitted.
171 //[N+ 0] Constant "CFINPUTRECIP".
172 //[N+ 1] Number of partial quotients to follow.
173 //[N+ 2] k, subscript of iteration (first subscript is 0).
174 //[N+ 3] dividend_k
175 //[N+ 4] divisor_k
176 //[N+ 5] a_k
177 //[N+ 6] remainder_k
178 //[N+ 7] p_k
179 //[N+ 8] q_k
180 //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
181 // quotients specified in [N+1].
182 //
183 //The next section of the output contains the continued fraction decomposition of the
184 //the corner point. If the numerator and denominator were not both constrained,
185 //this section will be omitted.
186 //[N+ 0] Constant "CCORNER".
187 //[N+ 1] Number of partial quotients to follow.
188 //[N+ 2] k, subscript of iteration (first subscript is 0).
189 //[N+ 3] dividend_k
190 //[N+ 4] divisor_k
191 //[N+ 5] a_k
192 //[N+ 6] remainder_k
193 //[N+ 7] p_k
194 //[N+ 8] q_k
195 //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
196 // quotients specified in [N+1].
197 //
198 //The next section of the output contains the continued fraction decomposition of the
199 //reciprocal of the corner point. If the numerator and denominator were not both constrained,
200 //this section will be omitted.
201 //[N+ 0] Constant "CCORNERRECIP".
202 //[N+ 1] Number of partial quotients to follow.
203 //[N+ 2] k, subscript of iteration (first subscript is 0).
204 //[N+ 3] dividend_k
205 //[N+ 4] divisor_k
206 //[N+ 5] a_k
207 //[N+ 6] remainder_k
208 //[N+ 7] p_k
209 //[N+ 8] q_k
210 //[N+ 9] k+1 ... repeats as with element [N+2] out to as many partial
211 // quotients specified in [N+1].
212 //
213 //The next section is the footer.
214 //[N] Constant "S", terminator line.
215
216 //The return value (exit code) from this subfunction is always 0.
217 //
218
219 #define MODULE_SUBFUNC_CFBRAP
220
221 #include <assert.h>
222 #include <ctype.h>
223 #include <stddef.h>
224 #include <stdio.h>
225 #include <stdlib.h>
226 #include <string.h>
227 #include <time.h>
228
229 #include <gmp.h>
230
231 #include "auxfuncs.h"
232 #include "subfunc_cfbrap.h"
233 #include "sieve_eratosthenes.h"
234
235
236 /****************************************************************************/
237 /* MODULE CONSTANTS */
238 /****************************************************************************/
239 #define SUBFUNC_CFBRAP_MAX_IN_DIGITS (1000)
240 //The maximum number of decimal digits that will be allowed in input rational
241 //numbers and limits.
242 #define SUBFUNC_CFBRAP_MAX_NEIGHBORS (1000)
243 //The maximum number of integer lattice rectangular region neighbors that will
244 //be allowed.
245
246 /****************************************************************************/
247 /* MODULE DATA STRUCTURES */
248 /****************************************************************************/
249 //A structure to hold all input parameters from the command-line.
250 //
251 struct SUBFUNC_CFBRAP_input_par_struct
252 {
253 mpz_t num;
254 mpz_t den;
255 mpz_t num_max;
256 mpz_t den_max;
257 int lneighbors;
258 int rneighbors;
259 int sig_fig;
260 int max_cpu;
261 };
262
263 //A structure to hold a single line that might be output from this
264 //program.
265 struct SUBFUNC_CFBRAP_line_buffer
266 {
267 char *line;
268 //The line itself, with zero terminator.
269 };
270
271 //A structure to hold the collection of lines that will eventually be
272 //output from this program. These must be buffered because it is
273 //not known how many there will be.
274 //
275 struct SUBFUNC_CFBRAP_program_output_buffer
276 {
277 int nlines;
278 //The number of lines.
279 struct SUBFUNC_CFBRAP_line_buffer *lines;
280 //Pointer to the first element of array of line structures.
281 };
282
283
284 /****************************************************************************/
285 /* PROGRAM OUTPUT BUFFER MANIPULATION FUNCTIONS */
286 /****************************************************************************/
287 void SUBFUNC_CFBRAP_pob_init(struct SUBFUNC_CFBRAP_program_output_buffer *arg)
288 {
289 arg->nlines = 0;
290 arg->lines = NULL;
291 }
292
293 void SUBFUNC_CFBRAP_pob_destroy(struct SUBFUNC_CFBRAP_program_output_buffer *arg)
294 {
295 int i;
296
297 for (i=0; i<arg->nlines; i++)
298 {
299 free(arg->lines[i].line);
300 }
301
302 if (i)
303 free(arg->lines);
304
305 arg->nlines = 0;
306 arg->lines = NULL;
307 }
308
309 //Tacks a line onto the output buffer.
310 //
311 void SUBFUNC_CFBRAP_pob_tack_line(struct SUBFUNC_CFBRAP_program_output_buffer *arg,
312 const char *line)
313 {
314 int tack_strlen;
315 //String length of the line to tack. Must allocate one more space for it.
316
317 //Figure out how long the input string is.
318 tack_strlen = strlen(line);
319
320 //If there are no lines in the buffer, allocate space for 1 else realloc.
321 if (!arg->nlines)
322 arg->lines = malloc(sizeof(struct SUBFUNC_CFBRAP_line_buffer));
323 else
324 arg->lines = realloc(arg->lines, (arg->nlines + 1) * sizeof(struct SUBFUNC_CFBRAP_line_buffer));
325
326 //Set up for the line itself.
327 arg->lines[arg->nlines].line = malloc(tack_strlen + 1);
328
329 //Copy in the line.
330 strcpy(arg->lines[arg->nlines].line, line);
331
332 //We now have one more line.
333 arg->nlines++;
334 }
335
336
337 //Changes a line in the buffer to be something different. The first line is "1". If the line
338 //does not already exist, this function does nothing.
339 //
340 void SUBFUNC_CFBRAP_pob_modify_line(struct SUBFUNC_CFBRAP_program_output_buffer *arg,
341 int which_line,
342 const char *new_line)
343 {
344 int modify_strlen;
345 //String length of the line to swap in. Must allocate one more space for it.
346
347 //Figure out how long the input string is.
348 modify_strlen = strlen(new_line);
349
350 //The line number specified must be at least number 1 and the line must already
351 //exist, else do nothing.
352 if ((which_line >= 1) && (which_line <= arg->nlines))
353 {
354 //Reallocate the space to hold the new line and copy it in.
355 arg->lines[which_line-1].line = realloc(arg->lines[which_line-1].line, modify_strlen + 1);
356 strcpy(arg->lines[which_line-1].line, new_line);
357 }
358 }
359
360
361 //Dumps the entire output buffer to the standard output.
362 //
363 void SUBFUNC_CFBRAP_pob_dump(struct SUBFUNC_CFBRAP_program_output_buffer *arg)
364 {
365 int i;
366
367 for (i=0; i<arg->nlines; i++)
368 {
369 printf("%s\n", arg->lines[i].line);
370 }
371 }
372
373
374 /****************************************************************************/
375 /* INPUT PARAMETER BLOCK MANIPULATION */
376 /****************************************************************************/
377 //Initializes the input parameter block (allocates initial storage).
378 //
379 void SUBFUNC_CFBRAP_ipblock_init(struct SUBFUNC_CFBRAP_input_par_struct *arg)
380 {
381 mpz_init(arg->num);
382 mpz_init(arg->den);
383 mpz_init(arg->num_max);
384 mpz_init(arg->den_max);
385 arg->lneighbors = 1;
386 arg->rneighbors = 1;
387 arg->sig_fig = 9;
388 arg->max_cpu = 20;
389 }
390
391 //Deallocates the input parameter block (deallocates storage).
392 //
393 void SUBFUNC_CFBRAP_ipblock_destroy(struct SUBFUNC_CFBRAP_input_par_struct *arg)
394 {
395 mpz_clear(arg->num);
396 mpz_clear(arg->den);
397 mpz_clear(arg->num_max);
398 mpz_clear(arg->den_max);
399 arg->lneighbors = 1;
400 arg->rneighbors = 1;
401 arg->sig_fig = 9;
402 arg->max_cpu = 20;
403 }
404
405
406 /****************************************************************************/
407 /* ERROR PATH OUTPUT */
408 /****************************************************************************/
409 //Dumps an error code and associated proper information out to the output stream
410 //and returns.
411 //
412 int SUBFUNC_CFBRAP_error_dump(int argc, char *argv[])
413 {
414 return 0;
415 }
416
417
418 /****************************************************************************/
419 /* INPUT PARAMETER PARSING */
420 /****************************************************************************/
421 //Parses input parameters, stuffs the structure containing these parameters,
422 //and in the event of an error will return 1 and will stuff the output
423 //buffer with only the error code.
424 int SUBFUNC_CFBRAP_parse_input_pars(
425 int argc,
426 char *argv[],
427 struct SUBFUNC_CFBRAP_input_par_struct *ipb,
428 struct SUBFUNC_CFBRAP_program_output_buffer *pob
429 )
430 {
431 char *scratch = NULL;
432
433 //There should be 8 input parameters in addition to the 2 required (the
434 //program name plus the subfunction code. Error out if wrong.
435 if (argc != 10)
436 {
437 SUBFUNC_CFBRAP_pob_tack_line(pob, "FNPAR");
438 return(1);
439 }
440
441 //The first input parameter should be the numerator of the rational number to
442 //approximate. We can parse this out and place it into the input parameter
443 //block.
444 scratch = malloc(strlen(argv[2]) + 1);
445 strcpy(scratch, argv[2]);
446 AUXFUNCS_remove_non_digits(scratch);
447 AUXFUNCS_remove_leading_zeros(scratch);
448
449 if (!strlen(scratch))
450 {
451 //The only possibility is that this was zero. Assign zero.
452 mpz_set_ui(ipb->num, 0);
453 }
454 else
455 {
456 //What is left must be a valid integer. We need to be sure it is not too
457 //long.
458 if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
459 {
460 SUBFUNC_CFBRAP_pob_tack_line(pob, "FNUM");
461 return(1);
462 }
463 else
464 {
465 mpz_set_str(ipb->num, scratch, 10);
466 }
467 }
468
469 //The second input parameter should be the denominator of the rational number to
470 //approximate. We can parse this out and place it into the input parameter
471 //block.
472 scratch = realloc(scratch, strlen(argv[3]) + 1);
473 strcpy(scratch, argv[3]);
474 AUXFUNCS_remove_non_digits(scratch);
475 AUXFUNCS_remove_leading_zeros(scratch);
476
477 if (!strlen(scratch))
478 {
479 //The only possibility is that this was zero. This is a no-no.
480 SUBFUNC_CFBRAP_pob_tack_line(pob, "FDEN");
481 return(1);
482 }
483 else
484 {
485 //What is left must be a valid integer. We need to be sure it is not too
486 //long.
487 if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
488 {
489 SUBFUNC_CFBRAP_pob_tack_line(pob, "FDEN");
490 return(1);
491 }
492 else
493 {
494 mpz_set_str(ipb->den, scratch, 10);
495 }
496 }
497
498 //The third input parameter should be the max numerator value for approximations.
499 //We can parse this out and place it into the input parameter
500 //block.
501 scratch = malloc(strlen(argv[4]) + 1);
502 strcpy(scratch, argv[4]);
503 AUXFUNCS_remove_non_digits(scratch);
504 AUXFUNCS_remove_leading_zeros(scratch);
505
506 if (!strlen(scratch))
507 {
508 //The only possibility is that this was zero. Assign zero.
509 mpz_set_ui(ipb->num_max, 0);
510 }
511 else
512 {
513 //What is left must be a valid integer. We need to be sure it is not too
514 //long.
515 if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
516 {
517 SUBFUNC_CFBRAP_pob_tack_line(pob, "FNUMMAX");
518 return(1);
519 }
520 else
521 {
522 mpz_set_str(ipb->num_max, scratch, 10);
523 }
524 }
525
526 //The fourth input parameter should be the max denominator value for approximations.
527 //We can parse this out and place it into the input parameter
528 //block.
529 scratch = malloc(strlen(argv[5]) + 1);
530 strcpy(scratch, argv[5]);
531 AUXFUNCS_remove_non_digits(scratch);
532 AUXFUNCS_remove_leading_zeros(scratch);
533
534 if (!strlen(scratch))
535 {
536 //The only possibility is that this was zero. Assign zero.
537 mpz_set_ui(ipb->den_max, 0);
538 }
539 else
540 {
541 //What is left must be a valid integer. We need to be sure it is not too
542 //long.
543 if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
544 {
545 SUBFUNC_CFBRAP_pob_tack_line(pob, "FDENMAX");
546 return(1);
547 }
548 else
549 {
550 mpz_set_str(ipb->den_max, scratch, 10);
551 }
552 }
553
554 //The fifth input parameter should be the number of desired left neighbors.
555 //We can parse this out and place it into the input parameter
556 //block.
557 scratch = malloc(strlen(argv[6]) + 1);
558 strcpy(scratch, argv[6]);
559 AUXFUNCS_remove_non_digits(scratch);
560 AUXFUNCS_remove_leading_zeros(scratch);
561
562 if (!strlen(scratch))
563 {
564 //The only possibility is that this was zero. Assign 0.
565 ipb->lneighbors = 0;
566 }
567 else
568 {
569 //What is left must be a valid integer. Scan it in.
570 //
571 if (strlen(scratch) > SUBFUNC_CFBRAP_MAX_IN_DIGITS)
572 {
573 SUBFUNC_CFBRAP_pob_tack_line(pob, "FDENMAX");
574 return(1);
575 }
576 else
577 {
578 mpz_set_str(ipb->den_max, scratch, 10);
579 }
580 }
581
582 return(0);
583 }
584
585
586 /****************************************************************************/
587 /* MAIN CALCULATION FUNCTION */
588 /****************************************************************************/
589 //Carries out the best rational approximation calculation and display, knowing that
590 //all parameters have been validated.
591 //
592 int SUBFUNC_CFBRAP_calc_brap(int argc, char *argv[])
593 {
594 return 0;
595 }
596
597
598
599 //Main function. Checks parameters and carries out the calculations.
600 //
601 int SUBFUNC_CFBRAP_main(int argc, char *argv[])
602 {
603 //The time snapshot against which we compare to see if we're over
604 //time budget.
605 time_t time_snapshot;
606
607 struct SUBFUNC_CFBRAP_input_par_struct ipb;
608 //The input parameters.
609
610 struct SUBFUNC_CFBRAP_program_output_buffer pob;
611 //The program output. Output is buffered because there are some lines
612 //early that point to later lines.
613
614 //Scratch structure.
615 char *scratchstr = NULL;
616
617 //Initialize the input parameter structure.
618 SUBFUNC_CFBRAP_ipblock_init(&ipb);
619
620 //Initialize the output buffer.
621 SUBFUNC_CFBRAP_pob_init(&pob);
622
623 //Parse, check, etc. the input parameters. If there are any issues,
624 //Jump to the end and just dump what we have.
625 if (SUBFUNC_CFBRAP_parse_input_pars(argc, argv, &ipb, &pob))
626 goto error_return;
627
628
629 //This is a success event. What this means is that we should store the output,
630 //which will then be send to stdout.
631 //
632 //Initial success code.
633 SUBFUNC_CFBRAP_pob_tack_line(&pob, "S");
634 //
635 //Total number of lines in the program. This is just a placeholder, until we know how
636 //many.
637 SUBFUNC_CFBRAP_pob_tack_line(&pob, "NUMLINES_PLACEHOLDER");
638 //
639 //Numerator of number to be approximated.
640 scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.num, 10) + 20);
641 gmp_sprintf(scratchstr, "%Zd", ipb.num);
642 SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
643 //
644 //Denominator of number to be approximated.
645 scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.den, 10) + 20);
646 gmp_sprintf(scratchstr, "%Zd", ipb.den);
647 SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
648 //
649 //Maximum numerator of approximations.
650 scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.num_max, 10) + 20);
651 gmp_sprintf(scratchstr, "%Zd", ipb.num_max);
652 SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
653 //
654 //Maximum denominator of approximations.
655 scratchstr = realloc(scratchstr, mpz_sizeinbase(ipb.den_max, 10) + 20);
656 gmp_sprintf(scratchstr, "%Zd", ipb.den_max);
657 SUBFUNC_CFBRAP_pob_tack_line(&pob, scratchstr);
658 //
659 //Fill in the number of lines that we have. This replaces the placeholder.
660 {
661 char buf[100];
662
663 sprintf(buf, "%d", pob.nlines);
664 SUBFUNC_CFBRAP_pob_modify_line(&pob, 2, buf);
665 }
666
667
668
669 error_return:
670
671 //Destroy the input parameter structure.
672 SUBFUNC_CFBRAP_ipblock_destroy(&ipb);
673
674 //Dump the output to STDOUT.
675 SUBFUNC_CFBRAP_pob_dump(&pob);
676
677 //Destroy the output buffer.
678 SUBFUNC_CFBRAP_pob_destroy(&pob);
679
680 //Always return 0.
681 return(0);
682 }
683
684 //********************************************************************************
685 // End of SUBFUNC_CFBRAP.C.
686 //********************************************************************************

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25