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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25