1 |
/* $Archive:: /ACM Rational Approximation Paper And Algorithms/C-Language Implementation/rap_c.c $ */
|
2 |
/* $Revision: 1.1 $ */
|
3 |
/* $Date: 2001/09/25 21:44:55 $ */
|
4 |
/* $Author: dtashley $ */
|
5 |
/* $Workfile:: rap_c.c $ */
|
6 |
/*
|
7 |
/*
|
8 |
//--------------------------------------------------------------------------------
|
9 |
//Copyright 2008 David T. Ashley
|
10 |
//-------------------------------------------------------------------------------------------------
|
11 |
//This source code and any program in which it is compiled/used is provided under the GNU GENERAL
|
12 |
//PUBLIC LICENSE, Version 3, full license text below.
|
13 |
//-------------------------------------------------------------------------------------------------
|
14 |
// GNU GENERAL PUBLIC LICENSE
|
15 |
// Version 3, 29 June 2007
|
16 |
//
|
17 |
// Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
18 |
// Everyone is permitted to copy and distribute verbatim copies
|
19 |
// of this license document, but changing it is not allowed.
|
20 |
//
|
21 |
// Preamble
|
22 |
//
|
23 |
// The GNU General Public License is a free, copyleft license for
|
24 |
//software and other kinds of works.
|
25 |
//
|
26 |
// The licenses for most software and other practical works are designed
|
27 |
//to take away your freedom to share and change the works. By contrast,
|
28 |
//the GNU General Public License is intended to guarantee your freedom to
|
29 |
//share and change all versions of a program--to make sure it remains free
|
30 |
//software for all its users. We, the Free Software Foundation, use the
|
31 |
//GNU General Public License for most of our software; it applies also to
|
32 |
//any other work released this way by its authors. You can apply it to
|
33 |
//your programs, too.
|
34 |
//
|
35 |
// When we speak of free software, we are referring to freedom, not
|
36 |
//price. Our General Public Licenses are designed to make sure that you
|
37 |
//have the freedom to distribute copies of free software (and charge for
|
38 |
//them if you wish), that you receive source code or can get it if you
|
39 |
//want it, that you can change the software or use pieces of it in new
|
40 |
//free programs, and that you know you can do these things.
|
41 |
//
|
42 |
// To protect your rights, we need to prevent others from denying you
|
43 |
//these rights or asking you to surrender the rights. Therefore, you have
|
44 |
//certain responsibilities if you distribute copies of the software, or if
|
45 |
//you modify it: responsibilities to respect the freedom of others.
|
46 |
//
|
47 |
// For example, if you distribute copies of such a program, whether
|
48 |
//gratis or for a fee, you must pass on to the recipients the same
|
49 |
//freedoms that you received. You must make sure that they, too, receive
|
50 |
//or can get the source code. And you must show them these terms so they
|
51 |
//know their rights.
|
52 |
//
|
53 |
// Developers that use the GNU GPL protect your rights with two steps:
|
54 |
//(1) assert copyright on the software, and (2) offer you this License
|
55 |
//giving you legal permission to copy, distribute and/or modify it.
|
56 |
//
|
57 |
// For the developers' and authors' protection, the GPL clearly explains
|
58 |
//that there is no warranty for this free software. For both users' and
|
59 |
//authors' sake, the GPL requires that modified versions be marked as
|
60 |
//changed, so that their problems will not be attributed erroneously to
|
61 |
//authors of previous versions.
|
62 |
//
|
63 |
// Some devices are designed to deny users access to install or run
|
64 |
//modified versions of the software inside them, although the manufacturer
|
65 |
//can do so. This is fundamentally incompatible with the aim of
|
66 |
//protecting users' freedom to change the software. The systematic
|
67 |
//pattern of such abuse occurs in the area of products for individuals to
|
68 |
//use, which is precisely where it is most unacceptable. Therefore, we
|
69 |
//have designed this version of the GPL to prohibit the practice for those
|
70 |
//products. If such problems arise substantially in other domains, we
|
71 |
//stand ready to extend this provision to those domains in future versions
|
72 |
//of the GPL, as needed to protect the freedom of users.
|
73 |
//
|
74 |
// Finally, every program is threatened constantly by software patents.
|
75 |
//States should not allow patents to restrict development and use of
|
76 |
//software on general-purpose computers, but in those that do, we wish to
|
77 |
//avoid the special danger that patents applied to a free program could
|
78 |
//make it effectively proprietary. To prevent this, the GPL assures that
|
79 |
//patents cannot be used to render the program non-free.
|
80 |
//
|
81 |
// The precise terms and conditions for copying, distribution and
|
82 |
//modification follow.
|
83 |
//
|
84 |
// TERMS AND CONDITIONS
|
85 |
//
|
86 |
// 0. Definitions.
|
87 |
//
|
88 |
// "This License" refers to version 3 of the GNU General Public License.
|
89 |
//
|
90 |
// "Copyright" also means copyright-like laws that apply to other kinds of
|
91 |
//works, such as semiconductor masks.
|
92 |
//
|
93 |
// "The Program" refers to any copyrightable work licensed under this
|
94 |
//License. Each licensee is addressed as "you". "Licensees" and
|
95 |
//"recipients" may be individuals or organizations.
|
96 |
//
|
97 |
// To "modify" a work means to copy from or adapt all or part of the work
|
98 |
//in a fashion requiring copyright permission, other than the making of an
|
99 |
//exact copy. The resulting work is called a "modified version" of the
|
100 |
//earlier work or a work "based on" the earlier work.
|
101 |
//
|
102 |
// A "covered work" means either the unmodified Program or a work based
|
103 |
//on the Program.
|
104 |
//
|
105 |
// To "propagate" a work means to do anything with it that, without
|
106 |
//permission, would make you directly or secondarily liable for
|
107 |
//infringement under applicable copyright law, except executing it on a
|
108 |
//computer or modifying a private copy. Propagation includes copying,
|
109 |
//distribution (with or without modification), making available to the
|
110 |
//public, and in some countries other activities as well.
|
111 |
//
|
112 |
// To "convey" a work means any kind of propagation that enables other
|
113 |
//parties to make or receive copies. Mere interaction with a user through
|
114 |
//a computer network, with no transfer of a copy, is not conveying.
|
115 |
//
|
116 |
// An interactive user interface displays "Appropriate Legal Notices"
|
117 |
//to the extent that it includes a convenient and prominently visible
|
118 |
//feature that (1) displays an appropriate copyright notice, and (2)
|
119 |
//tells the user that there is no warranty for the work (except to the
|
120 |
//extent that warranties are provided), that licensees may convey the
|
121 |
//work under this License, and how to view a copy of this License. If
|
122 |
//the interface presents a list of user commands or options, such as a
|
123 |
//menu, a prominent item in the list meets this criterion.
|
124 |
//
|
125 |
// 1. Source Code.
|
126 |
//
|
127 |
// The "source code" for a work means the preferred form of the work
|
128 |
//for making modifications to it. "Object code" means any non-source
|
129 |
//form of a work.
|
130 |
//
|
131 |
// A "Standard Interface" means an interface that either is an official
|
132 |
//standard defined by a recognized standards body, or, in the case of
|
133 |
//interfaces specified for a particular programming language, one that
|
134 |
//is widely used among developers working in that language.
|
135 |
//
|
136 |
// The "System Libraries" of an executable work include anything, other
|
137 |
//than the work as a whole, that (a) is included in the normal form of
|
138 |
//packaging a Major Component, but which is not part of that Major
|
139 |
//Component, and (b) serves only to enable use of the work with that
|
140 |
//Major Component, or to implement a Standard Interface for which an
|
141 |
//implementation is available to the public in source code form. A
|
142 |
//"Major Component", in this context, means a major essential component
|
143 |
//(kernel, window system, and so on) of the specific operating system
|
144 |
//(if any) on which the executable work runs, or a compiler used to
|
145 |
//produce the work, or an object code interpreter used to run it.
|
146 |
//
|
147 |
// The "Corresponding Source" for a work in object code form means all
|
148 |
//the source code needed to generate, install, and (for an executable
|
149 |
//work) run the object code and to modify the work, including scripts to
|
150 |
//control those activities. However, it does not include the work's
|
151 |
//System Libraries, or general-purpose tools or generally available free
|
152 |
//programs which are used unmodified in performing those activities but
|
153 |
//which are not part of the work. For example, Corresponding Source
|
154 |
//includes interface definition files associated with source files for
|
155 |
//the work, and the source code for shared libraries and dynamically
|
156 |
//linked subprograms that the work is specifically designed to require,
|
157 |
//such as by intimate data communication or control flow between those
|
158 |
//subprograms and other parts of the work.
|
159 |
//
|
160 |
// The Corresponding Source need not include anything that users
|
161 |
//can regenerate automatically from other parts of the Corresponding
|
162 |
//Source.
|
163 |
//
|
164 |
// The Corresponding Source for a work in source code form is that
|
165 |
//same work.
|
166 |
//
|
167 |
// 2. Basic Permissions.
|
168 |
//
|
169 |
// All rights granted under this License are granted for the term of
|
170 |
//copyright on the Program, and are irrevocable provided the stated
|
171 |
//conditions are met. This License explicitly affirms your unlimited
|
172 |
//permission to run the unmodified Program. The output from running a
|
173 |
//covered work is covered by this License only if the output, given its
|
174 |
//content, constitutes a covered work. This License acknowledges your
|
175 |
//rights of fair use or other equivalent, as provided by copyright law.
|
176 |
//
|
177 |
// You may make, run and propagate covered works that you do not
|
178 |
//convey, without conditions so long as your license otherwise remains
|
179 |
//in force. You may convey covered works to others for the sole purpose
|
180 |
//of having them make modifications exclusively for you, or provide you
|
181 |
//with facilities for running those works, provided that you comply with
|
182 |
//the terms of this License in conveying all material for which you do
|
183 |
//not control copyright. Those thus making or running the covered works
|
184 |
//for you must do so exclusively on your behalf, under your direction
|
185 |
//and control, on terms that prohibit them from making any copies of
|
186 |
//your copyrighted material outside their relationship with you.
|
187 |
//
|
188 |
// Conveying under any other circumstances is permitted solely under
|
189 |
//the conditions stated below. Sublicensing is not allowed; section 10
|
190 |
//makes it unnecessary.
|
191 |
//
|
192 |
// 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
193 |
//
|
194 |
// No covered work shall be deemed part of an effective technological
|
195 |
//measure under any applicable law fulfilling obligations under article
|
196 |
//11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
197 |
//similar laws prohibiting or restricting circumvention of such
|
198 |
//measures.
|
199 |
//
|
200 |
// When you convey a covered work, you waive any legal power to forbid
|
201 |
//circumvention of technological measures to the extent such circumvention
|
202 |
//is effected by exercising rights under this License with respect to
|
203 |
//the covered work, and you disclaim any intention to limit operation or
|
204 |
//modification of the work as a means of enforcing, against the work's
|
205 |
//users, your or third parties' legal rights to forbid circumvention of
|
206 |
//technological measures.
|
207 |
//
|
208 |
// 4. Conveying Verbatim Copies.
|
209 |
//
|
210 |
// You may convey verbatim copies of the Program's source code as you
|
211 |
//receive it, in any medium, provided that you conspicuously and
|
212 |
//appropriately publish on each copy an appropriate copyright notice;
|
213 |
//keep intact all notices stating that this License and any
|
214 |
//non-permissive terms added in accord with section 7 apply to the code;
|
215 |
//keep intact all notices of the absence of any warranty; and give all
|
216 |
//recipients a copy of this License along with the Program.
|
217 |
//
|
218 |
// You may charge any price or no price for each copy that you convey,
|
219 |
//and you may offer support or warranty protection for a fee.
|
220 |
//
|
221 |
// 5. Conveying Modified Source Versions.
|
222 |
//
|
223 |
// You may convey a work based on the Program, or the modifications to
|
224 |
//produce it from the Program, in the form of source code under the
|
225 |
//terms of section 4, provided that you also meet all of these conditions:
|
226 |
//
|
227 |
// a) The work must carry prominent notices stating that you modified
|
228 |
// it, and giving a relevant date.
|
229 |
//
|
230 |
// b) The work must carry prominent notices stating that it is
|
231 |
// released under this License and any conditions added under section
|
232 |
// 7. This requirement modifies the requirement in section 4 to
|
233 |
// "keep intact all notices".
|
234 |
//
|
235 |
// c) You must license the entire work, as a whole, under this
|
236 |
// License to anyone who comes into possession of a copy. This
|
237 |
// License will therefore apply, along with any applicable section 7
|
238 |
// additional terms, to the whole of the work, and all its parts,
|
239 |
// regardless of how they are packaged. This License gives no
|
240 |
// permission to license the work in any other way, but it does not
|
241 |
// invalidate such permission if you have separately received it.
|
242 |
//
|
243 |
// d) If the work has interactive user interfaces, each must display
|
244 |
// Appropriate Legal Notices; however, if the Program has interactive
|
245 |
// interfaces that do not display Appropriate Legal Notices, your
|
246 |
// work need not make them do so.
|
247 |
//
|
248 |
// A compilation of a covered work with other separate and independent
|
249 |
//works, which are not by their nature extensions of the covered work,
|
250 |
//and which are not combined with it such as to form a larger program,
|
251 |
//in or on a volume of a storage or distribution medium, is called an
|
252 |
//"aggregate" if the compilation and its resulting copyright are not
|
253 |
//used to limit the access or legal rights of the compilation's users
|
254 |
//beyond what the individual works permit. Inclusion of a covered work
|
255 |
//in an aggregate does not cause this License to apply to the other
|
256 |
//parts of the aggregate.
|
257 |
//
|
258 |
// 6. Conveying Non-Source Forms.
|
259 |
//
|
260 |
// You may convey a covered work in object code form under the terms
|
261 |
//of sections 4 and 5, provided that you also convey the
|
262 |
//machine-readable Corresponding Source under the terms of this License,
|
263 |
//in one of these ways:
|
264 |
//
|
265 |
// a) Convey the object code in, or embodied in, a physical product
|
266 |
// (including a physical distribution medium), accompanied by the
|
267 |
// Corresponding Source fixed on a durable physical medium
|
268 |
// customarily used for software interchange.
|
269 |
//
|
270 |
// b) Convey the object code in, or embodied in, a physical product
|
271 |
// (including a physical distribution medium), accompanied by a
|
272 |
// written offer, valid for at least three years and valid for as
|
273 |
// long as you offer spare parts or customer support for that product
|
274 |
// model, to give anyone who possesses the object code either (1) a
|
275 |
// copy of the Corresponding Source for all the software in the
|
276 |
// product that is covered by this License, on a durable physical
|
277 |
// medium customarily used for software interchange, for a price no
|
278 |
// more than your reasonable cost of physically performing this
|
279 |
// conveying of source, or (2) access to copy the
|
280 |
// Corresponding Source from a network server at no charge.
|
281 |
//
|
282 |
// c) Convey individual copies of the object code with a copy of the
|
283 |
// written offer to provide the Corresponding Source. This
|
284 |
// alternative is allowed only occasionally and noncommercially, and
|
285 |
// only if you received the object code with such an offer, in accord
|
286 |
// with subsection 6b.
|
287 |
//
|
288 |
// d) Convey the object code by offering access from a designated
|
289 |
// place (gratis or for a charge), and offer equivalent access to the
|
290 |
// Corresponding Source in the same way through the same place at no
|
291 |
// further charge. You need not require recipients to copy the
|
292 |
// Corresponding Source along with the object code. If the place to
|
293 |
// copy the object code is a network server, the Corresponding Source
|
294 |
// may be on a different server (operated by you or a third party)
|
295 |
// that supports equivalent copying facilities, provided you maintain
|
296 |
// clear directions next to the object code saying where to find the
|
297 |
// Corresponding Source. Regardless of what server hosts the
|
298 |
// Corresponding Source, you remain obligated to ensure that it is
|
299 |
// available for as long as needed to satisfy these requirements.
|
300 |
//
|
301 |
// e) Convey the object code using peer-to-peer transmission, provided
|
302 |
// you inform other peers where the object code and Corresponding
|
303 |
// Source of the work are being offered to the general public at no
|
304 |
// charge under subsection 6d.
|
305 |
//
|
306 |
// A separable portion of the object code, whose source code is excluded
|
307 |
//from the Corresponding Source as a System Library, need not be
|
308 |
//included in conveying the object code work.
|
309 |
//
|
310 |
// A "User Product" is either (1) a "consumer product", which means any
|
311 |
//tangible personal property which is normally used for personal, family,
|
312 |
//or household purposes, or (2) anything designed or sold for incorporation
|
313 |
//into a dwelling. In determining whether a product is a consumer product,
|
314 |
//doubtful cases shall be resolved in favor of coverage. For a particular
|
315 |
//product received by a particular user, "normally used" refers to a
|
316 |
//typical or common use of that class of product, regardless of the status
|
317 |
//of the particular user or of the way in which the particular user
|
318 |
//actually uses, or expects or is expected to use, the product. A product
|
319 |
//is a consumer product regardless of whether the product has substantial
|
320 |
//commercial, industrial or non-consumer uses, unless such uses represent
|
321 |
//the only significant mode of use of the product.
|
322 |
//
|
323 |
// "Installation Information" for a User Product means any methods,
|
324 |
//procedures, authorization keys, or other information required to install
|
325 |
//and execute modified versions of a covered work in that User Product from
|
326 |
//a modified version of its Corresponding Source. The information must
|
327 |
//suffice to ensure that the continued functioning of the modified object
|
328 |
//code is in no case prevented or interfered with solely because
|
329 |
//modification has been made.
|
330 |
//
|
331 |
// If you convey an object code work under this section in, or with, or
|
332 |
//specifically for use in, a User Product, and the conveying occurs as
|
333 |
//part of a transaction in which the right of possession and use of the
|
334 |
//User Product is transferred to the recipient in perpetuity or for a
|
335 |
//fixed term (regardless of how the transaction is characterized), the
|
336 |
//Corresponding Source conveyed under this section must be accompanied
|
337 |
//by the Installation Information. But this requirement does not apply
|
338 |
//if neither you nor any third party retains the ability to install
|
339 |
//modified object code on the User Product (for example, the work has
|
340 |
//been installed in ROM).
|
341 |
//
|
342 |
// The requirement to provide Installation Information does not include a
|
343 |
//requirement to continue to provide support service, warranty, or updates
|
344 |
//for a work that has been modified or installed by the recipient, or for
|
345 |
//the User Product in which it has been modified or installed. Access to a
|
346 |
//network may be denied when the modification itself materially and
|
347 |
//adversely affects the operation of the network or violates the rules and
|
348 |
//protocols for communication across the network.
|
349 |
//
|
350 |
// Corresponding Source conveyed, and Installation Information provided,
|
351 |
//in accord with this section must be in a format that is publicly
|
352 |
//documented (and with an implementation available to the public in
|
353 |
//source code form), and must require no special password or key for
|
354 |
//unpacking, reading or copying.
|
355 |
//
|
356 |
// 7. Additional Terms.
|
357 |
//
|
358 |
// "Additional permissions" are terms that supplement the terms of this
|
359 |
//License by making exceptions from one or more of its conditions.
|
360 |
//Additional permissions that are applicable to the entire Program shall
|
361 |
//be treated as though they were included in this License, to the extent
|
362 |
//that they are valid under applicable law. If additional permissions
|
363 |
//apply only to part of the Program, that part may be used separately
|
364 |
//under those permissions, but the entire Program remains governed by
|
365 |
//this License without regard to the additional permissions.
|
366 |
//
|
367 |
// When you convey a copy of a covered work, you may at your option
|
368 |
//remove any additional permissions from that copy, or from any part of
|
369 |
//it. (Additional permissions may be written to require their own
|
370 |
//removal in certain cases when you modify the work.) You may place
|
371 |
//additional permissions on material, added by you to a covered work,
|
372 |
//for which you have or can give appropriate copyright permission.
|
373 |
//
|
374 |
// Notwithstanding any other provision of this License, for material you
|
375 |
//add to a covered work, you may (if authorized by the copyright holders of
|
376 |
//that material) supplement the terms of this License with terms:
|
377 |
//
|
378 |
// a) Disclaiming warranty or limiting liability differently from the
|
379 |
// terms of sections 15 and 16 of this License; or
|
380 |
//
|
381 |
// b) Requiring preservation of specified reasonable legal notices or
|
382 |
// author attributions in that material or in the Appropriate Legal
|
383 |
// Notices displayed by works containing it; or
|
384 |
//
|
385 |
// c) Prohibiting misrepresentation of the origin of that material, or
|
386 |
// requiring that modified versions of such material be marked in
|
387 |
// reasonable ways as different from the original version; or
|
388 |
//
|
389 |
// d) Limiting the use for publicity purposes of names of licensors or
|
390 |
// authors of the material; or
|
391 |
//
|
392 |
// e) Declining to grant rights under trademark law for use of some
|
393 |
// trade names, trademarks, or service marks; or
|
394 |
//
|
395 |
// f) Requiring indemnification of licensors and authors of that
|
396 |
// material by anyone who conveys the material (or modified versions of
|
397 |
// it) with contractual assumptions of liability to the recipient, for
|
398 |
// any liability that these contractual assumptions directly impose on
|
399 |
// those licensors and authors.
|
400 |
//
|
401 |
// All other non-permissive additional terms are considered "further
|
402 |
//restrictions" within the meaning of section 10. If the Program as you
|
403 |
//received it, or any part of it, contains a notice stating that it is
|
404 |
//governed by this License along with a term that is a further
|
405 |
//restriction, you may remove that term. If a license document contains
|
406 |
//a further restriction but permits relicensing or conveying under this
|
407 |
//License, you may add to a covered work material governed by the terms
|
408 |
//of that license document, provided that the further restriction does
|
409 |
//not survive such relicensing or conveying.
|
410 |
//
|
411 |
// If you add terms to a covered work in accord with this section, you
|
412 |
//must place, in the relevant source files, a statement of the
|
413 |
//additional terms that apply to those files, or a notice indicating
|
414 |
//where to find the applicable terms.
|
415 |
//
|
416 |
// Additional terms, permissive or non-permissive, may be stated in the
|
417 |
//form of a separately written license, or stated as exceptions;
|
418 |
//the above requirements apply either way.
|
419 |
//
|
420 |
// 8. Termination.
|
421 |
//
|
422 |
// You may not propagate or modify a covered work except as expressly
|
423 |
//provided under this License. Any attempt otherwise to propagate or
|
424 |
//modify it is void, and will automatically terminate your rights under
|
425 |
//this License (including any patent licenses granted under the third
|
426 |
//paragraph of section 11).
|
427 |
//
|
428 |
// However, if you cease all violation of this License, then your
|
429 |
//license from a particular copyright holder is reinstated (a)
|
430 |
//provisionally, unless and until the copyright holder explicitly and
|
431 |
//finally terminates your license, and (b) permanently, if the copyright
|
432 |
//holder fails to notify you of the violation by some reasonable means
|
433 |
//prior to 60 days after the cessation.
|
434 |
//
|
435 |
// Moreover, your license from a particular copyright holder is
|
436 |
//reinstated permanently if the copyright holder notifies you of the
|
437 |
//violation by some reasonable means, this is the first time you have
|
438 |
//received notice of violation of this License (for any work) from that
|
439 |
//copyright holder, and you cure the violation prior to 30 days after
|
440 |
//your receipt of the notice.
|
441 |
//
|
442 |
// Termination of your rights under this section does not terminate the
|
443 |
//licenses of parties who have received copies or rights from you under
|
444 |
//this License. If your rights have been terminated and not permanently
|
445 |
//reinstated, you do not qualify to receive new licenses for the same
|
446 |
//material under section 10.
|
447 |
//
|
448 |
// 9. Acceptance Not Required for Having Copies.
|
449 |
//
|
450 |
// You are not required to accept this License in order to receive or
|
451 |
//run a copy of the Program. Ancillary propagation of a covered work
|
452 |
//occurring solely as a consequence of using peer-to-peer transmission
|
453 |
//to receive a copy likewise does not require acceptance. However,
|
454 |
//nothing other than this License grants you permission to propagate or
|
455 |
//modify any covered work. These actions infringe copyright if you do
|
456 |
//not accept this License. Therefore, by modifying or propagating a
|
457 |
//covered work, you indicate your acceptance of this License to do so.
|
458 |
//
|
459 |
// 10. Automatic Licensing of Downstream Recipients.
|
460 |
//
|
461 |
// Each time you convey a covered work, the recipient automatically
|
462 |
//receives a license from the original licensors, to run, modify and
|
463 |
//propagate that work, subject to this License. You are not responsible
|
464 |
//for enforcing compliance by third parties with this License.
|
465 |
//
|
466 |
// An "entity transaction" is a transaction transferring control of an
|
467 |
//organization, or substantially all assets of one, or subdividing an
|
468 |
//organization, or merging organizations. If propagation of a covered
|
469 |
//work results from an entity transaction, each party to that
|
470 |
//transaction who receives a copy of the work also receives whatever
|
471 |
//licenses to the work the party's predecessor in interest had or could
|
472 |
//give under the previous paragraph, plus a right to possession of the
|
473 |
//Corresponding Source of the work from the predecessor in interest, if
|
474 |
//the predecessor has it or can get it with reasonable efforts.
|
475 |
//
|
476 |
// You may not impose any further restrictions on the exercise of the
|
477 |
//rights granted or affirmed under this License. For example, you may
|
478 |
//not impose a license fee, royalty, or other charge for exercise of
|
479 |
//rights granted under this License, and you may not initiate litigation
|
480 |
//(including a cross-claim or counterclaim in a lawsuit) alleging that
|
481 |
//any patent claim is infringed by making, using, selling, offering for
|
482 |
//sale, or importing the Program or any portion of it.
|
483 |
//
|
484 |
// 11. Patents.
|
485 |
//
|
486 |
// A "contributor" is a copyright holder who authorizes use under this
|
487 |
//License of the Program or a work on which the Program is based. The
|
488 |
//work thus licensed is called the contributor's "contributor version".
|
489 |
//
|
490 |
// A contributor's "essential patent claims" are all patent claims
|
491 |
//owned or controlled by the contributor, whether already acquired or
|
492 |
//hereafter acquired, that would be infringed by some manner, permitted
|
493 |
//by this License, of making, using, or selling its contributor version,
|
494 |
//but do not include claims that would be infringed only as a
|
495 |
//consequence of further modification of the contributor version. For
|
496 |
//purposes of this definition, "control" includes the right to grant
|
497 |
//patent sublicenses in a manner consistent with the requirements of
|
498 |
//this License.
|
499 |
//
|
500 |
// Each contributor grants you a non-exclusive, worldwide, royalty-free
|
501 |
//patent license under the contributor's essential patent claims, to
|
502 |
//make, use, sell, offer for sale, import and otherwise run, modify and
|
503 |
//propagate the contents of its contributor version.
|
504 |
//
|
505 |
// In the following three paragraphs, a "patent license" is any express
|
506 |
//agreement or commitment, however denominated, not to enforce a patent
|
507 |
//(such as an express permission to practice a patent or covenant not to
|
508 |
//sue for patent infringement). To "grant" such a patent license to a
|
509 |
//party means to make such an agreement or commitment not to enforce a
|
510 |
//patent against the party.
|
511 |
//
|
512 |
// If you convey a covered work, knowingly relying on a patent license,
|
513 |
//and the Corresponding Source of the work is not available for anyone
|
514 |
//to copy, free of charge and under the terms of this License, through a
|
515 |
//publicly available network server or other readily accessible means,
|
516 |
//then you must either (1) cause the Corresponding Source to be so
|
517 |
//available, or (2) arrange to deprive yourself of the benefit of the
|
518 |
//patent license for this particular work, or (3) arrange, in a manner
|
519 |
//consistent with the requirements of this License, to extend the patent
|
520 |
//license to downstream recipients. "Knowingly relying" means you have
|
521 |
//actual knowledge that, but for the patent license, your conveying the
|
522 |
//covered work in a country, or your recipient's use of the covered work
|
523 |
//in a country, would infringe one or more identifiable patents in that
|
524 |
//country that you have reason to believe are valid.
|
525 |
//
|
526 |
// If, pursuant to or in connection with a single transaction or
|
527 |
//arrangement, you convey, or propagate by procuring conveyance of, a
|
528 |
//covered work, and grant a patent license to some of the parties
|
529 |
//receiving the covered work authorizing them to use, propagate, modify
|
530 |
//or convey a specific copy of the covered work, then the patent license
|
531 |
//you grant is automatically extended to all recipients of the covered
|
532 |
//work and works based on it.
|
533 |
//
|
534 |
// A patent license is "discriminatory" if it does not include within
|
535 |
//the scope of its coverage, prohibits the exercise of, or is
|
536 |
//conditioned on the non-exercise of one or more of the rights that are
|
537 |
//specifically granted under this License. You may not convey a covered
|
538 |
//work if you are a party to an arrangement with a third party that is
|
539 |
//in the business of distributing software, under which you make payment
|
540 |
//to the third party based on the extent of your activity of conveying
|
541 |
//the work, and under which the third party grants, to any of the
|
542 |
//parties who would receive the covered work from you, a discriminatory
|
543 |
//patent license (a) in connection with copies of the covered work
|
544 |
//conveyed by you (or copies made from those copies), or (b) primarily
|
545 |
//for and in connection with specific products or compilations that
|
546 |
//contain the covered work, unless you entered into that arrangement,
|
547 |
//or that patent license was granted, prior to 28 March 2007.
|
548 |
//
|
549 |
// Nothing in this License shall be construed as excluding or limiting
|
550 |
//any implied license or other defenses to infringement that may
|
551 |
//otherwise be available to you under applicable patent law.
|
552 |
//
|
553 |
// 12. No Surrender of Others' Freedom.
|
554 |
//
|
555 |
// If conditions are imposed on you (whether by court order, agreement or
|
556 |
//otherwise) that contradict the conditions of this License, they do not
|
557 |
//excuse you from the conditions of this License. If you cannot convey a
|
558 |
//covered work so as to satisfy simultaneously your obligations under this
|
559 |
//License and any other pertinent obligations, then as a consequence you may
|
560 |
//not convey it at all. For example, if you agree to terms that obligate you
|
561 |
//to collect a royalty for further conveying from those to whom you convey
|
562 |
//the Program, the only way you could satisfy both those terms and this
|
563 |
//License would be to refrain entirely from conveying the Program.
|
564 |
//
|
565 |
// 13. Use with the GNU Affero General Public License.
|
566 |
//
|
567 |
// Notwithstanding any other provision of this License, you have
|
568 |
//permission to link or combine any covered work with a work licensed
|
569 |
//under version 3 of the GNU Affero General Public License into a single
|
570 |
//combined work, and to convey the resulting work. The terms of this
|
571 |
//License will continue to apply to the part which is the covered work,
|
572 |
//but the special requirements of the GNU Affero General Public License,
|
573 |
//section 13, concerning interaction through a network will apply to the
|
574 |
//combination as such.
|
575 |
//
|
576 |
// 14. Revised Versions of this License.
|
577 |
//
|
578 |
// The Free Software Foundation may publish revised and/or new versions of
|
579 |
//the GNU General Public License from time to time. Such new versions will
|
580 |
//be similar in spirit to the present version, but may differ in detail to
|
581 |
//address new problems or concerns.
|
582 |
//
|
583 |
// Each version is given a distinguishing version number. If the
|
584 |
//Program specifies that a certain numbered version of the GNU General
|
585 |
//Public License "or any later version" applies to it, you have the
|
586 |
//option of following the terms and conditions either of that numbered
|
587 |
//version or of any later version published by the Free Software
|
588 |
//Foundation. If the Program does not specify a version number of the
|
589 |
//GNU General Public License, you may choose any version ever published
|
590 |
//by the Free Software Foundation.
|
591 |
//
|
592 |
// If the Program specifies that a proxy can decide which future
|
593 |
//versions of the GNU General Public License can be used, that proxy's
|
594 |
//public statement of acceptance of a version permanently authorizes you
|
595 |
//to choose that version for the Program.
|
596 |
//
|
597 |
// Later license versions may give you additional or different
|
598 |
//permissions. However, no additional obligations are imposed on any
|
599 |
//author or copyright holder as a result of your choosing to follow a
|
600 |
//later version.
|
601 |
//
|
602 |
// 15. Disclaimer of Warranty.
|
603 |
//
|
604 |
// THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
605 |
//APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
606 |
//HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
607 |
//OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
608 |
//THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
609 |
//PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
610 |
//IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
611 |
//ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
612 |
//
|
613 |
// 16. Limitation of Liability.
|
614 |
//
|
615 |
// IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
616 |
//WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
617 |
//THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
618 |
//GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
619 |
//USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
620 |
//DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
621 |
//PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
622 |
//EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
623 |
//SUCH DAMAGES.
|
624 |
//
|
625 |
// 17. Interpretation of Sections 15 and 16.
|
626 |
//
|
627 |
// If the disclaimer of warranty and limitation of liability provided
|
628 |
//above cannot be given local legal effect according to their terms,
|
629 |
//reviewing courts shall apply local law that most closely approximates
|
630 |
//an absolute waiver of all civil liability in connection with the
|
631 |
//Program, unless a warranty or assumption of liability accompanies a
|
632 |
//copy of the Program in return for a fee.
|
633 |
//
|
634 |
// END OF TERMS AND CONDITIONS
|
635 |
//
|
636 |
// How to Apply These Terms to Your New Programs
|
637 |
//
|
638 |
// If you develop a new program, and you want it to be of the greatest
|
639 |
//possible use to the public, the best way to achieve this is to make it
|
640 |
//free software which everyone can redistribute and change under these terms.
|
641 |
//
|
642 |
// To do so, attach the following notices to the program. It is safest
|
643 |
//to attach them to the start of each source file to most effectively
|
644 |
//state the exclusion of warranty; and each file should have at least
|
645 |
//the "copyright" line and a pointer to where the full notice is found.
|
646 |
//
|
647 |
// <one line to give the program's name and a brief idea of what it does.>
|
648 |
// Copyright (C) <year> <name of author>
|
649 |
//
|
650 |
// This program is free software: you can redistribute it and/or modify
|
651 |
// it under the terms of the GNU General Public License as published by
|
652 |
// the Free Software Foundation, either version 3 of the License, or
|
653 |
// (at your option) any later version.
|
654 |
//
|
655 |
// This program is distributed in the hope that it will be useful,
|
656 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
657 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
658 |
// GNU General Public License for more details.
|
659 |
//
|
660 |
// You should have received a copy of the GNU General Public License
|
661 |
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
662 |
//
|
663 |
//Also add information on how to contact you by electronic and paper mail.
|
664 |
//
|
665 |
// If the program does terminal interaction, make it output a short
|
666 |
//notice like this when it starts in an interactive mode:
|
667 |
//
|
668 |
// <program> Copyright (C) <year> <name of author>
|
669 |
// This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
670 |
// This is free software, and you are welcome to redistribute it
|
671 |
// under certain conditions; type `show c' for details.
|
672 |
//
|
673 |
//The hypothetical commands `show w' and `show c' should show the appropriate
|
674 |
//parts of the General Public License. Of course, your program's commands
|
675 |
//might be different; for a GUI interface, you would use an "about box".
|
676 |
//
|
677 |
// You should also get your employer (if you work as a programmer) or school,
|
678 |
//if any, to sign a "copyright disclaimer" for the program, if necessary.
|
679 |
//For more information on this, and how to apply and follow the GNU GPL, see
|
680 |
//<http://www.gnu.org/licenses/>.
|
681 |
//
|
682 |
// The GNU General Public License does not permit incorporating your program
|
683 |
//into proprietary programs. If your program is a subroutine library, you
|
684 |
//may consider it more useful to permit linking proprietary applications with
|
685 |
//the library. If this is what you want to do, use the GNU Lesser General
|
686 |
//Public License instead of this License. But first, please read
|
687 |
//<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
688 |
//-------------------------------------------------------------------------------------------------
|
689 |
//--------------------------------------------------------------------------------
|
690 |
** Rational Approximation Software Submitted To CALGO To Accompany TOMS Paper
|
691 |
** Entitled "On Best Rational Approximations Using Large Integers"
|
692 |
** --------------------------------------------------------------------------
|
693 |
** Please see accompanying user's guide for invocation instructions.
|
694 |
*/
|
695 |
|
696 |
#include <process.h>
|
697 |
/* For the exit() function. */
|
698 |
|
699 |
#include <stdio.h>
|
700 |
/* printf() and similar functions require the stdio.h header file. */
|
701 |
|
702 |
#include <string.h>
|
703 |
/* String functions and memory manipulation functions defined there. */
|
704 |
|
705 |
#include <malloc.h>
|
706 |
/* Necessary for memory allocation functions. */
|
707 |
|
708 |
|
709 |
/* It wasn't straightforward to locate the file containing the constants TRUE
|
710 |
** and FALSE. Must define them myself.
|
711 |
*/
|
712 |
#ifndef FALSE
|
713 |
#define FALSE (0)
|
714 |
#endif
|
715 |
#ifndef TRUE
|
716 |
#define TRUE (1)
|
717 |
#endif
|
718 |
|
719 |
|
720 |
/* This source file is broken into segments, each
|
721 |
** containing a specific family of functions
|
722 |
** that operate on a specific data type, or at a
|
723 |
** specific level of abstraction. In C++, these
|
724 |
** would often tend to be made into classes (and
|
725 |
** this could be done here), but it is a more
|
726 |
** humane experience on anyone who would like to
|
727 |
** recompile the program to keep everything in a
|
728 |
** single source file.
|
729 |
**
|
730 |
** Functions are arranged from the bottom of the calling tree upward. This
|
731 |
** way, no function prototypes are needed to ensure the compiler will
|
732 |
** detect definitions and invocations which are inconsistent.
|
733 |
*/
|
734 |
|
735 |
/****************************************************************************/
|
736 |
/****************************************************************************/
|
737 |
/************* C O M P I L A T I O N C O N S T A N T S ***************/
|
738 |
/****************************************************************************/
|
739 |
/****************************************************************************/
|
740 |
/* Many aspects of the program's behavior can be changed by simply changing
|
741 |
** the constants below. Many of the values chosen below are intended to
|
742 |
** keep the software clear of platform-specific limits. Changes to the
|
743 |
** constants may cause unforeseen difficulties.
|
744 |
*/
|
745 |
#define MAX_CMDLINE_PARS (10)
|
746 |
/* The maximum number of command-line parameters that will be accepted.
|
747 |
** This is ultimately dependent on what the subcommands take, but
|
748 |
** 10 is a safe value, and let's me be lazy and not search to find the
|
749 |
** command that takes the most parameters.
|
750 |
*/
|
751 |
|
752 |
#define INPUT_INTEGER_MAX_DIGITS (463)
|
753 |
/* This value was chosen to allow operation in the Farey series of up to
|
754 |
** order 2**1536.
|
755 |
*/
|
756 |
#define INTERMEDIATE_CALC_MAX_DIGITS (4000)
|
757 |
/* This value wasn't chosen scientifically. It is just known that
|
758 |
** multiplying a 463-digit integer by another will result in at most
|
759 |
** a 926-digit result ... it would be quite difficult in the calculations
|
760 |
** outlined in the TOMS paper to reach the 4,000 digit limit. Note that
|
761 |
** this is also the limit for the size of the integer components of
|
762 |
** rational results.
|
763 |
*/
|
764 |
#define STDIN_MAX_CHARS (32000)
|
765 |
/* The maximum number of digits that may be read from the standard input
|
766 |
** if batch mode is selected.
|
767 |
*/
|
768 |
#define LINE_LEN (78)
|
769 |
/* The number of columns assumed to be displayable on the output.
|
770 |
** because a standard monitor (legacy) was 80 columns wide, I've chosen
|
771 |
** a value just a tad less.
|
772 |
*/
|
773 |
#define NUMBER_DESC_WIDTH (20)
|
774 |
/* The number of characters at the left reserved for describing a particular
|
775 |
** integer.
|
776 |
*/
|
777 |
#define DIGITS_PER_LINE (27)
|
778 |
/* The number of digits to be displayed per line for very long
|
779 |
** integers.
|
780 |
*/
|
781 |
#define HORIZONTAL_BAR_SEP_CHAR ('-')
|
782 |
/* The character used to form large horizontal separators.
|
783 |
*/
|
784 |
|
785 |
/****************************************************************************/
|
786 |
/****************************************************************************/
|
787 |
/********* V E R S I O N C O N T R O L F U N C T I O N S ***********/
|
788 |
/****************************************************************************/
|
789 |
/****************************************************************************/
|
790 |
|
791 |
/****************************************************************************/
|
792 |
/* vcGetVcData(): */
|
793 |
/*--------------------------------------------------------------------------*/
|
794 |
/* DESCRIPTION */
|
795 |
/* Returns the embedded version control information for this program, */
|
796 |
/* arranged as a sequence of lines to be displayed on an 80-column */
|
797 |
/* monitor. */
|
798 |
/* */
|
799 |
/* INPUTS */
|
800 |
/* n : Line number to return. The first line is number 0. */
|
801 |
/* */
|
802 |
/* OUTPUTS */
|
803 |
/* <--: Pointer to a constant character string to display on that line, */
|
804 |
/* or NULL if there are no more lines of version control */
|
805 |
/* information to display. */
|
806 |
/****************************************************************************/
|
807 |
const char *vcGetVcData(unsigned n)
|
808 |
{
|
809 |
const char *RAP_version_string_array[]
|
810 |
= {"$Revision: 1.1 $ $Date: 2001/09/25 21:44:55 $"};
|
811 |
/* Note that the info above is filled in automatically by Visual
|
812 |
** Source Safe on every check-in--this is not manually maintained.
|
813 |
*/
|
814 |
|
815 |
if (n < (sizeof(RAP_version_string_array)/sizeof(RAP_version_string_array[0])))
|
816 |
{
|
817 |
return(RAP_version_string_array[n]);
|
818 |
}
|
819 |
else
|
820 |
{
|
821 |
return(NULL);
|
822 |
}
|
823 |
}
|
824 |
|
825 |
|
826 |
/****************************************************************************/
|
827 |
/****************************************************************************/
|
828 |
/****** G E N E R A L F O R M A T T I N G F U N C T I O N S *******/
|
829 |
/****************************************************************************/
|
830 |
/****************************************************************************/
|
831 |
|
832 |
/****************************************************************************/
|
833 |
/* gfRepChar(): */
|
834 |
/*--------------------------------------------------------------------------*/
|
835 |
/* DESCRIPTION */
|
836 |
/* Repeats a character to stdout the specified number of times. */
|
837 |
/* */
|
838 |
/* INPUTS */
|
839 |
/* c : The character to repeat. */
|
840 |
/* */
|
841 |
/* n : The number of times to repeat it. */
|
842 |
/****************************************************************************/
|
843 |
void gfRepChar(char c, unsigned n)
|
844 |
{
|
845 |
while(n--)
|
846 |
printf("%c", c);
|
847 |
}
|
848 |
|
849 |
|
850 |
/****************************************************************************/
|
851 |
/* gfHline(): */
|
852 |
/*--------------------------------------------------------------------------*/
|
853 |
/* DESCRIPTION */
|
854 |
/* Dumps a horizontal line of the standard length to the standard output. */
|
855 |
/****************************************************************************/
|
856 |
void gfHline(void)
|
857 |
{
|
858 |
gfRepChar(HORIZONTAL_BAR_SEP_CHAR, LINE_LEN);
|
859 |
printf("\n");
|
860 |
}
|
861 |
|
862 |
|
863 |
/****************************************************************************/
|
864 |
/* gfBannerHeading(): */
|
865 |
/*--------------------------------------------------------------------------*/
|
866 |
/* DESCRIPTION */
|
867 |
/* Prints a banner heading bracketed by astreisks to the standard output. */
|
868 |
/* This function is useful for separating different sections of output. */
|
869 |
/****************************************************************************/
|
870 |
void gfBannerHeading(char *s, int n_extra_lines)
|
871 |
{
|
872 |
const int lr_padding = 3;
|
873 |
/* The number of spaces on each side of what is printed.
|
874 |
*/
|
875 |
int i;
|
876 |
/* General iteration variable.
|
877 |
*/
|
878 |
int n_asterisks;
|
879 |
int input_arg_len;
|
880 |
int n_left_spaces;
|
881 |
int n_right_spaces;
|
882 |
|
883 |
/* The order of the source deck prevents me from using the assertion
|
884 |
** function without function prototypes, and I don't like function
|
885 |
** prototypes, and I'm too lazy to move the functions, so I'll just
|
886 |
** protect against naughty parameters causing bizarre behavior.
|
887 |
*/
|
888 |
if (!s)
|
889 |
s = "";
|
890 |
if (n_extra_lines < 0)
|
891 |
n_extra_lines = 0;
|
892 |
|
893 |
/* Print the right number of solid lines of asterisks to the
|
894 |
** standard output.
|
895 |
*/
|
896 |
for (i=0; i<n_extra_lines; i++)
|
897 |
{
|
898 |
gfRepChar('*', LINE_LEN);
|
899 |
printf("\n");
|
900 |
}
|
901 |
|
902 |
/* Figure out how many asterisks to print on each side of the
|
903 |
** argument, and how many spaces. We also need to figure out
|
904 |
** how many characters of the input argument to print--if there
|
905 |
** are too many characters, we need to truncate.
|
906 |
*/
|
907 |
input_arg_len = strlen(s);
|
908 |
if(input_arg_len > (LINE_LEN - 2 * lr_padding - 2))
|
909 |
input_arg_len = LINE_LEN - 2 * lr_padding - 2;
|
910 |
|
911 |
n_asterisks = (LINE_LEN - 2*lr_padding - input_arg_len)/2;
|
912 |
|
913 |
n_left_spaces = lr_padding;
|
914 |
|
915 |
if ((LINE_LEN - 2*lr_padding - input_arg_len) % 2)
|
916 |
{
|
917 |
/* Odd, need to pad the right by one. */
|
918 |
n_right_spaces = lr_padding+1;
|
919 |
}
|
920 |
else
|
921 |
{
|
922 |
n_right_spaces = lr_padding;
|
923 |
}
|
924 |
|
925 |
/* Print the text. */
|
926 |
gfRepChar('*', n_asterisks);
|
927 |
gfRepChar(' ', n_left_spaces);
|
928 |
for (i=0; i<input_arg_len; i++)
|
929 |
printf("%c", s[i]);
|
930 |
gfRepChar(' ', n_right_spaces);
|
931 |
gfRepChar('*', n_asterisks);
|
932 |
printf("\n");
|
933 |
|
934 |
/* Print the right number of solid lines of asterisks to the
|
935 |
** standard output.
|
936 |
*/
|
937 |
for (i=0; i<n_extra_lines; i++)
|
938 |
{
|
939 |
gfRepChar('*', LINE_LEN);
|
940 |
printf("\n");
|
941 |
}
|
942 |
}
|
943 |
|
944 |
|
945 |
/****************************************************************************/
|
946 |
/****************************************************************************/
|
947 |
/******* L O G I C A L A S S E R T I O N F U N C T I O N S ********/
|
948 |
/****************************************************************************/
|
949 |
/****************************************************************************/
|
950 |
|
951 |
/****************************************************************************/
|
952 |
/* asAssert(): */
|
953 |
/*--------------------------------------------------------------------------*/
|
954 |
/* DESCRIPTION */
|
955 |
/* Terminates the program abnormally if the logical condition specified */
|
956 |
/* is false. Roughly speaking, this fills the same role as the */
|
957 |
/* C-language assert() macro. */
|
958 |
/* */
|
959 |
/* INPUTS */
|
960 |
/* c : The logical condition tested (or, more precisely, the result of */
|
961 |
/* the code inserted by the compiler to stuff this parameter). */
|
962 |
/* */
|
963 |
/* l : The line number on which the call to this function occurs. */
|
964 |
/* This is filled in by using a special preprocessor symbol. */
|
965 |
/****************************************************************************/
|
966 |
void asAssert(unsigned c, unsigned long l)
|
967 |
{
|
968 |
if (!c)
|
969 |
{
|
970 |
gfHline();
|
971 |
printf("Abnormal termination; Assertion failed, line: %lu.\n", l);
|
972 |
gfHline();
|
973 |
|
974 |
/* Now need to convince the 'C' runtime environment to kill us.
|
975 |
*/
|
976 |
exit(0);
|
977 |
}
|
978 |
}
|
979 |
|
980 |
|
981 |
/****************************************************************************/
|
982 |
/* asFatal(): */
|
983 |
/*--------------------------------------------------------------------------*/
|
984 |
/* DESCRIPTION */
|
985 |
/* Terminates the program with a fatal error message. */
|
986 |
/* */
|
987 |
/* INPUTS */
|
988 |
/* *msg: The message to use. Must be fairly short. */
|
989 |
/****************************************************************************/
|
990 |
void asFatal(const char *msg)
|
991 |
{
|
992 |
asAssert(msg != NULL, __LINE__);
|
993 |
|
994 |
gfHline();
|
995 |
printf("FATAL ERROR: %s.\n", msg);
|
996 |
gfHline();
|
997 |
|
998 |
/* Now need to convince the 'C' runtime environment to kill us.
|
999 |
*/
|
1000 |
exit(0);
|
1001 |
}
|
1002 |
|
1003 |
|
1004 |
/****************************************************************************/
|
1005 |
/* asInfo(): */
|
1006 |
/*--------------------------------------------------------------------------*/
|
1007 |
/* DESCRIPTION */
|
1008 |
/* Prints informational message to stdout and terminates the program. */
|
1009 |
/****************************************************************************/
|
1010 |
void asInfo(void)
|
1011 |
{
|
1012 |
static char *msglines[] =
|
1013 |
{
|
1014 |
"RAP.EXE: rational approximation calculation program.",
|
1015 |
"!",
|
1016 |
"Copyright 2001, The Association For Computing Machinery (www.acm.org),",
|
1017 |
"David T. Ashley (dtashley@aol.com), Joseph P. DeVoe (jdevoe@visteon.com),",
|
1018 |
"Cory Pratt (cory_pratt@3com.com), Karl Perttunen (kperttun@visteon.com),",
|
1019 |
"and Anatoly Zhigljavsky (zhigljavskyaa@cardiff.ac.uk).",
|
1020 |
"!",
|
1021 |
"Please submit any bug reports or inquiries to all of the e-mail addresses",
|
1022 |
"listed above.",
|
1023 |
"!",
|
1024 |
"This program accompanies a paper entitled \"On Best Rational",
|
1025 |
"Approximations Using Large Integers\" submitted to ACM TOMS in late 2000/",
|
1026 |
"early 2001. The paper fully documents the algorithms employed in this",
|
1027 |
"software. In a nutshell, this program will execute algorithms on very",
|
1028 |
"large integers (up to 463 digits) and rational numbers with very large",
|
1029 |
"integer components which are helpful in finding best rational",
|
1030 |
"approximations in Farey series of very large order and in large rectangular",
|
1031 |
"regions of the integer lattice. The source code for this program should",
|
1032 |
"be available from CALGO (collected algorithms of the ACM).",
|
1033 |
"!",
|
1034 |
"Format legend: MANDATORY_PARAMETER",
|
1035 |
" [OPTIONAL_PARAMETER]",
|
1036 |
" {a, b ...} = Exactly one must be chosen from set.",
|
1037 |
" i... = Integer",
|
1038 |
" i+... = Non-Negative Integer",
|
1039 |
" i++... = Positive Integer",
|
1040 |
" r... = Rational Number",
|
1041 |
" r+... = Non-Negative Rational Number",
|
1042 |
" r++... = Positive Rational Number",
|
1043 |
"!",
|
1044 |
"How to specify an integer:",
|
1045 |
" [-]<digits>",
|
1046 |
" <digits>.<more_digits>e[{-,+}]<exponent>",
|
1047 |
" where the exponent creates an integer. Example: 3.14e2 is an integer",
|
1048 |
" but 3.14e1 is not (the former is 314, the latter is 31.4). Note that",
|
1049 |
" an integer can be substituted for a rational number, but a rational",
|
1050 |
" number cannot always be substituted for an integer.",
|
1051 |
"!",
|
1052 |
"How to specify a rational number:",
|
1053 |
" [-]<digits>/<more_digits>",
|
1054 |
" [-]<digits>.<more_digits>[e[{-,+}]<exponent>]",
|
1055 |
"!",
|
1056 |
"RAP + i1 i2",
|
1057 |
" Adds two integers to produce an integer result. Result is i1 + i2.",
|
1058 |
"!",
|
1059 |
"RAP + r1 r2",
|
1060 |
" Adds two rational numbers to produce a rational or integral result.",
|
1061 |
" Result is r1 + r2.",
|
1062 |
"!",
|
1063 |
"RAP - i1 i2",
|
1064 |
" Subtracts two integers to produce an integer result. Result is i1 - i2.",
|
1065 |
"!",
|
1066 |
"RAP * i1 i2",
|
1067 |
" Multiplies two integers to produce an integer result. Result is i1 * i2.",
|
1068 |
"!",
|
1069 |
"RAP / i1 i2",
|
1070 |
" Divides two integers to produce an integer result. Result is i1 / i2.",
|
1071 |
"!",
|
1072 |
"RAP / r1 r2",
|
1073 |
" Divides two rational numbers to produce a rational or integral result.",
|
1074 |
" Result is r1 / r2.",
|
1075 |
"!",
|
1076 |
"RAP % i1 i2",
|
1077 |
" Divides two integers and produces the remainder from the division. The",
|
1078 |
" result is the same as i1 % i2 as defined by the 'C' programming language",
|
1079 |
" except that much longer integers are accomodated.",
|
1080 |
"!",
|
1081 |
"RAP ** i1 i2+",
|
1082 |
" Exponentiates the integer i1 to the i2+'th power.",
|
1083 |
"!",
|
1084 |
"RAP ** r1 i1+",
|
1085 |
" Exponentiates the rational number r1 to the i1+'th power.",
|
1086 |
"!",
|
1087 |
"RAP gcd i1++ i2++",
|
1088 |
" Calculates the greatest common divisor of i1 and i2 using Euclid's",
|
1089 |
" algorithm.",
|
1090 |
"!",
|
1091 |
"RAP dap r1 i1+",
|
1092 |
" Given rational number r1, forms a rational approximation with a",
|
1093 |
" different denominator i1. This functionality is very useful",
|
1094 |
" for converting a rational number to a more familiar decimal",
|
1095 |
" approximation. The accompanying user's manual gives full",
|
1096 |
" details about the formula used by the DAP command. DAP is also",
|
1097 |
" used by several other commands to provide a more familiar",
|
1098 |
" output form.",
|
1099 |
"!",
|
1100 |
"RAP cf r1+",
|
1101 |
" Forms the continued fraction partial quotients and convergents",
|
1102 |
" of a non-negative rational number r1.",
|
1103 |
"!",
|
1104 |
"RAP fn r1+ i1++",
|
1105 |
" Finds the two best neighboring rational approximations to non-negative",
|
1106 |
" rational number r1 in the Farey series of order i1.",
|
1107 |
"!",
|
1108 |
"RAP fn r1++ i1++ i2++ i3++",
|
1109 |
" Same as form above except finds i2 neighbors on either side of r1",
|
1110 |
" (rather than the default of 1), and uses i3 as the denominator for",
|
1111 |
" presenting the approximations and errors in decimal form.",
|
1112 |
"!",
|
1113 |
"RAP mind r1+ r2+",
|
1114 |
" Calculates a rational number in the interval [r1, r2] with the minimum",
|
1115 |
" denominator. If the rational number in the interval with the minimum",
|
1116 |
" denominator is not unique (i.e. there is more than one with the same ",
|
1117 |
" denominator), no assurances are made about which of the numbers with",
|
1118 |
" minimum denominator will be returned (however, it is assured that the",
|
1119 |
" result will be one of them).",
|
1120 |
"!",
|
1121 |
"RAP fab r1+ i1++ i2++",
|
1122 |
" Finds the two neighbors to r1 in a rectangular area of the integer",
|
1123 |
" lattice specified by h<=i1 and k<=i2. This is a similar concept to",
|
1124 |
" the \"fn\" command, but with numerator and denominator both constrained.",
|
1125 |
" On output, 4 lines of digits after the decimal point are assumed by",
|
1126 |
" default.",
|
1127 |
"!",
|
1128 |
"RAP fab r1+ i1++ i2++ i3++ i4++",
|
1129 |
" Same as form above, except optional parameters i3 and i4 specify the",
|
1130 |
" number of neighbors on both the left and right to generate, and the",
|
1131 |
" denominator to use for display of DAP information.",
|
1132 |
"!",
|
1133 |
"RAP fndmax r1+ r2+ i++",
|
1134 |
" Provides an upper bound on the distance between successive terms of",
|
1135 |
" the Farey series of order i in the interval [r1, r2]. It is required",
|
1136 |
" that r1 < r2 and that r1 and r2 are both in the Farey series of order",
|
1137 |
" i.",
|
1138 |
"!",
|
1139 |
"RAP fndmax r1+ r2+ i++ j++",
|
1140 |
" Same as form above except j may override the default denominator of",
|
1141 |
" 1e108 for DAP presentation.",
|
1142 |
"!",
|
1143 |
"RAP fabdmax r1+ r2+ i1+ i2+",
|
1144 |
" Provides an upper bound on the distance between successive terms of",
|
1145 |
" the \"rectangular\" Farey series (doubly-constrained) with h <= i1 and",
|
1146 |
" j <= i2 in the interval [r1, r2]. It is required that r1 < r2 and that",
|
1147 |
" both meet the constraints (i.e. are in the \"rectangular\" series).",
|
1148 |
"!",
|
1149 |
"RAP fabdmax r1+ r2+ i1+ i2+ j++",
|
1150 |
" Same as form above except j may override the default denominator of 1e108",
|
1151 |
" for DAP presentation.",
|
1152 |
"!",
|
1153 |
"If this information has scrolled off the screen and can't be read, try re-",
|
1154 |
"directing it to a file (for example, RAP >OUT.TXT) and then viewing the file",
|
1155 |
"with a text editor, or piping it through \"more\" (for example, RAP|MORE).",
|
1156 |
"!"
|
1157 |
};
|
1158 |
|
1159 |
int i;
|
1160 |
|
1161 |
/* Dump out the whole array and terminate the program. Lines beginning
|
1162 |
** with an exclamation point should be replaced with a horizontal line.
|
1163 |
*/
|
1164 |
for (i=0; i<sizeof(msglines)/sizeof(msglines[0]); i++)
|
1165 |
{
|
1166 |
if ((msglines[i])[0] == '!')
|
1167 |
{
|
1168 |
gfHline();
|
1169 |
}
|
1170 |
else
|
1171 |
{
|
1172 |
printf("%s\n", msglines[i]);
|
1173 |
}
|
1174 |
}
|
1175 |
|
1176 |
exit(0);
|
1177 |
}
|
1178 |
|
1179 |
|
1180 |
|
1181 |
/****************************************************************************/
|
1182 |
/****************************************************************************/
|
1183 |
/*************** D A T A - D R I V E N F U N C T I O N S *************/
|
1184 |
/****************************************************************************/
|
1185 |
/****************************************************************************/
|
1186 |
/* This section is reserved for data-driven functions with no I/O
|
1187 |
** requirements and no side-effects.
|
1188 |
*/
|
1189 |
/****************************************************************************/
|
1190 |
/* ddCharToLower(): */
|
1191 |
/*--------------------------------------------------------------------------*/
|
1192 |
/* DESCRIPTION */
|
1193 |
/* If a character is upper-case, translates it to lower-case. */
|
1194 |
/****************************************************************************/
|
1195 |
char ddCharToLower(char c)
|
1196 |
{
|
1197 |
switch(c)
|
1198 |
{
|
1199 |
case 'A' : return ('a');
|
1200 |
break;
|
1201 |
case 'B' : return ('b');
|
1202 |
break;
|
1203 |
case 'C' : return ('c');
|
1204 |
break;
|
1205 |
case 'D' : return ('d');
|
1206 |
break;
|
1207 |
case 'E' : return ('e');
|
1208 |
break;
|
1209 |
case 'F' : return ('f');
|
1210 |
break;
|
1211 |
case 'G' : return ('g');
|
1212 |
break;
|
1213 |
case 'H' : return ('h');
|
1214 |
break;
|
1215 |
case 'I' : return ('i');
|
1216 |
break;
|
1217 |
case 'J' : return ('j');
|
1218 |
break;
|
1219 |
case 'K' : return ('k');
|
1220 |
break;
|
1221 |
case 'L' : return ('l');
|
1222 |
break;
|
1223 |
case 'M' : return ('m');
|
1224 |
break;
|
1225 |
case 'N' : return ('n');
|
1226 |
break;
|
1227 |
case 'O' : return ('o');
|
1228 |
break;
|
1229 |
case 'P' : return ('p');
|
1230 |
break;
|
1231 |
case 'Q' : return ('q');
|
1232 |
break;
|
1233 |
case 'R' : return ('r');
|
1234 |
break;
|
1235 |
case 'S' : return ('s');
|
1236 |
break;
|
1237 |
case 'T' : return ('t');
|
1238 |
break;
|
1239 |
case 'U' : return ('u');
|
1240 |
break;
|
1241 |
case 'V' : return ('v');
|
1242 |
break;
|
1243 |
case 'W' : return ('w');
|
1244 |
break;
|
1245 |
case 'X' : return ('x');
|
1246 |
break;
|
1247 |
case 'Y' : return ('y');
|
1248 |
break;
|
1249 |
case 'Z' : return ('z');
|
1250 |
break;
|
1251 |
default: return(c);
|
1252 |
break;
|
1253 |
}
|
1254 |
}
|
1255 |
|
1256 |
|
1257 |
/****************************************************************************/
|
1258 |
/* ddIsInfoChar(): */
|
1259 |
/*--------------------------------------------------------------------------*/
|
1260 |
/* DESCRIPTION */
|
1261 |
/* Returns TRUE if the passed character is a character that should be in */
|
1262 |
/* a token, or FALSE otherwise. */
|
1263 |
/****************************************************************************/
|
1264 |
unsigned ddIsInfoChar(char c)
|
1265 |
{
|
1266 |
int i;
|
1267 |
char d;
|
1268 |
const char CONST_info_characters[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
1269 |
'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
1270 |
'o', 'p', 'q', 'r', 's', 't', 'u',
|
1271 |
'v', 'w', 'x', 'y', 'z', '0', '1',
|
1272 |
'2', '3', '4', '5', '6', '7', '8',
|
1273 |
'9', '+', '-', '*', '/', '_', '.',
|
1274 |
'\\','%' };
|
1275 |
|
1276 |
d = ddCharToLower(c);
|
1277 |
|
1278 |
for (i=0; i<sizeof(CONST_info_characters)/sizeof(CONST_info_characters[0]); i++)
|
1279 |
{
|
1280 |
if (CONST_info_characters[i] == d)
|
1281 |
return(TRUE);
|
1282 |
}
|
1283 |
|
1284 |
return(FALSE);
|
1285 |
}
|
1286 |
|
1287 |
|
1288 |
/****************************************************************************/
|
1289 |
/* ddIsDiscardChar(): */
|
1290 |
/*--------------------------------------------------------------------------*/
|
1291 |
/* DESCRIPTION */
|
1292 |
/* Returns TRUE if the passed character is a character that should be */
|
1293 |
/* discarded, or FALSE otherwise. */
|
1294 |
/****************************************************************************/
|
1295 |
unsigned ddIsDiscardChar(char c)
|
1296 |
{
|
1297 |
int i;
|
1298 |
char d;
|
1299 |
const char CONST_discard_characters[] = {','};
|
1300 |
|
1301 |
d = ddCharToLower(c);
|
1302 |
|
1303 |
for (i=0; i<sizeof(CONST_discard_characters)/sizeof(CONST_discard_characters[0]); i++)
|
1304 |
{
|
1305 |
if (CONST_discard_characters[i] == d)
|
1306 |
return(TRUE);
|
1307 |
}
|
1308 |
|
1309 |
return(FALSE);
|
1310 |
}
|
1311 |
|
1312 |
|
1313 |
/****************************************************************************/
|
1314 |
/* ddIsWhitespaceChar(): */
|
1315 |
/*--------------------------------------------------------------------------*/
|
1316 |
/* DESCRIPTION */
|
1317 |
/* Returns TRUE if the passed character is a character that should be */
|
1318 |
/* treated as whitespace, or FALSE otherwise. */
|
1319 |
/****************************************************************************/
|
1320 |
unsigned ddIsWhitespaceChar(char c)
|
1321 |
{
|
1322 |
int i;
|
1323 |
char d;
|
1324 |
const char CONST_whitespace_chars[] = { ' ', '\t', '\n' };
|
1325 |
|
1326 |
d = ddCharToLower(c);
|
1327 |
|
1328 |
for (i=0; i<sizeof(CONST_whitespace_chars)/sizeof(CONST_whitespace_chars[0]); i++)
|
1329 |
{
|
1330 |
if (CONST_whitespace_chars[i] == d)
|
1331 |
return(TRUE);
|
1332 |
}
|
1333 |
|
1334 |
return(FALSE);
|
1335 |
}
|
1336 |
|
1337 |
|
1338 |
/****************************************************************************/
|
1339 |
/* ddIsDigit(): */
|
1340 |
/*--------------------------------------------------------------------------*/
|
1341 |
/* DESCRIPTION */
|
1342 |
/* Returns TRUE if the passed argument is a digit, or FALSE otherwise. */
|
1343 |
/* */
|
1344 |
/* INPUTS */
|
1345 |
/* c : Character to evaluate for digitness (or is that digiality??). */
|
1346 |
/* */
|
1347 |
/* OUTPUTS */
|
1348 |
/* <--: TRUE if a digit, FALSE otherwise. */
|
1349 |
/****************************************************************************/
|
1350 |
unsigned ddIsDigit(char c)
|
1351 |
{
|
1352 |
if ((c >= '0') && (c <= '9'))
|
1353 |
return(TRUE);
|
1354 |
else
|
1355 |
return(FALSE);
|
1356 |
}
|
1357 |
|
1358 |
|
1359 |
/****************************************************************************/
|
1360 |
/* ddDigitToValue(): */
|
1361 |
/*--------------------------------------------------------------------------*/
|
1362 |
/* DESCRIPTION */
|
1363 |
/* Converts from ASCII digit to unsigned integer value. Fatal to call */
|
1364 |
/* with non-digit. */
|
1365 |
/* */
|
1366 |
/* INPUTS */
|
1367 |
/* c : Character to convert to value. */
|
1368 |
/* */
|
1369 |
/* OUTPUTS */
|
1370 |
/* <--: Value. */
|
1371 |
/****************************************************************************/
|
1372 |
unsigned ddDigitToValue(char c)
|
1373 |
{
|
1374 |
if ((c >= '0') && (c <= '9'))
|
1375 |
{
|
1376 |
return(c - '0');
|
1377 |
}
|
1378 |
else
|
1379 |
{
|
1380 |
asAssert(0, __LINE__); /* Guaranteed fatal. */
|
1381 |
return(0); /* To satisfy compiler warning about path not
|
1382 |
** returning a value.
|
1383 |
*/
|
1384 |
}
|
1385 |
}
|
1386 |
|
1387 |
|
1388 |
/****************************************************************************/
|
1389 |
/* ddValueToDigit(): */
|
1390 |
/*--------------------------------------------------------------------------*/
|
1391 |
/* DESCRIPTION */
|
1392 |
/* Converts from unsigned value to digit '0'..'9'. Fatal to call with */
|
1393 |
/* with value out of range. */
|
1394 |
/* */
|
1395 |
/* INPUTS */
|
1396 |
/* i : Character to convert to value. */
|
1397 |
/* */
|
1398 |
/* OUTPUTS */
|
1399 |
/* <--: Value. */
|
1400 |
/****************************************************************************/
|
1401 |
char ddValueToDigit(unsigned i)
|
1402 |
{
|
1403 |
if (i < 10)
|
1404 |
{
|
1405 |
return(i + '0');
|
1406 |
}
|
1407 |
else
|
1408 |
{
|
1409 |
asAssert(0, __LINE__); /* Guaranteed fatal. */
|
1410 |
return('0'); /* To satisfy compiler warning about path not
|
1411 |
** returning a value.
|
1412 |
*/
|
1413 |
}
|
1414 |
}
|
1415 |
|
1416 |
|
1417 |
/****************************************************************************/
|
1418 |
/* ddStringContains(): */
|
1419 |
/*--------------------------------------------------------------------------*/
|
1420 |
/* DESCRIPTION */
|
1421 |
/* Determines whether STR1 contains any characters in STR2, and returns */
|
1422 |
/* TRUE if so or FALSE otherwise. */
|
1423 |
/****************************************************************************/
|
1424 |
int ddStringContains(const char *str1, const char *str2)
|
1425 |
{
|
1426 |
unsigned s1len, s2len;
|
1427 |
unsigned i, j;
|
1428 |
|
1429 |
asAssert(str1 != NULL, __LINE__);
|
1430 |
asAssert(str2 != NULL, __LINE__);
|
1431 |
|
1432 |
s1len = strlen(str1);
|
1433 |
s2len = strlen(str2);
|
1434 |
|
1435 |
for (i=0; i<s1len; i++)
|
1436 |
{
|
1437 |
for (j=0; j<s2len; j++)
|
1438 |
{
|
1439 |
if (str1[i] == str2[j])
|
1440 |
return(TRUE);
|
1441 |
}
|
1442 |
}
|
1443 |
|
1444 |
return(FALSE);
|
1445 |
}
|
1446 |
|
1447 |
|
1448 |
/****************************************************************************/
|
1449 |
/* ddStringContainsOnly(): */
|
1450 |
/*--------------------------------------------------------------------------*/
|
1451 |
/* DESCRIPTION */
|
1452 |
/* Returns TRUE if STR1 contains ONLY characters from STR2, or FALSE */
|
1453 |
/* otherwise. */
|
1454 |
/****************************************************************************/
|
1455 |
int ddStringContainsOnly(const char *str1, const char *str2)
|
1456 |
{
|
1457 |
int i, j;
|
1458 |
int l1, l2;
|
1459 |
|
1460 |
asAssert(str1 != NULL, __LINE__);
|
1461 |
asAssert(str2 != NULL, __LINE__);
|
1462 |
|
1463 |
l1 = strlen(str1);
|
1464 |
l2 = strlen(str2);
|
1465 |
|
1466 |
for (i=0; i<l1; i++)
|
1467 |
{
|
1468 |
for (j=0; j<l2; j++)
|
1469 |
{
|
1470 |
if (str1[i] == str2[j])
|
1471 |
break;
|
1472 |
}
|
1473 |
|
1474 |
if (j == l2)
|
1475 |
return(FALSE);
|
1476 |
}
|
1477 |
|
1478 |
return(TRUE);
|
1479 |
}
|
1480 |
|
1481 |
|
1482 |
/****************************************************************************/
|
1483 |
/* ddStringReverse(): */
|
1484 |
/*--------------------------------------------------------------------------*/
|
1485 |
/* DESCRIPTION */
|
1486 |
/* Reverses the order of characters in the string s. */
|
1487 |
/****************************************************************************/
|
1488 |
void ddStringReverse(char *s)
|
1489 |
{
|
1490 |
unsigned l;
|
1491 |
unsigned i;
|
1492 |
unsigned limit;
|
1493 |
char temp;
|
1494 |
|
1495 |
asAssert(s != NULL, __LINE__);
|
1496 |
|
1497 |
l = strlen(s);
|
1498 |
limit = l / 2;
|
1499 |
|
1500 |
for (i=0; i<limit; i++)
|
1501 |
{
|
1502 |
temp = s[i];
|
1503 |
s[i] = s[l-i-1];
|
1504 |
s[l-i-1] = temp;
|
1505 |
}
|
1506 |
}
|
1507 |
|
1508 |
|
1509 |
/****************************************************************************/
|
1510 |
/* ddStringDeleteLeadingChar(): */
|
1511 |
/*--------------------------------------------------------------------------*/
|
1512 |
/* DESCRIPTION */
|
1513 |
/* Deletes the leading character of a string. If there is no leading */
|
1514 |
/* character, takes no action. */
|
1515 |
/****************************************************************************/
|
1516 |
void ddStringDeleteLeadingChar(char *s)
|
1517 |
{
|
1518 |
int len;
|
1519 |
int i;
|
1520 |
|
1521 |
asAssert(s != NULL, __LINE__);
|
1522 |
|
1523 |
len = strlen(s);
|
1524 |
|
1525 |
for (i=0; i<len; i++)
|
1526 |
s[i] = s[i+1];
|
1527 |
}
|
1528 |
|
1529 |
|
1530 |
/****************************************************************************/
|
1531 |
/* ddFundamentalAdditionCell(): */
|
1532 |
/*--------------------------------------------------------------------------*/
|
1533 |
/* DESCRIPTION */
|
1534 |
/* Fundamental cell of addition, used to add one ASCII digit to another */
|
1535 |
/* ASCII digit, processing carries in and carries out. Unexpected values */
|
1536 |
/* will generate a fatal error. */
|
1537 |
/* */
|
1538 |
/* INPUTS */
|
1539 |
/* digit1: Digit 1 in. */
|
1540 |
/* digit2: Digit 2 in. */
|
1541 |
/* carry_in: Carry in. Must be '0' or '1'. */
|
1542 |
/* */
|
1543 |
/* OUTPUTS */
|
1544 |
/* *digit_out: Digit result out. */
|
1545 |
/* *carry_out: Carry out. Will be '0' or '1'. */
|
1546 |
/****************************************************************************/
|
1547 |
void ddFundamentalAdditionCell(char digit1,
|
1548 |
char digit2,
|
1549 |
char carry_in,
|
1550 |
char *digit_out,
|
1551 |
char *carry_out)
|
1552 |
{
|
1553 |
unsigned vd1;
|
1554 |
unsigned vd2;
|
1555 |
unsigned vci;
|
1556 |
unsigned total;
|
1557 |
|
1558 |
asAssert(ddIsDigit(digit1), __LINE__);
|
1559 |
asAssert(ddIsDigit(digit2), __LINE__);
|
1560 |
asAssert(ddDigitToValue(carry_in) <= 1, __LINE__);
|
1561 |
asAssert(digit_out != NULL, __LINE__);
|
1562 |
asAssert(carry_out != NULL, __LINE__);
|
1563 |
|
1564 |
vd1 = ddDigitToValue(digit1);
|
1565 |
vd2 = ddDigitToValue(digit2);
|
1566 |
vci = ddDigitToValue(carry_in);
|
1567 |
|
1568 |
total = vd1+vd2+vci;
|
1569 |
|
1570 |
*digit_out = ddValueToDigit(total % 10);
|
1571 |
*carry_out = ddValueToDigit(total / 10);
|
1572 |
}
|
1573 |
|
1574 |
|
1575 |
/****************************************************************************/
|
1576 |
/* ddFundamentalMultiplicationCell(): */
|
1577 |
/*--------------------------------------------------------------------------*/
|
1578 |
/* DESCRIPTION */
|
1579 |
/* Fundamental cell of multiplication, used to multiply one ASCII digit */
|
1580 |
/* by another, processing carries in and out. Unexpected inputs will */
|
1581 |
/* generate a fatal error. */
|
1582 |
/* */
|
1583 |
/* INPUTS */
|
1584 |
/* digit1: Digit 1 in. */
|
1585 |
/* digit2: Digit 2 in. */
|
1586 |
/* carry_in: Carry in. Because of the way multiplication works, */
|
1587 |
/* this must always be from '0' through '8'. */
|
1588 |
/* */
|
1589 |
/* OUTPUTS */
|
1590 |
/* *digit_out: Digit result out. */
|
1591 |
/* *carry_out: Carry out. Because of the way multiplication works, */
|
1592 |
/* this must always be from '0' through '8'. */
|
1593 |
/****************************************************************************/
|
1594 |
void ddFundamentalMultiplicationCell(char digit1,
|
1595 |
char digit2,
|
1596 |
char carry_in,
|
1597 |
char *digit_out,
|
1598 |
char *carry_out)
|
1599 |
{
|
1600 |
unsigned vd1;
|
1601 |
unsigned vd2;
|
1602 |
unsigned vci;
|
1603 |
unsigned total;
|
1604 |
|
1605 |
asAssert(ddIsDigit(digit1), __LINE__);
|
1606 |
asAssert(ddIsDigit(digit2), __LINE__);
|
1607 |
asAssert(ddDigitToValue(carry_in) <= 8, __LINE__);
|
1608 |
asAssert(digit_out != NULL, __LINE__);
|
1609 |
asAssert(carry_out != NULL, __LINE__);
|
1610 |
|
1611 |
vd1 = ddDigitToValue(digit1);
|
1612 |
vd2 = ddDigitToValue(digit2);
|
1613 |
vci = ddDigitToValue(carry_in);
|
1614 |
|
1615 |
total = (vd1 * vd2) + vci;
|
1616 |
|
1617 |
*digit_out = ddValueToDigit(total % 10);
|
1618 |
*carry_out = ddValueToDigit(total / 10);
|
1619 |
}
|
1620 |
|
1621 |
|
1622 |
/****************************************************************************/
|
1623 |
/* ddFundamentalSubtractionCell(): */
|
1624 |
/*--------------------------------------------------------------------------*/
|
1625 |
/* DESCRIPTION */
|
1626 |
/* Fundamental cell of subtraction, used to subtract one ASCII digit from */
|
1627 |
/* another ASCII digit, processing borrows in and borrows out. */
|
1628 |
/* Unexpected values will generate a fatal error. */
|
1629 |
/* */
|
1630 |
/* INPUTS */
|
1631 |
/* digit1: Digit 1 in. */
|
1632 |
/* digit2: Digit 2 in. */
|
1633 |
/* borrow_in: Borrow in. Must be '0' or '1'. */
|
1634 |
/* */
|
1635 |
/* OUTPUTS */
|
1636 |
/* *digit_out: Digit result out, digit1-digit2-borrow_in. */
|
1637 |
/* *borrow_out: Borrow out. Will be '0' or '1'. */
|
1638 |
/****************************************************************************/
|
1639 |
void ddFundamentalSubtractionCell(char digit1,
|
1640 |
char digit2,
|
1641 |
char borrow_in,
|
1642 |
char *digit_out,
|
1643 |
char *borrow_out)
|
1644 |
{
|
1645 |
unsigned vd1;
|
1646 |
unsigned vd2;
|
1647 |
unsigned vbi;
|
1648 |
unsigned total;
|
1649 |
|
1650 |
asAssert(ddIsDigit(digit1), __LINE__);
|
1651 |
asAssert(ddIsDigit(digit2), __LINE__);
|
1652 |
asAssert(ddDigitToValue(borrow_in) <= 1, __LINE__);
|
1653 |
asAssert(digit_out != NULL, __LINE__);
|
1654 |
asAssert(borrow_out != NULL, __LINE__);
|
1655 |
|
1656 |
vd1 = ddDigitToValue(digit1);
|
1657 |
vd2 = ddDigitToValue(digit2);
|
1658 |
vbi = ddDigitToValue(borrow_in);
|
1659 |
|
1660 |
total = 10+vd1-vd2-vbi;
|
1661 |
|
1662 |
*digit_out = ddValueToDigit(total % 10);
|
1663 |
if (total < 10)
|
1664 |
{
|
1665 |
*borrow_out = '1';
|
1666 |
/* If we went neggy neggy on the subtraction, we need a borrow.
|
1667 |
*/
|
1668 |
}
|
1669 |
else
|
1670 |
{
|
1671 |
*borrow_out = '0'; /* No borrow. */
|
1672 |
}
|
1673 |
}
|
1674 |
|
1675 |
|
1676 |
/****************************************************************************/
|
1677 |
/* ddUmin(): */
|
1678 |
/*--------------------------------------------------------------------------*/
|
1679 |
/* DESCRIPTION */
|
1680 |
/* Returns the minimum of two unsigned integers. */
|
1681 |
/* */
|
1682 |
/* INPUTS */
|
1683 |
/* arg1, arg2 : Unsigned integers to compare. */
|
1684 |
/* */
|
1685 |
/* OUTPUTS */
|
1686 |
/* <-- : Samller of arg1, arg2. */
|
1687 |
/****************************************************************************/
|
1688 |
unsigned ddUmin(unsigned arg1, unsigned arg2)
|
1689 |
{
|
1690 |
if (arg1 < arg2)
|
1691 |
return(arg1);
|
1692 |
else
|
1693 |
return(arg2);
|
1694 |
}
|
1695 |
|
1696 |
|
1697 |
|
1698 |
/****************************************************************************/
|
1699 |
/* ddUmax(): */
|
1700 |
/*--------------------------------------------------------------------------*/
|
1701 |
/* DESCRIPTION */
|
1702 |
/* Returns the maximum of two unsigned integers. */
|
1703 |
/* */
|
1704 |
/* INPUTS */
|
1705 |
/* arg1, arg2 : Unsigned integers to compare. */
|
1706 |
/* */
|
1707 |
/* OUTPUTS */
|
1708 |
/* <-- : Larger of arg1, arg2. */
|
1709 |
/****************************************************************************/
|
1710 |
unsigned ddUmax(unsigned arg1, unsigned arg2)
|
1711 |
{
|
1712 |
if (arg1 > arg2)
|
1713 |
return(arg1);
|
1714 |
else
|
1715 |
return(arg2);
|
1716 |
}
|
1717 |
|
1718 |
|
1719 |
/****************************************************************************/
|
1720 |
/* ddSmin(): */
|
1721 |
/*--------------------------------------------------------------------------*/
|
1722 |
/* DESCRIPTION */
|
1723 |
/* Returns the minimum of two signed integers. */
|
1724 |
/* */
|
1725 |
/* INPUTS */
|
1726 |
/* arg1, arg2 : Signed integers to compare. */
|
1727 |
/* */
|
1728 |
/* OUTPUTS */
|
1729 |
/* <-- : Samller of arg1, arg2. */
|
1730 |
/****************************************************************************/
|
1731 |
int ddSmin(int arg1, int arg2)
|
1732 |
{
|
1733 |
if (arg1 < arg2)
|
1734 |
return(arg1);
|
1735 |
else
|
1736 |
return(arg2);
|
1737 |
}
|
1738 |
|
1739 |
|
1740 |
|
1741 |
/****************************************************************************/
|
1742 |
/* ddSmax(): */
|
1743 |
/*--------------------------------------------------------------------------*/
|
1744 |
/* DESCRIPTION */
|
1745 |
/* Returns the maximum of two signed integer. */
|
1746 |
/* */
|
1747 |
/* INPUTS */
|
1748 |
/* arg1, arg2 : Signed integers to compare. */
|
1749 |
/* */
|
1750 |
/* OUTPUTS */
|
1751 |
/* <-- : Larger of arg1, arg2. */
|
1752 |
/****************************************************************************/
|
1753 |
int ddSmax(int arg1, int arg2)
|
1754 |
{
|
1755 |
if (arg1 > arg2)
|
1756 |
return(arg1);
|
1757 |
else
|
1758 |
return(arg2);
|
1759 |
}
|
1760 |
|
1761 |
|
1762 |
/****************************************************************************/
|
1763 |
/****************************************************************************/
|
1764 |
/******* M E M O R Y A L L O C A T I O N F U N C T I O N S ********/
|
1765 |
/****************************************************************************/
|
1766 |
/****************************************************************************/
|
1767 |
/* These functions are primarily wrappers for the standard 'C' library
|
1768 |
** functions. They will trap "out of memory" errors, and also provide a
|
1769 |
** place to insert debugging code if it becomes necessary.
|
1770 |
*/
|
1771 |
/****************************************************************************/
|
1772 |
/* maMalloc(): */
|
1773 |
/*--------------------------------------------------------------------------*/
|
1774 |
/* DESCRIPTION */
|
1775 |
/* Wrapper for malloc(). See malloc() documentation. */
|
1776 |
/****************************************************************************/
|
1777 |
void *maMalloc(size_t n)
|
1778 |
{
|
1779 |
void *rv;
|
1780 |
|
1781 |
rv = malloc(n);
|
1782 |
|
1783 |
asAssert(rv != NULL, __LINE__);
|
1784 |
|
1785 |
return(rv);
|
1786 |
}
|
1787 |
|
1788 |
|
1789 |
/****************************************************************************/
|
1790 |
/* maFree(): */
|
1791 |
/*--------------------------------------------------------------------------*/
|
1792 |
/* DESCRIPTION */
|
1793 |
/* Wrapper for free(). See free() documentation. */
|
1794 |
/****************************************************************************/
|
1795 |
void maFree(void *p)
|
1796 |
{
|
1797 |
asAssert(p != NULL, __LINE__);
|
1798 |
|
1799 |
free(p);
|
1800 |
}
|
1801 |
|
1802 |
|
1803 |
/****************************************************************************/
|
1804 |
/* maRealloc(): */
|
1805 |
/*--------------------------------------------------------------------------*/
|
1806 |
/* DESCRIPTION */
|
1807 |
/* Wrapper for realloc(). See realloc() documentation. */
|
1808 |
/****************************************************************************/
|
1809 |
void *maRealloc(void *ptr, size_t n)
|
1810 |
{
|
1811 |
void *rv;
|
1812 |
|
1813 |
rv = realloc(ptr, n);
|
1814 |
|
1815 |
asAssert(rv != NULL, __LINE__);
|
1816 |
|
1817 |
return(rv);
|
1818 |
}
|
1819 |
|
1820 |
|
1821 |
/****************************************************************************/
|
1822 |
/****************************************************************************/
|
1823 |
/******* S Y N T H E T I C I N T E G E R F U N C T I O N S ********/
|
1824 |
/****************************************************************************/
|
1825 |
/****************************************************************************/
|
1826 |
/* Definition of a synthetic integer.
|
1827 |
*/
|
1828 |
struct synthetic_integer_struct
|
1829 |
{
|
1830 |
unsigned nan;
|
1831 |
/* Boolean variable used to remember errors that render the integer
|
1832 |
** as "non a number", so that its value is invalid or unknown.
|
1833 |
** NAN's propagate so that performing any operating involving a NAN
|
1834 |
** also yields a NAN. A non-zero value here means that an error has
|
1835 |
** been thrown and the synthetic integer is invalid.
|
1836 |
*/
|
1837 |
unsigned neg;
|
1838 |
/* Only the absolute value of the integer is stored as a character
|
1839 |
** string. This boolean remembers if the number is negative.
|
1840 |
** A non-zero value here means the integer is negative. This may have
|
1841 |
** either value when the value of zero is represented by the
|
1842 |
** synthetic integer.
|
1843 |
*/
|
1844 |
unsigned len;
|
1845 |
/* The number of characters in the string representing the integer.
|
1846 |
** This is the same as would be returned by strlen(). This field
|
1847 |
** is maintained to avoid the expense of counting characters before
|
1848 |
** the terminator each time the length is needed.
|
1849 |
*/
|
1850 |
unsigned char digits[INTERMEDIATE_CALC_MAX_DIGITS + 1];
|
1851 |
/* The string representing the synthetic integer. To avoid the need
|
1852 |
** to move large blocks of characters, the integer is stored with the
|
1853 |
** least significant digits first. The string must be \0 terminated--
|
1854 |
** this is done primarily to make printing things for debugging
|
1855 |
** easier, although the terminator is redundant with the "len" field
|
1856 |
** above. The valid representation of zero is a "len" field of
|
1857 |
** zero and a terminating \0 as element [0] here. No commas or other
|
1858 |
** characters besides digits are allowed.
|
1859 |
*/
|
1860 |
};
|
1861 |
|
1862 |
|
1863 |
typedef struct synthetic_integer_struct SYNTHETIC_INTEGER;
|
1864 |
/* Typedef for more compact reference to data type.
|
1865 |
*/
|
1866 |
|
1867 |
|
1868 |
/****************************************************************************/
|
1869 |
/* siCreate(): */
|
1870 |
/*--------------------------------------------------------------------------*/
|
1871 |
/* DESCRIPTION */
|
1872 |
/* Creates a synthetic integer (allocates the memory and initializes) and */
|
1873 |
/* sets value to zero. */
|
1874 |
/* */
|
1875 |
/* INPUTS */
|
1876 |
/* *i : Pointer to pointer to synthetic integer. The caller's pointer */
|
1877 |
/* will be filled in to point to the allocated object. */
|
1878 |
/****************************************************************************/
|
1879 |
void siCreate(SYNTHETIC_INTEGER **i)
|
1880 |
{
|
1881 |
asAssert(i != NULL, __LINE__);
|
1882 |
/* Input pointer may not be NULL.
|
1883 |
*/
|
1884 |
|
1885 |
*i = maMalloc(sizeof(SYNTHETIC_INTEGER));
|
1886 |
/* Allocate the memory, stuff the pointer in the caller's
|
1887 |
** area.
|
1888 |
*/
|
1889 |
|
1890 |
/* Initialize the synthetic integer to what is required for
|
1891 |
** the number zero.
|
1892 |
*/
|
1893 |
(*i)->nan = 0;
|
1894 |
(*i)->neg = 0;
|
1895 |
(*i)->len = 0;
|
1896 |
(*i)->digits[0] = 0;
|
1897 |
}
|
1898 |
|
1899 |
|
1900 |
/****************************************************************************/
|
1901 |
/* siDestroy(): */
|
1902 |
/*--------------------------------------------------------------------------*/
|
1903 |
/* DESCRIPTION */
|
1904 |
/* Destroys a synthetic integer (deallocates the memory and sets the */
|
1905 |
/* caller's pointer to NULL. */
|
1906 |
/* */
|
1907 |
/* INPUTS */
|
1908 |
/* *i : Pointer to pointer to synthetic integer. The synthetic integer */
|
1909 |
/* will be destroyed and the caller's pointer will be filled to */
|
1910 |
/* NULL. */
|
1911 |
/****************************************************************************/
|
1912 |
void siDestroy(SYNTHETIC_INTEGER **i)
|
1913 |
{
|
1914 |
asAssert(i != NULL, __LINE__);
|
1915 |
/* Input pointer to pointer may not be NULL.
|
1916 |
*/
|
1917 |
asAssert(*i != NULL, __LINE__);
|
1918 |
/* Input pointer to block of memory may not be NULL.
|
1919 |
*/
|
1920 |
|
1921 |
maFree(*i);
|
1922 |
/* Deallocate block of memory.
|
1923 |
*/
|
1924 |
|
1925 |
*i = NULL;
|
1926 |
/* Fill in the caller's variable to NULL.
|
1927 |
*/
|
1928 |
}
|
1929 |
|
1930 |
|
1931 |
/****************************************************************************/
|
1932 |
/* siCopy(): */
|
1933 |
/*--------------------------------------------------------------------------*/
|
1934 |
/* DESCRIPTION */
|
1935 |
/* Copies a synthetic integer. The integer must already be created. */
|
1936 |
/* */
|
1937 |
/* INPUTS */
|
1938 |
/* *src, *dst : Source and destination synthetic integers. */
|
1939 |
/****************************************************************************/
|
1940 |
void siCopy(SYNTHETIC_INTEGER **src, SYNTHETIC_INTEGER **dst)
|
1941 |
{
|
1942 |
asAssert(src != NULL, __LINE__);
|
1943 |
asAssert(*src != NULL, __LINE__);
|
1944 |
asAssert(dst != NULL, __LINE__);
|
1945 |
asAssert(*dst != NULL, __LINE__);
|
1946 |
|
1947 |
/* There are a lot of ways to copy, and pros and cons.
|
1948 |
** I'll choose the one that gives the least typing
|
1949 |
** here in the source code, but maybe I'll need to
|
1950 |
** optimize it later.
|
1951 |
*/
|
1952 |
memcpy(*dst, *src, sizeof(SYNTHETIC_INTEGER));
|
1953 |
}
|
1954 |
|
1955 |
|
1956 |
/****************************************************************************/
|
1957 |
/* siMulByTen(): */
|
1958 |
/*--------------------------------------------------------------------------*/
|
1959 |
/* DESCRIPTION */
|
1960 |
/* Multiplies a synthetic integer by 10, producing a NAN result if there */
|
1961 |
/* is an overflow in the number of digits. This is a primitive operation */
|
1962 |
/* used in multiplication of arbitrary integers. */
|
1963 |
/****************************************************************************/
|
1964 |
void siMulByTen(SYNTHETIC_INTEGER **arg)
|
1965 |
{
|
1966 |
asAssert(arg != NULL, __LINE__);
|
1967 |
asAssert(*arg != NULL, __LINE__);
|
1968 |
|
1969 |
/* If the integer is already NAN, NAN it stays.
|
1970 |
*/
|
1971 |
if (!((*arg)->nan))
|
1972 |
{
|
1973 |
/* If the integer is 0, 0 it stays. */
|
1974 |
if ((*arg)->len)
|
1975 |
{
|
1976 |
/* The result will overflow iff the string is already
|
1977 |
** at its length limit. If so, must declare a NAN. Multiplication
|
1978 |
** by 10 is guaranteed to add exactly one digit.
|
1979 |
*/
|
1980 |
asAssert((*arg)->len <= INTERMEDIATE_CALC_MAX_DIGITS, __LINE__);
|
1981 |
if ((*arg)->len == INTERMEDIATE_CALC_MAX_DIGITS)
|
1982 |
{
|
1983 |
/* Overflow. Must declare a NAN. */
|
1984 |
(*arg)->digits[0] = '\0';
|
1985 |
(*arg)->len = 0;
|
1986 |
(*arg)->nan = TRUE;
|
1987 |
(*arg)->neg = FALSE;
|
1988 |
}
|
1989 |
else
|
1990 |
{
|
1991 |
/* The digit shift will come off alright. Carry it out.
|
1992 |
*/
|
1993 |
unsigned tgt_idx;
|
1994 |
|
1995 |
for (tgt_idx = (*arg)->len; tgt_idx >= 1; tgt_idx--)
|
1996 |
{
|
1997 |
(*arg)->digits[tgt_idx] = (*arg)->digits[tgt_idx-1];
|
1998 |
}
|
1999 |
(*arg)->digits[0] = '0';
|
2000 |
(*arg)->digits[(*arg)->len + 1] = '\0';
|
2001 |
((*arg)->len)++;
|
2002 |
}
|
2003 |
}
|
2004 |
}
|
2005 |
}
|
2006 |
|
2007 |
|
2008 |
/****************************************************************************/
|
2009 |
/* siDivByTen(): */
|
2010 |
/*--------------------------------------------------------------------------*/
|
2011 |
/* DESCRIPTION */
|
2012 |
/* Divides a synthetic integer by 10 using digit-shifting (remainders */
|
2013 |
/* are discarded. This function is used in division of arbitrary */
|
2014 |
/* integers. */
|
2015 |
/****************************************************************************/
|
2016 |
void siDivByTen(SYNTHETIC_INTEGER **arg)
|
2017 |
{
|
2018 |
asAssert(arg != NULL, __LINE__);
|
2019 |
asAssert(*arg != NULL, __LINE__);
|
2020 |
|
2021 |
/* If the integer is already NAN, NAN it stays.
|
2022 |
*/
|
2023 |
if (!((*arg)->nan))
|
2024 |
{
|
2025 |
/* If the integer is a single digit, it must go to zero.
|
2026 |
*/
|
2027 |
if ((*arg)->len == 1)
|
2028 |
{
|
2029 |
(*arg)->len = 0;
|
2030 |
(*arg)->digits[0] = '\0';
|
2031 |
(*arg)->neg = FALSE;
|
2032 |
}
|
2033 |
else
|
2034 |
{
|
2035 |
unsigned i;
|
2036 |
|
2037 |
asAssert((*arg)->len <= INTERMEDIATE_CALC_MAX_DIGITS, __LINE__);
|
2038 |
|
2039 |
/* This is just a normal digit shift. */
|
2040 |
for (i=0; i<((*arg)->len); i++)
|
2041 |
{
|
2042 |
(*arg)->digits[i] = (*arg)->digits[i+1];
|
2043 |
}
|
2044 |
|
2045 |
((*arg)->len)--;
|
2046 |
}
|
2047 |
}
|
2048 |
}
|
2049 |
|
2050 |
|
2051 |
/****************************************************************************/
|
2052 |
/* siMulByDigit(): */
|
2053 |
/*--------------------------------------------------------------------------*/
|
2054 |
/* DESCRIPTION */
|
2055 |
/* Multiplies a synthetic integer by an arbitrary digit, producing a */
|
2056 |
/* result that may be zero, the argument, or an integer of larger mag- */
|
2057 |
/* nitude. A NAN is declared on overflow. This is a primitive operation */
|
2058 |
/* used in multiplication of arbitrary integers. */
|
2059 |
/****************************************************************************/
|
2060 |
void siMulByDigit(SYNTHETIC_INTEGER **arg, char digit)
|
2061 |
{
|
2062 |
asAssert(arg != NULL, __LINE__);
|
2063 |
asAssert(*arg != NULL, __LINE__);
|
2064 |
asAssert(ddIsDigit(digit), __LINE__);
|
2065 |
|
2066 |
/* If the integer is already NAN, NAN it stays.
|
2067 |
*/
|
2068 |
if (!((*arg)->nan))
|
2069 |
{
|
2070 |
/* If the integer is 0 or the digit is '0', force the result
|
2071 |
** to 0.
|
2072 |
*/
|
2073 |
if (!((*arg)->len) || (digit == '0'))
|
2074 |
{
|
2075 |
(*arg)->digits[0] = '\0';
|
2076 |
(*arg)->len = 0;
|
2077 |
(*arg)->nan = FALSE;
|
2078 |
(*arg)->neg = FALSE;
|
2079 |
}
|
2080 |
else
|
2081 |
{
|
2082 |
/* This is now a valid multiplication. Regrettably, we can't
|
2083 |
** determine an overflow or lack of decisively except by carrying
|
2084 |
** the multiplication out to its end.
|
2085 |
*/
|
2086 |
char carry;
|
2087 |
char new_digit;
|
2088 |
unsigned cur_digit;
|
2089 |
|
2090 |
carry = '0';
|
2091 |
|
2092 |
asAssert((*arg)->len <= INTERMEDIATE_CALC_MAX_DIGITS, __LINE__);
|
2093 |
|
2094 |
for (cur_digit=0; cur_digit < (*arg)->len; cur_digit++)
|
2095 |
{
|
2096 |
ddFundamentalMultiplicationCell((*arg)->digits[cur_digit],
|
2097 |
digit,
|
2098 |
carry,
|
2099 |
&new_digit,
|
2100 |
&carry);
|
2101 |
|
2102 |
if (cur_digit == ((*arg)->len - 1)) /* If last digit in loop. */
|
2103 |
{
|
2104 |
if (cur_digit == (INTERMEDIATE_CALC_MAX_DIGITS-1)) /* arg was max len. */
|
2105 |
{
|
2106 |
if (carry != '0')
|
2107 |
{
|
2108 |
/* We have an SI that was at the length limit, we've processed.
|
2109 |
** the last digit, and there is a carry out. Must declare a NAN.
|
2110 |
*/
|
2111 |
(*arg)->digits[0] = '\0';
|
2112 |
(*arg)->len = 0;
|
2113 |
(*arg)->nan = TRUE;
|
2114 |
(*arg)->neg = FALSE;
|
2115 |
}
|
2116 |
else
|
2117 |
{
|
2118 |
/* We have an SI that was max length, but did not overflow.
|
2119 |
** Close it up normally.
|
2120 |
*/
|
2121 |
(*arg)->digits[cur_digit] = new_digit;
|
2122 |
/* Nothing else to do. Everything is preset. */
|
2123 |
}
|
2124 |
}
|
2125 |
else
|
2126 |
{
|
2127 |
/* We are at the last digit of multiplication, but not at the
|
2128 |
** maximum length of a string of digits. Cleanup without fear
|
2129 |
** of overflow.
|
2130 |
*/
|
2131 |
if (carry == '0')
|
2132 |
{
|
2133 |
/* Number stayed same length. Just assign digit. Terminator
|
2134 |
** and other info is still valid.
|
2135 |
*/
|
2136 |
(*arg)->digits[cur_digit] = new_digit;
|
2137 |
}
|
2138 |
else
|
2139 |
{
|
2140 |
/* At last digit of multiplication. Number grew by one digit.
|
2141 |
** Clean up.
|
2142 |
*/
|
2143 |
(*arg)->digits[cur_digit] = new_digit;
|
2144 |
(*arg)->digits[cur_digit+1] = carry;
|
2145 |
(*arg)->digits[cur_digit+2] = '\0';
|
2146 |
((*arg)->len)++;
|
2147 |
|
2148 |
/* Must break out of the for() loop. Otherwise, modifying
|
2149 |
** the length above will keep us going.
|
2150 |
*/
|
2151 |
break;
|
2152 |
}
|
2153 |
}
|
2154 |
}
|
2155 |
else
|
2156 |
{
|
2157 |
/* Not the last digit in the loop. Just assign digit.
|
2158 |
*/
|
2159 |
(*arg)->digits[cur_digit] = new_digit;
|
2160 |
}
|
2161 |
} /* End for() each digit. */
|
2162 |
}
|
2163 |
}
|
2164 |
}
|
2165 |
|
2166 |
|
2167 |
/****************************************************************************/
|
2168 |
/* siCompareAbs(): */
|
2169 |
/*--------------------------------------------------------------------------*/
|
2170 |
/* DESCRIPTION */
|
2171 |
/* Compares the absolute value of two synthetic integers (this involves */
|
2172 |
/* comparing only the string representation without considering the */
|
2173 |
/* sign). This function is useful from within the full compare function */
|
2174 |
/* to avoid duplication of code--it isn't very useful in any other */
|
2175 |
/* context. */
|
2176 |
/* */
|
2177 |
/* INPUTS */
|
2178 |
/* *arg1, *arg2 : Two synthetic integers whose absolute values should */
|
2179 |
/* be compared. */
|
2180 |
/* */
|
2181 |
/* OUTPUT */
|
2182 |
/* <-- : (-1) : ABS(*arg1) < ABS(*arg2) */
|
2183 |
/* (0) : ABS(*arg1) = ABS(*arg2) */
|
2184 |
/* (1) : ABS(*arg1) > ABS(*arg2) */
|
2185 |
/****************************************************************************/
|
2186 |
int siCompareAbs(SYNTHETIC_INTEGER **arg1, SYNTHETIC_INTEGER **arg2)
|
2187 |
{
|
2188 |
int i;
|
2189 |
|
2190 |
asAssert(arg1 != NULL, __LINE__);
|
2191 |
asAssert(*arg1 != NULL, __LINE__);
|
2192 |
asAssert(arg2 != NULL, __LINE__);
|
2193 |
asAssert(*arg2 != NULL, __LINE__);
|
2194 |
|
2195 |
if ((*arg1)->len < (*arg2)->len)
|
2196 |
{
|
2197 |
return(-1);
|
2198 |
}
|
2199 |
else if ((*arg1)->len > (*arg2)->len)
|
2200 |
{
|
2201 |
return(1);
|
2202 |
}
|
2203 |
else if (!((*arg1)->len) && !((*arg2)->len))
|
2204 |
{
|
2205 |
/* Both are zero, return equal. */
|
2206 |
return(0);
|
2207 |
}
|
2208 |
else
|
2209 |
{
|
2210 |
/* Lengths of strings are equal--must look at the strings in
|
2211 |
** more detail.
|
2212 |
*/
|
2213 |
for (i = (*arg1)->len; i >= 0; i--)
|
2214 |
{
|
2215 |
if ((*arg1)->digits[i] < (*arg2)->digits[i])
|
2216 |
{
|
2217 |
return(-1);
|
2218 |
}
|
2219 |
else if ((*arg1)->digits[i] > (*arg2)->digits[i])
|
2220 |
{
|
2221 |
return(1);
|
2222 |
}
|
2223 |
}
|
2224 |
|
2225 |
/* Have iterated through the strings--couldn't find any differences.
|
2226 |
** They are equal. This also covers the zero case.
|
2227 |
*/
|
2228 |
return(0);
|
2229 |
}
|
2230 |
}
|
2231 |
|
2232 |
|
2233 |
/****************************************************************************/
|
2234 |
/* siCompare(): */
|
2235 |
/*--------------------------------------------------------------------------*/
|
2236 |
/* DESCRIPTION */
|
2237 |
/* Establishes the logical ordering of two synthetic integers. */
|
2238 |
/* */
|
2239 |
/* INPUTS */
|
2240 |
/* *arg1, *arg2 : Two synthetic integers to compare. */
|
2241 |
/* */
|
2242 |
/* OUTPUT */
|
2243 |
/* <-- : (-1) : *arg1 < *arg2. */
|
2244 |
/* (0) : *arg1 = *arg2 */
|
2245 |
/* (1) : *arg1 > *arg2 */
|
2246 |
/****************************************************************************/
|
2247 |
int siCompare(SYNTHETIC_INTEGER **arg1, SYNTHETIC_INTEGER **arg2)
|
2248 |
{
|
2249 |
asAssert(arg1 != NULL, __LINE__);
|
2250 |
asAssert(*arg1 != NULL, __LINE__);
|
2251 |
asAssert(arg2 != NULL, __LINE__);
|
2252 |
asAssert(*arg2 != NULL, __LINE__);
|
2253 |
|
2254 |
/* If either integer has been marked NAN, we shouldn't be
|
2255 |
** comparing, and there is no reason to handle this case,
|
2256 |
** as it is a minority case and harmless whatever happens.
|
2257 |
*/
|
2258 |
/* Cover the two easiest cases, which are where one operand is
|
2259 |
** positive and the other is negative.
|
2260 |
*/
|
2261 |
if (((*arg1)->neg) && (!((*arg2)->neg)))
|
2262 |
{
|
2263 |
return(-1);
|
2264 |
}
|
2265 |
else if ((!((*arg1)->neg)) && ((*arg2)->neg))
|
2266 |
{
|
2267 |
return(1);
|
2268 |
}
|
2269 |
/* We know both integers are of the same sign. We can call the
|
2270 |
** absolute value compare function to get their ordering.
|
2271 |
*/
|
2272 |
else if ((*arg1)->neg)
|
2273 |
{
|
2274 |
return(siCompareAbs(arg2, arg1)); /* Reverse the order to negate the
|
2275 |
** results provided by
|
2276 |
** siCompareAbs().
|
2277 |
*/
|
2278 |
}
|
2279 |
else if (!((*arg1)->neg))
|
2280 |
{
|
2281 |
return(siCompareAbs(arg1, arg2)); /* Normal non-neg compare.
|
2282 |
*/
|
2283 |
}
|
2284 |
else
|
2285 |
{
|
2286 |
/* It should be impossible to reach this case.
|
2287 |
*/
|
2288 |
asAssert(0, __LINE__); /* Fatal. */
|
2289 |
return(0); /* Suppress compiler warning. */
|
2290 |
}
|
2291 |
}
|
2292 |
|
2293 |
|
2294 |
/****************************************************************************/
|
2295 |
/* siDump(): */
|
2296 |
/*--------------------------------------------------------------------------*/
|
2297 |
/* DESCRIPTION */
|
2298 |
/* Outputs a synthetic integer to the standard output stream. The output */
|
2299 |
/* includes a title, and provisions are made for NAN, for a description, */
|
2300 |
/* and prints commas. It is the caller's responsibility to provide lines */
|
2301 |
/* before and lines after if desired. Ths function assumes that it */
|
2302 |
/* starts with the cursor in column 1. */
|
2303 |
/* */
|
2304 |
/* INPUTS */
|
2305 |
/* **si : The synthetic integer which is being output. */
|
2306 |
/* */
|
2307 |
/* *desc : The description to use for the integer. It will be */
|
2308 |
/* right-justified up against the start of the integer, */
|
2309 |
/* and this function will automatically include a */
|
2310 |
/* colon. If the description is too long, this function */
|
2311 |
/* will truncate it to fit the space available. */
|
2312 |
/****************************************************************************/
|
2313 |
void siDump(SYNTHETIC_INTEGER **si, const char *desc)
|
2314 |
{
|
2315 |
unsigned cur_line;
|
2316 |
unsigned nlines;
|
2317 |
unsigned digits_per_line;
|
2318 |
|
2319 |
/* Make sure the caller isn't doing something bad for the program's health.
|
2320 |
*/
|
2321 |
asAssert(si != NULL, __LINE__);
|
2322 |
asAssert(*si != NULL, __LINE__);
|
2323 |
asAssert(desc != NULL, __LINE__);
|
2324 |
|
2325 |
/* The number of digits per line that we assume must be a multiple of
|
2326 |
** three. Round this up in case the preprocessor constant was set
|
2327 |
** dubiously.
|
2328 |
*/
|
2329 |
digits_per_line = ddUmax(3, ((DIGITS_PER_LINE + 2) /3) * 3);
|
2330 |
|
2331 |
/* As the first order of business, figure out how many lines the beast
|
2332 |
** will require.
|
2333 |
*/
|
2334 |
if ((*si)->nan)
|
2335 |
{
|
2336 |
nlines = 1; /* Only one line required for NAN verbeage. */
|
2337 |
}
|
2338 |
else if (!((*si)->len))
|
2339 |
{
|
2340 |
nlines = 1; /* The zero value requires one line. */
|
2341 |
}
|
2342 |
else
|
2343 |
{
|
2344 |
/* In any other case, have a formula.
|
2345 |
*/
|
2346 |
nlines = 1 + ((*si)->len - 1) / digits_per_line;
|
2347 |
}
|
2348 |
|
2349 |
/* Iterate through each line, spitting out whatever is appropriate. */
|
2350 |
for (cur_line = 0; cur_line < nlines; cur_line++)
|
2351 |
{
|
2352 |
unsigned cur_digit_on_line;
|
2353 |
|
2354 |
/* If this is the first line, spit out the description, right-aligned.
|
2355 |
** Otherwise, spit spaces.
|
2356 |
*/
|
2357 |
if (!cur_line)
|
2358 |
{
|
2359 |
/* First line. */
|
2360 |
unsigned len;
|
2361 |
|
2362 |
len = strlen(desc);
|
2363 |
|
2364 |
if (len <= NUMBER_DESC_WIDTH)
|
2365 |
{
|
2366 |
/* Description is shorter or equal, pad on left. */
|
2367 |
gfRepChar(' ', NUMBER_DESC_WIDTH - len);
|
2368 |
printf("%s", desc);
|
2369 |
}
|
2370 |
else
|
2371 |
{
|
2372 |
/* Description is too long, truncate. */
|
2373 |
unsigned i;
|
2374 |
|
2375 |
for (i=0; i<len; i++)
|
2376 |
printf("%c", desc[i]);
|
2377 |
}
|
2378 |
|
2379 |
printf(": ");
|
2380 |
|
2381 |
/* If the number is negative, throw in a minus sign. */
|
2382 |
if ((*si)->neg && !(*si)->nan)
|
2383 |
{
|
2384 |
printf("- ");
|
2385 |
}
|
2386 |
else
|
2387 |
{
|
2388 |
printf(" ");
|
2389 |
}
|
2390 |
}
|
2391 |
else
|
2392 |
{
|
2393 |
/* Every line but first line. */
|
2394 |
gfRepChar(' ', NUMBER_DESC_WIDTH+4);
|
2395 |
}
|
2396 |
|
2397 |
for(cur_digit_on_line=0; cur_digit_on_line < digits_per_line; cur_digit_on_line++)
|
2398 |
{
|
2399 |
unsigned idx_into_string;
|
2400 |
/* Index into the string which is our digit of interest.
|
2401 |
*/
|
2402 |
|
2403 |
/* Compute the index. The equation is based on the ordering
|
2404 |
** of presentation, for example,
|
2405 |
**
|
2406 |
** 7 6
|
2407 |
** 5 4 3
|
2408 |
** 2 1 0.
|
2409 |
**
|
2410 |
** With a little thought, the equation should make sense.
|
2411 |
** The index won't always be used to index into the string.
|
2412 |
*/
|
2413 |
idx_into_string =
|
2414 |
(((nlines-1) - cur_line) * digits_per_line)
|
2415 |
+
|
2416 |
(digits_per_line - 1 - cur_digit_on_line);
|
2417 |
|
2418 |
/* Print the appropriate digit or a space. The NAN case and the
|
2419 |
** zero case need to be treated specially.
|
2420 |
*/
|
2421 |
if ((*si)->nan)
|
2422 |
{
|
2423 |
/* Not a number. Everything is blank, except spell out NAN
|
2424 |
** at the end of the string of digits.
|
2425 |
*/
|
2426 |
if (cur_digit_on_line == (digits_per_line - 3))
|
2427 |
{
|
2428 |
printf("N");
|
2429 |
}
|
2430 |
else if (cur_digit_on_line == (digits_per_line - 2))
|
2431 |
{
|
2432 |
printf("A");
|
2433 |
}
|
2434 |
else if (cur_digit_on_line == (digits_per_line - 1))
|
2435 |
{
|
2436 |
printf("N");
|
2437 |
}
|
2438 |
else
|
2439 |
{
|
2440 |
printf(" ");
|
2441 |
}
|
2442 |
}
|
2443 |
else if (!(*si)->len)
|
2444 |
{
|
2445 |
/* This is the zero case. For zero, there is only one line,
|
2446 |
** and every character except the last one is a blank.
|
2447 |
*/
|
2448 |
if (cur_digit_on_line == (digits_per_line - 1))
|
2449 |
{
|
2450 |
printf("0");
|
2451 |
}
|
2452 |
else
|
2453 |
{
|
2454 |
printf(" ");
|
2455 |
}
|
2456 |
}
|
2457 |
else
|
2458 |
{
|
2459 |
/* This is a valid number which is not zero. Need to print
|
2460 |
** the digits.
|
2461 |
*/
|
2462 |
|
2463 |
if (idx_into_string < (*si)->len)
|
2464 |
{
|
2465 |
printf("%c", (*si)->digits[idx_into_string]);
|
2466 |
}
|
2467 |
else
|
2468 |
{
|
2469 |
printf(" ");
|
2470 |
}
|
2471 |
} /* End of digit case.
|
2472 |
|
2473 |
/* Now handle the commas. The rules for commas are straightforward.
|
2474 |
** a)NAN never has a comma.
|
2475 |
** b)Zeros never have a comma.
|
2476 |
** c)The final line, last digit never has a comma.
|
2477 |
** d)Everything else in multiples of three ...
|
2478 |
*/
|
2479 |
if (!(idx_into_string % 3) && (idx_into_string))
|
2480 |
{
|
2481 |
if ((*si)->nan)
|
2482 |
{
|
2483 |
printf(" ");
|
2484 |
}
|
2485 |
else if (!(*si)->len)
|
2486 |
{
|
2487 |
printf(" ");
|
2488 |
}
|
2489 |
else
|
2490 |
{
|
2491 |
if (idx_into_string < (*si)->len)
|
2492 |
{
|
2493 |
printf(",");
|
2494 |
}
|
2495 |
else
|
2496 |
{
|
2497 |
printf(" ");
|
2498 |
}
|
2499 |
}
|
2500 |
}
|
2501 |
} /* End for each digit on the current line. */
|
2502 |
|
2503 |
/* For the first line, print out an informative message
|
2504 |
** advising of the number of digits. For all other lines
|
2505 |
** print nothing.
|
2506 |
*/
|
2507 |
if (!cur_line && !((*si)->nan))
|
2508 |
{
|
2509 |
if (nlines == 1)
|
2510 |
printf(" ");
|
2511 |
|
2512 |
if ((*si)->len <= 1)
|
2513 |
{
|
2514 |
printf(" ( 1 digit)\n");
|
2515 |
}
|
2516 |
else if ((*si)->len < 1000)
|
2517 |
{
|
2518 |
printf(" (%5u digits)\n", (*si)->len);
|
2519 |
}
|
2520 |
else
|
2521 |
{
|
2522 |
printf(" (%u,%03u digits)\n", (*si)->len / 1000, (*si)->len % 1000);
|
2523 |
}
|
2524 |
}
|
2525 |
else
|
2526 |
{
|
2527 |
printf("\n");
|
2528 |
}
|
2529 |
} /* End for each line. */
|
2530 |
}
|
2531 |
|
2532 |
|
2533 |
/****************************************************************************/
|
2534 |
/* siSetToLong(): */
|
2535 |
/*--------------------------------------------------------------------------*/
|
2536 |
/* DESCRIPTION */
|
2537 |
/* Sets a synthetic integer (which must already be created) to a long */
|
2538 |
/* value. This is used primarily in preliminary unit testing. */
|
2539 |
/* */
|
2540 |
/* INPUTS */
|
2541 |
/* **si : The synthetic integer to operate on. */
|
2542 |
/* */
|
2543 |
/* val : The value to set the synthetic integer to. */
|
2544 |
/****************************************************************************/
|
2545 |
void siSetToLong(SYNTHETIC_INTEGER **si, long val)
|
2546 |
{
|
2547 |
char buf[100];
|
2548 |
char *p;
|
2549 |
unsigned len;
|
2550 |
unsigned idx;
|
2551 |
|
2552 |
asAssert(si != NULL, __LINE__);
|
2553 |
asAssert(*si != NULL, __LINE__);
|
2554 |
|
2555 |
sprintf(buf, "%ld", val);
|
2556 |
|
2557 |
if (buf[0] == '-')
|
2558 |
p = buf+1;
|
2559 |
else
|
2560 |
p = buf;
|
2561 |
|
2562 |
len = strlen(p);
|
2563 |
|
2564 |
(*si)->nan = FALSE;
|
2565 |
|
2566 |
if (val == 0)
|
2567 |
{
|
2568 |
(*si)->nan = FALSE;
|
2569 |
(*si)->neg = FALSE;
|
2570 |
(*si)->len = 0;
|
2571 |
(*si)->digits[0] = '\0';
|
2572 |
}
|
2573 |
else
|
2574 |
{
|
2575 |
if (val < 0)
|
2576 |
{
|
2577 |
(*si)->neg = TRUE;
|
2578 |
}
|
2579 |
else
|
2580 |
{
|
2581 |
(*si)->neg = FALSE;
|
2582 |
}
|
2583 |
|
2584 |
(*si)->len = len;
|
2585 |
|
2586 |
for (idx=0; idx<len; idx++)
|
2587 |
{
|
2588 |
(*si)->digits[idx] = p[len - idx - 1];
|
2589 |
}
|
2590 |
|
2591 |
(*si)->digits[len] = '\0';
|
2592 |
}
|
2593 |
}
|
2594 |
|
2595 |
|
2596 |
/****************************************************************************/
|
2597 |
/* siSetToNan(): */
|
2598 |
/*--------------------------------------------------------------------------*/
|
2599 |
/* DESCRIPTION */
|
2600 |
/* Sets a synthetic integer (which must already be created) to NAN (not */
|
2601 |
/* a number). */
|
2602 |
/* */
|
2603 |
/* INPUTS */
|
2604 |
/* **si : The synthetic integer to set to NAN. */
|
2605 |
/* */
|
2606 |
/* NOTES */
|
2607 |
/* This program "evolved", and this function evolved after many of the */
|
2608 |
/* functions that set a number to NAN. There are may places in the code */
|
2609 |
/* where an integer is set to NAN without the use of this function. */
|
2610 |
/****************************************************************************/
|
2611 |
void siSetToNan(SYNTHETIC_INTEGER **si)
|
2612 |
{
|
2613 |
asAssert(si != NULL, __LINE__);
|
2614 |
asAssert(*si != NULL, __LINE__);
|
2615 |
|
2616 |
(*si)->digits[0] = '\0';
|
2617 |
(*si)->len = 0;
|
2618 |
(*si)->nan = TRUE;
|
2619 |
(*si)->neg = FALSE;
|
2620 |
}
|
2621 |
|
2622 |
|
2623 |
/****************************************************************************/
|
2624 |
/* siSetToPowerOfTen(): */
|
2625 |
/*--------------------------------------------------------------------------*/
|
2626 |
/* DESCRIPTION */
|
2627 |
/* Sets a synthetic integer (which must already be created) to an */
|
2628 |
/* integral power of ten. This function is helpful for math in many */
|
2629 |
/* cases. */
|
2630 |
/* */
|
2631 |
/* INPUTS */
|
2632 |
/* **si : The synthetic integer to operate on. */
|
2633 |
/* */
|
2634 |
/* exp : The integral exponent value (non-negative). For */
|
2635 |
/* example, a value of 0 here will result in the */
|
2636 |
/* assignment of 1, 1 here will result in the assignment */
|
2637 |
/* of 10, 2 here will result in the assignment of 100. */
|
2638 |
/* */
|
2639 |
/* ERRORS */
|
2640 |
/* A negative exponent will result in an assertion failure. An exponent */
|
2641 |
/* too large will result in the assignment of NAN. */
|
2642 |
/* */
|
2643 |
/* NOTE */
|
2644 |
/* This program "evolved", and this function evolved after many of the */
|
2645 |
/* functions that set a number to a power of 10 "directly". There may be */
|
2646 |
/* many places in the code where an integer is set to a power of 10 */
|
2647 |
/* without the use of this function. */
|
2648 |
/****************************************************************************/
|
2649 |
void siSetToPowerOfTen(SYNTHETIC_INTEGER **si, int exp)
|
2650 |
{
|
2651 |
int i;
|
2652 |
|
2653 |
asAssert(si != NULL, __LINE__);
|
2654 |
asAssert(*si != NULL, __LINE__);
|
2655 |
asAssert(exp >= 0, __LINE__);
|
2656 |
|
2657 |
if (exp < INTERMEDIATE_CALC_MAX_DIGITS)
|
2658 |
{
|
2659 |
(*si)->len = exp+1;
|
2660 |
(*si)->nan = FALSE;
|
2661 |
(*si)->neg = FALSE;
|
2662 |
(*si)->digits[exp+1] = '\0';
|
2663 |
(*si)->digits[exp] = '1';
|
2664 |
for (i=0; i<exp; i++)
|
2665 |
(*si)->digits[i] = '0';
|
2666 |
}
|
2667 |
else
|
2668 |
{
|
2669 |
siSetToNan(si);
|
2670 |
}
|
2671 |
}
|
2672 |
|
2673 |
|
2674 |
/****************************************************************************/
|
2675 |
/* siAddTwoNonnegative(): */
|
2676 |
/*--------------------------------------------------------------------------*/
|
2677 |
/* DESCRIPTION */
|
2678 |
/* Adds two synthetic integers which are guaranteed to be non-negative. */
|
2679 |
/* The result may be set NAN if there is an overflow. This is a low- */
|
2680 |
/* level function called by other higher-level functions to do more */
|
2681 |
/* complex arithmetic. */
|
2682 |
/* */
|
2683 |
/* INPUTS */
|
2684 |
/* **arg1, **arg2 : The two operands to add. Both operands must be */
|
2685 |
/* non-negative. It is legal for both SI's to */
|
2686 |
/* use the same storage or to be the same variable. */
|
2687 |
/* */
|
2688 |
/* OUTPUTS */
|
2689 |
/* **result : The synthetic integer where the output result is */
|
2690 |
/* placed. This may be the same SI as either or both */
|
2691 |
/* of the inputs. */
|
2692 |
/****************************************************************************/
|
2693 |
void siAddTwoNonnegative(SYNTHETIC_INTEGER **arg1,
|
2694 |
SYNTHETIC_INTEGER **arg2,
|
2695 |
SYNTHETIC_INTEGER **result)
|
2696 |
{
|
2697 |
SYNTHETIC_INTEGER *callers_orig_value = NULL;
|
2698 |
unsigned i;
|
2699 |
unsigned len1, len2, lenmax;
|
2700 |
char carry;
|
2701 |
char operand1, operand2, digitresult;
|
2702 |
|
2703 |
/* Be sure the caller isn't doing anything silly. */
|
2704 |
asAssert(arg1 != NULL, __LINE__);
|
2705 |
asAssert(*arg1 != NULL, __LINE__);
|
2706 |
asAssert(!((*arg1)->neg), __LINE__);
|
2707 |
asAssert(arg2 != NULL, __LINE__);
|
2708 |
asAssert(*arg2 != NULL, __LINE__);
|
2709 |
asAssert(!((*arg2)->neg), __LINE__);
|
2710 |
asAssert(result != NULL, __LINE__);
|
2711 |
asAssert(*result != NULL, __LINE__);
|
2712 |
asAssert((arg1 != arg2) && (arg2 != result) && (result != arg1), __LINE__);
|
2713 |
|
2714 |
/* If either input is NAN, the output is NAN by definition.
|
2715 |
*/
|
2716 |
if (((*arg1)->nan) || ((*arg2)->nan))
|
2717 |
{
|
2718 |
(*result)->nan = TRUE;
|
2719 |
}
|
2720 |
else
|
2721 |
{
|
2722 |
/* The two input arguments don't matter because they aren't written,
|
2723 |
** but if the caller has allowed the result to be the same as the
|
2724 |
** either or both of the two inputs, must use a different memory
|
2725 |
** location. However, only do this if need to, as will slow things
|
2726 |
** down to create and destroy.
|
2727 |
*/
|
2728 |
if ((*arg1 == *result) || (*arg2 == *result))
|
2729 |
{
|
2730 |
/* Caller has allowed result to be the same as either
|
2731 |
** or both inputs. Must replace caller's pointer temporarily.
|
2732 |
*/
|
2733 |
callers_orig_value = *result;
|
2734 |
siCreate(result);
|
2735 |
}
|
2736 |
|
2737 |
/* Zero out the potential result.
|
2738 |
*/
|
2739 |
(*result)->neg = FALSE;
|
2740 |
(*result)->nan = FALSE;
|
2741 |
(*result)->len = 0;
|
2742 |
(*result)->digits[0] = '\0';
|
2743 |
|
2744 |
/* Buffer important handy values.
|
2745 |
*/
|
2746 |
len1 = (*arg1)->len;
|
2747 |
len2 = (*arg2)->len;
|
2748 |
lenmax = ddUmax(len1, len2);
|
2749 |
|
2750 |
/* Be absolutely sure that both lengths are permissible values. Memory
|
2751 |
** reference errors can be hard to track down.
|
2752 |
*/
|
2753 |
asAssert(lenmax <= INTERMEDIATE_CALC_MAX_DIGITS, __LINE__);
|
2754 |
|
2755 |
/* Start off with an LSD carry input of '0', as there is no carry into the
|
2756 |
** first digit.
|
2757 |
*/
|
2758 |
carry = '0';
|
2759 |
|
2760 |
/* Iterate through, performing the addition, character by character.
|
2761 |
** characters that are unpopulated are treated as zero.
|
2762 |
*/
|
2763 |
for (i=0; i<lenmax; i++)
|
2764 |
{
|
2765 |
/* Grab the right character from the arguments. */
|
2766 |
if (i < len1)
|
2767 |
operand1 = (*arg1)->digits[i];
|
2768 |
else
|
2769 |
operand1 = '0';
|
2770 |
if (i < len2)
|
2771 |
operand2 = (*arg2)->digits[i];
|
2772 |
else
|
2773 |
operand2 = '0';
|
2774 |
|
2775 |
/* Perform the actual addition. Note that the carry value is copied
|
2776 |
** copied onto the stack for the function call, so carry can double
|
2777 |
** as both input and output.
|
2778 |
*/
|
2779 |
ddFundamentalAdditionCell(operand1, operand2, carry, &digitresult, &carry);
|
2780 |
|
2781 |
/* Stuff the result digit in the right place. */
|
2782 |
(*result)->digits[i] = digitresult;
|
2783 |
}
|
2784 |
|
2785 |
/* After we're out of the loop, there are a few possible outcomes. If the
|
2786 |
** carry is zero, then there is no risk of any kind of overflow.
|
2787 |
*/
|
2788 |
if (carry == '0')
|
2789 |
{
|
2790 |
/* No risk of overflow. */
|
2791 |
(*result)->digits[i] = '\0';
|
2792 |
(*result)->len = i;
|
2793 |
}
|
2794 |
else
|
2795 |
{
|
2796 |
/* carry == '1' */
|
2797 |
/* There are two possibilities here. Either the result has grown one
|
2798 |
** digit more than the longest input operand, and this is legal, or the
|
2799 |
** result has grown one digit more and there is an overflow,
|
2800 |
** forcing declaration of a NAN.
|
2801 |
*/
|
2802 |
if (i == INTERMEDIATE_CALC_MAX_DIGITS)
|
2803 |
{
|
2804 |
(*result)->nan = TRUE;
|
2805 |
(*result)->len = 0;
|
2806 |
(*result)->digits[0] = '\0';
|
2807 |
}
|
2808 |
else
|
2809 |
{
|
2810 |
(*result)->len = i+1;
|
2811 |
(*result)->digits[i] = carry;
|
2812 |
(*result)->digits[i+1] = '\0';
|
2813 |
}
|
2814 |
}
|
2815 |
|
2816 |
/* If it was necessary to evacuate the caller's result area, swap it back
|
2817 |
** and deallocate memory.
|
2818 |
*/
|
2819 |
if (callers_orig_value)
|
2820 |
{
|
2821 |
siCopy(result, &callers_orig_value);
|
2822 |
siDestroy(result);
|
2823 |
*result = callers_orig_value;
|
2824 |
}
|
2825 |
}
|
2826 |
}
|
2827 |
|
2828 |
|
2829 |
/****************************************************************************/
|
2830 |
/* siSubtractToProduceNonnegativeResult(): */
|
2831 |
/*--------------------------------------------------------------------------*/
|
2832 |
/* DESCRIPTION */
|
2833 |
/* Subtracts two synthetic integers, with the understanding that the */
|
2834 |
/* result will be non-negative. This function is used as a building */
|
2835 |
/* block for subtraction which can span zero. */
|
2836 |
/* */
|
2837 |
/* INPUTS */
|
2838 |
/* **arg1, **arg2 : The two operands to subtract. Both must be non- */
|
2839 |
/* negative. */
|
2840 |
/* */
|
2841 |
/* OUTPUTS */
|
2842 |
/* **result : **arg1 - **arg2, or a fatal error if the result */
|
2843 |
/* would be negative. */
|
2844 |
/****************************************************************************/
|
2845 |
void siSubtractToProduceNonnegativeResult(SYNTHETIC_INTEGER **arg1,
|
2846 |
SYNTHETIC_INTEGER **arg2,
|
2847 |
SYNTHETIC_INTEGER **result)
|
2848 |
{
|
2849 |
SYNTHETIC_INTEGER *callers_orig_value = NULL;
|
2850 |
unsigned i;
|
2851 |
unsigned len;
|
2852 |
char borrow;
|
2853 |
char operand1, operand2, digitresult;
|
2854 |
|
2855 |
/* Be sure the caller isn't doing anything silly. */
|
2856 |
asAssert(arg1 != NULL, __LINE__);
|
2857 |
asAssert(*arg1 != NULL, __LINE__);
|
2858 |
asAssert(!((*arg1)->neg), __LINE__);
|
2859 |
asAssert(arg2 != NULL, __LINE__);
|
2860 |
asAssert(*arg2 != NULL, __LINE__);
|
2861 |
asAssert(!((*arg2)->neg), __LINE__);
|
2862 |
asAssert(result != NULL, __LINE__);
|
2863 |
asAssert(*result != NULL, __LINE__);
|
2864 |
asAssert((arg1 != arg2) && (arg2 != result) && (result != arg1), __LINE__);
|
2865 |
|
2866 |
/* If either input is NAN, the output is NAN by definition.
|
2867 |
*/
|
2868 |
if (((*arg1)->nan) || ((*arg2)->nan))
|
2869 |
{
|
2870 |
(*result)->nan = TRUE;
|
2871 |
}
|
2872 |
else
|
2873 |
{
|
2874 |
/* The two input arguments don't matter because they aren't written,
|
2875 |
** but if the caller has allowed the result to be the same as the
|
2876 |
** either or both of the two inputs, must use a different memory
|
2877 |
** location. However, only do this if need to, as will slow things
|
2878 |
** down to create and destroy.
|
2879 |
*/
|
2880 |
if ((*arg1 == *result) || (*arg2 == *result))
|
2881 |
{
|
2882 |
/* Caller has allowed result to be the same as either
|
2883 |
** or both inputs. Must replace caller's pointer temporarily.
|
2884 |
*/
|
2885 |
callers_orig_value = *result;
|
2886 |
siCreate(result);
|
2887 |
}
|
2888 |
|
2889 |
/* Zero out the potential result.
|
2890 |
*/
|
2891 |
(*result)->neg = FALSE;
|
2892 |
(*result)->nan = FALSE;
|
2893 |
(*result)->len = 0;
|
2894 |
(*result)->digits[0] = '\0';
|
2895 |
|
2896 |
/* Buffer important handy values.
|
2897 |
*/
|
2898 |
len = (*arg1)->len; /* By definition, this one is the max. */
|
2899 |
|
2900 |
/* Be absolutely sure that the length used for iteration is a
|
2901 |
** permissible value.
|
2902 |
*/
|
2903 |
asAssert(len <= INTERMEDIATE_CALC_MAX_DIGITS, __LINE__);
|
2904 |
|
2905 |
/* Start off with an LSD borrow input of '0', as there is no borrow into the
|
2906 |
** first digit.
|
2907 |
*/
|
2908 |
borrow = '0';
|
2909 |
|
2910 |
/* Iterate through, performing the subtraction, character by character.
|
2911 |
** Characters that are unpopulated are treated as zero.
|
2912 |
*/
|
2913 |
for (i=0; i<len; i++)
|
2914 |
{
|
2915 |
/* Grab the right character from the arguments. */
|
2916 |
operand1 = (*arg1)->digits[i];
|
2917 |
if (i < (*arg2)->len)
|
2918 |
operand2 = (*arg2)->digits[i];
|
2919 |
else
|
2920 |
operand2 = '0';
|
2921 |
|
2922 |
/* Perform the actual subtraction. Note that the borrow value is
|
2923 |
** copied onto the stack for the function call, so double can double
|
2924 |
** as both input and output.
|
2925 |
*/
|
2926 |
/* printf("Idx: %u, borrow in: %c, ", i, borrow); */
|
2927 |
|
2928 |
ddFundamentalSubtractionCell(operand1, operand2, borrow, &digitresult, &borrow);
|
2929 |
|
2930 |
/* printf("op1: %c, op2: %c, borrow out: %c, result out: %c.\n",
|
2931 |
operand1,
|
2932 |
operand2,
|
2933 |
borrow,
|
2934 |
digitresult); */
|
2935 |
|
2936 |
/* Stuff the result digit in the right place. */
|
2937 |
(*result)->digits[i] = digitresult;
|
2938 |
}
|
2939 |
|
2940 |
/* Trim the leading zeros from the subtraction result. It would be more
|
2941 |
** elegant to just identify the ripstop during the subtraction, but
|
2942 |
** this will work, too.
|
2943 |
*/
|
2944 |
if (!i)
|
2945 |
{
|
2946 |
/* We had a 0-0 subtraction. */
|
2947 |
(*result)->digits[0] = '\0';
|
2948 |
(*result)->len = 0;
|
2949 |
}
|
2950 |
else
|
2951 |
{
|
2952 |
(*result)->digits[i] = '\0';
|
2953 |
(*result)->len = i;
|
2954 |
while ((i >= 1) && ((*result)->digits[i-1] == '0'))
|
2955 |
{
|
2956 |
(*result)->digits[i-1] = '\0';
|
2957 |
(*result)->len = i-1;
|
2958 |
i--;
|
2959 |
}
|
2960 |
}
|
2961 |
|
2962 |
/* If it was necessary to evacuate the caller's result area, swap it back
|
2963 |
** and deallocate memory.
|
2964 |
*/
|
2965 |
if (callers_orig_value)
|
2966 |
{
|
2967 |
siCopy(result, &callers_orig_value);
|
2968 |
siDestroy(result);
|
2969 |
*result = callers_orig_value;
|
2970 |
}
|
2971 |
}
|
2972 |
}
|
2973 |
|
2974 |
|
2975 |
/****************************************************************************/
|
2976 |
/* siUnrestrictedAddition(): */
|
2977 |
/*--------------------------------------------------------------------------*/
|
2978 |
/* DESCRIPTION */
|
2979 |
/* Adds two integers of any sign. NAN is produced if anything overflows. */
|
2980 |
/* */
|
2981 |
/* INPUTS */
|
2982 |
/* **arg1, **arg2 : The two synthetic integer operand to add. It is */
|
2983 |
/* permitted for both to point to the same place. */
|
2984 |
/* */
|
2985 |
/* OUTPUTS */
|
2986 |
/* **result : The result. This may point to the same place as */
|
2987 |
/* either or both of arg1, arg2. */
|
2988 |
/****************************************************************************/
|
2989 |
void siUnrestrictedAddition(SYNTHETIC_INTEGER **arg1,
|
2990 |
SYNTHETIC_INTEGER **arg2,
|
2991 |
SYNTHETIC_INTEGER **result)
|
2992 |
{
|
2993 |
SYNTHETIC_INTEGER *callers_orig_value = NULL;
|
2994 |
int arg1_rel_arg2;
|
2995 |
unsigned arg1_is_neg;
|
2996 |
unsigned arg2_is_neg;
|
2997 |
unsigned case_number;
|
2998 |
|
2999 |
/* Be sure the caller isn't doing anything silly. Because double-
|
3000 |
** indirection is involved, another word of explanation is needed.
|
3001 |
** The caller is passing a pointer to his pointer. This isn't necessary
|
3002 |
** in this circumstance (we'll never need to reallocate his object, for
|
3003 |
** example), but it is just simpler to keep everthing consistent
|
3004 |
** throughout the program. When I say that the caller can have pointers
|
3005 |
** the same for the args and the result, I mean that the caller can have
|
3006 |
** separate physical pointers which point to the same thing. However, the
|
3007 |
** caller may not have one physical pointer only and pass us three identical
|
3008 |
** pointers to the same physical pointer. This is illegal. The caller must
|
3009 |
** have three seperate pointers, even if they point to the same place.
|
3010 |
*/
|
3011 |
asAssert(arg1 != NULL, __LINE__);
|
3012 |
asAssert(*arg1 != NULL, __LINE__);
|
3013 |
asAssert(arg2 != NULL, __LINE__);
|
3014 |
asAssert(*arg2 != NULL, __LINE__);
|
3015 |
asAssert(result != NULL, __LINE__);
|
3016 |
asAssert(*result != NULL, __LINE__);
|
3017 |
asAssert((arg1 != arg2) && (arg2 != result) && (result != arg1), __LINE__);
|
3018 |
|
3019 |
/* The two input arguments don't matter because they aren't written,
|
3020 |
** but if the caller has allowed the result to be the same as the
|
3021 |
** either or both of the two inputs, must use a different memory
|
3022 |
** location. However, only do this if need to, as will slow things
|
3023 |
** down to create and destroy.
|
3024 |
*/
|
3025 |
if ((*arg1 == *result) || (*arg2 == *result))
|
3026 |
{
|
3027 |
/* Caller has allowed result to be the same as either
|
3028 |
** or both inputs. Must replace caller's pointer temporarily.
|
3029 |
*/
|
3030 |
callers_orig_value = *result;
|
3031 |
siCreate(result);
|
3032 |
}
|
3033 |
|
3034 |
/* Zero out the potential result.
|
3035 |
*/
|
3036 |
(*result)->neg = FALSE;
|
3037 |
(*result)->nan = FALSE;
|
3038 |
(*result)->len = 0;
|
3039 |
(*result)->digits[0] = '\0';
|
3040 |
|
3041 |
/* If either operand is NAN, the result is NAN. That is all the
|
3042 |
** needs to be said.
|
3043 |
*/
|
3044 |
if (((*arg1)->nan) || ((*arg2)->nan))
|
3045 |
{
|
3046 |
(*result)->nan = TRUE;
|
3047 |
}
|
3048 |
else
|
3049 |
{
|
3050 |
/* Gather some vital statistics about the two numbers passed. These
|
3051 |
** will be used to break into cases.
|
3052 |
*/
|
3053 |
arg1_rel_arg2 = siCompareAbs(arg1, arg2) + 1;
|
3054 |
arg1_is_neg = (*arg1)->neg;
|
3055 |
arg2_is_neg = (*arg2)->neg;
|
3056 |
|
3057 |
/* Zero out the signs of the two numbers. They will be restored
|
3058 |
** later.
|
3059 |
*/
|
3060 |
(*arg1)->neg = FALSE;
|
3061 |
(*arg2)->neg = FALSE;
|
3062 |
|
3063 |
/* Create a case number based on the above examination. It is easier
|
3064 |
** to do it this way so there is only one switch statement.
|
3065 |
*/
|
3066 |
case_number = ((unsigned)arg1_rel_arg2 * 4)
|
3067 |
+ arg1_is_neg * 2
|
3068 |
+ arg2_is_neg;
|
3069 |
|
3070 |
/* printf("Case number: %u.\n", case_number); */
|
3071 |
|
3072 |
switch(case_number)
|
3073 |
{
|
3074 |
/*********************************************************************/
|
3075 |
case 0:
|
3076 |
/* abs(arg1) < abs(arg2) */
|
3077 |
/* arg1 >= 0 */
|
3078 |
/* arg2 >= 0 */
|
3079 |
/* Both arguments were non-negative. The result will be non-
|
3080 |
** negative, perhaps NAN. Just add the two numbers, perhaps
|
3081 |
** resulting in NAN.
|
3082 |
*/
|
3083 |
siAddTwoNonnegative(arg1, arg2, result);
|
3084 |
break;
|
3085 |
/*********************************************************************/
|
3086 |
case 1:
|
3087 |
/* abs(arg1) < abs(arg2) */
|
3088 |
/* arg1 >= 0 */
|
3089 |
/* arg2 < 0 */
|
3090 |
/* arg2 is negative, and will overwhelm arg1 and produce a negative
|
3091 |
** result. Get the positive result and flip the sign.
|
3092 |
*/
|
3093 |
siSubtractToProduceNonnegativeResult(arg2, arg1, result);
|
3094 |
if (!((*result)->nan))
|
3095 |
(*result)->neg = TRUE;
|
3096 |
break;
|
3097 |
/*********************************************************************/
|
3098 |
case 2:
|
3099 |
/* abs(arg1) < abs(arg2) */
|
3100 |
/* arg1 < 0 */
|
3101 |
/* arg2 >= 0 */
|
3102 |
/* Result will be positive, dominated by arg2. */
|
3103 |
siSubtractToProduceNonnegativeResult(arg2, arg1, result);
|
3104 |
break;
|
3105 |
/*********************************************************************/
|
3106 |
case 3:
|
3107 |
/* abs(arg1) < abs(arg2) */
|
3108 |
/* arg1 < 0 */
|
3109 |
/* arg2 < 0 */
|
3110 |
/* arg1 and arg2 both negative. Add them in a positive sense and
|
3111 |
** negate the result.
|
3112 |
*/
|
3113 |
siAddTwoNonnegative(arg1, arg2, result);
|
3114 |
if (!((*result)->nan))
|
3115 |
(*result)->neg = TRUE;
|
3116 |
break;
|
3117 |
/*********************************************************************/
|
3118 |
case 4:
|
3119 |
/* abs(arg1) == abs(arg2) */
|
3120 |
/* arg1 >= 0 */
|
3121 |
/* arg2 >= 0 */
|
3122 |
/* Two are equal and non-negative. Just add.
|
3123 |
*/
|
3124 |
siAddTwoNonnegative(arg1, arg2, result);
|
3125 |
break;
|
3126 |
/*********************************************************************/
|
3127 |
case 5:
|
3128 |
/* abs(arg1) == abs(arg2) */
|
3129 |
/* arg1 >= 0 */
|
3130 |
/* arg2 < 0 */
|
3131 |
/* Result is zero. Just leave the result the way it is, as we
|
3132 |
** set the result to zero higher up in the code.
|
3133 |
*/
|
3134 |
break;
|
3135 |
/*********************************************************************/
|
3136 |
case 6:
|
3137 |
/* abs(arg1) == abs(arg2) */
|
3138 |
/* arg1 < 0 */
|
3139 |
/* arg2 >= 0 */
|
3140 |
/* Result is zero. Just leave the result the way it is, as we
|
3141 |
** set the result to zero higher up in the code.
|
3142 |
*/
|
3143 |
break;
|
3144 |
/*********************************************************************/
|
3145 |
case 7:
|
3146 |
/* abs(arg1) == abs(arg2) */
|
3147 |
/* arg1 < 0 */
|
3148 |
/* arg2 < 0 */
|
3149 |
/* Two are equal and negative. Add and negate.
|
3150 |
*/
|
3151 |
siAddTwoNonnegative(arg1, arg2, result);
|
3152 |
if (!((*result)->nan))
|
3153 |
(*result)->neg = TRUE;
|
3154 |
break;
|
3155 |
/*********************************************************************/
|
3156 |
case 8:
|
3157 |
/* abs(arg1) > abs(arg2) */
|
3158 |
/* arg1 >= 0 */
|
3159 |
/* arg2 >= 0 */
|
3160 |
/* Both non-negative. Just add.
|
3161 |
*/
|
3162 |
siAddTwoNonnegative(arg1, arg2, result);
|
3163 |
break;
|
3164 |
/*********************************************************************/
|
3165 |
case 9:
|
3166 |
/* abs(arg1) > abs(arg2) */
|
3167 |
/* arg1 >= 0 */
|
3168 |
/* arg2 < 0 */
|
3169 |
/* Result is positive and driven by arg1. Subtract. */
|
3170 |
siSubtractToProduceNonnegativeResult(arg1, arg2, result);
|
3171 |
break;
|
3172 |
/*********************************************************************/
|
3173 |
case 10:
|
3174 |
/* abs(arg1) > abs(arg2) */
|
3175 |
/* arg1 < 0 */
|
3176 |
/* arg2 >= 0 */
|
3177 |
/* Result is negative and driven by arg1. Subtract and negate.
|
3178 |
*/
|
3179 |
siSubtractToProduceNonnegativeResult(arg1, arg2, result);
|
3180 |
if (!((*result)->nan))
|
3181 |
(*result)->neg = TRUE;
|
3182 |
break;
|
3183 |
/*********************************************************************/
|
3184 |
case 11:
|
3185 |
/* abs(arg1) > abs(arg2) */
|
3186 |
/* arg1 < 0 */
|
3187 |
/* arg2 < 0 */
|
3188 |
/* Result is negative. Add and negate.
|
3189 |
*/
|
3190 |
siAddTwoNonnegative(arg1, arg2, result);
|
3191 |
if (!((*result)->nan))
|
3192 |
(*result)->neg = TRUE;
|
3193 |
break;
|
3194 |
/*********************************************************************/
|
3195 |
default:
|
3196 |
/* Should never be here. Fatal out. */
|
3197 |
asAssert(0, __LINE__);
|
3198 |
break;
|
3199 |
/*********************************************************************/
|
3200 |
}
|
3201 |
|
3202 |
/* Restore the results of the input arguments. We will really mess up
|
3203 |
** the caller if we don't.
|
3204 |
*/
|
3205 |
(*arg1)->neg = arg1_is_neg;
|
3206 |
(*arg2)->neg = arg2_is_neg;
|
3207 |
}
|
3208 |
|
3209 |
|
3210 |
/* If it was necessary to evacuate the caller's result area, swap it back
|
3211 |
** and deallocate memory.
|
3212 |
*/
|
3213 |
if (callers_orig_value)
|
3214 |
{
|
3215 |
siCopy(result, &callers_orig_value);
|
3216 |
siDestroy(result);
|
3217 |
*result = callers_orig_value;
|
3218 |
}
|
3219 |
}
|
3220 |
|
3221 |
/****************************************************************************/
|
3222 |
/* siUnrestrictedSubtraction(): */
|
3223 |
/*--------------------------------------------------------------------------*/
|
3224 |
/* DESCRIPTION */
|
3225 |
/* Subtracts two integers of any sign. NAN is produced if anything */
|
3226 |
/* overflows. */
|
3227 |
/* */
|
3228 |
/* INPUTS */
|
3229 |
/* **arg1, **arg2 : The two synthetic integer operand to subtract. */
|
3230 |
/* Both may point to the same place. */
|
3231 |
/* */
|
3232 |
/* OUTPUTS */
|
3233 |
/* **result : The result, arg1-arg2. May point to the same */
|
3234 |
/* place as either or both of arg1, arg2. */
|
3235 |
/****************************************************************************/
|
3236 |
void siUnrestrictedSubtraction(SYNTHETIC_INTEGER **arg1,
|
3237 |
SYNTHETIC_INTEGER **arg2,
|
3238 |
SYNTHETIC_INTEGER **result)
|
3239 |
{
|
3240 |
unsigned neg;
|
3241 |
|
3242 |
/* Be sure the caller is doing nothing silly. */
|
3243 |
asAssert(arg1 != NULL, __LINE__);
|
3244 |
asAssert(*arg1 != NULL, __LINE__);
|
3245 |
asAssert(arg2 != NULL, __LINE__);
|
3246 |
asAssert(*arg2 != NULL, __LINE__);
|
3247 |
asAssert(result != NULL, __LINE__);
|
3248 |
asAssert(*result != NULL, __LINE__);
|
3249 |
asAssert((arg1 != arg2) && (arg2 != result) && (result != arg1), __LINE__);
|
3250 |
|
3251 |
/* If either operand is NAN, the result is NAN. */
|
3252 |
if ((*arg1)->nan || (*arg2)->nan)
|
3253 |
{
|
3254 |
(*result)->digits[0] = '\0';
|
3255 |
(*result)->len = 0;
|
3256 |
(*result)->nan = TRUE;
|
3257 |
(*result)->neg = FALSE;
|
3258 |
}
|
3259 |
else
|
3260 |
{
|
3261 |
/* Subtraction is easy to express in terms of addition, since the
|
3262 |
** addition function already handles both operands of both signs.
|
3263 |
*/
|
3264 |
if ((*arg2)->len) /* Can't negate zero in this way. */
|
3265 |
{
|
3266 |
neg = (*arg2)->neg;
|
3267 |
(*arg2)->neg = !((*arg2)->neg);
|
3268 |
}
|
3269 |
|
3270 |
siUnrestrictedAddition(arg1, arg2, result);
|
3271 |
|
3272 |
if ((*arg2)->len)
|
3273 |
(*arg2)->neg = neg;
|
3274 |
}
|
3275 |
}
|
3276 |
|
3277 |
|
3278 |
/****************************************************************************/
|
3279 |
/* siUnrestrictedMultiplication(): */
|
3280 |
/*--------------------------------------------------------------------------*/
|
3281 |
/* DESCRIPTION */
|
3282 |
/* Muiltiplies two integers of any sign. NAN is produced if anything */
|
3283 |
/* overflows. */
|
3284 |
/* */
|
3285 |
/* INPUTS */
|
3286 |
/* **arg1, **arg2 : The two synthetic integer operands to multiply. */
|
3287 |
/* Both may point to the same place. */
|
3288 |
/* */
|
3289 |
/* OUTPUTS */
|
3290 |
/* **result : The result, arg1*arg2. May point to the same */
|
3291 |
/* place as either or both of arg1, arg2. */
|
3292 |
/****************************************************************************/
|
3293 |
void siUnrestrictedMultiplication(SYNTHETIC_INTEGER **arg1,
|
3294 |
SYNTHETIC_INTEGER **arg2,
|
3295 |
SYNTHETIC_INTEGER **result)
|
3296 |
{
|
3297 |
/* Be sure the caller is doing nothing silly. */
|
3298 |
asAssert(arg1 != NULL, __LINE__);
|
3299 |
asAssert(*arg1 != NULL, __LINE__);
|
3300 |
asAssert(arg2 != NULL, __LINE__);
|
3301 |
asAssert(*arg2 != NULL, __LINE__);
|
3302 |
asAssert(result != NULL, __LINE__);
|
3303 |
asAssert(*result != NULL, __LINE__);
|
3304 |
asAssert((arg1 != arg2) && (arg2 != result) && (result != arg1), __LINE__);
|
3305 |
|
3306 |
/* If either argument is NAN, the result is NAN.
|
3307 |
*/
|
3308 |
if ((*arg1)->nan || (*arg2)->nan)
|
3309 |
{
|
3310 |
(*result)->digits[0] = '\0';
|
3311 |
(*result)->len = 0;
|
3312 |
(*result)->nan = TRUE;
|
3313 |
(*result)->neg = FALSE;
|
3314 |
}
|
3315 |
/* If either argument is zero, result is zero. */
|
3316 |
else if (!((*arg1)->len) || !((*arg2)->len))
|
3317 |
{
|
3318 |
(*result)->digits[0] = '\0';
|
3319 |
(*result)->len = 0;
|
3320 |
(*result)->nan = FALSE;
|
3321 |
(*result)->neg = FALSE;
|
3322 |
}
|
3323 |
else
|
3324 |
{
|
3325 |
/* We have two non-zero operands, fit to be multiplied.
|
3326 |
*/
|
3327 |
SYNTHETIC_INTEGER *rt, *temp, *rt2;
|
3328 |
int cidx, len;
|
3329 |
char cur_digit;
|
3330 |
unsigned negarg1, negarg2;
|
3331 |
|
3332 |
/* Must save the signs of the arguments and restore. */
|
3333 |
negarg1 = (*arg1)->neg;
|
3334 |
negarg2 = (*arg2)->neg;
|
3335 |
(*arg1)->neg = FALSE;
|
3336 |
(*arg2)->neg = FALSE;
|
3337 |
|
3338 |
/* Create (allocate) a synthetic integer to contain the result
|
3339 |
** that will be returned to the caller.
|
3340 |
*/
|
3341 |
siCreate(&rt);
|
3342 |
|
3343 |
/* Must create an alias. The reasons for this are complex. I coded
|
3344 |
** myself into a corner and have to live with it.
|
3345 |
*/
|
3346 |
rt2 = rt;
|
3347 |
|
3348 |
/* Create (allocate) a synthetic integer that will be used to hold
|
3349 |
** the result of multiplying arg2 by a digit.
|
3350 |
*/
|
3351 |
siCreate(&temp);
|
3352 |
|
3353 |
/* Go through, multiplying in much the same way as one would by hand.
|
3354 |
*/
|
3355 |
len = (*arg1)->len;
|
3356 |
|
3357 |
for (cidx = len-1; cidx >= 0; cidx--)
|
3358 |
{
|
3359 |
#if 0
|
3360 |
printf("cidx: %d\n", cidx);
|
3361 |
printf("rt before * 10 multiply\n");
|
3362 |
siDump(&rt, "rt before");
|
3363 |
/* Multiply the pending result by 10 */
|
3364 |
#endif
|
3365 |
siMulByTen(&rt);
|
3366 |
/* siDump(&rt, "rt after"); */
|
3367 |
|
3368 |
/* Grab the current digit of interest and multiply arg2 by it. */
|
3369 |
cur_digit = (*arg1)->digits[cidx];
|
3370 |
/* printf("cur digit: %c\n", cur_digit); */
|
3371 |
|
3372 |
siCopy(arg2, &temp);
|
3373 |
/* siDump(&temp, "copy of arg2"); */
|
3374 |
siMulByDigit(&temp, cur_digit);
|
3375 |
/* siDump(&temp, "arg2 * digit"); */
|
3376 |
|
3377 |
/* Add the result of the multiplication to the pending
|
3378 |
** result.
|
3379 |
*/
|
3380 |
siUnrestrictedAddition(&rt2, &temp, &rt);
|
3381 |
|
3382 |
#if 0
|
3383 |
siDump(&rt2, "rt2");
|
3384 |
siDump(&rt, "rt");
|
3385 |
siDump(&temp, "temp");
|
3386 |
#endif
|
3387 |
}
|
3388 |
|
3389 |
/* We're done with the mathematical operation. Signs should be a self-
|
3390 |
** healing matter.
|
3391 |
*/
|
3392 |
/* Copy the result back to caller's area. */
|
3393 |
siCopy(&rt, result);
|
3394 |
|
3395 |
/* Destroy temporary areas. */
|
3396 |
siDestroy(&rt);
|
3397 |
siDestroy(&temp);
|
3398 |
|
3399 |
/* Restore the signs of the integers that were arguments, then the
|
3400 |
** sign of the result.
|
3401 |
*/
|
3402 |
(*arg1)->neg = negarg1;
|
3403 |
(*arg2)->neg = negarg2;
|
3404 |
|
3405 |
if ((negarg1 && negarg2) || (!negarg1 && !negarg2))
|
3406 |
(*result)->neg = FALSE;
|
3407 |
else
|
3408 |
(*result)->neg = TRUE;
|
3409 |
|
3410 |
/* siDump(result, "result"); */
|
3411 |
}
|
3412 |
}
|
3413 |
|
3414 |
|
3415 |
/****************************************************************************/
|
3416 |
/* siUnrestrictedDivision(): */
|
3417 |
/*--------------------------------------------------------------------------*/
|
3418 |
/* DESCRIPTION */
|
3419 |
/* Divides two synthetic integers of any sign, producing an integer */
|
3420 |
/* quotient and integer remainder. NAN is assigned to both the quotient */
|
3421 |
/* and remainder on invalid inputs. NAN due to overflow is not possible */
|
3422 |
/* in this function, as any integer divided by 1 or -1 yields an integer */
|
3423 |
/* of the same magnitude. */
|
3424 |
/* */
|
3425 |
/* INPUTS */
|
3426 |
/* **dividend : The dividend of the division. May be any value. */
|
3427 |
/* */
|
3428 |
/* **divisor : The divisor of the division. May be any value */
|
3429 |
/* except zero. */
|
3430 |
/* */
|
3431 |
/* OUTPUTS */
|
3432 |
/* **quotient : The integer quotient of the division. This should */
|
3433 |
/* behave identically to the C "/" operator when */
|
3434 |
/* applied to integers. */
|
3435 |
/* */
|
3436 |
/* **remainder : The remainder of the division. This should behave */
|
3437 |
/* identically to the C "%" operator. There was some */
|
3438 |
/* question in my mind about the best way to define a */
|
3439 |
/* remainder with a negative dividend or divisor, but */
|
3440 |
/* I simply used the behavior of the "%" operator in */
|
3441 |
/* C as a guide. */
|
3442 |
/* */
|
3443 |
/* USAGE NOTES */
|
3444 |
/* The functions in this program are inconsistent about whether they */
|
3445 |
/* allow the inputs and the outputs to be pointers to the same memory */
|
3446 |
/* locations, etc. This program was constructed impromptu, and I made */
|
3447 |
/* up the rules as I went along. I've now decided that it isn't that */
|
3448 |
/* useful to allow this, so for this function I'll require uniqueness */
|
3449 |
/* between the four parameters. This doesn't affect the correctness */
|
3450 |
/* of the program--just its internal elegance. These inconsistent */
|
3451 |
/* decisions are not visible by using the program. */
|
3452 |
/****************************************************************************/
|
3453 |
void siUnrestrictedDivision(SYNTHETIC_INTEGER **dividend,
|
3454 |
SYNTHETIC_INTEGER **divisor,
|
3455 |
SYNTHETIC_INTEGER **quotient,
|
3456 |
SYNTHETIC_INTEGER **remainder)
|
3457 |
{
|
3458 |
/* Be sure the caller is doing nothing silly. */
|
3459 |
/* No first- or second-level pointers may be NULL. */
|
3460 |
asAssert(dividend != NULL, __LINE__);
|
3461 |
asAssert(*dividend != NULL, __LINE__);
|
3462 |
asAssert(divisor != NULL, __LINE__);
|
3463 |
asAssert(*divisor != NULL, __LINE__);
|
3464 |
asAssert(quotient != NULL, __LINE__);
|
3465 |
asAssert(*quotient != NULL, __LINE__);
|
3466 |
asAssert(remainder != NULL, __LINE__);
|
3467 |
asAssert(*remainder != NULL, __LINE__);
|
3468 |
/* All pointers must be mutually exclusive. */
|
3469 |
asAssert((dividend != divisor) && (dividend != quotient) && (dividend != remainder), __LINE__);
|
3470 |
asAssert((*dividend != *divisor) && (*dividend != *quotient) && (*dividend != *remainder), __LINE__);
|
3471 |
asAssert((divisor != quotient) && (divisor != remainder), __LINE__);
|
3472 |
asAssert((*divisor != *quotient) && (*divisor != *remainder), __LINE__);
|
3473 |
asAssert(quotient != remainder, __LINE__);
|
3474 |
asAssert(*quotient != *remainder, __LINE__);
|
3475 |
|
3476 |
/* If either argument is NAN, the results are NAN. Also, if the divisor is zero,
|
3477 |
** that causes two NAN's, as well.
|
3478 |
*/
|
3479 |
if ((*dividend)->nan || (*divisor)->nan || !((*divisor)->len))
|
3480 |
{
|
3481 |
(*quotient)->digits[0] = '\0';
|
3482 |
(*quotient)->len = 0;
|
3483 |
(*quotient)->nan = TRUE;
|
3484 |
(*quotient)->neg = FALSE;
|
3485 |
(*remainder)->digits[0] = '\0';
|
3486 |
(*remainder)->len = 0;
|
3487 |
(*remainder)->nan = TRUE;
|
3488 |
(*remainder)->neg = FALSE;
|
3489 |
}
|
3490 |
/* Zero in the numerator always gets us zero on both outputs.
|
3491 |
*/
|
3492 |
else if (!((*dividend)->len))
|
3493 |
{
|
3494 |
siSetToLong(quotient, 0);
|
3495 |
siSetToLong(remainder, 0);
|
3496 |
}
|
3497 |
/* Must do a legitimate long division. We know for sure that
|
3498 |
** both dividend and divisor are non-zero.
|
3499 |
*/
|
3500 |
else
|
3501 |
{
|
3502 |
unsigned dividend_is_neg;
|
3503 |
unsigned divisor_is_neg;
|
3504 |
/* Signs of dividend and divisor, saved so we only
|
3505 |
** operate on positive numbers.
|
3506 |
*/
|
3507 |
int quotient_ndigits;
|
3508 |
/* The number of digits in the quotient.
|
3509 |
*/
|
3510 |
int i;
|
3511 |
/* General-purpose iteration variable.
|
3512 |
*/
|
3513 |
char j;
|
3514 |
/* Trial digit for trial multiplication.
|
3515 |
*/
|
3516 |
SYNTHETIC_INTEGER *si_temp1 = NULL,
|
3517 |
*si_temp2 = NULL,
|
3518 |
*si_temp3 = NULL;
|
3519 |
/* Temporary large integers. These need to be set
|
3520 |
** to NULL here, because in the event of an
|
3521 |
** error or unexpected condition, need to know
|
3522 |
** which ones to release.
|
3523 |
*/
|
3524 |
|
3525 |
/* Remember and reset the signs of the passed dividend and
|
3526 |
** divisor. It makes it simpler just to consider positive
|
3527 |
** numbers.
|
3528 |
*/
|
3529 |
dividend_is_neg = (*dividend)->neg;
|
3530 |
divisor_is_neg = (*divisor)->neg;
|
3531 |
(*dividend)->neg = 0;
|
3532 |
(*divisor)->neg = 0;
|
3533 |
|
3534 |
/* If the dividend is less (in magnitude) than the divisor,
|
3535 |
** the quotient is zero and the remainder is the
|
3536 |
** dividend.
|
3537 |
*/
|
3538 |
if (siCompare(dividend, divisor) == -1)
|
3539 |
{
|
3540 |
siSetToLong(quotient, 0);
|
3541 |
siCopy(dividend, remainder);
|
3542 |
(*remainder)->neg = dividend_is_neg;
|
3543 |
}
|
3544 |
else
|
3545 |
{
|
3546 |
/* Allocate all of the temporary integers.
|
3547 |
** Done all in one place to eliminate paths
|
3548 |
** through the code where may allocate something
|
3549 |
** already allocated and cause a memory leak.
|
3550 |
*/
|
3551 |
siCreate(&si_temp1);
|
3552 |
siCreate(&si_temp2);
|
3553 |
siCreate(&si_temp3);
|
3554 |
|
3555 |
/* Establish the number of digits in the
|
3556 |
** quotient. There is a window near the maximum
|
3557 |
** number of digits where we won't be able to
|
3558 |
** successfully start the division because we
|
3559 |
** can't form an upper bound which is a power
|
3560 |
** of 10 times the divisor. In this case,
|
3561 |
** just return NAN. This window won't be a problem
|
3562 |
** in practice. It could be worked around, but
|
3563 |
** no need to close it.
|
3564 |
*/
|
3565 |
siCopy(divisor, &si_temp1);
|
3566 |
siMulByTen(&si_temp1);
|
3567 |
quotient_ndigits = 1;
|
3568 |
while(siCompare(&si_temp1, dividend) <= 0)
|
3569 |
{
|
3570 |
siMulByTen(&si_temp1);
|
3571 |
if (si_temp1->nan)
|
3572 |
goto nan_return;
|
3573 |
quotient_ndigits++;
|
3574 |
}
|
3575 |
|
3576 |
siDivByTen(&si_temp1);
|
3577 |
|
3578 |
/* printf("quotient number of digits: %d\n",
|
3579 |
quotient_ndigits);
|
3580 |
siDump(&si_temp1, "trial divisor"); */
|
3581 |
|
3582 |
/* We now know the number of digits that the
|
3583 |
** quotient will contain. We also know the
|
3584 |
** starting point to use for trial subtraction.
|
3585 |
** Count down from the highest order digit to the
|
3586 |
** lowest-order digit, subtracting the maximum
|
3587 |
** amount each time.
|
3588 |
*/
|
3589 |
/* si_temp1 is the trial divisor reference
|
3590 |
** copy.
|
3591 |
*/
|
3592 |
/* si_temp2 is a copy of the trial divisor,
|
3593 |
** used to see what happens as we try multiplying
|
3594 |
** by various trial digits.
|
3595 |
*/
|
3596 |
/* remainder (in the caller's area) is used for
|
3597 |
** staging the dividend after subtractions made.
|
3598 |
** This will end up with the remainder in the
|
3599 |
** end.
|
3600 |
*/
|
3601 |
/* quotient (in the caller's area) contains the
|
3602 |
** quotient. We'll stage it directly there.
|
3603 |
*/
|
3604 |
(*quotient)->len = (unsigned)quotient_ndigits;
|
3605 |
(*quotient)->digits[(*quotient)->len] = '\0';
|
3606 |
siCopy(dividend, remainder);
|
3607 |
|
3608 |
/* For each digit in the result, going from most
|
3609 |
** significant to least significant.
|
3610 |
*/
|
3611 |
for (i=quotient_ndigits-1; i>=0; i--)
|
3612 |
{
|
3613 |
/* Try to find the largest digit for the spot
|
3614 |
** that will not overflow the remainder.
|
3615 |
** This is the right digit.
|
3616 |
*/
|
3617 |
/* For each digit we might try.
|
3618 |
*/
|
3619 |
for (j='0'; j<='9'; j++)
|
3620 |
{
|
3621 |
siCopy(&si_temp1, &si_temp2);
|
3622 |
/* Buffer the value so we can do a trial
|
3623 |
** multiplication.
|
3624 |
*/
|
3625 |
siMulByDigit(&si_temp2, j);
|
3626 |
/* Perform the trial multiplication
|
3627 |
** by a digit.
|
3628 |
*/
|
3629 |
siUnrestrictedSubtraction(remainder,
|
3630 |
&si_temp2,
|
3631 |
&si_temp3);
|
3632 |
/* Perform a trial subtraction involving the trial
|
3633 |
** digit.
|
3634 |
*/
|
3635 |
|
3636 |
/* We have success if what is left over after
|
3637 |
** the trial subtraction is less than the
|
3638 |
** trial divisor.
|
3639 |
*/
|
3640 |
if (siCompare(&si_temp3, &si_temp1) < 0)
|
3641 |
break;
|
3642 |
|
3643 |
/* It is a fatal internal software error if
|
3644 |
** we are at the digit '9' and the constraint
|
3645 |
** still is not met.
|
3646 |
*/
|
3647 |
asAssert(j != '9', __LINE__);
|
3648 |
} /* End for each possible digit. */
|
3649 |
|
3650 |
/* OK, we have the digit, and it is in the
|
3651 |
** variable 'j'. We also have the value
|
3652 |
** we should subtract and the result.
|
3653 |
** Stuff the digit, and the result.
|
3654 |
*/
|
3655 |
(*quotient)->digits[i] = j;
|
3656 |
siCopy(&si_temp3, remainder);
|
3657 |
|
3658 |
/* Divide the trial divisor by 10 for the
|
3659 |
** next iteration.
|
3660 |
*/
|
3661 |
siDivByTen(&si_temp1);
|
3662 |
} /* End for each digit position. */
|
3663 |
|
3664 |
/* We now need to figure out what the sign
|
3665 |
** of the quotient and the remainder are.
|
3666 |
*/
|
3667 |
if ((dividend_is_neg && !divisor_is_neg) ||
|
3668 |
(!dividend_is_neg && divisor_is_neg))
|
3669 |
(*quotient)->neg = TRUE;
|
3670 |
else
|
3671 |
(*quotient)->neg = FALSE;
|
3672 |
|
3673 |
if (dividend_is_neg && (*remainder)->len)
|
3674 |
(*remainder)->neg = TRUE;
|
3675 |
else
|
3676 |
(*remainder)->neg = FALSE;
|
3677 |
}
|
3678 |
|
3679 |
goto normal_return;
|
3680 |
nan_return: ;
|
3681 |
/* This is the return point where the quotient
|
3682 |
** and remainder are marked NAN. Thank goodness
|
3683 |
** they didn't forget about the "goto" in 'C'.
|
3684 |
*/
|
3685 |
|
3686 |
normal_return:
|
3687 |
/* Restore the signs of the input arguments.
|
3688 |
*/
|
3689 |
(*dividend)->neg = dividend_is_neg;
|
3690 |
(*divisor)->neg = divisor_is_neg;
|
3691 |
|
3692 |
/* Deallocate all allocated memory.
|
3693 |
*/
|
3694 |
if (si_temp1)
|
3695 |
siDestroy(&si_temp1);
|
3696 |
if (si_temp2)
|
3697 |
siDestroy(&si_temp2);
|
3698 |
if (si_temp3)
|
3699 |
siDestroy(&si_temp3);
|
3700 |
}
|
3701 |
}
|
3702 |
|
3703 |
|
3704 |
/****************************************************************************/
|
3705 |
/* siGcd(): */
|
3706 |
/*--------------------------------------------------------------------------*/
|
3707 |
/* DESCRIPTION */
|
3708 |
/* Applies Euclid's algorithm to obtain the GCD of two positive integers. */
|
3709 |
/* Any unexpected input operands will generate a NAN for the GCD. */
|
3710 |
/* */
|
3711 |
/* INPUTS */
|
3712 |
/* **arg1, arg2 : The two positive integers whose GCD is to be found. */
|
3713 |
/* */
|
3714 |
/* OUTPUTS */
|
3715 |
/* **result : gcd(**arg1, **arg2). */
|
3716 |
/****************************************************************************/
|
3717 |
void siGcd(SYNTHETIC_INTEGER **arg1,
|
3718 |
SYNTHETIC_INTEGER **arg2,
|
3719 |
SYNTHETIC_INTEGER **result)
|
3720 |
{
|
3721 |
|
3722 |
/* Be sure the caller isn't doing anything silly. */
|
3723 |
asAssert(arg1 != NULL, __LINE__);
|
3724 |
asAssert(*arg1 != NULL, __LINE__);
|
3725 |
asAssert(arg2 != NULL, __LINE__);
|
3726 |
asAssert(*arg2 != NULL, __LINE__);
|
3727 |
asAssert(result != NULL, __LINE__);
|
3728 |
asAssert(*result != NULL, __LINE__);
|
3729 |
|
3730 |
/* A NAN input or zero or negative integers gets a NAN result.
|
3731 |
*/
|
3732 |
if ((*arg1)->nan || (*arg2)->nan || !(*arg1)->len || !(*arg2)->len
|
3733 |
|| (*arg1)->neg || (*arg2)->neg)
|
3734 |
{
|
3735 |
(*result)->digits[0] = '\0';
|
3736 |
(*result)->len = 0;
|
3737 |
(*result)->nan = TRUE;
|
3738 |
(*result)->neg = FALSE;
|
3739 |
}
|
3740 |
else
|
3741 |
{
|
3742 |
/* This algorithm is so well known and documented that I won't insult
|
3743 |
** the reader with comments.
|
3744 |
*/
|
3745 |
SYNTHETIC_INTEGER *h, *k, *q, *r;
|
3746 |
|
3747 |
siCreate(&h);
|
3748 |
siCreate(&k);
|
3749 |
siCreate(&q);
|
3750 |
siCreate(&r);
|
3751 |
|
3752 |
if (siCompare(arg1, arg2) == -1)
|
3753 |
{
|
3754 |
siCopy(arg1, &h);
|
3755 |
siCopy(arg2, &k);
|
3756 |
}
|
3757 |
else
|
3758 |
{
|
3759 |
siCopy(arg1, &k);
|
3760 |
siCopy(arg2, &h);
|
3761 |
}
|
3762 |
|
3763 |
siCopy(&h, &r);
|
3764 |
|
3765 |
do
|
3766 |
{
|
3767 |
siCopy(&r, result);
|
3768 |
siUnrestrictedDivision(&h,&k,&q,&r);
|
3769 |
siCopy(&k, &h);
|
3770 |
siCopy(&r, &k);
|
3771 |
} while (r->len);
|
3772 |
|
3773 |
siDestroy(&h);
|
3774 |
siDestroy(&k);
|
3775 |
siDestroy(&q);
|
3776 |
siDestroy(&r);
|
3777 |
}
|
3778 |
}
|
3779 |
|
3780 |
|
3781 |
/****************************************************************************/
|
3782 |
/* siIntegerExponentiation(): */
|
3783 |
/*--------------------------------------------------------------------------*/
|
3784 |
/* DESCRIPTION */
|
3785 |
/* Exponentiates one integer to the integral power of another. The */
|
3786 |
/* integer to be exponentiated may be of any sign, but the exponent must */
|
3787 |
/* be non-negative. Invalid or overflow conditions result in the */
|
3788 |
/* assignment of NAN. */
|
3789 |
/* */
|
3790 |
/* INPUTS */
|
3791 |
/* **arg : Integer to be exponentiated. */
|
3792 |
/* */
|
3793 |
/* **exponent : Exponent to use. Must be non-negative. */
|
3794 |
/* */
|
3795 |
/* OUTPUTS */
|
3796 |
/* **result : The result, arg1**arg2. */
|
3797 |
/* */
|
3798 |
/* NOTE */
|
3799 |
/* In other functions (written chronologically earlier), it was allowed */
|
3800 |
/* for the arguments and the result to be the same physical object. This */
|
3801 |
/* didn't prove to be a useful feature, so it is disallowed in this */
|
3802 |
/* function. */
|
3803 |
/****************************************************************************/
|
3804 |
void siIntegerExponentiation(SYNTHETIC_INTEGER **arg,
|
3805 |
SYNTHETIC_INTEGER **exponent,
|
3806 |
SYNTHETIC_INTEGER **result)
|
3807 |
{
|
3808 |
/* Be sure the caller is doing nothing silly. */
|
3809 |
asAssert(arg != NULL, __LINE__);
|
3810 |
asAssert(*arg != NULL, __LINE__);
|
3811 |
asAssert(exponent != NULL, __LINE__);
|
3812 |
asAssert(*exponent != NULL, __LINE__);
|
3813 |
asAssert(result != NULL, __LINE__);
|
3814 |
asAssert(*result != NULL, __LINE__);
|
3815 |
asAssert((arg != exponent) && (exponent != result) && (result != arg), __LINE__);
|
3816 |
asAssert((*arg != *exponent) && (*exponent != *result) && (*result != *arg), __LINE__);
|
3817 |
|
3818 |
/* If either argument is NAN, the result is NAN. */
|
3819 |
if (((*arg)->nan) || ((*exponent)->nan))
|
3820 |
{
|
3821 |
(*result)->digits[0] = '\0';
|
3822 |
(*result)->len = 0;
|
3823 |
(*result)->nan = TRUE;
|
3824 |
(*result)->neg = FALSE;
|
3825 |
}
|
3826 |
/* If we're trying to raise 0 to the 0th power, this is a no-no,
|
3827 |
** as well.
|
3828 |
*/
|
3829 |
else if (!((*arg)->len) && !((*exponent)->len))
|
3830 |
{
|
3831 |
(*result)->digits[0] = '\0';
|
3832 |
(*result)->len = 0;
|
3833 |
(*result)->nan = TRUE;
|
3834 |
(*result)->neg = FALSE;
|
3835 |
}
|
3836 |
/* A negative exponent is a no-no, as well.
|
3837 |
*/
|
3838 |
else if ((*exponent)->neg)
|
3839 |
{
|
3840 |
(*result)->digits[0] = '\0';
|
3841 |
(*result)->len = 0;
|
3842 |
(*result)->nan = TRUE;
|
3843 |
(*result)->neg = FALSE;
|
3844 |
}
|
3845 |
/* Zero to any power but zero is zero.
|
3846 |
*/
|
3847 |
else if (!((*arg)->len))
|
3848 |
{
|
3849 |
siSetToLong(result, 0);
|
3850 |
}
|
3851 |
/* Any number but zero to the zeroth power is one. */
|
3852 |
else if (!((*exponent)->len))
|
3853 |
{
|
3854 |
siSetToLong(result, 1);
|
3855 |
}
|
3856 |
else
|
3857 |
{
|
3858 |
unsigned binary_exponent;
|
3859 |
SYNTHETIC_INTEGER *temp_si1, *result_copy1, *temp_si2, *temp_si3;
|
3860 |
|
3861 |
/* Here we have a non-zero integer raised to a non-zero power.
|
3862 |
** The best algorithm to do this is to examine the bit pattern
|
3863 |
** corresponding to the exponent--we can generate arg**2,
|
3864 |
** arg**4, arg**8, etc., just by repeatedly squaring it. NAN's
|
3865 |
** are picked up automatically.
|
3866 |
*/
|
3867 |
/* First, it is convenient convert the exponent to an
|
3868 |
** unsigned integer, so we can examine the
|
3869 |
** bit pattern directly. Will agree that anything over
|
3870 |
** 32000 is treated as 32000, to avoid platform issues.
|
3871 |
*/
|
3872 |
siCreate(&temp_si1);
|
3873 |
siCreate(&temp_si2);
|
3874 |
siCreate(&temp_si3);
|
3875 |
siCreate(&result_copy1);
|
3876 |
|
3877 |
siSetToLong(&temp_si1, 32000);
|
3878 |
|
3879 |
if (siCompare(exponent, &temp_si1) > 0)
|
3880 |
{
|
3881 |
asFatal("exponent too large (max is 32,000)");
|
3882 |
}
|
3883 |
else
|
3884 |
{
|
3885 |
/* Must convert from the string representation
|
3886 |
** buried in the synthetic integer to a binary
|
3887 |
** unsigned integer. This is a bit tricky because the
|
3888 |
** string is in reverse order from the traditional.
|
3889 |
*/
|
3890 |
{
|
3891 |
int sidx;
|
3892 |
|
3893 |
sidx = (*exponent)->len - 1;
|
3894 |
binary_exponent = 0;
|
3895 |
|
3896 |
while (sidx >= 0)
|
3897 |
{
|
3898 |
binary_exponent *= 10;
|
3899 |
binary_exponent += ddDigitToValue((*exponent)->digits[sidx]);
|
3900 |
sidx--;
|
3901 |
}
|
3902 |
}
|
3903 |
}
|
3904 |
|
3905 |
/* Start off with a result of 1 */
|
3906 |
siSetToLong(result, 1);
|
3907 |
siSetToLong(&result_copy1, 1);
|
3908 |
|
3909 |
/* Start off with arg**1 */
|
3910 |
siCopy(arg, &temp_si1);
|
3911 |
siCopy(arg, &temp_si2);
|
3912 |
siCopy(arg, &temp_si3);
|
3913 |
|
3914 |
while (binary_exponent)
|
3915 |
{
|
3916 |
/* Multiply result by the working register iff we have a 1 as the
|
3917 |
** LSB of the exponent.
|
3918 |
*/
|
3919 |
if (binary_exponent & 1)
|
3920 |
{
|
3921 |
siUnrestrictedMultiplication(
|
3922 |
&result_copy1,
|
3923 |
&temp_si1,
|
3924 |
result);
|
3925 |
|
3926 |
/* Clone out the result, because we're keeping an additional copy. */
|
3927 |
siCopy(result, &result_copy1);
|
3928 |
}
|
3929 |
|
3930 |
|
3931 |
/* Square the quantity cloned from the argument, and clone the copies
|
3932 |
** back.
|
3933 |
*/
|
3934 |
siUnrestrictedMultiplication(
|
3935 |
&temp_si1,
|
3936 |
&temp_si2,
|
3937 |
&temp_si3);
|
3938 |
siCopy(&temp_si3, &temp_si1);
|
3939 |
siCopy(&temp_si3, &temp_si2);
|
3940 |
|
3941 |
/* Shift the exponent down one bit. */
|
3942 |
binary_exponent >>= 1;
|
3943 |
}
|
3944 |
|
3945 |
/* Destroy all of the data structures created on the fly. */
|
3946 |
siDestroy(&temp_si1);
|
3947 |
siDestroy(&temp_si2);
|
3948 |
siDestroy(&temp_si3);
|
3949 |
siDestroy(&result_copy1);
|
3950 |
|
3951 |
/* At this point the result should contain the right value and
|
3952 |
** we should be ready to return.
|
3953 |
*/
|
3954 |
}
|
3955 |
}
|
3956 |
|
3957 |
|
3958 |
/****************************************************************************/
|
3959 |
/****************************************************************************/
|
3960 |
/********** R A T I O N A L N U M B E R F U N C T I O N S *********/
|
3961 |
/****************************************************************************/
|
3962 |
/****************************************************************************/
|
3963 |
/* This section is reserved for functions which operate on rational numbers.
|
3964 |
** For directness, rational numbers are represented as integer pairs (no
|
3965 |
** sense adding more data structures to this program.
|
3966 |
*/
|
3967 |
|
3968 |
/****************************************************************************/
|
3969 |
/* rnSum(): */
|
3970 |
/*--------------------------------------------------------------------------*/
|
3971 |
/* DESCRIPTION */
|
3972 |
/* Calculates the sum of two rational numbers, supplying the results in */
|
3973 |
/* lowest terms. */
|
3974 |
/* */
|
3975 |
/* INPUTS */
|
3976 |
/* **h1_formal_par_in, */
|
3977 |
/* **k1_formal_par_in, */
|
3978 |
/* **h2_formal_par_in, */
|
3979 |
/* **k2_formal_par_in : The numerators and denominators of the two */
|
3980 |
/* rational numbers to add. Zero denominators */
|
3981 |
/* are not allowed, but duplicate pointers of all */
|
3982 |
/* types are. */
|
3983 |
/* **h_result, */
|
3984 |
/* **k_result : The result, in lowest terms. Zero is repre- */
|
3985 |
/* sented canonically as 0/1. The memory must be */
|
3986 |
/* allocated in the caller's area, and the two */
|
3987 |
/* data items must be distinct. */
|
3988 |
/****************************************************************************/
|
3989 |
void rnSum(SYNTHETIC_INTEGER **h1_formal_par_in,
|
3990 |
SYNTHETIC_INTEGER **k1_formal_par_in,
|
3991 |
SYNTHETIC_INTEGER **h2_formal_par_in,
|
3992 |
SYNTHETIC_INTEGER **k2_formal_par_in,
|
3993 |
SYNTHETIC_INTEGER **h_result,
|
3994 |
SYNTHETIC_INTEGER **k_result)
|
3995 |
{
|
3996 |
SYNTHETIC_INTEGER *arg1_h,
|
3997 |
*arg1_k,
|
3998 |
*arg2_h,
|
3999 |
*arg2_k,
|
4000 |
*common_denominator,
|
4001 |
*arg1_numerator,
|
4002 |
*arg2_numerator,
|
4003 |
*cumulative_numerator,
|
4004 |
*result_gcd,
|
4005 |
*trash_remainder;
|
4006 |
|
4007 |
unsigned is_neg = FALSE;
|
4008 |
|
4009 |
/* Be sure the caller isn't doing anything silly with pointers.
|
4010 |
*/
|
4011 |
asAssert(h1_formal_par_in != NULL, __LINE__);
|
4012 |
asAssert(*h1_formal_par_in != NULL, __LINE__);
|
4013 |
asAssert(k1_formal_par_in != NULL, __LINE__);
|
4014 |
asAssert(*k1_formal_par_in != NULL, __LINE__);
|
4015 |
asAssert(h2_formal_par_in != NULL, __LINE__);
|
4016 |
asAssert(*h2_formal_par_in != NULL, __LINE__);
|
4017 |
asAssert(k2_formal_par_in != NULL, __LINE__);
|
4018 |
asAssert(*k2_formal_par_in != NULL, __LINE__);
|
4019 |
asAssert(h_result != NULL, __LINE__);
|
4020 |
asAssert(*h_result != NULL, __LINE__);
|
4021 |
asAssert(k_result != NULL, __LINE__);
|
4022 |
asAssert(*k_result != NULL, __LINE__);
|
4023 |
asAssert(h_result != k_result, __LINE__);
|
4024 |
asAssert(*h_result != *k_result, __LINE__);
|
4025 |
|
4026 |
/* Allocate space for temporary variables.
|
4027 |
*/
|
4028 |
siCreate(&arg1_h);
|
4029 |
siCreate(&arg1_k);
|
4030 |
siCreate(&arg2_h);
|
4031 |
siCreate(&arg2_k);
|
4032 |
siCreate(&common_denominator);
|
4033 |
siCreate(&arg1_numerator);
|
4034 |
siCreate(&arg2_numerator);
|
4035 |
siCreate(&cumulative_numerator);
|
4036 |
siCreate(&result_gcd);
|
4037 |
siCreate(&trash_remainder);
|
4038 |
|
4039 |
/* Copy over the formal parameters to local variables. This
|
4040 |
** means we can modify the inputs without worry.
|
4041 |
*/
|
4042 |
siCopy(h1_formal_par_in, &arg1_h);
|
4043 |
siCopy(k1_formal_par_in, &arg1_k);
|
4044 |
siCopy(h2_formal_par_in, &arg2_h);
|
4045 |
siCopy(k2_formal_par_in, &arg2_k);
|
4046 |
|
4047 |
/* If any of the four inputs are NAN, the results must be
|
4048 |
** NAN.
|
4049 |
*/
|
4050 |
if (arg1_h->nan || arg1_k->nan || arg2_h->nan || arg2_k->nan)
|
4051 |
{
|
4052 |
goto nan_return;
|
4053 |
}
|
4054 |
|
4055 |
/* If either denominator is zero, the result is NAN.
|
4056 |
*/
|
4057 |
if (!(arg1_k->len) || !(arg2_k->len))
|
4058 |
{
|
4059 |
goto nan_return;
|
4060 |
}
|
4061 |
|
4062 |
/* Adjust the signs of the the arguments so that the denominators are
|
4063 |
** always positive.
|
4064 |
*/
|
4065 |
if (arg1_h->neg && arg1_k->neg)
|
4066 |
{
|
4067 |
arg1_h->neg = FALSE;
|
4068 |
arg1_k->neg = FALSE;
|
4069 |
}
|
4070 |
else if (!(arg1_h->neg) && arg1_k->neg)
|
4071 |
{
|
4072 |
arg1_h->neg = TRUE;
|
4073 |
arg1_k->neg = FALSE;
|
4074 |
}
|
4075 |
|
4076 |
if (arg2_h->neg && arg2_k->neg)
|
4077 |
{
|
4078 |
arg2_h->neg = FALSE;
|
4079 |
arg2_k->neg = FALSE;
|
4080 |
}
|
4081 |
else if (!(arg2_h->neg) && arg2_k->neg)
|
4082 |
{
|
4083 |
arg2_h->neg = TRUE;
|
4084 |
arg2_k->neg = FALSE;
|
4085 |
}
|
4086 |
|
4087 |
/* Calculate the common denominator.
|
4088 |
*/
|
4089 |
siUnrestrictedMultiplication(&arg1_k, &arg2_k, &common_denominator);
|
4090 |
|
4091 |
/* Calculate the arg1 numerator.
|
4092 |
*/
|
4093 |
siUnrestrictedMultiplication(&arg1_h, &arg2_k, &arg1_numerator);
|
4094 |
|
4095 |
/* Calculate the arg2 numerator.
|
4096 |
*/
|
4097 |
siUnrestrictedMultiplication(&arg2_h, &arg1_k, &arg2_numerator);
|
4098 |
|
4099 |
/* Add the numerators to get the additive result. */
|
4100 |
siUnrestrictedAddition(&arg1_numerator,
|
4101 |
&arg2_numerator,
|
4102 |
&cumulative_numerator);
|
4103 |
|
4104 |
/* If we NAN'd out ...
|
4105 |
*/
|
4106 |
if (cumulative_numerator->nan)
|
4107 |
goto nan_return;
|
4108 |
|
4109 |
/* If we've reached a result of zero, it won't be legal to form
|
4110 |
** a gcd(). Assign the canonical form of zero.
|
4111 |
*/
|
4112 |
if (!(cumulative_numerator->len))
|
4113 |
{
|
4114 |
siSetToLong(h_result, 0);
|
4115 |
siSetToLong(k_result, 1);
|
4116 |
goto normal_return;
|
4117 |
}
|
4118 |
|
4119 |
/* Snatch the sign temporarily.
|
4120 |
*/
|
4121 |
if (cumulative_numerator->neg)
|
4122 |
{
|
4123 |
is_neg = TRUE;
|
4124 |
cumulative_numerator->neg = FALSE;
|
4125 |
}
|
4126 |
|
4127 |
/* Form the gcd. */
|
4128 |
siGcd(&cumulative_numerator,
|
4129 |
&common_denominator,
|
4130 |
&result_gcd);
|
4131 |
|
4132 |
/* Set the sign back. */
|
4133 |
cumulative_numerator->neg = is_neg;
|
4134 |
|
4135 |
/* Divide both numerator and denominator by
|
4136 |
** the gcd().
|
4137 |
*/
|
4138 |
siUnrestrictedDivision(&cumulative_numerator,
|
4139 |
&result_gcd,
|
4140 |
h_result,
|
4141 |
&trash_remainder);
|
4142 |
siUnrestrictedDivision(&common_denominator,
|
4143 |
&result_gcd,
|
4144 |
k_result,
|
4145 |
&trash_remainder);
|
4146 |
|
4147 |
goto normal_return;
|
4148 |
nan_return: ;
|
4149 |
siSetToNan(h_result);
|
4150 |
siSetToNan(k_result);
|
4151 |
normal_return: ;
|
4152 |
|
4153 |
/* Destroy temporary variables.
|
4154 |
*/
|
4155 |
siDestroy(&arg1_h);
|
4156 |
siDestroy(&arg1_k);
|
4157 |
siDestroy(&arg2_h);
|
4158 |
siDestroy(&arg2_k);
|
4159 |
siDestroy(&common_denominator);
|
4160 |
siDestroy(&arg1_numerator);
|
4161 |
siDestroy(&arg2_numerator);
|
4162 |
siDestroy(&cumulative_numerator);
|
4163 |
siDestroy(&result_gcd);
|
4164 |
siDestroy(&trash_remainder);
|
4165 |
}
|
4166 |
|
4167 |
|
4168 |
/****************************************************************************/
|
4169 |
/* rnDifference(): */
|
4170 |
/*--------------------------------------------------------------------------*/
|
4171 |
/* DESCRIPTION */
|
4172 |
/* Calculates the difference of two rational numbers, returning the */
|
4173 |
/* results in lowest terms. */
|
4174 |
/* */
|
4175 |
/* INPUTS */
|
4176 |
/* **h1_formal_par_in, */
|
4177 |
/* **k1_formal_par_in, */
|
4178 |
/* **h2_formal_par_in, */
|
4179 |
/* **k2_formal_par_in : The numerators and denominators of the two */
|
4180 |
/* rational numbers to subtract. Zero denominators */
|
4181 |
/* are not allowed, but duplicate pointers of all */
|
4182 |
/* types are. */
|
4183 |
/* **h_result, */
|
4184 |
/* **k_result : The result, in lowest terms. Zero is repre- */
|
4185 |
/* sented canonically as 0/1. The memory must be */
|
4186 |
/* allocated in the caller's area, and the two */
|
4187 |
/* data items must be distinct. */
|
4188 |
/****************************************************************************/
|
4189 |
void rnDifference(SYNTHETIC_INTEGER **h1_formal_par_in,
|
4190 |
SYNTHETIC_INTEGER **k1_formal_par_in,
|
4191 |
SYNTHETIC_INTEGER **h2_formal_par_in,
|
4192 |
SYNTHETIC_INTEGER **k2_formal_par_in,
|
4193 |
SYNTHETIC_INTEGER **h_result,
|
4194 |
SYNTHETIC_INTEGER **k_result)
|
4195 |
{
|
4196 |
SYNTHETIC_INTEGER *arg1_h,
|
4197 |
*arg1_k,
|
4198 |
*arg2_h,
|
4199 |
*arg2_k,
|
4200 |
*common_denominator,
|
4201 |
*arg1_numerator,
|
4202 |
*arg2_numerator,
|
4203 |
*cumulative_numerator,
|
4204 |
*result_gcd,
|
4205 |
*trash_remainder;
|
4206 |
|
4207 |
unsigned is_neg = FALSE;
|
4208 |
|
4209 |
/* Be sure the caller isn't doing anything silly with pointers.
|
4210 |
*/
|
4211 |
asAssert(h1_formal_par_in != NULL, __LINE__);
|
4212 |
asAssert(*h1_formal_par_in != NULL, __LINE__);
|
4213 |
asAssert(k1_formal_par_in != NULL, __LINE__);
|
4214 |
asAssert(*k1_formal_par_in != NULL, __LINE__);
|
4215 |
asAssert(h2_formal_par_in != NULL, __LINE__);
|
4216 |
asAssert(*h2_formal_par_in != NULL, __LINE__);
|
4217 |
asAssert(k2_formal_par_in != NULL, __LINE__);
|
4218 |
asAssert(*k2_formal_par_in != NULL, __LINE__);
|
4219 |
asAssert(h_result != NULL, __LINE__);
|
4220 |
asAssert(*h_result != NULL, __LINE__);
|
4221 |
asAssert(k_result != NULL, __LINE__);
|
4222 |
asAssert(*k_result != NULL, __LINE__);
|
4223 |
asAssert(h_result != k_result, __LINE__);
|
4224 |
asAssert(*h_result != *k_result, __LINE__);
|
4225 |
|
4226 |
/* Allocate space for temporary variables.
|
4227 |
*/
|
4228 |
siCreate(&arg1_h);
|
4229 |
siCreate(&arg1_k);
|
4230 |
siCreate(&arg2_h);
|
4231 |
siCreate(&arg2_k);
|
4232 |
siCreate(&common_denominator);
|
4233 |
siCreate(&arg1_numerator);
|
4234 |
siCreate(&arg2_numerator);
|
4235 |
siCreate(&cumulative_numerator);
|
4236 |
siCreate(&result_gcd);
|
4237 |
siCreate(&trash_remainder);
|
4238 |
|
4239 |
/* Copy over the formal parameters to local variables. This
|
4240 |
** means we can modify the inputs without worry.
|
4241 |
*/
|
4242 |
siCopy(h1_formal_par_in, &arg1_h);
|
4243 |
siCopy(k1_formal_par_in, &arg1_k);
|
4244 |
siCopy(h2_formal_par_in, &arg2_h);
|
4245 |
siCopy(k2_formal_par_in, &arg2_k);
|
4246 |
|
4247 |
/* If any of the four inputs are NAN, the results must be
|
4248 |
** NAN.
|
4249 |
*/
|
4250 |
if (arg1_h->nan || arg1_k->nan || arg2_h->nan || arg2_k->nan)
|
4251 |
{
|
4252 |
goto nan_return;
|
4253 |
}
|
4254 |
|
4255 |
/* If either denominator is zero, the result is NAN.
|
4256 |
*/
|
4257 |
if (!(arg1_k->len) || !(arg2_k->len))
|
4258 |
{
|
4259 |
goto nan_return;
|
4260 |
}
|
4261 |
|
4262 |
/* Adjust the signs of the the arguments so that the denominators are
|
4263 |
** always positive.
|
4264 |
*/
|
4265 |
if (arg1_h->neg && arg1_k->neg)
|
4266 |
{
|
4267 |
arg1_h->neg = FALSE;
|
4268 |
arg1_k->neg = FALSE;
|
4269 |
}
|
4270 |
else if (!(arg1_h->neg) && arg1_k->neg)
|
4271 |
{
|
4272 |
arg1_h->neg = TRUE;
|
4273 |
arg1_k->neg = FALSE;
|
4274 |
}
|
4275 |
|
4276 |
if (arg2_h->neg && arg2_k->neg)
|
4277 |
{
|
4278 |
arg2_h->neg = FALSE;
|
4279 |
arg2_k->neg = FALSE;
|
4280 |
}
|
4281 |
else if (!(arg2_h->neg) && arg2_k->neg)
|
4282 |
{
|
4283 |
arg2_h->neg = TRUE;
|
4284 |
arg2_k->neg = FALSE;
|
4285 |
}
|
4286 |
|
4287 |
/* Calculate the common denominator.
|
4288 |
*/
|
4289 |
siUnrestrictedMultiplication(&arg1_k, &arg2_k, &common_denominator);
|
4290 |
|
4291 |
/* Calculate the arg1 numerator.
|
4292 |
*/
|
4293 |
siUnrestrictedMultiplication(&arg1_h, &arg2_k, &arg1_numerator);
|
4294 |
|
4295 |
/* Calculate the arg2 numerator.
|
4296 |
*/
|
4297 |
siUnrestrictedMultiplication(&arg2_h, &arg1_k, &arg2_numerator);
|
4298 |
|
4299 |
/* Subtract the numerators to get the result. */
|
4300 |
siUnrestrictedSubtraction(&arg1_numerator,
|
4301 |
&arg2_numerator,
|
4302 |
&cumulative_numerator);
|
4303 |
|
4304 |
/* If we NAN'd out ...
|
4305 |
*/
|
4306 |
if (cumulative_numerator->nan)
|
4307 |
goto nan_return;
|
4308 |
|
4309 |
/* If we've reached a result of zero, it won't be legal to form
|
4310 |
** a gcd(). Assign the canonical form of zero.
|
4311 |
*/
|
4312 |
if (!(cumulative_numerator->len))
|
4313 |
{
|
4314 |
siSetToLong(h_result, 0);
|
4315 |
siSetToLong(k_result, 1);
|
4316 |
goto normal_return;
|
4317 |
}
|
4318 |
|
4319 |
/* Snatch the sign temporarily.
|
4320 |
*/
|
4321 |
if (cumulative_numerator->neg)
|
4322 |
{
|
4323 |
is_neg = TRUE;
|
4324 |
cumulative_numerator->neg = FALSE;
|
4325 |
}
|
4326 |
|
4327 |
/* Form the gcd. */
|
4328 |
siGcd(&cumulative_numerator,
|
4329 |
&common_denominator,
|
4330 |
&result_gcd);
|
4331 |
|
4332 |
/* Set the sign back. */
|
4333 |
cumulative_numerator->neg = is_neg;
|
4334 |
|
4335 |
/* Divide both numerator and denominator by
|
4336 |
** the gcd().
|
4337 |
*/
|
4338 |
siUnrestrictedDivision(&cumulative_numerator,
|
4339 |
&result_gcd,
|
4340 |
h_result,
|
4341 |
&trash_remainder);
|
4342 |
siUnrestrictedDivision(&common_denominator,
|
4343 |
&result_gcd,
|
4344 |
k_result,
|
4345 |
&trash_remainder);
|
4346 |
|
4347 |
goto normal_return;
|
4348 |
nan_return: ;
|
4349 |
siSetToNan(h_result);
|
4350 |
siSetToNan(k_result);
|
4351 |
normal_return: ;
|
4352 |
|
4353 |
/* Destroy temporary variables.
|
4354 |
*/
|
4355 |
siDestroy(&arg1_h);
|
4356 |
siDestroy(&arg1_k);
|
4357 |
siDestroy(&arg2_h);
|
4358 |
siDestroy(&arg2_k);
|
4359 |
siDestroy(&common_denominator);
|
4360 |
siDestroy(&arg1_numerator);
|
4361 |
siDestroy(&arg2_numerator);
|
4362 |
siDestroy(&cumulative_numerator);
|
4363 |
siDestroy(&result_gcd);
|
4364 |
siDestroy(&trash_remainder);
|
4365 |
}
|
4366 |
|
4367 |
|
4368 |
/****************************************************************************/
|
4369 |
/* rnProduct(): */
|
4370 |
/*--------------------------------------------------------------------------*/
|
4371 |
/* DESCRIPTION */
|
4372 |
/* Calculates the product of two rational numbers, returning the */
|
4373 |
/* results in lowest terms. */
|
4374 |
/* */
|
4375 |
/* INPUTS */
|
4376 |
/* **h1_formal_par_in, */
|
4377 |
/* **k1_formal_par_in, */
|
4378 |
/* **h2_formal_par_in, */
|
4379 |
/* **k2_formal_par_in : The numerators and denominators of the two */
|
4380 |
/* rational numbers to multiply. Zero denominators */
|
4381 |
/* are not allowed, but duplicate pointers of all */
|
4382 |
/* types are. */
|
4383 |
/* **h_result, */
|
4384 |
/* **k_result : The result, in lowest terms. Zero is repre- */
|
4385 |
/* sented canonically as 0/1. The memory must be */
|
4386 |
/* allocated in the caller's area, and the two */
|
4387 |
/* data items must be distinct. */
|
4388 |
/****************************************************************************/
|
4389 |
void rnProduct(SYNTHETIC_INTEGER **h1_formal_par_in,
|
4390 |
SYNTHETIC_INTEGER **k1_formal_par_in,
|
4391 |
SYNTHETIC_INTEGER **h2_formal_par_in,
|
4392 |
SYNTHETIC_INTEGER **k2_formal_par_in,
|
4393 |
SYNTHETIC_INTEGER **h_result,
|
4394 |
SYNTHETIC_INTEGER **k_result)
|
4395 |
{
|
4396 |
SYNTHETIC_INTEGER *arg1_h,
|
4397 |
*arg1_k,
|
4398 |
*arg2_h,
|
4399 |
*arg2_k,
|
4400 |
*result_numerator,
|
4401 |
*result_denominator,
|
4402 |
*gcd,
|
4403 |
*trash_remainder;
|
4404 |
|
4405 |
unsigned is_neg = FALSE;
|
4406 |
|
4407 |
/* Be sure the caller isn't doing anything silly with pointers.
|
4408 |
*/
|
4409 |
asAssert(h1_formal_par_in != NULL, __LINE__);
|
4410 |
asAssert(*h1_formal_par_in != NULL, __LINE__);
|
4411 |
asAssert(k1_formal_par_in != NULL, __LINE__);
|
4412 |
asAssert(*k1_formal_par_in != NULL, __LINE__);
|
4413 |
asAssert(h2_formal_par_in != NULL, __LINE__);
|
4414 |
asAssert(*h2_formal_par_in != NULL, __LINE__);
|
4415 |
asAssert(k2_formal_par_in != NULL, __LINE__);
|
4416 |
asAssert(*k2_formal_par_in != NULL, __LINE__);
|
4417 |
asAssert(h_result != NULL, __LINE__);
|
4418 |
asAssert(*h_result != NULL, __LINE__);
|
4419 |
asAssert(k_result != NULL, __LINE__);
|
4420 |
asAssert(*k_result != NULL, __LINE__);
|
4421 |
asAssert(h_result != k_result, __LINE__);
|
4422 |
asAssert(*h_result != *k_result, __LINE__);
|
4423 |
|
4424 |
/* Allocate space for temporary variables.
|
4425 |
*/
|
4426 |
siCreate(&arg1_h);
|
4427 |
siCreate(&arg1_k);
|
4428 |
siCreate(&arg2_h);
|
4429 |
siCreate(&arg2_k);
|
4430 |
siCreate(&result_numerator);
|
4431 |
siCreate(&result_denominator);
|
4432 |
siCreate(&gcd);
|
4433 |
siCreate(&trash_remainder);
|
4434 |
|
4435 |
/* Copy over the formal parameters to local variables. This
|
4436 |
** means we can modify the inputs without worry.
|
4437 |
*/
|
4438 |
siCopy(h1_formal_par_in, &arg1_h);
|
4439 |
siCopy(k1_formal_par_in, &arg1_k);
|
4440 |
siCopy(h2_formal_par_in, &arg2_h);
|
4441 |
siCopy(k2_formal_par_in, &arg2_k);
|
4442 |
|
4443 |
/* If any of the four inputs are NAN, the results must be
|
4444 |
** NAN.
|
4445 |
*/
|
4446 |
if (arg1_h->nan || arg1_k->nan || arg2_h->nan || arg2_k->nan)
|
4447 |
{
|
4448 |
goto nan_return;
|
4449 |
}
|
4450 |
|
4451 |
/* If either denominator is zero, the result is NAN.
|
4452 |
*/
|
4453 |
if (!(arg1_k->len) || !(arg2_k->len))
|
4454 |
{
|
4455 |
goto nan_return;
|
4456 |
}
|
4457 |
|
4458 |
/* Carry out the multiplication of numerators and denominators to get
|
4459 |
** the two products.
|
4460 |
*/
|
4461 |
siUnrestrictedMultiplication(&arg1_h, &arg2_h, &result_numerator);
|
4462 |
siUnrestrictedMultiplication(&arg1_k, &arg2_k, &result_denominator);
|
4463 |
|
4464 |
/* If either result is NAN, the results are NAN.
|
4465 |
*/
|
4466 |
if (result_numerator->nan || result_denominator->nan)
|
4467 |
{
|
4468 |
goto nan_return;
|
4469 |
}
|
4470 |
|
4471 |
/* If the numerator is zero, we must return canonical zero.
|
4472 |
*/
|
4473 |
if (!(result_numerator->len))
|
4474 |
{
|
4475 |
siSetToLong(h_result, 0);
|
4476 |
siSetToLong(k_result, 1);
|
4477 |
goto normal_return;
|
4478 |
}
|
4479 |
|
4480 |
/* We need to acquire the sign and make both results positive otherwise
|
4481 |
** can't obtain the GCD.
|
4482 |
*/
|
4483 |
if (result_numerator->neg)
|
4484 |
{
|
4485 |
is_neg = TRUE;
|
4486 |
result_numerator->neg = FALSE;
|
4487 |
}
|
4488 |
if (result_denominator->neg)
|
4489 |
{
|
4490 |
is_neg = !is_neg;
|
4491 |
result_denominator->neg = FALSE;
|
4492 |
}
|
4493 |
|
4494 |
/* Form the gcd. */
|
4495 |
siGcd(&result_numerator,
|
4496 |
&result_denominator,
|
4497 |
&gcd);
|
4498 |
|
4499 |
/* Set the sign back. */
|
4500 |
result_numerator->neg = is_neg;
|
4501 |
|
4502 |
/* Divide both numerator and denominator by
|
4503 |
** the gcd().
|
4504 |
*/
|
4505 |
siUnrestrictedDivision(&result_numerator,
|
4506 |
&gcd,
|
4507 |
h_result,
|
4508 |
&trash_remainder);
|
4509 |
siUnrestrictedDivision(&result_denominator,
|
4510 |
&gcd,
|
4511 |
k_result,
|
4512 |
&trash_remainder);
|
4513 |
|
4514 |
goto normal_return;
|
4515 |
nan_return: ;
|
4516 |
siSetToNan(h_result);
|
4517 |
siSetToNan(k_result);
|
4518 |
normal_return: ;
|
4519 |
|
4520 |
/* Destroy temporary variables.
|
4521 |
*/
|
4522 |
siDestroy(&arg1_h);
|
4523 |
siDestroy(&arg1_k);
|
4524 |
siDestroy(&arg2_h);
|
4525 |
siDestroy(&arg2_k);
|
4526 |
siDestroy(&result_numerator);
|
4527 |
siDestroy(&result_denominator);
|
4528 |
siDestroy(&gcd);
|
4529 |
siDestroy(&trash_remainder);
|
4530 |
}
|
4531 |
|
4532 |
|
4533 |
/****************************************************************************/
|
4534 |
/* rnQuotient(): */
|
4535 |
/*--------------------------------------------------------------------------*/
|
4536 |
/* DESCRIPTION */
|
4537 |
/* Calculates the quotient of two rational numbers, returning the */
|
4538 |
/* results in lowest terms. */
|
4539 |
/* */
|
4540 |
/* INPUTS */
|
4541 |
/* **h1_formal_par_in, */
|
4542 |
/* **k1_formal_par_in, */
|
4543 |
/* **h2_formal_par_in, */
|
4544 |
/* **k2_formal_par_in : The numerators and denominators of the two */
|
4545 |
/* rational numbers to divide. Zero denominators */
|
4546 |
/* and zero divisors are not allowed, but duplicate */
|
4547 |
/* pointers of all types are. */
|
4548 |
/* **h_result, */
|
4549 |
/* **k_result : The result, in lowest terms. Zero is repre- */
|
4550 |
/* sented canonically as 0/1. The memory must be */
|
4551 |
/* allocated in the caller's area, and the two */
|
4552 |
/* data items must be distinct. */
|
4553 |
/****************************************************************************/
|
4554 |
void rnQuotient(SYNTHETIC_INTEGER **h1_formal_par_in,
|
4555 |
SYNTHETIC_INTEGER **k1_formal_par_in,
|
4556 |
SYNTHETIC_INTEGER **h2_formal_par_in,
|
4557 |
SYNTHETIC_INTEGER **k2_formal_par_in,
|
4558 |
SYNTHETIC_INTEGER **h_result,
|
4559 |
SYNTHETIC_INTEGER **k_result)
|
4560 |
{
|
4561 |
SYNTHETIC_INTEGER *arg1_h,
|
4562 |
*arg1_k,
|
4563 |
*arg2_h,
|
4564 |
*arg2_k,
|
4565 |
*result_numerator,
|
4566 |
*result_denominator,
|
4567 |
*gcd,
|
4568 |
*trash_remainder;
|
4569 |
|
4570 |
unsigned is_neg = FALSE;
|
4571 |
|
4572 |
/* Be sure the caller isn't doing anything silly with pointers.
|
4573 |
*/
|
4574 |
asAssert(h1_formal_par_in != NULL, __LINE__);
|
4575 |
asAssert(*h1_formal_par_in != NULL, __LINE__);
|
4576 |
asAssert(k1_formal_par_in != NULL, __LINE__);
|
4577 |
asAssert(*k1_formal_par_in != NULL, __LINE__);
|
4578 |
asAssert(h2_formal_par_in != NULL, __LINE__);
|
4579 |
asAssert(*h2_formal_par_in != NULL, __LINE__);
|
4580 |
asAssert(k2_formal_par_in != NULL, __LINE__);
|
4581 |
asAssert(*k2_formal_par_in != NULL, __LINE__);
|
4582 |
asAssert(h_result != NULL, __LINE__);
|
4583 |
asAssert(*h_result != NULL, __LINE__);
|
4584 |
asAssert(k_result != NULL, __LINE__);
|
4585 |
asAssert(*k_result != NULL, __LINE__);
|
4586 |
asAssert(h_result != k_result, __LINE__);
|
4587 |
asAssert(*h_result != *k_result, __LINE__);
|
4588 |
|
4589 |
/* Allocate space for temporary variables.
|
4590 |
*/
|
4591 |
siCreate(&arg1_h);
|
4592 |
siCreate(&arg1_k);
|
4593 |
siCreate(&arg2_h);
|
4594 |
siCreate(&arg2_k);
|
4595 |
siCreate(&result_numerator);
|
4596 |
siCreate(&result_denominator);
|
4597 |
siCreate(&gcd);
|
4598 |
siCreate(&trash_remainder);
|
4599 |
|
4600 |
/* Copy over the formal parameters to local variables. This
|
4601 |
** means we can modify the inputs without worry.
|
4602 |
*/
|
4603 |
siCopy(h1_formal_par_in, &arg1_h);
|
4604 |
siCopy(k1_formal_par_in, &arg1_k);
|
4605 |
siCopy(h2_formal_par_in, &arg2_h);
|
4606 |
siCopy(k2_formal_par_in, &arg2_k);
|
4607 |
|
4608 |
/* If any of the four inputs are NAN, the results must be
|
4609 |
** NAN.
|
4610 |
*/
|
4611 |
if (arg1_h->nan || arg1_k->nan || arg2_h->nan || arg2_k->nan)
|
4612 |
{
|
4613 |
goto nan_return;
|
4614 |
}
|
4615 |
|
4616 |
/* If either denominator is zero, the result is NAN.
|
4617 |
*/
|
4618 |
if (!(arg1_k->len) || !(arg2_k->len))
|
4619 |
{
|
4620 |
goto nan_return;
|
4621 |
}
|
4622 |
|
4623 |
/* Carry out the multiplication of numerators and denominators to get
|
4624 |
** the two products.
|
4625 |
*/
|
4626 |
siUnrestrictedMultiplication(&arg1_h, &arg2_k, &result_numerator);
|
4627 |
siUnrestrictedMultiplication(&arg1_k, &arg2_h, &result_denominator);
|
4628 |
|
4629 |
/* If either result is NAN, the results are NAN.
|
4630 |
*/
|
4631 |
if (result_numerator->nan || result_denominator->nan)
|
4632 |
{
|
4633 |
goto nan_return;
|
4634 |
}
|
4635 |
|
4636 |
/* If the denominator of the result is zero, this is a no-no-NAN, too.
|
4637 |
*/
|
4638 |
if (!(result_denominator->len))
|
4639 |
{
|
4640 |
goto nan_return;
|
4641 |
}
|
4642 |
|
4643 |
/* If the numerator is zero, we must return canonical zero.
|
4644 |
*/
|
4645 |
if (!(result_numerator->len))
|
4646 |
{
|
4647 |
siSetToLong(h_result, 0);
|
4648 |
siSetToLong(k_result, 1);
|
4649 |
goto normal_return;
|
4650 |
}
|
4651 |
|
4652 |
/* We need to acquire the sign and make both results positive otherwise
|
4653 |
** can't obtain the GCD.
|
4654 |
*/
|
4655 |
if (result_numerator->neg)
|
4656 |
{
|
4657 |
is_neg = TRUE;
|
4658 |
result_numerator->neg = FALSE;
|
4659 |
}
|
4660 |
if (result_denominator->neg)
|
4661 |
{
|
4662 |
is_neg = !is_neg;
|
4663 |
result_denominator->neg = FALSE;
|
4664 |
}
|
4665 |
|
4666 |
/* Form the gcd. */
|
4667 |
siGcd(&result_numerator,
|
4668 |
&result_denominator,
|
4669 |
&gcd);
|
4670 |
|
4671 |
/* Set the sign back. */
|
4672 |
result_numerator->neg = is_neg;
|
4673 |
|
4674 |
/* Divide both numerator and denominator by
|
4675 |
** the gcd().
|
4676 |
*/
|
4677 |
siUnrestrictedDivision(&result_numerator,
|
4678 |
&gcd,
|
4679 |
h_result,
|
4680 |
&trash_remainder);
|
4681 |
siUnrestrictedDivision(&result_denominator,
|
4682 |
&gcd,
|
4683 |
k_result,
|
4684 |
&trash_remainder);
|
4685 |
|
4686 |
goto normal_return;
|
4687 |
nan_return: ;
|
4688 |
siSetToNan(h_result);
|
4689 |
siSetToNan(k_result);
|
4690 |
normal_return: ;
|
4691 |
|
4692 |
/* Destroy temporary variables.
|
4693 |
*/
|
4694 |
siDestroy(&arg1_h);
|
4695 |
siDestroy(&arg1_k);
|
4696 |
siDestroy(&arg2_h);
|
4697 |
siDestroy(&arg2_k);
|
4698 |
siDestroy(&result_numerator);
|
4699 |
siDestroy(&result_denominator);
|
4700 |
siDestroy(&gcd);
|
4701 |
siDestroy(&trash_remainder);
|
4702 |
}
|
4703 |
|
4704 |
|
4705 |
/****************************************************************************/
|
4706 |
/* rnCanonize(): */
|
4707 |
/*--------------------------------------------------------------------------*/
|
4708 |
/* DESCRIPTION */
|
4709 |
/* Puts the rational number passed into a canonical form, which means: */
|
4710 |
/* a)If either synthetic integer is NAN, both are marked NAN. */
|
4711 |
/* b)If the denominator is zero, both synthetic integers are marked */
|
4712 |
/* NAN. */
|
4713 |
/* c)If the number has a value of zero, it is set to the canonical */
|
4714 |
/* form of 0/1. */
|
4715 |
/* d)If the number represents a positive value, the signs of both */
|
4716 |
/* synthetic integers are set +. If the number represents a */
|
4717 |
/* negative value, the numerator will be set - and the denominator */
|
4718 |
/* -. */
|
4719 |
/* e)Any g.c.d. will be removed so that the number is in lowest */
|
4720 |
/* terms. */
|
4721 |
/* */
|
4722 |
/* INPUTS (AND OUTPUTS) */
|
4723 |
/* **h_formal_par_in, */
|
4724 |
/* **k_formal_par_in : The numerator and denominator of the number to */
|
4725 |
/* operate on. */
|
4726 |
/****************************************************************************/
|
4727 |
void rnCanonize(SYNTHETIC_INTEGER **h_formal_par_in,
|
4728 |
SYNTHETIC_INTEGER **k_formal_par_in)
|
4729 |
{
|
4730 |
int is_neg = FALSE;
|
4731 |
SYNTHETIC_INTEGER *gcd, *trash_remainder, *si_temp;
|
4732 |
|
4733 |
/* Be sure the caller isn't doing anything silly with pointers.
|
4734 |
*/
|
4735 |
asAssert(h_formal_par_in != NULL, __LINE__);
|
4736 |
asAssert(*h_formal_par_in != NULL, __LINE__);
|
4737 |
asAssert(k_formal_par_in != NULL, __LINE__);
|
4738 |
asAssert(*k_formal_par_in != NULL, __LINE__);
|
4739 |
asAssert(h_formal_par_in != k_formal_par_in, __LINE__);
|
4740 |
asAssert(*h_formal_par_in != *k_formal_par_in, __LINE__);
|
4741 |
|
4742 |
/* Create the local integers.
|
4743 |
*/
|
4744 |
siCreate(&gcd);
|
4745 |
siCreate(&trash_remainder);
|
4746 |
siCreate(&si_temp);
|
4747 |
|
4748 |
/* If either input is NAN, must mark both NAN.
|
4749 |
*/
|
4750 |
if ((*h_formal_par_in)->nan || (*k_formal_par_in)->nan)
|
4751 |
goto nan_return;
|
4752 |
|
4753 |
/* If the denominator is zero, must also mark both NAN.
|
4754 |
*/
|
4755 |
if (!((*k_formal_par_in)->len))
|
4756 |
goto nan_return;
|
4757 |
|
4758 |
/* If the numerator is zero, the right answer is canonical zero, and
|
4759 |
** must return canonical 0/1.
|
4760 |
*/
|
4761 |
if (!((*h_formal_par_in)->len))
|
4762 |
goto zero_return;
|
4763 |
|
4764 |
/* If we made it to this point, we have two non-zero integers, and the
|
4765 |
** result will be non-zero. Must canonize the sign and factor out
|
4766 |
** any g.c.d.
|
4767 |
*/
|
4768 |
if ((((*h_formal_par_in)->neg) && !((*k_formal_par_in)->neg))
|
4769 |
||
|
4770 |
(!((*h_formal_par_in)->neg) && ((*k_formal_par_in)->neg)))
|
4771 |
{
|
4772 |
is_neg = TRUE;
|
4773 |
}
|
4774 |
|
4775 |
(*h_formal_par_in)->neg = FALSE;
|
4776 |
(*k_formal_par_in)->neg = FALSE;
|
4777 |
|
4778 |
siGcd(h_formal_par_in, k_formal_par_in, &gcd);
|
4779 |
|
4780 |
siUnrestrictedDivision(h_formal_par_in, &gcd,
|
4781 |
&si_temp, &trash_remainder);
|
4782 |
siCopy(&si_temp, h_formal_par_in);
|
4783 |
siUnrestrictedDivision(k_formal_par_in, &gcd,
|
4784 |
&si_temp, &trash_remainder);
|
4785 |
siCopy(&si_temp, k_formal_par_in);
|
4786 |
|
4787 |
if (is_neg)
|
4788 |
(*h_formal_par_in)->neg = TRUE;
|
4789 |
|
4790 |
goto normal_return;
|
4791 |
nan_return: ;
|
4792 |
siSetToNan(h_formal_par_in);
|
4793 |
siSetToNan(k_formal_par_in);
|
4794 |
goto normal_return;
|
4795 |
zero_return:
|
4796 |
siSetToLong(h_formal_par_in, 0);
|
4797 |
siSetToLong(k_formal_par_in, 1);
|
4798 |
goto normal_return;
|
4799 |
normal_return: ;
|
4800 |
|
4801 |
/* Destroy the local integers.
|
4802 |
*/
|
4803 |
siDestroy(&gcd);
|
4804 |
siDestroy(&trash_remainder);
|
4805 |
siDestroy(&si_temp);
|
4806 |
}
|
4807 |
|
4808 |
|
4809 |
/****************************************************************************/
|
4810 |
/* rnCompare(): */
|
4811 |
/*--------------------------------------------------------------------------*/
|
4812 |
/* DESCRIPTION */
|
4813 |
/* Compares two rational numbers to determine thier ranking on the number */
|
4814 |
/* line. */
|
4815 |
/* */
|
4816 |
/* INPUTS . */
|
4817 |
/* **h_1, **k_1, */
|
4818 |
/* **h_2, **k_2 : The two rational numbers to compare. They are not */
|
4819 |
/* required to be in canonical form, but the */
|
4820 |
/* denominators may not be zero. */
|
4821 |
/* */
|
4822 |
/* OUTPUT */
|
4823 |
/* <-- : -1 if h1/k1 < h2/k2 */
|
4824 |
/* 0 if h1/k1 = h2/k2 */
|
4825 |
/* 1 if h1/k1 > h2/k2 */
|
4826 |
/****************************************************************************/
|
4827 |
int rnCompare(SYNTHETIC_INTEGER **h_1,
|
4828 |
SYNTHETIC_INTEGER **k_1,
|
4829 |
SYNTHETIC_INTEGER **h_2,
|
4830 |
SYNTHETIC_INTEGER **k_2)
|
4831 |
{
|
4832 |
int rv=0;
|
4833 |
|
4834 |
SYNTHETIC_INTEGER *h1,
|
4835 |
*k1,
|
4836 |
*h2,
|
4837 |
*k2,
|
4838 |
*left_cross_product,
|
4839 |
*right_cross_product;
|
4840 |
|
4841 |
/* Be sure the caller isn't doing anything silly with pointers.
|
4842 |
*/
|
4843 |
asAssert(h_1 != NULL, __LINE__);
|
4844 |
asAssert(*h_1 != NULL, __LINE__);
|
4845 |
asAssert(k_1 != NULL, __LINE__);
|
4846 |
asAssert(*k_1 != NULL, __LINE__);
|
4847 |
asAssert(h_2 != NULL, __LINE__);
|
4848 |
asAssert(*h_2 != NULL, __LINE__);
|
4849 |
asAssert(k_2 != NULL, __LINE__);
|
4850 |
asAssert(*k_2 != NULL, __LINE__);
|
4851 |
|
4852 |
/* Allocate all of our temps.
|
4853 |
*/
|
4854 |
siCreate(&h1);
|
4855 |
siCreate(&k1);
|
4856 |
siCreate(&h2);
|
4857 |
siCreate(&k2);
|
4858 |
siCreate(&left_cross_product);
|
4859 |
siCreate(&right_cross_product);
|
4860 |
|
4861 |
/* Copy the formal parameters to the temps so we can mess
|
4862 |
** around with them.
|
4863 |
*/
|
4864 |
siCopy(h_1, &h1);
|
4865 |
siCopy(k_1, &k1);
|
4866 |
siCopy(h_2, &h2);
|
4867 |
siCopy(k_2, &k2);
|
4868 |
|
4869 |
/* The denominators may not be zero.
|
4870 |
*/
|
4871 |
asAssert((k1->len != 0) && (k2->len != 0) ,__LINE__);
|
4872 |
|
4873 |
/* We need to normalize the signs on the two fractions.
|
4874 |
** The cross-product inequality utilized breaks down
|
4875 |
** if either denominator is negative.
|
4876 |
*/
|
4877 |
if ((!(h1->neg) && (k1->neg)) || ((h1->neg) && !(k1->neg)))
|
4878 |
{
|
4879 |
h1->neg = TRUE;
|
4880 |
k1->neg = FALSE;
|
4881 |
}
|
4882 |
else
|
4883 |
{
|
4884 |
h1->neg = FALSE;
|
4885 |
k1->neg = FALSE;
|
4886 |
}
|
4887 |
|
4888 |
if ((!(h2->neg) && (k2->neg)) || ((h2->neg) && !(k2->neg)))
|
4889 |
{
|
4890 |
h2->neg = TRUE;
|
4891 |
k2->neg = FALSE;
|
4892 |
}
|
4893 |
else
|
4894 |
{
|
4895 |
h2->neg = FALSE;
|
4896 |
k2->neg = FALSE;
|
4897 |
}
|
4898 |
|
4899 |
/* Form the left cross-product and right cross-product. If we get
|
4900 |
** a NAN, we have to kill this function, as it would compromise
|
4901 |
** the integrity of the program (there is no notion of NAN for a
|
4902 |
** comparison result).
|
4903 |
*/
|
4904 |
siUnrestrictedMultiplication(&h1, &k2, &left_cross_product);
|
4905 |
siUnrestrictedMultiplication(&h2, &k1, &right_cross_product);
|
4906 |
asAssert(!(left_cross_product->nan) && !(right_cross_product->nan), __LINE__);
|
4907 |
|
4908 |
/* The comparison result is the same as the relationship between the
|
4909 |
** two cross-products. A few words should be said about this.
|
4910 |
**
|
4911 |
** Let a/b and c/d be the two rational numbers.
|
4912 |
** Assume that b>0 and d>0.
|
4913 |
** ad < bc
|
4914 |
** -> ad/b < c
|
4915 |
** ->a/b < c/d.
|
4916 |
** and the same logic can be applied to the other relational
|
4917 |
** operators.
|
4918 |
*/
|
4919 |
rv = siCompare(&left_cross_product, &right_cross_product);
|
4920 |
|
4921 |
#if 0
|
4922 |
siDump(&left_cross_product, "left");
|
4923 |
siDump(&right_cross_product, "right");
|
4924 |
#endif
|
4925 |
|
4926 |
/* Destroy all of our temps.
|
4927 |
*/
|
4928 |
siDestroy(&h1);
|
4929 |
siDestroy(&k1);
|
4930 |
siDestroy(&h2);
|
4931 |
siDestroy(&k2);
|
4932 |
siDestroy(&left_cross_product);
|
4933 |
siDestroy(&right_cross_product);
|
4934 |
|
4935 |
/* Return the return value.
|
4936 |
*/
|
4937 |
return(rv);
|
4938 |
}
|
4939 |
|
4940 |
|
4941 |
/****************************************************************************/
|
4942 |
/* rnDap(): */
|
4943 |
/*--------------------------------------------------------------------------*/
|
4944 |
/* DESCRIPTION */
|
4945 |
/* Converts a rational number to an approximately equivalent value */
|
4946 |
/* with a different denominator. This functionality is the same as */
|
4947 |
/* implemented by the DAP command. */
|
4948 |
/* */
|
4949 |
/* INPUTS . */
|
4950 |
/* **h, **k : The rational number to represent differently. */
|
4951 |
/* The denominator may not be zero. */
|
4952 |
/* */
|
4953 |
/* **D : The new denominator. May not be zero. */
|
4954 |
/* */
|
4955 |
/* OUTPUTS */
|
4956 |
/* **N : The new numerator. */
|
4957 |
/****************************************************************************/
|
4958 |
void rnDap(SYNTHETIC_INTEGER **h,
|
4959 |
SYNTHETIC_INTEGER **k,
|
4960 |
SYNTHETIC_INTEGER **N,
|
4961 |
SYNTHETIC_INTEGER **D)
|
4962 |
{
|
4963 |
SYNTHETIC_INTEGER *numerator_product,
|
4964 |
*quotient,
|
4965 |
*trash_remainder;
|
4966 |
|
4967 |
/* Be sure the caller is doing nothing silly with pointers.
|
4968 |
*/
|
4969 |
asAssert(h != NULL, __LINE__);
|
4970 |
asAssert(*h != NULL, __LINE__);
|
4971 |
asAssert(k != NULL, __LINE__);
|
4972 |
asAssert(*k != NULL, __LINE__);
|
4973 |
asAssert(N != NULL, __LINE__);
|
4974 |
asAssert(*N != NULL, __LINE__);
|
4975 |
asAssert(D != NULL, __LINE__);
|
4976 |
asAssert(*D != NULL, __LINE__);
|
4977 |
|
4978 |
/* Allocate our locals.
|
4979 |
*/
|
4980 |
siCreate(&numerator_product);
|
4981 |
siCreate("ient);
|
4982 |
siCreate(&trash_remainder);
|
4983 |
|
4984 |
/* If anything is NAN, the result is necessarily NAN.
|
4985 |
*/
|
4986 |
if ((*h)->nan || (*k)->nan || (*D)->nan)
|
4987 |
goto nan_return;
|
4988 |
|
4989 |
/* If the old denominator is zero, the result is necessarily NAN.
|
4990 |
*/
|
4991 |
if (!((*k)->len))
|
4992 |
goto nan_return;
|
4993 |
|
4994 |
/* If the new denominator requested is zero, the result is necessarily NAN.
|
4995 |
*/
|
4996 |
if (!((*D)->len))
|
4997 |
goto nan_return;
|
4998 |
|
4999 |
/* Calculate the numerator as specified in the manual under the DAP
|
5000 |
** command.
|
5001 |
*/
|
5002 |
siUnrestrictedMultiplication(h, D, &numerator_product);
|
5003 |
|
5004 |
/* Divide to get the value.
|
5005 |
*/
|
5006 |
siUnrestrictedDivision(&numerator_product, k, "ient, &trash_remainder);
|
5007 |
|
5008 |
/* Copy to caller's area.
|
5009 |
*/
|
5010 |
siCopy("ient, N);
|
5011 |
|
5012 |
goto normal_return;
|
5013 |
nan_return:
|
5014 |
siSetToNan(N);
|
5015 |
normal_return: ;
|
5016 |
|
5017 |
/* Destroy our locals.
|
5018 |
*/
|
5019 |
siDestroy(&numerator_product);
|
5020 |
siDestroy("ient);
|
5021 |
siDestroy(&trash_remainder);
|
5022 |
}
|
5023 |
|
5024 |
|
5025 |
/****************************************************************************/
|
5026 |
/* rnFareyTraverse(): */
|
5027 |
/*--------------------------------------------------------------------------*/
|
5028 |
/* DESCRIPTION */
|
5029 |
/* Uses the standard recursive formulas to traverse the Farey series */
|
5030 |
/* in either direction. Two successive terms, in lowest terms, are */
|
5031 |
/* needed. */
|
5032 |
/* */
|
5033 |
/* INPUTS . */
|
5034 |
/* **h1in, **k1in: The first rational number in the series of interest, */
|
5035 |
/* which must have a positive denominator and a non- */
|
5036 |
/* negative numerator. */
|
5037 |
/* */
|
5038 |
/* **h2in, **k2in: The second rational number in the series of interest, */
|
5039 |
/* same rules as above and must be greater than first */
|
5040 |
/* term h1in/k1in. */
|
5041 |
/* */
|
5042 |
/* **N : The order of the series to form. */
|
5043 |
/* */
|
5044 |
/* dir : (-1): The series is advanced backwards. r(2)=r(1), */
|
5045 |
/* and r(1) = new term < r(2). */
|
5046 |
/* (+1): The series is advanced forwards. r(1)=r(2), */
|
5047 |
/* and r(2) = new term > r(1). */
|
5048 |
/****************************************************************************/
|
5049 |
void rnFareyTraverse(SYNTHETIC_INTEGER **h1in,
|
5050 |
SYNTHETIC_INTEGER **k1in,
|
5051 |
SYNTHETIC_INTEGER **h2in,
|
5052 |
SYNTHETIC_INTEGER **k2in,
|
5053 |
SYNTHETIC_INTEGER **N,
|
5054 |
int dir)
|
5055 |
{
|
5056 |
SYNTHETIC_INTEGER *t1, *t2, *t3, *new_h, *new_k;
|
5057 |
|
5058 |
/* Be sure the caller isn't doing anything silly with pointers.
|
5059 |
*/
|
5060 |
asAssert(h1in != NULL, __LINE__);
|
5061 |
asAssert(*h1in != NULL, __LINE__);
|
5062 |
asAssert(k1in != NULL, __LINE__);
|
5063 |
asAssert(*k1in != NULL, __LINE__);
|
5064 |
asAssert(h2in != NULL, __LINE__);
|
5065 |
asAssert(*h2in != NULL, __LINE__);
|
5066 |
asAssert(k2in != NULL, __LINE__);
|
5067 |
asAssert(*k2in != NULL, __LINE__);
|
5068 |
asAssert(N != NULL, __LINE__);
|
5069 |
asAssert(*N != NULL, __LINE__);
|
5070 |
|
5071 |
/* It is also critical that none of the pointers be duplicates,
|
5072 |
** but this isn't checked.
|
5073 |
*/
|
5074 |
|
5075 |
/* Allocate local variables.
|
5076 |
*/
|
5077 |
siCreate(&t1);
|
5078 |
siCreate(&t2);
|
5079 |
siCreate(&t3);
|
5080 |
siCreate(&new_h);
|
5081 |
siCreate(&new_k);
|
5082 |
|
5083 |
/* Split into cases based on the direction.
|
5084 |
*/
|
5085 |
if (dir > 0)
|
5086 |
{
|
5087 |
/* Forward
|
5088 |
*/
|
5089 |
/* Calculate the term floor((k[j-2] + N)/k[j-1]), which we'll need
|
5090 |
** twice. The result is left in "t2".
|
5091 |
*/
|
5092 |
siUnrestrictedAddition(k1in, N, &t1);
|
5093 |
siUnrestrictedDivision(&t1, k2in, &t2, &t3);
|
5094 |
|
5095 |
/* Multiply by h[j-1] and place in "t1".
|
5096 |
*/
|
5097 |
siUnrestrictedMultiplication(&t2, h2in, &t1);
|
5098 |
|
5099 |
/* Subtract off h[j-2] and this is our new h.
|
5100 |
*/
|
5101 |
siUnrestrictedSubtraction(&t1, h1in, &new_h);
|
5102 |
|
5103 |
/* Multiply intermediate term by k[j-1] and place in "t1".
|
5104 |
*/
|
5105 |
siUnrestrictedMultiplication(&t2, k2in, &t1);
|
5106 |
|
5107 |
/* Subtract off k[j-2] and this is our new k.
|
5108 |
*/
|
5109 |
siUnrestrictedSubtraction(&t1, k1in, &new_k);
|
5110 |
|
5111 |
/* Place the new results.
|
5112 |
*/
|
5113 |
siCopy(h2in, h1in);
|
5114 |
siCopy(k2in, k1in);
|
5115 |
siCopy(&new_h, h2in);
|
5116 |
siCopy(&new_k, k2in);
|
5117 |
}
|
5118 |
else
|
5119 |
{
|
5120 |
/* Reverse: steps symmetrical with forward.
|
5121 |
*/
|
5122 |
siUnrestrictedAddition(k2in, N, &t1);
|
5123 |
siUnrestrictedDivision(&t1, k1in, &t2, &t3);
|
5124 |
siUnrestrictedMultiplication(&t2, h1in, &t1);
|
5125 |
siUnrestrictedSubtraction(&t1, h2in, &new_h);
|
5126 |
siUnrestrictedMultiplication(&t2, k1in, &t1);
|
5127 |
siUnrestrictedSubtraction(&t1, k2in, &new_k);
|
5128 |
|
5129 |
/* Place the new results.
|
5130 |
*/
|
5131 |
siCopy(h1in, h2in);
|
5132 |
siCopy(k1in, k2in);
|
5133 |
siCopy(&new_h, h1in);
|
5134 |
siCopy(&new_k, k1in);
|
5135 |
}
|
5136 |
|
5137 |
|
5138 |
/* Destroy local variables.
|
5139 |
*/
|
5140 |
siDestroy(&t1);
|
5141 |
siDestroy(&t2);
|
5142 |
siDestroy(&t3);
|
5143 |
siDestroy(&new_h);
|
5144 |
siDestroy(&new_k);
|
5145 |
}
|
5146 |
|
5147 |
|
5148 |
/****************************************************************************/
|
5149 |
/****************************************************************************/
|
5150 |
/******* C O N T I N U E D F R A C T I O N F U N C T I O N S ******/
|
5151 |
/****************************************************************************/
|
5152 |
/****************************************************************************/
|
5153 |
/* This section is reserved for functions which form and manipulate
|
5154 |
** continued fractions and convergents. Note that every number has at
|
5155 |
** least a 0th order CF partial quotient and at least a 0th order
|
5156 |
** convergent (the integer part).
|
5157 |
*/
|
5158 |
typedef struct
|
5159 |
{
|
5160 |
SYNTHETIC_INTEGER *raw_numerator;
|
5161 |
SYNTHETIC_INTEGER *raw_denominator;
|
5162 |
/* The raw numerator and denominator passed to the function which
|
5163 |
** calculates partial quotients and convergents. This might
|
5164 |
** not be in lowest terms. No negative integers are allowed,
|
5165 |
** and zero must be represented canonically as 0/(D>0).
|
5166 |
*/
|
5167 |
SYNTHETIC_INTEGER *numerator;
|
5168 |
SYNTHETIC_INTEGER *denominator;
|
5169 |
/* The numerator and denominator, in lowest terms, of the
|
5170 |
** rational number whose continued fraction expansion we
|
5171 |
** are forming. No negative integers are allowed, and
|
5172 |
** zero must be represented canonically as 0/1.
|
5173 |
*/
|
5174 |
int n;
|
5175 |
/* The number of elements in the parallel arrays of partial
|
5176 |
** quotients, etc., which are maintained. This must be
|
5177 |
** at least 1, which would mean that only the 0th-order
|
5178 |
** items are filled in.
|
5179 |
*/
|
5180 |
SYNTHETIC_INTEGER **a;
|
5181 |
/* Pointer to a dynamically allocated array of n pointers,
|
5182 |
** each of which points to a synthetic integer. This
|
5183 |
** pointer may be shifted on any operation on this data
|
5184 |
** structure (due to the behavior of "realloc()"), so
|
5185 |
** a caller should never retain internal pointers when
|
5186 |
** making function calls which might resize anything
|
5187 |
** internally in this data structure. The same sizing arguments
|
5188 |
** here apply to all the other parallel elements, so it won't
|
5189 |
** be described again.
|
5190 |
*/
|
5191 |
SYNTHETIC_INTEGER **p;
|
5192 |
SYNTHETIC_INTEGER **q;
|
5193 |
/* Convergents of continued fraction expansion of the
|
5194 |
** rational number.
|
5195 |
*/
|
5196 |
} CF_EXPANSION;
|
5197 |
|
5198 |
|
5199 |
/****************************************************************************/
|
5200 |
/* pqCreate(): */
|
5201 |
/*--------------------------------------------------------------------------*/
|
5202 |
/* DESCRIPTION */
|
5203 |
/* Creates the continued fraction partial quotient expansion of a non- */
|
5204 |
/* negative rational number, and also creates the convergents. */
|
5205 |
/* */
|
5206 |
/* INPUTS */
|
5207 |
/* **h_in */
|
5208 |
/* **k_in : The numerator and denominator of the rational */
|
5209 |
/* number whose continued fraction expansion and */
|
5210 |
/* convergents to form. Both must be positive. */
|
5211 |
/* */
|
5212 |
/* **expansion : The continued fraction expansion and the */
|
5213 |
/* convergents. */
|
5214 |
/****************************************************************************/
|
5215 |
void pqCreate(SYNTHETIC_INTEGER **h_in,
|
5216 |
SYNTHETIC_INTEGER **k_in,
|
5217 |
CF_EXPANSION **expansion)
|
5218 |
{
|
5219 |
SYNTHETIC_INTEGER *dividend,
|
5220 |
*divisor,
|
5221 |
*quotient,
|
5222 |
*remainder,
|
5223 |
*p_k_minus_1,
|
5224 |
*p_k_minus_2,
|
5225 |
*q_k_minus_1,
|
5226 |
*q_k_minus_2,
|
5227 |
*si_temp1,
|
5228 |
*si_temp2,
|
5229 |
*si_temp3,
|
5230 |
*si_temp4;
|
5231 |
|
5232 |
/* Be sure that the caller isn't doing anything silly.
|
5233 |
*/
|
5234 |
asAssert(h_in != NULL, __LINE__);
|
5235 |
asAssert(*h_in != NULL, __LINE__);
|
5236 |
asAssert(k_in != NULL, __LINE__);
|
5237 |
asAssert(*k_in != NULL, __LINE__);
|
5238 |
asAssert(expansion != NULL, __LINE__);
|
5239 |
|
5240 |
/* The numerator and denominator in cannot be negative,
|
5241 |
** and the denominator cannot be zero.
|
5242 |
*/
|
5243 |
asAssert(!((*h_in)->neg), __LINE__);
|
5244 |
asAssert(!((*k_in)->neg), __LINE__);
|
5245 |
asAssert((*k_in)->len != 0, __LINE__);
|
5246 |
|
5247 |
/* Allocate space for all of the temporary integers
|
5248 |
** we use during the process of forming partial
|
5249 |
** quotients and convergents.
|
5250 |
*/
|
5251 |
siCreate(÷nd);
|
5252 |
siCreate(&divisor);
|
5253 |
siCreate("ient);
|
5254 |
siCreate(&remainder);
|
5255 |
siCreate(&p_k_minus_1);
|
5256 |
siCreate(&p_k_minus_2);
|
5257 |
siCreate(&q_k_minus_1);
|
5258 |
siCreate(&q_k_minus_2);
|
5259 |
siCreate(&si_temp1);
|
5260 |
siCreate(&si_temp2);
|
5261 |
siCreate(&si_temp3);
|
5262 |
siCreate(&si_temp4);
|
5263 |
|
5264 |
/* printf("Entering function.\n"); */
|
5265 |
|
5266 |
/* Allocate the memory for the head data block.
|
5267 |
*/
|
5268 |
*expansion = maMalloc(sizeof(CF_EXPANSION));
|
5269 |
|
5270 |
/* Set all of the data elements of the head data block
|
5271 |
** to known default values.
|
5272 |
*/
|
5273 |
(*expansion)->raw_numerator = NULL;
|
5274 |
(*expansion)->raw_denominator = NULL;
|
5275 |
(*expansion)->numerator = NULL;
|
5276 |
(*expansion)->denominator = NULL;
|
5277 |
(*expansion)->n = 0;
|
5278 |
(*expansion)->a = NULL;
|
5279 |
(*expansion)->p = NULL;
|
5280 |
(*expansion)->q = NULL;
|
5281 |
|
5282 |
/* Assign in the original raw numerator and
|
5283 |
** denominator.
|
5284 |
*/
|
5285 |
siCreate(&((*expansion)->raw_numerator));
|
5286 |
siCreate(&((*expansion)->raw_denominator));
|
5287 |
siCopy(h_in, &((*expansion)->raw_numerator));
|
5288 |
siCopy(k_in, &((*expansion)->raw_denominator));
|
5289 |
|
5290 |
/* Allocate the space for the lowest-terms numerator
|
5291 |
** and denominator, but let them be zero for now.
|
5292 |
*/
|
5293 |
siCreate(&((*expansion)->numerator));
|
5294 |
siCreate(&((*expansion)->denominator));
|
5295 |
|
5296 |
/* Begin with the dividend and divisor as the
|
5297 |
** numerator and denominator.
|
5298 |
*/
|
5299 |
siCopy(&((*expansion)->raw_numerator), ÷nd);
|
5300 |
siCopy(&((*expansion)->raw_denominator), &divisor);
|
5301 |
|
5302 |
/* Enter a do ... while() loop to compute the continued
|
5303 |
** fraction partial quotients and convergents. Because
|
5304 |
** the convergents don't require any "look-ahead" into
|
5305 |
** the partial quotients, they can be computed
|
5306 |
** in parallel
|
5307 |
*/
|
5308 |
|
5309 |
do
|
5310 |
{
|
5311 |
int curidx;
|
5312 |
/* Current index.
|
5313 |
*/
|
5314 |
|
5315 |
/* Buffer the current index value to the local variable (less
|
5316 |
** typing). The current index is what we're currently
|
5317 |
** operating on.
|
5318 |
*/
|
5319 |
curidx = (*expansion)->n;
|
5320 |
|
5321 |
/* Increment the number of elements in the
|
5322 |
** three parallel arrays.
|
5323 |
*/
|
5324 |
((*expansion)->n)++;
|
5325 |
|
5326 |
/* Allocate the memory for the memory block in the
|
5327 |
** four parallel arrays. There are two cases to
|
5328 |
** consider, either this is the first element or
|
5329 |
** else not the first.
|
5330 |
*/
|
5331 |
if (!((*expansion)->a))
|
5332 |
{
|
5333 |
/* First time, first element.
|
5334 |
*/
|
5335 |
(*expansion)->a =
|
5336 |
maMalloc(sizeof(SYNTHETIC_INTEGER *));
|
5337 |
(*expansion)->p =
|
5338 |
maMalloc(sizeof(SYNTHETIC_INTEGER *));
|
5339 |
(*expansion)->q =
|
5340 |
maMalloc(sizeof(SYNTHETIC_INTEGER *));
|
5341 |
}
|
5342 |
else
|
5343 |
{
|
5344 |
/* Not the first time. Blow up the arrays of
|
5345 |
** pointers to a larger size to accomodate one more
|
5346 |
** pointer.
|
5347 |
*/
|
5348 |
(*expansion)->a =
|
5349 |
maRealloc((*expansion)->a,
|
5350 |
(sizeof(SYNTHETIC_INTEGER *)) * (curidx+1));
|
5351 |
(*expansion)->p =
|
5352 |
maRealloc((*expansion)->p,
|
5353 |
(sizeof(SYNTHETIC_INTEGER *)) * (curidx+1));
|
5354 |
(*expansion)->q =
|
5355 |
maRealloc((*expansion)->q,
|
5356 |
(sizeof(SYNTHETIC_INTEGER *)) * (curidx+1));
|
5357 |
}
|
5358 |
|
5359 |
/* Allocate the synthetic integers to go along with
|
5360 |
** blown-up arrays.
|
5361 |
*/
|
5362 |
siCreate((*expansion)->a + curidx);
|
5363 |
siCreate((*expansion)->p + curidx);
|
5364 |
siCreate((*expansion)->q + curidx);
|
5365 |
|
5366 |
/* Calculate the current continued fraction partial quotient,
|
5367 |
** and bump the dividend and divisor for the next round.
|
5368 |
*/
|
5369 |
siUnrestrictedDivision(÷nd,
|
5370 |
&divisor,
|
5371 |
(*expansion)->a + curidx,
|
5372 |
&remainder);
|
5373 |
/* siDump((*expansion)->a + curidx, "a_k"); */
|
5374 |
siCopy(&divisor, ÷nd);
|
5375 |
siCopy(&remainder, &divisor);
|
5376 |
|
5377 |
/* Calculate the convergents using the standard
|
5378 |
** recursive formulas.
|
5379 |
*/
|
5380 |
if (curidx == 0)
|
5381 |
{
|
5382 |
/* p(0) = a(0) */
|
5383 |
siCopy((*expansion)->a + 0, (*expansion)->p + 0);
|
5384 |
/* q(0) = 1 */
|
5385 |
siSetToLong((*expansion)->q + 0, 1);
|
5386 |
}
|
5387 |
else if (curidx == 1)
|
5388 |
{
|
5389 |
/* p(1) = a(1)p(0) + 1 */
|
5390 |
siSetToLong(&si_temp1, 1);
|
5391 |
siUnrestrictedMultiplication((*expansion)->a + 1,
|
5392 |
(*expansion)->p + 0,
|
5393 |
&si_temp2);
|
5394 |
siUnrestrictedAddition(&si_temp2,
|
5395 |
&si_temp1,
|
5396 |
(*expansion)->p + 1);
|
5397 |
/* q(1) = a(1) */
|
5398 |
siCopy((*expansion)->a + 1, (*expansion)->q + 1);
|
5399 |
}
|
5400 |
else /* curidx >= 2 */
|
5401 |
{
|
5402 |
/* In this case, apply the full recursive formulas. */
|
5403 |
/* p(k) = a(k)p(k-1) + p(k-2) */
|
5404 |
siUnrestrictedMultiplication((*expansion)->a + curidx,
|
5405 |
(*expansion)->p + (curidx-1),
|
5406 |
&si_temp2);
|
5407 |
siUnrestrictedAddition(&si_temp2,
|
5408 |
(*expansion)->p + (curidx-2),
|
5409 |
(*expansion)->p + curidx);
|
5410 |
|
5411 |
/* q(k) = a(k)q(k-1) + q(k-2) */
|
5412 |
siUnrestrictedMultiplication((*expansion)->a + curidx,
|
5413 |
(*expansion)->q + (curidx-1),
|
5414 |
&si_temp2);
|
5415 |
siUnrestrictedAddition(&si_temp2,
|
5416 |
(*expansion)->q + (curidx-2),
|
5417 |
(*expansion)->q + curidx);
|
5418 |
}
|
5419 |
|
5420 |
/* siDump((*expansion)->p + curidx, "p_k"); */
|
5421 |
/* siDump((*expansion)->q + curidx, "q_k"); */
|
5422 |
|
5423 |
/* Put in a safety test for the loop. I've never had this loop fail to
|
5424 |
** terminate. Mathematically, it *can't* fail to terminate, but if there
|
5425 |
** were a bug somewhere in the large integer math or a NAN condition,
|
5426 |
** I wouldn't want to have a machine lockup without a diagnostic message.
|
5427 |
** The value of 32000 is used because that approaches the limits of the
|
5428 |
** minimum that an ANSI 'C' int is required to hold. If we've gone
|
5429 |
** around this loop 32000 times, something is very wrong.
|
5430 |
*/
|
5431 |
asAssert(curidx < 32000, __LINE__);
|
5432 |
}
|
5433 |
while (remainder->len);
|
5434 |
|
5435 |
/* The lowest terms representation of the rational number supplied will
|
5436 |
** be the final convergent. This doesn't apply very much to this program,
|
5437 |
** because the parsing functions automatically strip out the gcd() before
|
5438 |
** passing data on, so the "raw" and "final" will be the same. Will assign
|
5439 |
** it anyway.
|
5440 |
*/
|
5441 |
siCopy((*expansion)->p + ((*expansion)->n - 1), &((*expansion)->numerator));
|
5442 |
siCopy((*expansion)->q + ((*expansion)->n - 1), &((*expansion)->denominator));
|
5443 |
|
5444 |
/* Destroy the temporary integers.
|
5445 |
*/
|
5446 |
siDestroy(÷nd);
|
5447 |
siDestroy(&divisor);
|
5448 |
siDestroy("ient);
|
5449 |
siDestroy(&remainder);
|
5450 |
siDestroy(&p_k_minus_1);
|
5451 |
siDestroy(&p_k_minus_2);
|
5452 |
siDestroy(&q_k_minus_1);
|
5453 |
siDestroy(&q_k_minus_2);
|
5454 |
siDestroy(&si_temp1);
|
5455 |
siDestroy(&si_temp2);
|
5456 |
siDestroy(&si_temp3);
|
5457 |
siDestroy(&si_temp4);
|
5458 |
}
|
5459 |
|
5460 |
|
5461 |
/****************************************************************************/
|
5462 |
/* pqDestroy(): */
|
5463 |
/*--------------------------------------------------------------------------*/
|
5464 |
/* DESCRIPTION */
|
5465 |
/* Deallocates the dynamic data structures associated with the CF */
|
5466 |
/* expansion and convergents, and sets the caller's pointer to NULL. */
|
5467 |
/* */
|
5468 |
/* **expansion : The continued fraction expansion and the */
|
5469 |
/* convergents. */
|
5470 |
/****************************************************************************/
|
5471 |
void pqDestroy(CF_EXPANSION **expansion)
|
5472 |
{
|
5473 |
int idx;
|
5474 |
|
5475 |
/* Be sure the caller isn't doing anything silly. with pointers.
|
5476 |
*/
|
5477 |
asAssert(expansion != NULL, __LINE__);
|
5478 |
asAssert(*expansion != NULL, __LINE__);
|
5479 |
|
5480 |
/* The general strategy at this point is to deallocate the data structure
|
5481 |
** from the bottom up. It must be done this way because once a higher
|
5482 |
** data structure is deallocated, the memory ain't yours, so any access
|
5483 |
** even to deallocate "lower" pointers is a violation. Checks all along
|
5484 |
** the way are performed to be sure that nothing looks suspicious.
|
5485 |
*/
|
5486 |
|
5487 |
asAssert((*expansion)->n > 0, __LINE__); /* Even a 0th order expansion (an integer)
|
5488 |
** has the "n" at 1.
|
5489 |
*/
|
5490 |
/* Check for suspicious conditions in the base data
|
5491 |
** structure.
|
5492 |
*/
|
5493 |
asAssert((*expansion)->raw_numerator != NULL, __LINE__);
|
5494 |
asAssert((*expansion)->raw_denominator != NULL, __LINE__);
|
5495 |
asAssert((*expansion)->numerator != NULL, __LINE__);
|
5496 |
asAssert((*expansion)->denominator != NULL, __LINE__);
|
5497 |
asAssert((*expansion)->a != NULL, __LINE__);
|
5498 |
asAssert((*expansion)->p != NULL, __LINE__);
|
5499 |
asAssert((*expansion)->q != NULL, __LINE__);
|
5500 |
|
5501 |
|
5502 |
/* Deallocate the directly linked synthetic integers.
|
5503 |
*/
|
5504 |
siDestroy(&((*expansion)->raw_numerator));
|
5505 |
siDestroy(&((*expansion)->raw_denominator));
|
5506 |
siDestroy(&((*expansion)->numerator));
|
5507 |
siDestroy(&((*expansion)->denominator));
|
5508 |
|
5509 |
/* Deallocate each of the synthetic integers that are the partial
|
5510 |
** quotients and convergents.
|
5511 |
*/
|
5512 |
for (idx = 0; idx < ((*expansion)->n); idx++)
|
5513 |
{
|
5514 |
asAssert((((*expansion)->a)[idx]) != NULL, __LINE__);
|
5515 |
asAssert((((*expansion)->p)[idx]) != NULL, __LINE__);
|
5516 |
asAssert((((*expansion)->q)[idx]) != NULL, __LINE__);
|
5517 |
|
5518 |
siDestroy((*expansion)->a + idx);
|
5519 |
siDestroy((*expansion)->p + idx);
|
5520 |
siDestroy((*expansion)->q + idx);
|
5521 |
}
|
5522 |
|
5523 |
/* Deallocate the arrays of pointers.
|
5524 |
*/
|
5525 |
maFree((*expansion)->a);
|
5526 |
maFree((*expansion)->p);
|
5527 |
maFree((*expansion)->q);
|
5528 |
|
5529 |
/* Deallocate the base data structure and set the caller's pointer
|
5530 |
** to NULL.
|
5531 |
*/
|
5532 |
maFree(*expansion);
|
5533 |
*expansion = NULL;
|
5534 |
}
|
5535 |
|
5536 |
|
5537 |
/****************************************************************************/
|
5538 |
/* pqDump(): */
|
5539 |
/*--------------------------------------------------------------------------*/
|
5540 |
/* DESCRIPTION */
|
5541 |
/* Prints the entire CF expansion and list of convergents to the standard */
|
5542 |
/* output stream, with an optional description. */
|
5543 |
/* */
|
5544 |
/* **expansion : The continued fraction expansion and the */
|
5545 |
/* convergents. */
|
5546 |
/* *desc : Description to use. If this is a zero-length */
|
5547 |
/* string, omits the description. */
|
5548 |
/* p_raw : Boolean flag to indicate if the raw numerator and */
|
5549 |
/* denominator should be printed distinctly from the */
|
5550 |
/* final CF convergent. For most of the application */
|
5551 |
/* in this program, the answer is no, because the */
|
5552 |
/* rational number is already reduced at the time it */
|
5553 |
/* is CF'd, and the raw rational number will be */
|
5554 |
/* identical to the final convergent. To print it */
|
5555 |
/* would just waste space. */
|
5556 |
/****************************************************************************/
|
5557 |
void pqDump(CF_EXPANSION **expansion, char *desc, int p_raw)
|
5558 |
{
|
5559 |
int i;
|
5560 |
char buf[100];
|
5561 |
|
5562 |
/* Be sure the caller isn't doing any pointer suicide.
|
5563 |
*/
|
5564 |
asAssert(expansion != NULL, __LINE__);
|
5565 |
asAssert(*expansion != NULL, __LINE__);
|
5566 |
asAssert(desc != NULL, __LINE__);
|
5567 |
|
5568 |
/* If a description was passed print it out as a banner headline.
|
5569 |
*/
|
5570 |
if (strlen(desc))
|
5571 |
{
|
5572 |
gfBannerHeading(desc, 0);
|
5573 |
}
|
5574 |
|
5575 |
/* Banner announcing inputs. */
|
5576 |
gfBannerHeading("Inputs To CF Calculation", 0);
|
5577 |
gfHline();
|
5578 |
|
5579 |
/* Print out the raw numerator and denominator. */
|
5580 |
siDump(&((*expansion)->raw_numerator), "h_in");
|
5581 |
gfHline();
|
5582 |
siDump(&((*expansion)->raw_denominator), "k_in");
|
5583 |
gfHline();
|
5584 |
|
5585 |
/* Print out each of the continued-fraction partial
|
5586 |
** quotients.
|
5587 |
*/
|
5588 |
/* Banner announcing partial quotients. */
|
5589 |
gfBannerHeading("CF Partial Quotients", 0);
|
5590 |
gfHline();
|
5591 |
|
5592 |
for (i=0; i<((*expansion)->n); i++)
|
5593 |
{
|
5594 |
sprintf(buf, "a(%d)", i);
|
5595 |
siDump((*expansion)->a + i, buf);
|
5596 |
gfHline();
|
5597 |
}
|
5598 |
|
5599 |
/* Priint out the convergents. */
|
5600 |
/* Banner announcing partial convergents. */
|
5601 |
gfBannerHeading("CF Convergents", 0);
|
5602 |
gfHline();
|
5603 |
|
5604 |
for (i=0; i<((*expansion)->n); i++)
|
5605 |
{
|
5606 |
sprintf(buf, "p(%d)", i);
|
5607 |
siDump((*expansion)->p + i, buf);
|
5608 |
sprintf(buf, "q(%d)", i);
|
5609 |
siDump((*expansion)->q + i, buf);
|
5610 |
gfHline();
|
5611 |
}
|
5612 |
}
|
5613 |
|
5614 |
|
5615 |
/****************************************************************************/
|
5616 |
/* pqBapp(): */
|
5617 |
/*--------------------------------------------------------------------------*/
|
5618 |
/* DESCRIPTION */
|
5619 |
/* Extracts the two best rational approximations to a rational number */
|
5620 |
/* in the Farey series of order N, using a CF decomposition that must */
|
5621 |
/* have already been done on the rational number. */
|
5622 |
/* */
|
5623 |
/* The function behaves subtly differently depending on whether the */
|
5624 |
/* rational number passed is in the Farey series of order N. If the */
|
5625 |
/* number is not in F_N, the two Farey neighbors are returned, in an */
|
5626 |
/* order that depends on whether the rational number has an odd or */
|
5627 |
/* an even number of partial quotients. If the number is in F_N, the */
|
5628 |
/* number itself (in lowest terms) is returned, along with the left or */
|
5629 |
/* right Farey neighbor, with which again depending on whether the number */
|
5630 |
/* has an odd or even number of partial quotients. */
|
5631 |
/* */
|
5632 |
/* This function is typically used to get two consecutive Farey terms */
|
5633 |
/* so that the recursive formulas can be applied. */
|
5634 |
/* */
|
5635 |
/* INPUTS */
|
5636 |
/* **expansion : The CF expansion that must have already been done on */
|
5637 |
/* the [non-negative] number. */
|
5638 |
/* **N : The [positive] order of the Farey series being */
|
5639 |
/* considered. */
|
5640 |
/* */
|
5641 |
/* OUTPUTS */
|
5642 |
/* **conv_h, */
|
5643 |
/* **conv_k : The highest-order convergent with a denominator not */
|
5644 |
/* larger than N. */
|
5645 |
/* **neigh_h, */
|
5646 |
/* **neigh_k : The intermediate fraction as specified by the */
|
5647 |
/* equation in the TOMS paper. This will be a Farey */
|
5648 |
/* neighbor to the rational number of interest. */
|
5649 |
/* *convergent_number */
|
5650 |
/* The index of the convergent that was the highest-order */
|
5651 |
/* convergent with a denominator not larger than N. */
|
5652 |
/****************************************************************************/
|
5653 |
void pqBapp(CF_EXPANSION **expansion,
|
5654 |
SYNTHETIC_INTEGER **N,
|
5655 |
SYNTHETIC_INTEGER **conv_h,
|
5656 |
SYNTHETIC_INTEGER **conv_k,
|
5657 |
SYNTHETIC_INTEGER **neigh_h,
|
5658 |
SYNTHETIC_INTEGER **neigh_k,
|
5659 |
int *convergent_number)
|
5660 |
{
|
5661 |
SYNTHETIC_INTEGER *constant_1,
|
5662 |
*t1,
|
5663 |
*t2,
|
5664 |
*t3;
|
5665 |
|
5666 |
/* Make sure the caller isn't doing anything silly with pointers.
|
5667 |
** Catastropies are checked, but not duplicate pointers, etc.
|
5668 |
*/
|
5669 |
asAssert(expansion != NULL, __LINE__);
|
5670 |
asAssert(*expansion != NULL, __LINE__);
|
5671 |
asAssert(N != NULL, __LINE__);
|
5672 |
asAssert(*N != NULL, __LINE__);
|
5673 |
asAssert(conv_h != NULL, __LINE__);
|
5674 |
asAssert(*conv_h != NULL, __LINE__);
|
5675 |
asAssert(conv_k != NULL, __LINE__);
|
5676 |
asAssert(*conv_k != NULL, __LINE__);
|
5677 |
asAssert(neigh_h != NULL, __LINE__);
|
5678 |
asAssert(*neigh_h != NULL, __LINE__);
|
5679 |
asAssert(neigh_k != NULL, __LINE__);
|
5680 |
asAssert(*neigh_k != NULL, __LINE__);
|
5681 |
asAssert(convergent_number != NULL, __LINE__);
|
5682 |
|
5683 |
/* Allocate all temporary variables.
|
5684 |
*/
|
5685 |
siCreate(&constant_1);
|
5686 |
siSetToLong(&constant_1, 1);
|
5687 |
siCreate(&t1);
|
5688 |
siCreate(&t2);
|
5689 |
siCreate(&t3);
|
5690 |
|
5691 |
/* Branch based on the order of the decomposition.
|
5692 |
*/
|
5693 |
if ((*expansion)->n == 1)
|
5694 |
{
|
5695 |
/* If we have a 0th order expansion, this means that
|
5696 |
** it is an integer. We can't process this using the standard
|
5697 |
** recursive equations because we don't have a p(-1) or a
|
5698 |
** q(-1). However, it can be shown easily that the right
|
5699 |
** value here is always (N * p(0) + 1)/N.
|
5700 |
*/
|
5701 |
siCopy((*expansion)->p + 0, conv_h);
|
5702 |
siCopy((*expansion)->q + 0, conv_k);
|
5703 |
siUnrestrictedMultiplication(N, (*expansion)->p + 0, &t1);
|
5704 |
siUnrestrictedAddition(&constant_1, &t1, neigh_h);
|
5705 |
siCopy(N, neigh_k);
|
5706 |
*convergent_number = 0;
|
5707 |
}
|
5708 |
else
|
5709 |
{
|
5710 |
/* If we have a first-order or greater decomposition, we
|
5711 |
** can apply the standard recursive formulas.
|
5712 |
*/
|
5713 |
int i = 0;
|
5714 |
|
5715 |
/* We need to locate the convergent with the largest denominator
|
5716 |
** not larger than N.
|
5717 |
*/
|
5718 |
if (siCompare((*expansion)->q + ((*expansion)->n - 1), N) <= 0)
|
5719 |
{
|
5720 |
/* The final convergent is equal to N or less than N. We must
|
5721 |
** choose the final convergent.
|
5722 |
*/
|
5723 |
*convergent_number = i = (*expansion)->n - 1;
|
5724 |
}
|
5725 |
else
|
5726 |
{
|
5727 |
/* Iterate through until we find that the next convergent is too
|
5728 |
** big.
|
5729 |
*/
|
5730 |
while (siCompare((*expansion)->q + (i + 1), N) <= 0)
|
5731 |
{
|
5732 |
i++;
|
5733 |
|
5734 |
/* Do a sanity check here. If "i" has grown to where the
|
5735 |
** next convergent to examine isn't valid, something is
|
5736 |
** very wrong.
|
5737 |
*/
|
5738 |
asAssert((i+1) < ((*expansion)->n), __LINE__);
|
5739 |
}
|
5740 |
}
|
5741 |
|
5742 |
/* Assign this convergent, advise the caller of which one.
|
5743 |
*/
|
5744 |
siCopy((*expansion)->p + i, conv_h);
|
5745 |
siCopy((*expansion)->q + i, conv_k);
|
5746 |
*convergent_number = i;
|
5747 |
|
5748 |
/* We now know the convergent that is the last not greater
|
5749 |
** than the order N. Can apply the standard recursive formulas.
|
5750 |
** Must split into two cases because if the right convergent
|
5751 |
** to use is the zero'th one, we can't apply the recursive
|
5752 |
** formulas.
|
5753 |
*/
|
5754 |
if (i==0)
|
5755 |
{
|
5756 |
siUnrestrictedMultiplication(N, (*expansion)->p + 0, &t1);
|
5757 |
siUnrestrictedAddition(&constant_1, &t1, neigh_h);
|
5758 |
siCopy(N, neigh_k);
|
5759 |
}
|
5760 |
else
|
5761 |
{
|
5762 |
/* First, calculate the quantity floor((N-q[k-1])/q[k]), as
|
5763 |
** we'll use this more than once. Leave this in "t1".
|
5764 |
*/
|
5765 |
siUnrestrictedSubtraction(N, (*expansion)->q + (i-1), &t2);
|
5766 |
siUnrestrictedDivision(&t2, (*expansion)->q + i, &t1, &t3);
|
5767 |
|
5768 |
/* Calculate the numerator of the neighbor.
|
5769 |
*/
|
5770 |
siUnrestrictedMultiplication(&t1, (*expansion)->p + i, &t2);
|
5771 |
siUnrestrictedAddition(&t2, (*expansion)->p + (i-1), neigh_h);
|
5772 |
|
5773 |
/* Calculate the denominator of the neighbor.
|
5774 |
*/
|
5775 |
siUnrestrictedMultiplication(&t1, (*expansion)->q + i, &t2);
|
5776 |
siUnrestrictedAddition(&t2, (*expansion)->q + (i-1), neigh_k);
|
5777 |
}
|
5778 |
}
|
5779 |
|
5780 |
/* Destroy all temporary variables.
|
5781 |
*/
|
5782 |
siDestroy(&constant_1);
|
5783 |
siDestroy(&t1);
|
5784 |
siDestroy(&t2);
|
5785 |
siDestroy(&t3);
|
5786 |
}
|
5787 |
|
5788 |
|
5789 |
/****************************************************************************/
|
5790 |
/****************************************************************************/
|
5791 |
/****** N U M E R I C A L A L G O R I T H M F U N C T I O N S *****/
|
5792 |
/****************************************************************************/
|
5793 |
/****************************************************************************/
|
5794 |
/* This section is reserved for functions which apply specific numerical
|
5795 |
** algorithms (GCD, for example).
|
5796 |
*/
|
5797 |
/****************************************************************************/
|
5798 |
/* naMind(): */
|
5799 |
/*--------------------------------------------------------------------------*/
|
5800 |
/* DESCRIPTION */
|
5801 |
/* Locates the rational number with the smallest denominator in an */
|
5802 |
/* interval, using the continued fraction algorithm presented in the */
|
5803 |
/* paper. */
|
5804 |
/****************************************************************************/
|
5805 |
void naMind(SYNTHETIC_INTEGER **h1par,
|
5806 |
SYNTHETIC_INTEGER **k1par,
|
5807 |
SYNTHETIC_INTEGER **h2par,
|
5808 |
SYNTHETIC_INTEGER **k2par,
|
5809 |
SYNTHETIC_INTEGER **result_h,
|
5810 |
SYNTHETIC_INTEGER **result_k,
|
5811 |
int emit_midpoint,
|
5812 |
int emit_cfdata,
|
5813 |
int emit_result)
|
5814 |
{
|
5815 |
SYNTHETIC_INTEGER *h1, *k1, *h2, *k2, *midpoint_h, *midpoint_k,
|
5816 |
*t1, *t2, *t3, *t4, *t5, *t6,
|
5817 |
*t7, *t8, *t9, *t10, *t11, *t12,
|
5818 |
*constant_1, *constant_0, *p_minus_1, *q_minus_1;
|
5819 |
CF_EXPANSION *midpoint_expansion;
|
5820 |
int k;
|
5821 |
int done;
|
5822 |
|
5823 |
/* Be sure there is no pointer nonsense.
|
5824 |
*/
|
5825 |
asAssert(h1par != NULL, __LINE__);
|
5826 |
asAssert(*h1par != NULL, __LINE__);
|
5827 |
asAssert(k1par != NULL, __LINE__);
|
5828 |
asAssert(*k1par != NULL, __LINE__);
|
5829 |
asAssert(h2par != NULL, __LINE__);
|
5830 |
asAssert(*h2par != NULL, __LINE__);
|
5831 |
asAssert(k2par != NULL, __LINE__);
|
5832 |
asAssert(*k2par != NULL, __LINE__);
|
5833 |
asAssert(result_h != NULL, __LINE__);
|
5834 |
asAssert(*result_h != NULL, __LINE__);
|
5835 |
asAssert(result_k != NULL, __LINE__);
|
5836 |
asAssert(*result_k != NULL, __LINE__);
|
5837 |
|
5838 |
/* Allocate locals
|
5839 |
*/
|
5840 |
siCreate(&h1);
|
5841 |
siCreate(&k1);
|
5842 |
siCreate(&h2);
|
5843 |
siCreate(&k2);
|
5844 |
siCreate(&midpoint_h);
|
5845 |
siCreate(&midpoint_k);
|
5846 |
siCreate(&t1);
|
5847 |
siCreate(&t2);
|
5848 |
siCreate(&t3);
|
5849 |
siCreate(&t4);
|
5850 |
siCreate(&t5);
|
5851 |
siCreate(&t6);
|
5852 |
siCreate(&t7);
|
5853 |
siCreate(&t8);
|
5854 |
siCreate(&t9);
|
5855 |
siCreate(&t10);
|
5856 |
siCreate(&t11);
|
5857 |
siCreate(&t12);
|
5858 |
siCreate(&constant_1);
|
5859 |
siSetToLong(&constant_1, 1);
|
5860 |
siCreate(&constant_0);
|
5861 |
siSetToLong(&constant_0, 0);
|
5862 |
siCreate(&p_minus_1);
|
5863 |
siCreate(&q_minus_1);
|
5864 |
|
5865 |
/* Copy the input parameters to our locals.
|
5866 |
*/
|
5867 |
siCopy(h1par, &h1);
|
5868 |
siCopy(k1par, &k1);
|
5869 |
siCopy(h2par, &h2);
|
5870 |
siCopy(k2par, &k2);
|
5871 |
|
5872 |
/* Swap the input parameters if the input parameters
|
5873 |
** are in the wrong order.
|
5874 |
*/
|
5875 |
if (rnCompare(&h1, &k1, &h2, &k2) == 1)
|
5876 |
{
|
5877 |
SYNTHETIC_INTEGER *temp;
|
5878 |
|
5879 |
temp = h1;
|
5880 |
h1 = h2;
|
5881 |
h2 = temp;
|
5882 |
|
5883 |
temp = k2;
|
5884 |
k1 = k2;
|
5885 |
k2 = temp;
|
5886 |
}
|
5887 |
|
5888 |
/* Calculate the midpoint of the interval. This
|
5889 |
** is (l+r)/2.
|
5890 |
*/
|
5891 |
rnSum(&h1, &k1, &h2, &k2, &midpoint_h, &midpoint_k);
|
5892 |
|
5893 |
{
|
5894 |
SYNTHETIC_INTEGER *constant_2, *tempresult;
|
5895 |
|
5896 |
siCreate(&constant_2);
|
5897 |
siCreate(&tempresult);
|
5898 |
|
5899 |
siSetToLong(&constant_2, 2);
|
5900 |
|
5901 |
siUnrestrictedMultiplication(&midpoint_k, &constant_2, &tempresult);
|
5902 |
|
5903 |
siCopy(&tempresult, &midpoint_k);
|
5904 |
|
5905 |
rnCanonize(&midpoint_h, &midpoint_k);
|
5906 |
|
5907 |
siDestroy(&constant_2);
|
5908 |
siDestroy(&tempresult);
|
5909 |
}
|
5910 |
|
5911 |
/* If the midpoint should be printed for informative
|
5912 |
** purposes, print it.
|
5913 |
*/
|
5914 |
if (emit_midpoint)
|
5915 |
{
|
5916 |
siDump(&midpoint_h, "midpoint_h");
|
5917 |
gfHline();
|
5918 |
siDump(&midpoint_k, "midpoint_k");
|
5919 |
gfHline();
|
5920 |
}
|
5921 |
|
5922 |
/* Form the partial quotients and convergents of the
|
5923 |
** midpoint.
|
5924 |
*/
|
5925 |
pqCreate(&midpoint_h,
|
5926 |
&midpoint_k,
|
5927 |
&midpoint_expansion);
|
5928 |
|
5929 |
/* Print out the partial quotients and convergents, if the
|
5930 |
** caller has requested it.
|
5931 |
*/
|
5932 |
if (emit_cfdata)
|
5933 |
{
|
5934 |
pqDump(&midpoint_expansion, "CF Representation Of Interval Midpoint", FALSE);
|
5935 |
}
|
5936 |
|
5937 |
/* At this point, can apply the algorithm listed in the paper.
|
5938 |
*/
|
5939 |
done = FALSE;
|
5940 |
for (k=0; k<midpoint_expansion->n && !done; k++)
|
5941 |
/* For each convergent, in order of increasing k.
|
5942 |
*/
|
5943 |
{
|
5944 |
/* printf("k is : %d\n", k); */
|
5945 |
|
5946 |
/* Calculate the p and q one back. Must do this
|
5947 |
** explicitly and can't index into array, because
|
5948 |
** case of [0] not covered.
|
5949 |
*/
|
5950 |
if (k==0)
|
5951 |
{
|
5952 |
siSetToLong(&p_minus_1, 1);
|
5953 |
siSetToLong(&q_minus_1, 0);
|
5954 |
}
|
5955 |
else
|
5956 |
{
|
5957 |
siCopy(&(midpoint_expansion->p[k-1]), &p_minus_1);
|
5958 |
siCopy(&(midpoint_expansion->q[k-1]), &q_minus_1);
|
5959 |
}
|
5960 |
|
5961 |
/* Test convergent for membership in [l,r]. This means >= l and
|
5962 |
** <= r. If we have membership, we're done.
|
5963 |
*/
|
5964 |
if ((rnCompare(&h1, &k1, &(midpoint_expansion->p[k]), &(midpoint_expansion->q[k])) <= 0) &&
|
5965 |
(rnCompare(&h2, &k2, &(midpoint_expansion->p[k]), &(midpoint_expansion->q[k])) >= 0))
|
5966 |
{
|
5967 |
/* The convergent is in the interval. Assign result and signal done.
|
5968 |
*/
|
5969 |
siCopy(&(midpoint_expansion->p[k]), result_h);
|
5970 |
siCopy(&(midpoint_expansion->q[k]), result_k);
|
5971 |
done = TRUE;
|
5972 |
}
|
5973 |
else
|
5974 |
{
|
5975 |
/* Must look at potential intermediate fractions.
|
5976 |
*/
|
5977 |
if ((k & 0x1) == 0) /* i is even */
|
5978 |
{
|
5979 |
/* Calculate the value of "i" that will be the minimum
|
5980 |
** required to potentially put the intermediate fraction
|
5981 |
** in the interval [l,r]. This is in accordance with
|
5982 |
** the paper.
|
5983 |
*/
|
5984 |
siUnrestrictedMultiplication(&h2,
|
5985 |
&q_minus_1,
|
5986 |
&t1);
|
5987 |
siUnrestrictedMultiplication(&k2,
|
5988 |
&p_minus_1,
|
5989 |
&t2);
|
5990 |
siUnrestrictedSubtraction(&t1, &t2, &t3);
|
5991 |
siUnrestrictedMultiplication(&k2,
|
5992 |
&(midpoint_expansion->p[k]),
|
5993 |
&t4);
|
5994 |
siUnrestrictedMultiplication(&h2,
|
5995 |
&(midpoint_expansion->q[k]),
|
5996 |
&t5);
|
5997 |
siUnrestrictedSubtraction(&t4, &t5, &t6);
|
5998 |
|
5999 |
/* We have the numerator and denominator. We would like
|
6000 |
** to form the ceiling of the quotient. Using integer math,
|
6001 |
** the best way to do that is to add the denominator to the
|
6002 |
** numerator minus one and use the integer quotient However, first
|
6003 |
** would like to normalize numerator and denominator so
|
6004 |
** both neg or both pos. It should never be possible to
|
6005 |
** have different signs.
|
6006 |
*/
|
6007 |
asAssert((t3->neg && t6->neg) || (!(t3->neg) && !(t6->neg)), __LINE__);
|
6008 |
if (t3->neg)
|
6009 |
{
|
6010 |
t3->neg = FALSE;
|
6011 |
t6->neg = FALSE;
|
6012 |
}
|
6013 |
|
6014 |
siUnrestrictedAddition(&t6, &t3, &t8);
|
6015 |
siUnrestrictedSubtraction(&t8, &constant_1, &t7);
|
6016 |
|
6017 |
/* Now get the quotient. This quotient should be the
|
6018 |
** ceiling, because we added the numerator to the
|
6019 |
** denominator minus one. "t8" should contain the "i" as
|
6020 |
** specified in the paper.
|
6021 |
*/
|
6022 |
siUnrestrictedDivision(&t7, &t6, &t8, &t9);
|
6023 |
|
6024 |
/* siDump(&t8, "i"); */
|
6025 |
|
6026 |
}
|
6027 |
else /* i is odd */
|
6028 |
{
|
6029 |
/* printf("Odd\n"); */
|
6030 |
|
6031 |
/* Calculate the value of "i" that will be the minimum
|
6032 |
** required to potentially put the intermediate fraction
|
6033 |
** in the interval [l,r]. This is in accordance with
|
6034 |
** the paper.
|
6035 |
*/
|
6036 |
siUnrestrictedMultiplication(&h1,
|
6037 |
&q_minus_1,
|
6038 |
&t1);
|
6039 |
siUnrestrictedMultiplication(&k1,
|
6040 |
&p_minus_1,
|
6041 |
&t2);
|
6042 |
siUnrestrictedSubtraction(&t1, &t2, &t3);
|
6043 |
siUnrestrictedMultiplication(&k1,
|
6044 |
&(midpoint_expansion->p[k]),
|
6045 |
&t4);
|
6046 |
siUnrestrictedMultiplication(&h1,
|
6047 |
&(midpoint_expansion->q[k]),
|
6048 |
&t5);
|
6049 |
siUnrestrictedSubtraction(&t4, &t5, &t6);
|
6050 |
|
6051 |
/* We have the numerator and denominator. We would like
|
6052 |
** to form the ceiling of the quotient. Using integer math,
|
6053 |
** the best way to do that is to add the denominator to the
|
6054 |
** numerator minus one and use the integer quotient However, first
|
6055 |
** would like to normalize numerator and denominator so
|
6056 |
** both neg or both pos. It should never be possible to
|
6057 |
** have different signs.
|
6058 |
*/
|
6059 |
asAssert((t3->neg && t6->neg) || (!(t3->neg) && !(t6->neg)), __LINE__);
|
6060 |
if (t3->neg)
|
6061 |
{
|
6062 |
t3->neg = FALSE;
|
6063 |
t6->neg = FALSE;
|
6064 |
}
|
6065 |
|
6066 |
siUnrestrictedAddition(&t6, &t3, &t8);
|
6067 |
siUnrestrictedSubtraction(&t8, &constant_1, &t7);
|
6068 |
|
6069 |
/* Now get the quotient. This quotient should be the
|
6070 |
** ceiling, because we added the numerator to the
|
6071 |
** denominator minus one. "t8" should contain the "i" as
|
6072 |
** specified in the paper.
|
6073 |
*/
|
6074 |
siUnrestrictedDivision(&t7, &t6, &t8, &t9);
|
6075 |
|
6076 |
/* siDump(&t8, "i"); */
|
6077 |
|
6078 |
}
|
6079 |
|
6080 |
/* At this point, we have a potential coefficient on intermediate fractions.
|
6081 |
** Must examine the result.
|
6082 |
*/
|
6083 |
/* Disregard if >= partial quotient.
|
6084 |
*/
|
6085 |
/* printf("k: %d\n", k); */
|
6086 |
/* siDump(&t8, "i"); */
|
6087 |
/* siDump(&(midpoint_expansion->a[k]), "ak"); */
|
6088 |
|
6089 |
/* Need to be extremely careful, because about to index one past k on the
|
6090 |
** assumption that can't be at last place, or convergent would have matched.
|
6091 |
*/
|
6092 |
asAssert((k+1) < midpoint_expansion->n, __LINE__);
|
6093 |
|
6094 |
if (siCompare(&(midpoint_expansion->a[k+1]), &t8) > 0)
|
6095 |
{
|
6096 |
/* Form the intermediate fraction involved. It is guaranteed
|
6097 |
** to be irreducible.
|
6098 |
*/
|
6099 |
siUnrestrictedMultiplication(&t8, &(midpoint_expansion->p[k]), &t1);
|
6100 |
siUnrestrictedAddition(&t1, &p_minus_1, &t2);
|
6101 |
siUnrestrictedMultiplication(&t8, &(midpoint_expansion->q[k]), &t3);
|
6102 |
siUnrestrictedAddition(&t3, &q_minus_1, &t4);
|
6103 |
|
6104 |
/* The fraction is t2/t4.
|
6105 |
*/
|
6106 |
/* siDump(&t2, "potential_h"); */
|
6107 |
/* siDump(&t4, "potential_k"); */
|
6108 |
|
6109 |
/* Evaluate this for membership in [l,r]
|
6110 |
*/
|
6111 |
if (rnCompare(&h1, &k1, &t2, &t4) <= 0) /* >= l */
|
6112 |
{
|
6113 |
if (rnCompare(&h2, &k2, &t2, &t4) >= 0) /* <= r */
|
6114 |
{
|
6115 |
siCopy(&t2, result_h);
|
6116 |
siCopy(&t4, result_k);
|
6117 |
done = TRUE;
|
6118 |
}
|
6119 |
}
|
6120 |
}
|
6121 |
} /* End if must look at intermediate fractions. */
|
6122 |
} /* End for() */
|
6123 |
|
6124 |
/* We should have our answer. Mathematically, if nothing else, the final
|
6125 |
** convergent must be in the interval. Will just put this extra paranoid
|
6126 |
** assertion in.
|
6127 |
*/
|
6128 |
asAssert(done != 0, __LINE__);
|
6129 |
|
6130 |
/* Destroy the continued fraction expansion.
|
6131 |
*/
|
6132 |
pqDestroy(&midpoint_expansion);
|
6133 |
|
6134 |
/* Copy the caller's inputs to our local variables.
|
6135 |
*/
|
6136 |
siDestroy(&h1);
|
6137 |
siDestroy(&k1);
|
6138 |
siDestroy(&h2);
|
6139 |
siDestroy(&k2);
|
6140 |
siDestroy(&midpoint_h);
|
6141 |
siDestroy(&midpoint_k);
|
6142 |
siDestroy(&t1);
|
6143 |
siDestroy(&t2);
|
6144 |
siDestroy(&t3);
|
6145 |
siDestroy(&t4);
|
6146 |
siDestroy(&t5);
|
6147 |
siDestroy(&t6);
|
6148 |
siDestroy(&t7);
|
6149 |
siDestroy(&t8);
|
6150 |
siDestroy(&t9);
|
6151 |
siDestroy(&t10);
|
6152 |
siDestroy(&t11);
|
6153 |
siDestroy(&t12);
|
6154 |
siDestroy(&constant_1);
|
6155 |
siDestroy(&constant_0);
|
6156 |
siDestroy(&p_minus_1);
|
6157 |
siDestroy(&q_minus_1);
|
6158 |
}
|
6159 |
|
6160 |
|
6161 |
/****************************************************************************/
|
6162 |
/****************************************************************************/
|
6163 |
/****************** C O M M A N D F U N C T I O N S ******************/
|
6164 |
/****************************************************************************/
|
6165 |
/****************************************************************************/
|
6166 |
/* This section is reserved for functions which carry out the commands which
|
6167 |
** are subfunctions of how the RAP program operates. Each of these commands
|
6168 |
** is tabulated to be matched in a template for what it does and the types
|
6169 |
** of operands it will accept.
|
6170 |
*/
|
6171 |
/* The first thing to define is the different types of things that an
|
6172 |
** individual input parameter can be. I don't want to use enum here
|
6173 |
** because there are some potential compiler portability annoyances if somebody
|
6174 |
** sicks a C++ compiler on this deck.
|
6175 |
*/
|
6176 |
#define CMDLINE_PAR_TYPE_UNASSIGNED (0)
|
6177 |
/* Not filled in yet.
|
6178 |
*/
|
6179 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS (1)
|
6180 |
/* The "+" sign alone.
|
6181 |
*/
|
6182 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS (2)
|
6183 |
/* The "-" sign alone.
|
6184 |
*/
|
6185 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES (3)
|
6186 |
/* The "*" token alone.
|
6187 |
*/
|
6188 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT (4)
|
6189 |
/* The "/" token alone.
|
6190 |
*/
|
6191 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO (5)
|
6192 |
/* The "%" token alone.
|
6193 |
*/
|
6194 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER (6)
|
6195 |
/* The "**" token alone.
|
6196 |
*/
|
6197 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_GCD (7)
|
6198 |
/* The "GCD" token alone.
|
6199 |
*/
|
6200 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP (8)
|
6201 |
/* The "DAP" token alone.
|
6202 |
*/
|
6203 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND (9)
|
6204 |
/* The "MIND" token alone.
|
6205 |
*/
|
6206 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_CF (10)
|
6207 |
/* The "CF" token alone.
|
6208 |
*/
|
6209 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN (11)
|
6210 |
/* The "FN" token alone.
|
6211 |
*/
|
6212 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX (12)
|
6213 |
/* The "CF" token alone.
|
6214 |
*/
|
6215 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB (13)
|
6216 |
/* The "FAB" token alone.
|
6217 |
*/
|
6218 |
#define CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX (14)
|
6219 |
/* The "FABDMAX" token alone.
|
6220 |
*/
|
6221 |
#define CMDLINE_PAR_TYPE_INTNEG (15)
|
6222 |
/* A negative integer.
|
6223 |
*/
|
6224 |
#define CMDLINE_PAR_TYPE_INTZERO (16)
|
6225 |
/* The integer zero.
|
6226 |
*/
|
6227 |
#define CMDLINE_PAR_TYPE_INTPOS (17)
|
6228 |
/* A positive integer.
|
6229 |
*/
|
6230 |
#define CMDLINE_PAR_TYPE_RATNEG (18)
|
6231 |
/* A negative rational number.
|
6232 |
*/
|
6233 |
#define CMDLINE_PAR_TYPE_RATZERO (19)
|
6234 |
/* A rational number whose value is zero.
|
6235 |
*/
|
6236 |
#define CMDLINE_PAR_TYPE_RATPOS (20)
|
6237 |
/* A positive rational number.
|
6238 |
*/
|
6239 |
#define CMDLINE_PAR_TYPE_UNKNOWN (21)
|
6240 |
/* Couldn't figure out what it was.
|
6241 |
*/
|
6242 |
|
6243 |
/* The next thing to define is the data type which holds a command-line
|
6244 |
** parameter (or parameters from a file, same thing).
|
6245 |
*/
|
6246 |
typedef struct
|
6247 |
{
|
6248 |
int ftype;
|
6249 |
/* The fundamental type, using one of the enumerated constants
|
6250 |
** above.
|
6251 |
*/
|
6252 |
char *orig_string;
|
6253 |
/* The string value that was supplied on the command line, after
|
6254 |
** everything was converted to upper case and token concatenation
|
6255 |
** is done. This will be a dynamically allocated string.
|
6256 |
*/
|
6257 |
SYNTHETIC_INTEGER *raw_numerator;
|
6258 |
SYNTHETIC_INTEGER *raw_denominator;
|
6259 |
/* Filled exactly as specified on the command line. If only an
|
6260 |
** integer was specified, the denominator pointer is NULL. If
|
6261 |
** the caller specified a rational number as a float, the original
|
6262 |
** rational number formed by adding zeros to the numerator and
|
6263 |
** making the denominator a power of ten is placed here.
|
6264 |
*/
|
6265 |
SYNTHETIC_INTEGER *canonical_numerator;
|
6266 |
SYNTHETIC_INTEGER *canonical_denominator;
|
6267 |
/* The parsing takes steps to put any numerical argument into
|
6268 |
** a canonical form. Here are the steps taken.
|
6269 |
**
|
6270 |
** a)Any rational number with a zero denominator will terminate
|
6271 |
** the program with an error message.
|
6272 |
**
|
6273 |
** b)Integers are left unchanged (there is really nothing more
|
6274 |
** canonical.
|
6275 |
**
|
6276 |
** c)The GCD is always removed from the input argument, using
|
6277 |
** Euclid's algorithm (directly or indirectly). If a rational
|
6278 |
** number supplied is actually an integer (after GCD calculated),
|
6279 |
** it is treated as such (NULL denominator pointer).
|
6280 |
**
|
6281 |
** d)If the rational number is positive and was specified as
|
6282 |
** the quotient of two negative integers, the "negs" are
|
6283 |
** removed.
|
6284 |
**
|
6285 |
** e)Any negative rational number will be expressed as a negative
|
6286 |
** numerator and positive denominator.
|
6287 |
**
|
6288 |
** f)Any rational number which has value 0 (such as 0/-1293981),
|
6289 |
** will be stored canonically as 0/1.
|
6290 |
*/
|
6291 |
} CMD_LINE_PAR;
|
6292 |
|
6293 |
|
6294 |
/* A single data structure which holds the complete set of command-line
|
6295 |
** parameters. It is easier to do it this way rather than dynamically
|
6296 |
** resized arrays, etc.
|
6297 |
*/
|
6298 |
struct ipParBlockStruct
|
6299 |
{
|
6300 |
int n;
|
6301 |
/* The number of array elements filled in the array of
|
6302 |
** command-line parameters.
|
6303 |
*/
|
6304 |
CMD_LINE_PAR pars[MAX_CMDLINE_PARS];
|
6305 |
/* Space for the command-line parameters.
|
6306 |
*/
|
6307 |
} par_block;
|
6308 |
|
6309 |
|
6310 |
/****************************************************************************/
|
6311 |
/* cfSimple2ParIntegerAddition(): */
|
6312 |
/*--------------------------------------------------------------------------*/
|
6313 |
/* DESCRIPTION */
|
6314 |
/* Handles addition of two arbitrary integers and displaying the result. */
|
6315 |
/* Called in response to a template match. */
|
6316 |
/****************************************************************************/
|
6317 |
void cfSimple2ParIntegerAddition(void)
|
6318 |
{
|
6319 |
SYNTHETIC_INTEGER *result;
|
6320 |
|
6321 |
siCreate(&result);
|
6322 |
siUnrestrictedAddition(&(par_block.pars[1].canonical_numerator),
|
6323 |
&(par_block.pars[2].canonical_numerator),
|
6324 |
&result);
|
6325 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6326 |
gfHline();
|
6327 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6328 |
gfHline();
|
6329 |
siDump(&result, "arg1 + arg2");
|
6330 |
gfHline();
|
6331 |
}
|
6332 |
|
6333 |
|
6334 |
/****************************************************************************/
|
6335 |
/* cfSimple2ParRationalRationalAddition(): */
|
6336 |
/*--------------------------------------------------------------------------*/
|
6337 |
/* DESCRIPTION */
|
6338 |
/* Handles addition of two arbitrary rational numbers. Called in */
|
6339 |
/* response to a template match. */
|
6340 |
/****************************************************************************/
|
6341 |
void cfSimple2ParRationalRationalAddition(void)
|
6342 |
{
|
6343 |
SYNTHETIC_INTEGER *arg1_h,
|
6344 |
*arg1_k,
|
6345 |
*arg2_h,
|
6346 |
*arg2_k,
|
6347 |
*constant_1,
|
6348 |
*result_numerator,
|
6349 |
*result_denominator;
|
6350 |
|
6351 |
siCreate(&arg1_h);
|
6352 |
siCreate(&arg1_k);
|
6353 |
siCreate(&arg2_h);
|
6354 |
siCreate(&arg2_k);
|
6355 |
siCreate(&constant_1);
|
6356 |
siSetToLong(&constant_1, 1);
|
6357 |
siCreate(&result_numerator);
|
6358 |
siCreate(&result_denominator);
|
6359 |
|
6360 |
/* Since this function handles the general case where either
|
6361 |
** or both arguments are rational, we need to watch out and
|
6362 |
** condition any integer argument to be rational. We need
|
6363 |
** to watch out for a missing denominator and assign it to
|
6364 |
** be "1" if it is missing (meaning that the original argument
|
6365 |
** was an integer.
|
6366 |
*/
|
6367 |
/* Copy over to our scratch space, watching out for integers.
|
6368 |
*/
|
6369 |
siCopy(&(par_block.pars[1].canonical_numerator), &arg1_h);
|
6370 |
if (par_block.pars[1].canonical_denominator)
|
6371 |
siCopy(&(par_block.pars[1].canonical_denominator), &arg1_k);
|
6372 |
else
|
6373 |
siSetToLong(&arg1_k, 1);
|
6374 |
|
6375 |
siCopy(&(par_block.pars[2].canonical_numerator), &arg2_h);
|
6376 |
if (par_block.pars[2].canonical_denominator)
|
6377 |
siCopy(&(par_block.pars[2].canonical_denominator), &arg2_k);
|
6378 |
else
|
6379 |
siSetToLong(&arg2_k, 1);
|
6380 |
|
6381 |
/* Make the call to the rational number addition function.
|
6382 |
*/
|
6383 |
rnSum(&arg1_h, &arg1_k, &arg2_h, &arg2_k, &result_numerator, &result_denominator);
|
6384 |
|
6385 |
/* Print out the first argument. We display it differently
|
6386 |
** depending on if it was rational or integral.
|
6387 |
*/
|
6388 |
if (par_block.pars[1].canonical_denominator)
|
6389 |
{
|
6390 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1_h");
|
6391 |
gfHline();
|
6392 |
siDump(&(par_block.pars[1].canonical_denominator), "arg1_k");
|
6393 |
gfHline();
|
6394 |
}
|
6395 |
else
|
6396 |
{
|
6397 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6398 |
gfHline();
|
6399 |
}
|
6400 |
|
6401 |
/* Print out the first argument. We display it differently
|
6402 |
** depending on if it was rational or integral.
|
6403 |
*/
|
6404 |
if (par_block.pars[2].canonical_denominator)
|
6405 |
{
|
6406 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2_h");
|
6407 |
gfHline();
|
6408 |
siDump(&(par_block.pars[2].canonical_denominator), "arg2_k");
|
6409 |
gfHline();
|
6410 |
}
|
6411 |
else
|
6412 |
{
|
6413 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6414 |
gfHline();
|
6415 |
}
|
6416 |
|
6417 |
/* Print out the result. We display it differently, depending
|
6418 |
** on whether it is rational or integral.
|
6419 |
*/
|
6420 |
if (!siCompare(&result_denominator, &constant_1))
|
6421 |
{
|
6422 |
/* Denominator is equal to 1. This is an integer.
|
6423 |
*/
|
6424 |
siDump(&result_numerator, "result");
|
6425 |
gfHline();
|
6426 |
}
|
6427 |
else
|
6428 |
{
|
6429 |
siDump(&result_numerator, "result_h");
|
6430 |
gfHline();
|
6431 |
siDump(&result_denominator, "result_k");
|
6432 |
gfHline();
|
6433 |
}
|
6434 |
|
6435 |
siDestroy(&arg1_h);
|
6436 |
siDestroy(&arg1_k);
|
6437 |
siDestroy(&arg2_h);
|
6438 |
siDestroy(&arg2_k);
|
6439 |
siDestroy(&constant_1);
|
6440 |
siDestroy(&result_numerator);
|
6441 |
siDestroy(&result_denominator);
|
6442 |
}
|
6443 |
|
6444 |
|
6445 |
/****************************************************************************/
|
6446 |
/* cfSimple2ParIntegerSubtraction(): */
|
6447 |
/*--------------------------------------------------------------------------*/
|
6448 |
/* DESCRIPTION */
|
6449 |
/* Handles subtraction of two arbitrary integers and displaying the */
|
6450 |
/* result. Called in response to a template match. */
|
6451 |
/****************************************************************************/
|
6452 |
void cfSimple2ParIntegerSubtraction(void)
|
6453 |
{
|
6454 |
SYNTHETIC_INTEGER *result;
|
6455 |
|
6456 |
siCreate(&result);
|
6457 |
siUnrestrictedSubtraction(&(par_block.pars[1].canonical_numerator),
|
6458 |
&(par_block.pars[2].canonical_numerator),
|
6459 |
&result);
|
6460 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6461 |
gfHline();
|
6462 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6463 |
gfHline();
|
6464 |
siDump(&result, "arg1 - arg2");
|
6465 |
gfHline();
|
6466 |
siDestroy(&result);
|
6467 |
}
|
6468 |
|
6469 |
|
6470 |
/****************************************************************************/
|
6471 |
/* cfSimple2ParRationalRationalSubtraction(): */
|
6472 |
/*--------------------------------------------------------------------------*/
|
6473 |
/* DESCRIPTION */
|
6474 |
/* Handles subtraction of two arbitrary rational numbers. Called in */
|
6475 |
/* response to a template match. */
|
6476 |
/****************************************************************************/
|
6477 |
void cfSimple2ParRationalRationalSubtraction(void)
|
6478 |
{
|
6479 |
SYNTHETIC_INTEGER *arg1_h,
|
6480 |
*arg1_k,
|
6481 |
*arg2_h,
|
6482 |
*arg2_k,
|
6483 |
*constant_1,
|
6484 |
*result_numerator,
|
6485 |
*result_denominator;
|
6486 |
|
6487 |
siCreate(&arg1_h);
|
6488 |
siCreate(&arg1_k);
|
6489 |
siCreate(&arg2_h);
|
6490 |
siCreate(&arg2_k);
|
6491 |
siCreate(&constant_1);
|
6492 |
siSetToLong(&constant_1, 1);
|
6493 |
siCreate(&result_numerator);
|
6494 |
siCreate(&result_denominator);
|
6495 |
|
6496 |
/* Since this function handles the general case where either
|
6497 |
** or both arguments are rational, we need to watch out and
|
6498 |
** condition any integer argument to be rational. We need
|
6499 |
** to watch out for a missing denominator and assign it to
|
6500 |
** be "1" if it is missing (meaning that the original argument
|
6501 |
** was an integer.
|
6502 |
*/
|
6503 |
/* Copy over to our scratch space, watching out for integers.
|
6504 |
*/
|
6505 |
siCopy(&(par_block.pars[1].canonical_numerator), &arg1_h);
|
6506 |
if (par_block.pars[1].canonical_denominator)
|
6507 |
siCopy(&(par_block.pars[1].canonical_denominator), &arg1_k);
|
6508 |
else
|
6509 |
siSetToLong(&arg1_k, 1);
|
6510 |
|
6511 |
siCopy(&(par_block.pars[2].canonical_numerator), &arg2_h);
|
6512 |
if (par_block.pars[2].canonical_denominator)
|
6513 |
siCopy(&(par_block.pars[2].canonical_denominator), &arg2_k);
|
6514 |
else
|
6515 |
siSetToLong(&arg2_k, 1);
|
6516 |
|
6517 |
/* Make the call to the rational number addition function.
|
6518 |
*/
|
6519 |
rnDifference(&arg1_h, &arg1_k, &arg2_h, &arg2_k, &result_numerator, &result_denominator);
|
6520 |
|
6521 |
/* Print out the first argument. We display it differently
|
6522 |
** depending on if it was rational or integral.
|
6523 |
*/
|
6524 |
if (par_block.pars[1].canonical_denominator)
|
6525 |
{
|
6526 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1_h");
|
6527 |
gfHline();
|
6528 |
siDump(&(par_block.pars[1].canonical_denominator), "arg1_k");
|
6529 |
gfHline();
|
6530 |
}
|
6531 |
else
|
6532 |
{
|
6533 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6534 |
gfHline();
|
6535 |
}
|
6536 |
|
6537 |
/* Print out the first argument. We display it differently
|
6538 |
** depending on if it was rational or integral.
|
6539 |
*/
|
6540 |
if (par_block.pars[2].canonical_denominator)
|
6541 |
{
|
6542 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2_h");
|
6543 |
gfHline();
|
6544 |
siDump(&(par_block.pars[2].canonical_denominator), "arg2_k");
|
6545 |
gfHline();
|
6546 |
}
|
6547 |
else
|
6548 |
{
|
6549 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6550 |
gfHline();
|
6551 |
}
|
6552 |
|
6553 |
/* Print out the result. We display it differently, depending
|
6554 |
** on whether it is rational or integral.
|
6555 |
*/
|
6556 |
if (!siCompare(&result_denominator, &constant_1))
|
6557 |
{
|
6558 |
/* Denominator is equal to 1. This is an integer.
|
6559 |
*/
|
6560 |
siDump(&result_numerator, "result");
|
6561 |
gfHline();
|
6562 |
}
|
6563 |
else
|
6564 |
{
|
6565 |
siDump(&result_numerator, "result_h");
|
6566 |
gfHline();
|
6567 |
siDump(&result_denominator, "result_k");
|
6568 |
gfHline();
|
6569 |
}
|
6570 |
|
6571 |
siDestroy(&arg1_h);
|
6572 |
siDestroy(&arg1_k);
|
6573 |
siDestroy(&arg2_h);
|
6574 |
siDestroy(&arg2_k);
|
6575 |
siDestroy(&constant_1);
|
6576 |
siDestroy(&result_numerator);
|
6577 |
siDestroy(&result_denominator);
|
6578 |
}
|
6579 |
|
6580 |
|
6581 |
/****************************************************************************/
|
6582 |
/* cfSimple2ParIntegerMultiplication(): */
|
6583 |
/*--------------------------------------------------------------------------*/
|
6584 |
/* DESCRIPTION */
|
6585 |
/* Handles multiplication of two arbitrary integers and displaying the */
|
6586 |
/* result. Called in response to a template match. */
|
6587 |
/****************************************************************************/
|
6588 |
void cfSimple2ParIntegerMultiplication(void)
|
6589 |
{
|
6590 |
SYNTHETIC_INTEGER *result;
|
6591 |
|
6592 |
siCreate(&result);
|
6593 |
siUnrestrictedMultiplication(&(par_block.pars[1].canonical_numerator),
|
6594 |
&(par_block.pars[2].canonical_numerator),
|
6595 |
&result);
|
6596 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6597 |
gfHline();
|
6598 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6599 |
gfHline();
|
6600 |
siDump(&result, "arg1 * arg2");
|
6601 |
gfHline();
|
6602 |
siDestroy(&result);
|
6603 |
}
|
6604 |
|
6605 |
|
6606 |
/****************************************************************************/
|
6607 |
/* cfSimple2ParRationalRationalMultiplication(): */
|
6608 |
/*--------------------------------------------------------------------------*/
|
6609 |
/* DESCRIPTION */
|
6610 |
/* Handles multiplication of two arbitrary rational numbers. Called in */
|
6611 |
/* response to a template match. */
|
6612 |
/****************************************************************************/
|
6613 |
void cfSimple2ParRationalRationalMultiplication(void)
|
6614 |
{
|
6615 |
SYNTHETIC_INTEGER *arg1_h,
|
6616 |
*arg1_k,
|
6617 |
*arg2_h,
|
6618 |
*arg2_k,
|
6619 |
*constant_1,
|
6620 |
*result_numerator,
|
6621 |
*result_denominator;
|
6622 |
|
6623 |
siCreate(&arg1_h);
|
6624 |
siCreate(&arg1_k);
|
6625 |
siCreate(&arg2_h);
|
6626 |
siCreate(&arg2_k);
|
6627 |
siCreate(&constant_1);
|
6628 |
siSetToLong(&constant_1, 1);
|
6629 |
siCreate(&result_numerator);
|
6630 |
siCreate(&result_denominator);
|
6631 |
|
6632 |
/* Since this function handles the general case where either
|
6633 |
** or both arguments are rational, we need to watch out and
|
6634 |
** condition any integer argument to be rational. We need
|
6635 |
** to watch out for a missing denominator and assign it to
|
6636 |
** be "1" if it is missing (meaning that the original argument
|
6637 |
** was an integer.
|
6638 |
*/
|
6639 |
/* Copy over to our scratch space, watching out for integers.
|
6640 |
*/
|
6641 |
siCopy(&(par_block.pars[1].canonical_numerator), &arg1_h);
|
6642 |
if (par_block.pars[1].canonical_denominator)
|
6643 |
siCopy(&(par_block.pars[1].canonical_denominator), &arg1_k);
|
6644 |
else
|
6645 |
siSetToLong(&arg1_k, 1);
|
6646 |
|
6647 |
siCopy(&(par_block.pars[2].canonical_numerator), &arg2_h);
|
6648 |
if (par_block.pars[2].canonical_denominator)
|
6649 |
siCopy(&(par_block.pars[2].canonical_denominator), &arg2_k);
|
6650 |
else
|
6651 |
siSetToLong(&arg2_k, 1);
|
6652 |
|
6653 |
/* Call the function to calculate the rational product.
|
6654 |
*/
|
6655 |
rnProduct(&arg1_h, &arg1_k, &arg2_h, &arg2_k, &result_numerator, &result_denominator);
|
6656 |
|
6657 |
/* Print out the first argument. We display it differently
|
6658 |
** depending on if it was rational or integral.
|
6659 |
*/
|
6660 |
if (par_block.pars[1].canonical_denominator)
|
6661 |
{
|
6662 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1_h");
|
6663 |
gfHline();
|
6664 |
siDump(&(par_block.pars[1].canonical_denominator), "arg1_k");
|
6665 |
gfHline();
|
6666 |
}
|
6667 |
else
|
6668 |
{
|
6669 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6670 |
gfHline();
|
6671 |
}
|
6672 |
|
6673 |
/* Print out the first argument. We display it differently
|
6674 |
** depending on if it was rational or integral.
|
6675 |
*/
|
6676 |
if (par_block.pars[2].canonical_denominator)
|
6677 |
{
|
6678 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2_h");
|
6679 |
gfHline();
|
6680 |
siDump(&(par_block.pars[2].canonical_denominator), "arg2_k");
|
6681 |
gfHline();
|
6682 |
}
|
6683 |
else
|
6684 |
{
|
6685 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6686 |
gfHline();
|
6687 |
}
|
6688 |
|
6689 |
/* Print out the result. We display it differently, depending
|
6690 |
** on whether it is rational or integral.
|
6691 |
*/
|
6692 |
if (!siCompare(&result_denominator, &constant_1))
|
6693 |
{
|
6694 |
/* Denominator is equal to 1. This is an integer.
|
6695 |
*/
|
6696 |
siDump(&result_numerator, "result");
|
6697 |
gfHline();
|
6698 |
}
|
6699 |
else
|
6700 |
{
|
6701 |
siDump(&result_numerator, "result_h");
|
6702 |
gfHline();
|
6703 |
siDump(&result_denominator, "result_k");
|
6704 |
gfHline();
|
6705 |
}
|
6706 |
|
6707 |
siDestroy(&arg1_h);
|
6708 |
siDestroy(&arg1_k);
|
6709 |
siDestroy(&arg2_h);
|
6710 |
siDestroy(&arg2_k);
|
6711 |
siDestroy(&constant_1);
|
6712 |
siDestroy(&result_numerator);
|
6713 |
siDestroy(&result_denominator);
|
6714 |
}
|
6715 |
|
6716 |
|
6717 |
/****************************************************************************/
|
6718 |
/* cfSimple2ParIntegerExponentiation(): */
|
6719 |
/*--------------------------------------------------------------------------*/
|
6720 |
/* DESCRIPTION */
|
6721 |
/* Handles simple integer exponentiation. Called in response to a */
|
6722 |
/* template match. */
|
6723 |
/****************************************************************************/
|
6724 |
void cfSimple2ParIntegerExponentiation(void)
|
6725 |
{
|
6726 |
SYNTHETIC_INTEGER *result;
|
6727 |
|
6728 |
siCreate(&result);
|
6729 |
siIntegerExponentiation(&(par_block.pars[1].canonical_numerator),
|
6730 |
&(par_block.pars[2].canonical_numerator),
|
6731 |
&result);
|
6732 |
siDump(&(par_block.pars[1].canonical_numerator), "arg");
|
6733 |
gfHline();
|
6734 |
siDump(&(par_block.pars[2].canonical_numerator), "exponent");
|
6735 |
gfHline();
|
6736 |
siDump(&result, "arg ** exponent");
|
6737 |
gfHline();
|
6738 |
siDestroy(&result);
|
6739 |
}
|
6740 |
|
6741 |
|
6742 |
/****************************************************************************/
|
6743 |
/* cfSimple2ParIntegerExponentiationOfRational(): */
|
6744 |
/*--------------------------------------------------------------------------*/
|
6745 |
/* DESCRIPTION */
|
6746 |
/* Handles a rational raised to an integer power. Called in response */
|
6747 |
/* to a template match. */
|
6748 |
/****************************************************************************/
|
6749 |
void cfSimple2ParIntegerExponentiationOfRational(void)
|
6750 |
{
|
6751 |
/* There isn't a need to do any conversion, before or after. Since
|
6752 |
** the gcd() is removed from numerator and denominator, and since
|
6753 |
** it isn't an integer, then the numerator and denominator have
|
6754 |
** different prime components, exponentiating to any power
|
6755 |
** can't create an integer or even anything that can be reduced.
|
6756 |
** It would be fruitless to GCD the result.
|
6757 |
*/
|
6758 |
SYNTHETIC_INTEGER *result_numerator;
|
6759 |
SYNTHETIC_INTEGER *result_denominator;
|
6760 |
|
6761 |
siCreate(&result_numerator);
|
6762 |
siCreate(&result_denominator);
|
6763 |
|
6764 |
siIntegerExponentiation(&(par_block.pars[1].canonical_numerator),
|
6765 |
&(par_block.pars[2].canonical_numerator),
|
6766 |
&result_numerator);
|
6767 |
siIntegerExponentiation(&(par_block.pars[1].canonical_denominator),
|
6768 |
&(par_block.pars[2].canonical_numerator),
|
6769 |
&result_denominator);
|
6770 |
|
6771 |
siDump(&(par_block.pars[1].canonical_numerator), "arg_h");
|
6772 |
gfHline();
|
6773 |
siDump(&(par_block.pars[1].canonical_denominator), "arg_k");
|
6774 |
gfHline();
|
6775 |
siDump(&(par_block.pars[2].canonical_numerator), "exponent");
|
6776 |
gfHline();
|
6777 |
siDump(&result_numerator, "arg_h ** exponent");
|
6778 |
gfHline();
|
6779 |
siDump(&result_denominator, "arg_k ** exponent");
|
6780 |
gfHline();
|
6781 |
|
6782 |
siDestroy(&result_numerator);
|
6783 |
siDestroy(&result_denominator);
|
6784 |
}
|
6785 |
|
6786 |
|
6787 |
/****************************************************************************/
|
6788 |
/* cfSimple2ParIntegerQuotient(): */
|
6789 |
/*--------------------------------------------------------------------------*/
|
6790 |
/* DESCRIPTION */
|
6791 |
/* Handles simple integer division. As a courtesy, the remainder is */
|
6792 |
/* returned as well. */
|
6793 |
/****************************************************************************/
|
6794 |
void cfSimple2ParIntegerQuotient(void)
|
6795 |
{
|
6796 |
SYNTHETIC_INTEGER *quotient;
|
6797 |
SYNTHETIC_INTEGER *remainder;
|
6798 |
|
6799 |
siCreate("ient);
|
6800 |
siCreate(&remainder);
|
6801 |
siUnrestrictedDivision(&(par_block.pars[1].canonical_numerator),
|
6802 |
&(par_block.pars[2].canonical_numerator),
|
6803 |
"ient,
|
6804 |
&remainder);
|
6805 |
siDump(&(par_block.pars[1].canonical_numerator), "dividend");
|
6806 |
gfHline();
|
6807 |
siDump(&(par_block.pars[2].canonical_numerator), "divisor");
|
6808 |
gfHline();
|
6809 |
siDump(&remainder, "dividend % divisor");
|
6810 |
gfHline();
|
6811 |
siDump("ient, "dividend / divisor");
|
6812 |
gfHline();
|
6813 |
siDestroy("ient);
|
6814 |
siDestroy(&remainder);
|
6815 |
}
|
6816 |
|
6817 |
|
6818 |
/****************************************************************************/
|
6819 |
/* cfSimple2ParIntegerRemainder(): */
|
6820 |
/*--------------------------------------------------------------------------*/
|
6821 |
/* DESCRIPTION */
|
6822 |
/* Handles simple integer remainder. As a courtesy, the quotient is */
|
6823 |
/* returned as well. */
|
6824 |
/****************************************************************************/
|
6825 |
void cfSimple2ParIntegerRemainder(void)
|
6826 |
{
|
6827 |
SYNTHETIC_INTEGER *quotient;
|
6828 |
SYNTHETIC_INTEGER *remainder;
|
6829 |
|
6830 |
siCreate("ient);
|
6831 |
siCreate(&remainder);
|
6832 |
siUnrestrictedDivision(&(par_block.pars[1].canonical_numerator),
|
6833 |
&(par_block.pars[2].canonical_numerator),
|
6834 |
"ient,
|
6835 |
&remainder);
|
6836 |
siDump(&(par_block.pars[1].canonical_numerator), "dividend");
|
6837 |
gfHline();
|
6838 |
siDump(&(par_block.pars[2].canonical_numerator), "divisor");
|
6839 |
gfHline();
|
6840 |
siDump("ient, "dividend / divisor");
|
6841 |
gfHline();
|
6842 |
siDump(&remainder, "dividend % divisor");
|
6843 |
gfHline();
|
6844 |
siDestroy("ient);
|
6845 |
siDestroy(&remainder);
|
6846 |
}
|
6847 |
|
6848 |
|
6849 |
/****************************************************************************/
|
6850 |
/* cfSimple2ParRationalRationalQuotient(): */
|
6851 |
/*--------------------------------------------------------------------------*/
|
6852 |
/* DESCRIPTION */
|
6853 |
/* Handles division of two arbitrary rational numbers. Called in */
|
6854 |
/* response to a template match. */
|
6855 |
/****************************************************************************/
|
6856 |
void cfSimple2ParRationalRationalQuotient(void)
|
6857 |
{
|
6858 |
SYNTHETIC_INTEGER *arg1_h,
|
6859 |
*arg1_k,
|
6860 |
*arg2_h,
|
6861 |
*arg2_k,
|
6862 |
*constant_1,
|
6863 |
*result_numerator,
|
6864 |
*result_denominator;
|
6865 |
|
6866 |
siCreate(&arg1_h);
|
6867 |
siCreate(&arg1_k);
|
6868 |
siCreate(&arg2_h);
|
6869 |
siCreate(&arg2_k);
|
6870 |
siCreate(&constant_1);
|
6871 |
siSetToLong(&constant_1, 1);
|
6872 |
siCreate(&result_numerator);
|
6873 |
siCreate(&result_denominator);
|
6874 |
|
6875 |
/* Since this function handles the general case where either
|
6876 |
** or both arguments are rational, we need to watch out and
|
6877 |
** condition any integer argument to be rational. We need
|
6878 |
** to watch out for a missing denominator and assign it to
|
6879 |
** be "1" if it is missing (meaning that the original argument
|
6880 |
** was an integer.
|
6881 |
*/
|
6882 |
/* Copy over to our scratch space, watching out for integers.
|
6883 |
*/
|
6884 |
siCopy(&(par_block.pars[1].canonical_numerator), &arg1_h);
|
6885 |
if (par_block.pars[1].canonical_denominator)
|
6886 |
siCopy(&(par_block.pars[1].canonical_denominator), &arg1_k);
|
6887 |
else
|
6888 |
siSetToLong(&arg1_k, 1);
|
6889 |
|
6890 |
siCopy(&(par_block.pars[2].canonical_numerator), &arg2_h);
|
6891 |
if (par_block.pars[2].canonical_denominator)
|
6892 |
siCopy(&(par_block.pars[2].canonical_denominator), &arg2_k);
|
6893 |
else
|
6894 |
siSetToLong(&arg2_k, 1);
|
6895 |
|
6896 |
/* Call the function to calculate the rational product.
|
6897 |
*/
|
6898 |
rnQuotient(&arg1_h, &arg1_k, &arg2_h, &arg2_k, &result_numerator, &result_denominator);
|
6899 |
|
6900 |
/* Print out the first argument. We display it differently
|
6901 |
** depending on if it was rational or integral.
|
6902 |
*/
|
6903 |
if (par_block.pars[1].canonical_denominator)
|
6904 |
{
|
6905 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1_h");
|
6906 |
gfHline();
|
6907 |
siDump(&(par_block.pars[1].canonical_denominator), "arg1_k");
|
6908 |
gfHline();
|
6909 |
}
|
6910 |
else
|
6911 |
{
|
6912 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6913 |
gfHline();
|
6914 |
}
|
6915 |
|
6916 |
/* Print out the first argument. We display it differently
|
6917 |
** depending on if it was rational or integral.
|
6918 |
*/
|
6919 |
if (par_block.pars[2].canonical_denominator)
|
6920 |
{
|
6921 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2_h");
|
6922 |
gfHline();
|
6923 |
siDump(&(par_block.pars[2].canonical_denominator), "arg2_k");
|
6924 |
gfHline();
|
6925 |
}
|
6926 |
else
|
6927 |
{
|
6928 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6929 |
gfHline();
|
6930 |
}
|
6931 |
|
6932 |
/* Print out the result. We display it differently, depending
|
6933 |
** on whether it is rational or integral.
|
6934 |
*/
|
6935 |
if (!siCompare(&result_denominator, &constant_1))
|
6936 |
{
|
6937 |
/* Denominator is equal to 1. This is an integer.
|
6938 |
*/
|
6939 |
siDump(&result_numerator, "result");
|
6940 |
gfHline();
|
6941 |
}
|
6942 |
else
|
6943 |
{
|
6944 |
siDump(&result_numerator, "result_h");
|
6945 |
gfHline();
|
6946 |
siDump(&result_denominator, "result_k");
|
6947 |
gfHline();
|
6948 |
}
|
6949 |
|
6950 |
siDestroy(&arg1_h);
|
6951 |
siDestroy(&arg1_k);
|
6952 |
siDestroy(&arg2_h);
|
6953 |
siDestroy(&arg2_k);
|
6954 |
siDestroy(&constant_1);
|
6955 |
siDestroy(&result_numerator);
|
6956 |
siDestroy(&result_denominator);
|
6957 |
}
|
6958 |
|
6959 |
|
6960 |
/****************************************************************************/
|
6961 |
/* cfSimple2ParIntegerGcd(): */
|
6962 |
/*--------------------------------------------------------------------------*/
|
6963 |
/* DESCRIPTION */
|
6964 |
/* Applies Euclid's algorithm to obtain the gcd() of two positive */
|
6965 |
/* integers. */
|
6966 |
/****************************************************************************/
|
6967 |
void cfSimple2ParIntegerGcd(void)
|
6968 |
{
|
6969 |
SYNTHETIC_INTEGER *result;
|
6970 |
|
6971 |
siCreate(&result);
|
6972 |
siGcd(&(par_block.pars[1].canonical_numerator),
|
6973 |
&(par_block.pars[2].canonical_numerator),
|
6974 |
&result);
|
6975 |
siDump(&(par_block.pars[1].canonical_numerator), "arg1");
|
6976 |
gfHline();
|
6977 |
siDump(&(par_block.pars[2].canonical_numerator), "arg2");
|
6978 |
gfHline();
|
6979 |
siDump(&result, "gcd(arg1, arg2)");
|
6980 |
gfHline();
|
6981 |
siDestroy(&result);
|
6982 |
}
|
6983 |
|
6984 |
|
6985 |
/****************************************************************************/
|
6986 |
/* cfDap(): */
|
6987 |
/*--------------------------------------------------------------------------*/
|
6988 |
/* DESCRIPTION */
|
6989 |
/* Applies the DAP function as outlined in the manual. */
|
6990 |
/****************************************************************************/
|
6991 |
void cfDap(void)
|
6992 |
{
|
6993 |
SYNTHETIC_INTEGER *D, /* The denominator chosen. */
|
6994 |
*hD, /* Product of input h and D. */
|
6995 |
*k, /* Denominator to be used. */
|
6996 |
*hD_over_k, /* Final result. */
|
6997 |
*trash_remainder; /* Remainder not used. */
|
6998 |
|
6999 |
/* Create all of our locals.
|
7000 |
*/
|
7001 |
siCreate(&D);
|
7002 |
siCreate(&hD);
|
7003 |
siCreate(&k);
|
7004 |
siCreate(&hD_over_k);
|
7005 |
siCreate(&trash_remainder);
|
7006 |
|
7007 |
/* There are two cases to consider. Either the user has
|
7008 |
** specified a second parameter (the denominator to use),
|
7009 |
** or we use a default. Let's assign the default, then
|
7010 |
** overwrite it with the user's choice.
|
7011 |
*/
|
7012 |
siSetToPowerOfTen(&D, DIGITS_PER_LINE * 4);
|
7013 |
|
7014 |
/* If the user has specified a second parameter, set D to be
|
7015 |
** that second parameter. This overwrites the default
|
7016 |
** choice of four lines.
|
7017 |
*/
|
7018 |
if (par_block.pars[2].ftype == CMDLINE_PAR_TYPE_INTPOS)
|
7019 |
{
|
7020 |
asAssert(par_block.pars[2].canonical_numerator != NULL, __LINE__);
|
7021 |
|
7022 |
siCopy(&(par_block.pars[2].canonical_numerator), &D);
|
7023 |
}
|
7024 |
|
7025 |
/* Assign the value of k, in case the user is trying to DAP an integer,
|
7026 |
** which doesn't make sense.
|
7027 |
*/
|
7028 |
if (par_block.pars[1].canonical_denominator)
|
7029 |
siCopy(&(par_block.pars[1].canonical_denominator), &k);
|
7030 |
else
|
7031 |
siSetToLong(&k, 1);
|
7032 |
|
7033 |
/* Perform the actual DAP calculation. */
|
7034 |
asAssert(par_block.pars[1].canonical_numerator != NULL, __LINE__);
|
7035 |
siUnrestrictedMultiplication(&(par_block.pars[1].canonical_numerator),
|
7036 |
&D,
|
7037 |
&hD);
|
7038 |
siUnrestrictedDivision(&hD,
|
7039 |
&k,
|
7040 |
&hD_over_k,
|
7041 |
&trash_remainder);
|
7042 |
|
7043 |
/* Print the results. */
|
7044 |
if (par_block.pars[1].canonical_denominator)
|
7045 |
{
|
7046 |
siDump(&(par_block.pars[1].canonical_numerator), "arg_h");
|
7047 |
gfHline();
|
7048 |
siDump(&(par_block.pars[1].canonical_denominator), "arg_k");
|
7049 |
gfHline();
|
7050 |
}
|
7051 |
else
|
7052 |
{
|
7053 |
siDump(&(par_block.pars[1].canonical_numerator), "arg");
|
7054 |
gfHline();
|
7055 |
}
|
7056 |
|
7057 |
siDump(&hD_over_k, "N");
|
7058 |
gfHline();
|
7059 |
siDump(&D, "D");
|
7060 |
gfHline();
|
7061 |
|
7062 |
/* Destroy all of our locals.
|
7063 |
*/
|
7064 |
siDestroy(&D);
|
7065 |
siDestroy(&hD);
|
7066 |
siDestroy(&k);
|
7067 |
siDestroy(&hD_over_k);
|
7068 |
siDestroy(&trash_remainder);
|
7069 |
}
|
7070 |
|
7071 |
|
7072 |
/****************************************************************************/
|
7073 |
/* cfCf(): */
|
7074 |
/*--------------------------------------------------------------------------*/
|
7075 |
/* DESCRIPTION */
|
7076 |
/* Forms the continued fraction decomposition and convergents of a */
|
7077 |
/* non-negative rational number. */
|
7078 |
/****************************************************************************/
|
7079 |
void cfCf(void)
|
7080 |
{
|
7081 |
SYNTHETIC_INTEGER *h, *k; /* The numerator and denominator to use
|
7082 |
** for the continued fraction expansion.
|
7083 |
*/
|
7084 |
CF_EXPANSION *e; /* The continued fraction expansion.
|
7085 |
*/
|
7086 |
|
7087 |
/* Allocate the integers.
|
7088 |
*/
|
7089 |
siCreate(&h);
|
7090 |
siCreate(&k);
|
7091 |
|
7092 |
/* Be absolutely sure that we have a viable numerator, and
|
7093 |
** copy it to what we are using for our numerator.
|
7094 |
*/
|
7095 |
asAssert(par_block.pars[1].canonical_numerator != NULL, __LINE__);
|
7096 |
siCopy(&(par_block.pars[1].canonical_numerator), &h);
|
7097 |
|
7098 |
/* Use the denominator available, unless it doesn't exist, in
|
7099 |
** which case will use "1".
|
7100 |
*/
|
7101 |
if (par_block.pars[1].canonical_denominator)
|
7102 |
{
|
7103 |
siCopy(&(par_block.pars[1].canonical_denominator), &k);
|
7104 |
}
|
7105 |
else
|
7106 |
{
|
7107 |
siSetToLong(&k, 1);
|
7108 |
}
|
7109 |
|
7110 |
/* Create the CF expansion.
|
7111 |
*/
|
7112 |
pqCreate(&h, &k, &e);
|
7113 |
|
7114 |
/* Print it out. No description is required.
|
7115 |
*/
|
7116 |
pqDump(&e, "", 0);
|
7117 |
|
7118 |
/* Destroy the expansion.
|
7119 |
*/
|
7120 |
pqDestroy(&e);
|
7121 |
|
7122 |
/* Destroy the integers.
|
7123 |
*/
|
7124 |
siDestroy(&h);
|
7125 |
siDestroy(&k);
|
7126 |
}
|
7127 |
|
7128 |
|
7129 |
/****************************************************************************/
|
7130 |
/* cfFn(): */
|
7131 |
/*--------------------------------------------------------------------------*/
|
7132 |
/* DESCRIPTION */
|
7133 |
/* Locates the enclosing Farey neighbors and prints them out. This func- */
|
7134 |
/* tion is called in response to a template match. */
|
7135 |
/****************************************************************************/
|
7136 |
void cfFn(void)
|
7137 |
{
|
7138 |
int convergent_number;
|
7139 |
int nneighbors;
|
7140 |
int arg_in_series = FALSE;
|
7141 |
int cur_series_term;
|
7142 |
|
7143 |
SYNTHETIC_INTEGER *D, *h, *k, *N, *conv_h, *conv_k, *neigh_h, *neigh_k,
|
7144 |
*hleft, *kleft, *hright, *kright, *error_h, *error_k,
|
7145 |
*dap_h, *dap_k, *t1, *t2;
|
7146 |
CF_EXPANSION *expansion;
|
7147 |
char buf[100];
|
7148 |
|
7149 |
/* Create all temporary variables.
|
7150 |
*/
|
7151 |
siCreate(&D);
|
7152 |
siCreate(&h);
|
7153 |
siCreate(&k);
|
7154 |
siCreate(&N);
|
7155 |
siCreate(&conv_h);
|
7156 |
siCreate(&conv_k);
|
7157 |
siCreate(&neigh_h);
|
7158 |
siCreate(&neigh_k);
|
7159 |
siCreate(&hleft);
|
7160 |
siCreate(&kleft);
|
7161 |
siCreate(&hright);
|
7162 |
siCreate(&kright);
|
7163 |
siCreate(&error_h);
|
7164 |
siCreate(&error_k);
|
7165 |
siCreate(&dap_h);
|
7166 |
siCreate(&dap_k);
|
7167 |
siCreate(&t1);
|
7168 |
siCreate(&t2);
|
7169 |
|
7170 |
/* There are either two or four parameters to this command. For
|
7171 |
** the optional parameters, they override defaults.
|
7172 |
** Assign the defaults first, before the optional parameters are
|
7173 |
** processed.
|
7174 |
*/
|
7175 |
|
7176 |
/* By default, just generate one Farey neighbor on each side of
|
7177 |
** the rational number supplied.
|
7178 |
*/
|
7179 |
nneighbors = 1;
|
7180 |
|
7181 |
/* By default, the denominator used for presentation is good for
|
7182 |
** four lines of zeros.
|
7183 |
*/
|
7184 |
siSetToPowerOfTen(&D, DIGITS_PER_LINE * 4);
|
7185 |
|
7186 |
/* Copy the rational number specified for this command to our area,
|
7187 |
** and if it is an integer provide a denominator of 1 automatically.
|
7188 |
*/
|
7189 |
siCopy(&(par_block.pars[1].canonical_numerator), &h);
|
7190 |
if (par_block.pars[1].canonical_denominator)
|
7191 |
siCopy(&(par_block.pars[1].canonical_denominator), &k);
|
7192 |
else
|
7193 |
siSetToLong(&k, 1);
|
7194 |
|
7195 |
/* Copy the order of the series to our area.
|
7196 |
*/
|
7197 |
siCopy(&(par_block.pars[2].canonical_numerator), &N);
|
7198 |
|
7199 |
/* Convert the number of neighbors to an integer if this command has
|
7200 |
** the optional arguments.
|
7201 |
*/
|
7202 |
if (par_block.pars[3].canonical_numerator)
|
7203 |
{
|
7204 |
SYNTHETIC_INTEGER *n;
|
7205 |
|
7206 |
siCreate(&n);
|
7207 |
|
7208 |
siSetToLong(&n, 10000);
|
7209 |
|
7210 |
if (siCompare(&n, &(par_block.pars[3].canonical_numerator)) <= 0)
|
7211 |
{
|
7212 |
nneighbors = 10000;
|
7213 |
}
|
7214 |
else
|
7215 |
{
|
7216 |
sscanf(par_block.pars[3].orig_string, "%d", &nneighbors);
|
7217 |
}
|
7218 |
|
7219 |
siDestroy(&n);
|
7220 |
}
|
7221 |
|
7222 |
/* Override the denominator if that parameter is present.
|
7223 |
*/
|
7224 |
if (par_block.pars[4].canonical_numerator)
|
7225 |
siCopy(&(par_block.pars[4].canonical_numerator), &D);
|
7226 |
|
7227 |
/* Form the continued fraction representation of the
|
7228 |
** rational number.
|
7229 |
*/
|
7230 |
pqCreate(&h, &k, &expansion);
|
7231 |
|
7232 |
/* Print out the number and expansion and other input parameters
|
7233 |
** as output.
|
7234 |
*/
|
7235 |
gfBannerHeading("Rational Number h_in/k_in To Approximate", 0);
|
7236 |
gfHline();
|
7237 |
siDump(&h, "h_in");
|
7238 |
gfHline();
|
7239 |
siDump(&k, "k_in");
|
7240 |
gfHline();
|
7241 |
gfBannerHeading("Other Solution Parameters", 0);
|
7242 |
gfHline();
|
7243 |
siDump(&N, "Order");
|
7244 |
gfHline();
|
7245 |
|
7246 |
{
|
7247 |
SYNTHETIC_INTEGER *scratch;
|
7248 |
|
7249 |
siCreate(&scratch);
|
7250 |
|
7251 |
siSetToLong(&scratch, nneighbors);
|
7252 |
|
7253 |
siDump(&scratch, "NNEIGHBORS");
|
7254 |
|
7255 |
siDestroy(&scratch);
|
7256 |
}
|
7257 |
|
7258 |
gfHline();
|
7259 |
siDump(&D, "DAP Denominator");
|
7260 |
gfHline();
|
7261 |
gfBannerHeading("Continued Fraction Expansion Of h_in/k_in", 0);
|
7262 |
gfHline();
|
7263 |
pqDump(&expansion, "", 0);
|
7264 |
|
7265 |
/* Obtain the two best rational approximations to the number.
|
7266 |
*/
|
7267 |
pqBapp(&expansion,
|
7268 |
&N,
|
7269 |
&conv_h,
|
7270 |
&conv_k,
|
7271 |
&neigh_h,
|
7272 |
&neigh_k,
|
7273 |
&convergent_number);
|
7274 |
|
7275 |
/* Print out the information generated by the call above
|
7276 |
*/
|
7277 |
gfBannerHeading("Highest-Order Convergent With q(i)<=N", 0);
|
7278 |
gfHline();
|
7279 |
sprintf(buf, "p(%d)", convergent_number);
|
7280 |
siDump(&conv_h, buf);
|
7281 |
sprintf(buf, "q(%d)", convergent_number);
|
7282 |
siDump(&conv_k, buf);
|
7283 |
gfHline();
|
7284 |
gfBannerHeading("Accompanying Intermediate Fraction", 0);
|
7285 |
gfHline();
|
7286 |
siDump(&neigh_h, "intermediate_h");
|
7287 |
siDump(&neigh_k, "intermediate_k");
|
7288 |
gfHline();
|
7289 |
|
7290 |
/* Decide, remember, and announce if the term of interest is already in
|
7291 |
** the Farey series of interest. This will be true if and only if
|
7292 |
** the convergent chosen has the same value as the rational argument.
|
7293 |
*/
|
7294 |
if (!rnCompare(&conv_h, &conv_k, &h, &k))
|
7295 |
{
|
7296 |
gfBannerHeading("h_in/k_in IS In Farey Series Of Interest", 1);
|
7297 |
arg_in_series = TRUE;
|
7298 |
}
|
7299 |
else
|
7300 |
{
|
7301 |
gfBannerHeading("h_in/k_in IS NOT In Farey Series Of Interest", 1);
|
7302 |
}
|
7303 |
gfHline();
|
7304 |
|
7305 |
/* We need to sort the convergent and neighbor back from the cfBapp()
|
7306 |
** function. But there is a bit of a catch. We need to know the
|
7307 |
** correct index to go along with the left one. This gets a bit
|
7308 |
** complicated if the convergent was already in the Farey series.
|
7309 |
** We'll only give the subscript of 0 if the rational number is
|
7310 |
** in the Farey series.
|
7311 |
*/
|
7312 |
if (rnCompare(&conv_h, &conv_k, &neigh_h, &neigh_k) < 0)
|
7313 |
{
|
7314 |
siCopy(&conv_h, &hleft);
|
7315 |
siCopy(&conv_k, &kleft);
|
7316 |
siCopy(&neigh_h, &hright);
|
7317 |
siCopy(&neigh_k, &kright);
|
7318 |
|
7319 |
if (arg_in_series)
|
7320 |
cur_series_term = 0;
|
7321 |
else
|
7322 |
cur_series_term = -1;
|
7323 |
}
|
7324 |
else
|
7325 |
{
|
7326 |
siCopy(&neigh_h, &hleft);
|
7327 |
siCopy(&neigh_k, &kleft);
|
7328 |
siCopy(&conv_h, &hright);
|
7329 |
siCopy(&conv_k, &kright);
|
7330 |
|
7331 |
cur_series_term = -1;
|
7332 |
}
|
7333 |
|
7334 |
/* Loop backwards through the Farey series until either we hit zero
|
7335 |
** or we hit the number of neighbors we need.
|
7336 |
*/
|
7337 |
while ((hleft->len) && (cur_series_term > -nneighbors))
|
7338 |
{
|
7339 |
rnFareyTraverse(&hleft, &kleft, &hright, &kright, &N, -1);
|
7340 |
cur_series_term--;
|
7341 |
}
|
7342 |
|
7343 |
/* Now, go forward. If the rational number specified was already in
|
7344 |
** the series, we use the subscript zero, otherwise not.
|
7345 |
*/
|
7346 |
while (cur_series_term <= nneighbors)
|
7347 |
{
|
7348 |
/* Heading */
|
7349 |
sprintf(buf, "Farey Neighbor Index %d", cur_series_term);
|
7350 |
gfBannerHeading(buf, 0);
|
7351 |
gfHline();
|
7352 |
|
7353 |
/* The actual term. */
|
7354 |
sprintf(buf, "h(%d)", cur_series_term);
|
7355 |
siDump(&hleft, buf);
|
7356 |
gfHline();
|
7357 |
buf[0] = 'k';
|
7358 |
siDump(&kleft, buf);
|
7359 |
gfHline();
|
7360 |
|
7361 |
/* Also present the rational number as a decimal.
|
7362 |
*/
|
7363 |
siCopy(&D, &dap_k);
|
7364 |
rnDap(&hleft, &kleft, &dap_h, &dap_k);
|
7365 |
sprintf(buf, "DAP_N(%d)", cur_series_term);
|
7366 |
siDump(&dap_h, buf);
|
7367 |
gfHline();
|
7368 |
sprintf(buf, "DAP_D(%d)", cur_series_term);
|
7369 |
siDump(&dap_k, buf);
|
7370 |
gfHline();
|
7371 |
|
7372 |
/* Rational difference between the rational number we're trying
|
7373 |
** to approximate and the approximation we have. Canonically, we
|
7374 |
** want a larger approximation to have a positive error, so we
|
7375 |
** define error as (approximation - actual).
|
7376 |
*/
|
7377 |
/* Calculate the difference as a rational number.
|
7378 |
*/
|
7379 |
rnDifference(&hleft, &kleft, &h, &k, &error_h, &error_k);
|
7380 |
|
7381 |
/* Present it as a rational number. */
|
7382 |
sprintf(buf, "error_h(%d)", cur_series_term);
|
7383 |
siDump(&error_h, buf);
|
7384 |
gfHline();
|
7385 |
sprintf(buf, "error_k(%d)", cur_series_term);
|
7386 |
siDump(&error_k, buf);
|
7387 |
gfHline();
|
7388 |
|
7389 |
|
7390 |
/* Present it as a DAP. */
|
7391 |
siCopy(&D, &dap_k);
|
7392 |
rnDap(&error_h, &error_k, &dap_h, &dap_k);
|
7393 |
sprintf(buf, "ERROR_DAP_N(%d)", cur_series_term);
|
7394 |
siDump(&dap_h, buf);
|
7395 |
gfHline();
|
7396 |
sprintf(buf, "ERROR_DAP_D(%d)", cur_series_term);
|
7397 |
siDump(&dap_k, buf);
|
7398 |
gfHline();
|
7399 |
|
7400 |
|
7401 |
rnFareyTraverse(&hleft, &kleft, &hright, &kright, &N, 1);
|
7402 |
|
7403 |
if (arg_in_series)
|
7404 |
{
|
7405 |
cur_series_term++;
|
7406 |
}
|
7407 |
else
|
7408 |
{
|
7409 |
if (cur_series_term == -1)
|
7410 |
cur_series_term = 1;
|
7411 |
else
|
7412 |
cur_series_term++;
|
7413 |
}
|
7414 |
}
|
7415 |
|
7416 |
/* Destroy all local variables.
|
7417 |
*/
|
7418 |
siDestroy(&D);
|
7419 |
siDestroy(&h);
|
7420 |
siDestroy(&k);
|
7421 |
siDestroy(&N);
|
7422 |
siDestroy(&conv_h);
|
7423 |
siDestroy(&conv_k);
|
7424 |
siDestroy(&neigh_h);
|
7425 |
siDestroy(&neigh_k);
|
7426 |
siDestroy(&hleft);
|
7427 |
siDestroy(&kleft);
|
7428 |
siDestroy(&hright);
|
7429 |
siDestroy(&kright);
|
7430 |
siDestroy(&error_h);
|
7431 |
siDestroy(&error_k);
|
7432 |
siDestroy(&dap_h);
|
7433 |
siDestroy(&dap_k);
|
7434 |
siDestroy(&t1);
|
7435 |
siDestroy(&t2);
|
7436 |
}
|
7437 |
|
7438 |
|
7439 |
/****************************************************************************/
|
7440 |
/* cfMind(): */
|
7441 |
/*--------------------------------------------------------------------------*/
|
7442 |
/* DESCRIPTION */
|
7443 |
/* Locates the enclosing Farey neighbors and prints them out. This func- */
|
7444 |
/* tion is called in response to a template match. */
|
7445 |
/****************************************************************************/
|
7446 |
void cfMind(void)
|
7447 |
{
|
7448 |
SYNTHETIC_INTEGER *r1_h, *r1_k, *r2_h, *r2_k,
|
7449 |
*result_h, *result_k;
|
7450 |
|
7451 |
/* Allocate all of our local variables.
|
7452 |
*/
|
7453 |
siCreate(&r1_h);
|
7454 |
siCreate(&r1_k);
|
7455 |
siCreate(&r2_h);
|
7456 |
siCreate(&r2_k);
|
7457 |
siCreate(&result_h);
|
7458 |
siCreate(&result_k);
|
7459 |
|
7460 |
/* State the two input parameters as rational numbers, in case
|
7461 |
** on or both are integers.
|
7462 |
*/
|
7463 |
asAssert(par_block.pars[1].canonical_numerator != NULL, __LINE__);
|
7464 |
asAssert(par_block.pars[2].canonical_numerator != NULL, __LINE__);
|
7465 |
siCopy(&(par_block.pars[1].canonical_numerator), &r1_h);
|
7466 |
siCopy(&(par_block.pars[2].canonical_numerator), &r2_h);
|
7467 |
if (par_block.pars[1].canonical_denominator)
|
7468 |
siCopy(&(par_block.pars[1].canonical_denominator), &r1_k);
|
7469 |
else
|
7470 |
siSetToLong(&r1_k, 1);
|
7471 |
if (par_block.pars[2].canonical_denominator)
|
7472 |
siCopy(&(par_block.pars[2].canonical_denominator), &r2_k);
|
7473 |
else
|
7474 |
siSetToLong(&r2_k, 1);
|
7475 |
|
7476 |
/* If the parameters for the interval are out of order,
|
7477 |
** swap them.
|
7478 |
*/
|
7479 |
if (rnCompare(&r1_h, &r1_k, &r2_h, &r2_k) == 1)
|
7480 |
{
|
7481 |
SYNTHETIC_INTEGER *temp;
|
7482 |
|
7483 |
/* Out of order, swap them. For our application,
|
7484 |
** can just play with pointers.
|
7485 |
*/
|
7486 |
temp = r1_h;
|
7487 |
r1_h = r2_h;
|
7488 |
r2_h = temp;
|
7489 |
temp = r1_k;
|
7490 |
r1_k = r2_k;
|
7491 |
r2_k = temp;
|
7492 |
}
|
7493 |
|
7494 |
/* Echo back the parameters for the caller.
|
7495 |
*/
|
7496 |
siDump(&r1_h, "l_h");
|
7497 |
gfHline();
|
7498 |
siDump(&r1_k, "l_k");
|
7499 |
gfHline();
|
7500 |
siDump(&r2_h, "r_h");
|
7501 |
gfHline();
|
7502 |
siDump(&r2_k, "r_k");
|
7503 |
gfHline();
|
7504 |
|
7505 |
/* Do the calculation proper.
|
7506 |
*/
|
7507 |
naMind(&r1_h,
|
7508 |
&r1_k,
|
7509 |
&r2_h,
|
7510 |
&r2_k,
|
7511 |
&result_h,
|
7512 |
&result_k,
|
7513 |
TRUE,
|
7514 |
TRUE,
|
7515 |
FALSE
|
7516 |
);
|
7517 |
|
7518 |
/* Emit the results.
|
7519 |
*/
|
7520 |
gfBannerHeading("A Rational Number With Smallest Denominator In Interval", 0);
|
7521 |
gfHline();
|
7522 |
siDump(&result_h, "result_h");
|
7523 |
gfHline();
|
7524 |
siDump(&result_k, "result_k");
|
7525 |
gfHline();
|
7526 |
|
7527 |
/* Destroy the locals.
|
7528 |
*/
|
7529 |
siDestroy(&r1_h);
|
7530 |
siDestroy(&r1_k);
|
7531 |
siDestroy(&r2_h);
|
7532 |
siDestroy(&r2_k);
|
7533 |
siDestroy(&result_h);
|
7534 |
siDestroy(&result_k);
|
7535 |
}
|
7536 |
|
7537 |
|
7538 |
/****************************************************************************/
|
7539 |
/* cfFab(): */
|
7540 |
/*--------------------------------------------------------------------------*/
|
7541 |
/* DESCRIPTION */
|
7542 |
/* Locates the enclosing Farey neighbors in the doubly-constrained series */
|
7543 |
/* and prints them out. Called in response to a template match. */
|
7544 |
/****************************************************************************/
|
7545 |
void cfFab(void)
|
7546 |
{
|
7547 |
int convergent_number;
|
7548 |
/* The convergent number we are iterating through.
|
7549 |
*/
|
7550 |
int nneighbors;
|
7551 |
/* The number of neighbors on both sides to generate.
|
7552 |
*/
|
7553 |
int arg_in_series = FALSE;
|
7554 |
/* TRUE if the rational argument supplied is in the
|
7555 |
** series, or FALSE otherwise.
|
7556 |
*/
|
7557 |
int cur_series_term;
|
7558 |
/* The current series term we're iterating through.
|
7559 |
** Terms are indexed backwards and forwards from
|
7560 |
** zero.
|
7561 |
*/
|
7562 |
int done = FALSE;
|
7563 |
/* Flag used to exit from the forward-generation loop, as successive
|
7564 |
** Farey terms are displayed.
|
7565 |
*/
|
7566 |
|
7567 |
SYNTHETIC_INTEGER *D, /* The denominator that will be used for
|
7568 |
** decimal approximation.
|
7569 |
*/
|
7570 |
*h, *k,
|
7571 |
/* Numerator and denominator of rational
|
7572 |
** number that we are bracketing with
|
7573 |
** Farey terms.
|
7574 |
*/
|
7575 |
*hmax,
|
7576 |
*kmax,
|
7577 |
/* The maximum numerator and denominator,
|
7578 |
** i.e. this defines the rectangular
|
7579 |
** area of the integer lattice we are
|
7580 |
** considering.
|
7581 |
*/
|
7582 |
*canonical_hmax,
|
7583 |
*canonical_kmax,
|
7584 |
/* The reduced form of hmax and kmax, i.e.
|
7585 |
** with the g.c.d. removed. This is necessary
|
7586 |
** because hmax and kmax proper are used to
|
7587 |
** test denominators, but this value will
|
7588 |
** show up in the Farey series.
|
7589 |
*/
|
7590 |
*normal_corner_predecessor_h,
|
7591 |
*normal_corner_predecessor_k,
|
7592 |
/* The predecessor to the corner point
|
7593 |
** along the "right" edge of the rectangle.
|
7594 |
*/
|
7595 |
*reciprocal_corner_successor_h,
|
7596 |
*reciprocal_corner_successor_k,
|
7597 |
/* The successor to the corner point
|
7598 |
** in the series along the "top" of
|
7599 |
** the rectangle.
|
7600 |
*/
|
7601 |
*constant_1,
|
7602 |
*constant_0,
|
7603 |
/* Numerical constants for easy comparison.
|
7604 |
*/
|
7605 |
*conv_h,
|
7606 |
*conv_k,
|
7607 |
/* The highest-order convergent with denominator
|
7608 |
** not larger than the order of the Farey series.
|
7609 |
** Used for calls to pqBapp().
|
7610 |
*/
|
7611 |
*neigh_h,
|
7612 |
*neigh_k,
|
7613 |
/* The neighbor to the number of interest. Used for
|
7614 |
** calls to pqBapp().
|
7615 |
*/
|
7616 |
*hleft,
|
7617 |
*kleft,
|
7618 |
*hright,
|
7619 |
*kright,
|
7620 |
/* The left and right numbers used to iterate through the
|
7621 |
** Farey series using the recursive formulas.
|
7622 |
*/
|
7623 |
*error_h,
|
7624 |
*error_k,
|
7625 |
/* The error for an approximation, as a rational number.
|
7626 |
*/
|
7627 |
*dap_h,
|
7628 |
*dap_k,
|
7629 |
/* The error for an approximation, expressed with a
|
7630 |
** different denominator, chosen either by default
|
7631 |
** or from the command line.
|
7632 |
*/
|
7633 |
*t1,
|
7634 |
*t2;
|
7635 |
/* General-purpose temporary variables.
|
7636 |
*/
|
7637 |
|
7638 |
CF_EXPANSION *rn_expansion = NULL,
|
7639 |
/* The continued fraction and convergent
|
7640 |
** expansion of the rational number to approximate.
|
7641 |
*/
|
7642 |
*rn_reciprocal_expansion = NULL,
|
7643 |
/* The continued fraction and convergent expansion
|
7644 |
** of the reciprocal of the number to be
|
7645 |
** approximated. This can only be done if the
|
7646 |
** number is non-zero.
|
7647 |
*/
|
7648 |
*corner_point_expansion = NULL,
|
7649 |
/* The CF expansion of the corner point. This is
|
7650 |
** necessary to get the neighbor just to the left
|
7651 |
** in F_N.
|
7652 |
*/
|
7653 |
*corner_point_reciprocal_expansion = NULL;
|
7654 |
/* The expansion of the reciprocal of the
|
7655 |
** corner point. This is necessary to get
|
7656 |
** the neighbor along the "top" of the lattice.
|
7657 |
*/
|
7658 |
|
7659 |
char buf[100];
|
7660 |
/* String buffer, used to stage things to be printed.
|
7661 |
*/
|
7662 |
|
7663 |
/* Create all temporary variables.
|
7664 |
*/
|
7665 |
siCreate(&D);
|
7666 |
siCreate(&h);
|
7667 |
siCreate(&k);
|
7668 |
siCreate(&hmax);
|
7669 |
siCreate(&kmax);
|
7670 |
siCreate(&canonical_hmax);
|
7671 |
siCreate(&canonical_kmax);
|
7672 |
siCreate(&normal_corner_predecessor_h);
|
7673 |
siCreate(&normal_corner_predecessor_k);
|
7674 |
siCreate(&reciprocal_corner_successor_h);
|
7675 |
siCreate(&reciprocal_corner_successor_k);
|
7676 |
siCreate(&constant_1);
|
7677 |
siSetToLong(&constant_1, 1);
|
7678 |
siCreate(&constant_0);
|
7679 |
siSetToLong(&constant_0, 0);
|
7680 |
siCreate(&conv_h);
|
7681 |
siCreate(&conv_k);
|
7682 |
siCreate(&neigh_h);
|
7683 |
siCreate(&neigh_k);
|
7684 |
siCreate(&hleft);
|
7685 |
siCreate(&kleft);
|
7686 |
siCreate(&hright);
|
7687 |
siCreate(&kright);
|
7688 |
siCreate(&error_h);
|
7689 |
siCreate(&error_k);
|
7690 |
siCreate(&dap_h);
|
7691 |
siCreate(&dap_k);
|
7692 |
siCreate(&t1);
|
7693 |
siCreate(&t2);
|
7694 |
|
7695 |
/* There are either three or five parameters to this command. For
|
7696 |
** the optional parameters, they override defaults.
|
7697 |
** Assign the defaults first, before the optional parameters are
|
7698 |
** processed.
|
7699 |
*/
|
7700 |
|
7701 |
/* By default, just generate one Farey neighbor on each side of
|
7702 |
** the rational number supplied.
|
7703 |
*/
|
7704 |
nneighbors = 1;
|
7705 |
|
7706 |
/* By default, the denominator used for presentation is good for
|
7707 |
** four lines of zeros.
|
7708 |
*/
|
7709 |
siSetToPowerOfTen(&D, DIGITS_PER_LINE * 4);
|
7710 |
|
7711 |
/* Copy the rational number specified for this command to our area,
|
7712 |
** and if it is an integer provide a denominator of 1 automatically.
|
7713 |
*/
|
7714 |
siCopy(&(par_block.pars[1].canonical_numerator), &h);
|
7715 |
if (par_block.pars[1].canonical_denominator)
|
7716 |
siCopy(&(par_block.pars[1].canonical_denominator), &k);
|
7717 |
else
|
7718 |
siSetToLong(&k, 1);
|
7719 |
|
7720 |
/* Copy the maximum h and maximum k to our area.
|
7721 |
*/
|
7722 |
siCopy(&(par_block.pars[2].canonical_numerator), &hmax);
|
7723 |
siCopy(&(par_block.pars[3].canonical_numerator), &kmax);
|
7724 |
|
7725 |
/* Copy an extra copy of these to the canonical values,
|
7726 |
** and must remove the GCD.
|
7727 |
*/
|
7728 |
siCopy(&hmax, &canonical_hmax);
|
7729 |
siCopy(&kmax, &canonical_kmax);
|
7730 |
rnCanonize(&canonical_hmax, &canonical_kmax);
|
7731 |
|
7732 |
/* Convert the number of neighbors to an integer if this command has
|
7733 |
** the optional arguments.
|
7734 |
*/
|
7735 |
if (par_block.pars[4].canonical_numerator)
|
7736 |
{
|
7737 |
SYNTHETIC_INTEGER *n;
|
7738 |
|
7739 |
siCreate(&n);
|
7740 |
|
7741 |
siSetToLong(&n, 10000);
|
7742 |
|
7743 |
if (siCompare(&n, &(par_block.pars[4].canonical_numerator)) <= 0)
|
7744 |
{
|
7745 |
nneighbors = 10000;
|
7746 |
}
|
7747 |
else
|
7748 |
{
|
7749 |
sscanf(par_block.pars[4].orig_string, "%d", &nneighbors);
|
7750 |
}
|
7751 |
|
7752 |
siDestroy(&n);
|
7753 |
}
|
7754 |
|
7755 |
/* Override the denominator if that parameter is present.
|
7756 |
*/
|
7757 |
if (par_block.pars[5].canonical_numerator)
|
7758 |
siCopy(&(par_block.pars[5].canonical_numerator), &D);
|
7759 |
|
7760 |
/* Form the continued fraction representation of the
|
7761 |
** rational number.
|
7762 |
*/
|
7763 |
pqCreate(&h, &k, &rn_expansion);
|
7764 |
|
7765 |
/* Form the continued fraction representation of the
|
7766 |
** reciprocal in any case besides the number
|
7767 |
** zero.
|
7768 |
*/
|
7769 |
if (h->len)
|
7770 |
pqCreate(&k, &h, &rn_reciprocal_expansion);
|
7771 |
|
7772 |
/* Print out the number and expansion and other input parameters
|
7773 |
** as output.
|
7774 |
*/
|
7775 |
gfBannerHeading("Rational Number h_in/k_in To Approximate", 0);
|
7776 |
gfHline();
|
7777 |
siDump(&h, "h_in");
|
7778 |
gfHline();
|
7779 |
siDump(&k, "k_in");
|
7780 |
gfHline();
|
7781 |
gfBannerHeading("Other Solution Parameters", 0);
|
7782 |
gfHline();
|
7783 |
siDump(&hmax, "hmax");
|
7784 |
gfHline();
|
7785 |
siDump(&kmax, "kmax");
|
7786 |
gfHline();
|
7787 |
|
7788 |
{
|
7789 |
SYNTHETIC_INTEGER *scratch;
|
7790 |
|
7791 |
siCreate(&scratch);
|
7792 |
|
7793 |
siSetToLong(&scratch, nneighbors);
|
7794 |
|
7795 |
siDump(&scratch, "NNEIGHBORS");
|
7796 |
|
7797 |
siDestroy(&scratch);
|
7798 |
}
|
7799 |
|
7800 |
gfHline();
|
7801 |
siDump(&D, "DAP Denominator");
|
7802 |
gfHline();
|
7803 |
gfBannerHeading("Continued Fraction Expansion Of h_in/k_in", 0);
|
7804 |
gfHline();
|
7805 |
pqDump(&rn_expansion, "", 0);
|
7806 |
|
7807 |
if (rn_reciprocal_expansion)
|
7808 |
{
|
7809 |
gfBannerHeading("Continued Fraction Expansion Of k_in/h_in", 0);
|
7810 |
gfHline();
|
7811 |
pqDump(&rn_reciprocal_expansion, "", 0);
|
7812 |
}
|
7813 |
|
7814 |
/* Now we need to obtain the neighbors of the "corner point"
|
7815 |
** in both of the Farey series involved. It is more
|
7816 |
** straightforward to generate them in advance.
|
7817 |
*/
|
7818 |
/* First, get the continued fraction expansion of the
|
7819 |
** corner point in normal coordinates, and output the result.
|
7820 |
*/
|
7821 |
pqCreate(&canonical_hmax, &canonical_kmax, &corner_point_expansion);
|
7822 |
gfBannerHeading("Continued Fraction Expansion Of Corner Point", 0);
|
7823 |
gfHline();
|
7824 |
pqDump(&corner_point_expansion, "", 0);
|
7825 |
|
7826 |
/* Now, get the continued fraction expansion of the
|
7827 |
** corner point in inverted coordinates, and output the result.
|
7828 |
*/
|
7829 |
pqCreate(&canonical_kmax, &canonical_hmax, &corner_point_reciprocal_expansion);
|
7830 |
gfBannerHeading("Continued Fraction Expansion Of Corner Point Reciprocal", 0);
|
7831 |
gfHline();
|
7832 |
pqDump(&corner_point_reciprocal_expansion, "", 0);
|
7833 |
|
7834 |
/* Find the best approximation along the right edge to the corner
|
7835 |
** point. Depending on whether have even or odd convergents,
|
7836 |
** may get above or below the corner point. If get above,
|
7837 |
** must go down using standard recursive formulas.
|
7838 |
*/
|
7839 |
pqBapp(&corner_point_expansion,
|
7840 |
&kmax,
|
7841 |
&conv_h,
|
7842 |
&conv_k,
|
7843 |
&normal_corner_predecessor_h,
|
7844 |
&normal_corner_predecessor_k,
|
7845 |
&convergent_number);
|
7846 |
/* We may have the Farey term either left or right. If right,
|
7847 |
** must backtrack by one.
|
7848 |
*/
|
7849 |
if (rnCompare(&canonical_hmax, &canonical_kmax,
|
7850 |
&normal_corner_predecessor_h, &normal_corner_predecessor_k)
|
7851 |
< 0)
|
7852 |
{
|
7853 |
SYNTHETIC_INTEGER *temp_h, *temp_k;
|
7854 |
|
7855 |
/* printf("REVERSE! (corner point predecessor)\n"); */
|
7856 |
|
7857 |
/* Must get the predecessor.
|
7858 |
*/
|
7859 |
siCreate(&temp_h);
|
7860 |
siCreate(&temp_k);
|
7861 |
|
7862 |
siCopy(&canonical_hmax, &temp_h);
|
7863 |
siCopy(&canonical_kmax, &temp_k);
|
7864 |
|
7865 |
rnFareyTraverse(&temp_h,
|
7866 |
&temp_k,
|
7867 |
&normal_corner_predecessor_h,
|
7868 |
&normal_corner_predecessor_k,
|
7869 |
&kmax,
|
7870 |
-1);
|
7871 |
siCopy(&temp_h, &normal_corner_predecessor_h);
|
7872 |
siCopy(&temp_k, &normal_corner_predecessor_k);
|
7873 |
|
7874 |
siDestroy(&temp_h);
|
7875 |
siDestroy(&temp_k);
|
7876 |
}
|
7877 |
|
7878 |
gfBannerHeading("Corner Point Neighbors", 0);
|
7879 |
gfHline();
|
7880 |
siDump(&normal_corner_predecessor_h, "corner_pred_h");
|
7881 |
siDump(&normal_corner_predecessor_k, "corner_pred_k");
|
7882 |
gfHline();
|
7883 |
|
7884 |
/* Find the best approximation along the top edge to the corner
|
7885 |
** point. Depending on whether have even or odd convergents,
|
7886 |
** may get left or right of the corner point. If get left,
|
7887 |
** must go right using standard recursive formulas. There is, however,
|
7888 |
** one exception. If kmax = 1, there will be nothing to the right
|
7889 |
** of the corner point, and must just keep value as zero over zero
|
7890 |
** as a marker.
|
7891 |
*/
|
7892 |
if (siCompare(&constant_1, &kmax) == 0)
|
7893 |
{
|
7894 |
/* In this case, there is no point to the right.
|
7895 |
** Assign the successor to be be 0/0, as a marker.
|
7896 |
*/
|
7897 |
siSetToLong(&reciprocal_corner_successor_h, 0);
|
7898 |
siSetToLong(&reciprocal_corner_successor_k, 0);
|
7899 |
}
|
7900 |
else
|
7901 |
{
|
7902 |
/* There is a successor to the right.
|
7903 |
*/
|
7904 |
|
7905 |
SYNTHETIC_INTEGER *temph, *tempk;
|
7906 |
|
7907 |
siCreate(&temph);
|
7908 |
siCreate(&tempk);
|
7909 |
|
7910 |
/* There is a point to the right. It will take a few
|
7911 |
** contortions to find it.
|
7912 |
*/
|
7913 |
/* What this statement does is to operate in the
|
7914 |
** inverted series along the top edge of the
|
7915 |
** rectangle.
|
7916 |
*/
|
7917 |
pqBapp(&corner_point_reciprocal_expansion,
|
7918 |
&hmax,
|
7919 |
&conv_k,
|
7920 |
&conv_h,
|
7921 |
&reciprocal_corner_successor_k,
|
7922 |
&reciprocal_corner_successor_h,
|
7923 |
&convergent_number);
|
7924 |
|
7925 |
/* We may have either the left or the right neighbor, but we
|
7926 |
** need the right. This gets messy. We need to invert when finding, including
|
7927 |
** inverting the order.
|
7928 |
*/
|
7929 |
if (rnCompare(&canonical_hmax,
|
7930 |
&canonical_kmax,
|
7931 |
&reciprocal_corner_successor_h,
|
7932 |
&reciprocal_corner_successor_k) == 1)
|
7933 |
{
|
7934 |
/* We wanted something to the right, but we got it to the left.
|
7935 |
** We need to find the PREDECESSOR (not the successor)
|
7936 |
** in the inverted Farey series.
|
7937 |
*/
|
7938 |
|
7939 |
/* printf("REVERSE! (corner point successor)\n"); */
|
7940 |
/* Must get the predecessor.
|
7941 |
*/
|
7942 |
|
7943 |
siCopy(&canonical_hmax, &temph);
|
7944 |
siCopy(&canonical_kmax, &tempk);
|
7945 |
|
7946 |
rnFareyTraverse(&tempk,
|
7947 |
&temph,
|
7948 |
&reciprocal_corner_successor_k,
|
7949 |
&reciprocal_corner_successor_h,
|
7950 |
&hmax,
|
7951 |
-1);
|
7952 |
siCopy(&temph, &reciprocal_corner_successor_h);
|
7953 |
siCopy(&tempk, &reciprocal_corner_successor_k);
|
7954 |
}
|
7955 |
|
7956 |
siDestroy(&temph);
|
7957 |
siDestroy(&tempk);
|
7958 |
}
|
7959 |
|
7960 |
siDump(&reciprocal_corner_successor_h, "corner_succ_h");
|
7961 |
siDump(&reciprocal_corner_successor_k, "corner_succ_k");
|
7962 |
gfHline();
|
7963 |
|
7964 |
/* Decide, remember, and announce if the term of interest is already in
|
7965 |
** the Farey series of interest. The easiest test for this under two
|
7966 |
** constraints is that both numerator and denominator would be in bounds.
|
7967 |
*/
|
7968 |
if ((siCompare(&h,&hmax) <= 0) && (siCompare(&k, &kmax) <= 0))
|
7969 |
{
|
7970 |
gfBannerHeading("h_in/k_in IS In Rectangular Farey Series Of Interest", 1);
|
7971 |
arg_in_series = TRUE;
|
7972 |
}
|
7973 |
else
|
7974 |
{
|
7975 |
gfBannerHeading("h_in/k_in IS NOT In Rectangular Farey Series Of Interest", 1);
|
7976 |
}
|
7977 |
gfHline();
|
7978 |
|
7979 |
|
7980 |
/* Obtain the two best rational approximations to the number. We want to create
|
7981 |
** two numbers such that the left one is either our number or its left neighbor,
|
7982 |
** and the right one is our numbers's right neighbor, if it has one.
|
7983 |
**
|
7984 |
** There are four cases to consider:
|
7985 |
**
|
7986 |
** hmax/1 <= h/k
|
7987 |
** In this case, the right neighbor is undefined and the left
|
7988 |
** neighbor is hmax/1.
|
7989 |
**
|
7990 |
** hmax/kmax < h/k < hmax/1
|
7991 |
** The neighbors can be found by searching in the "inverted"
|
7992 |
** Farey series.
|
7993 |
**
|
7994 |
** h/k = hmax/kmax
|
7995 |
** The left neighbor is h/k, the right is an adjacent point to the
|
7996 |
** corner point.
|
7997 |
**
|
7998 |
** 0 <= h/k < hmax/kmax
|
7999 |
** The neighbors can be found by searching in the normal Farey
|
8000 |
** series.
|
8001 |
*/
|
8002 |
if (rnCompare(&hmax, &constant_1, &h, &k) <= 0)
|
8003 |
{
|
8004 |
/* hmax/1 <= h/k
|
8005 |
** In this case, the right neighbor is undefined and the left
|
8006 |
** neighbor is hmax/1.
|
8007 |
*/
|
8008 |
/* This is a much simpler case. Can just assign.
|
8009 |
*/
|
8010 |
gfBannerHeading("hmax/1 <= h/k", 0);
|
8011 |
gfHline();
|
8012 |
|
8013 |
siCopy(&hmax, &hleft);
|
8014 |
siSetToLong(&kleft, 1);
|
8015 |
siSetToLong(&hright, 0);
|
8016 |
siSetToLong(&kright, 0);
|
8017 |
|
8018 |
if (arg_in_series)
|
8019 |
cur_series_term = 0;
|
8020 |
else
|
8021 |
cur_series_term = -1;
|
8022 |
}
|
8023 |
else if (rnCompare(&hmax, &kmax, &h, &k) < 0)
|
8024 |
{
|
8025 |
/* hmax/kmax < h/k < hmax/1
|
8026 |
** The neighbors can be found by searching in the "inverted"
|
8027 |
** Farey series.
|
8028 |
*/
|
8029 |
pqBapp(&rn_reciprocal_expansion,
|
8030 |
&hmax,
|
8031 |
&conv_k,
|
8032 |
&conv_h,
|
8033 |
&neigh_k,
|
8034 |
&neigh_h,
|
8035 |
&convergent_number);
|
8036 |
|
8037 |
/* Print out the information generated by the call above
|
8038 |
*/
|
8039 |
gfBannerHeading("hmax/kmax < h/k < hmax/1", 0);
|
8040 |
gfHline();
|
8041 |
gfBannerHeading("Highest-Order Convergent With q(i)<=N", 0);
|
8042 |
gfHline();
|
8043 |
sprintf(buf, "p(%d)", convergent_number);
|
8044 |
siDump(&conv_h, buf);
|
8045 |
sprintf(buf, "q(%d)", convergent_number);
|
8046 |
siDump(&conv_k, buf);
|
8047 |
gfHline();
|
8048 |
gfBannerHeading("Accompanying Intermediate Fraction", 0);
|
8049 |
gfHline();
|
8050 |
siDump(&neigh_h, "intermediate_h");
|
8051 |
siDump(&neigh_k, "intermediate_k");
|
8052 |
gfHline();
|
8053 |
|
8054 |
/* We need to sort the convergent and neighbor back from the cfBapp()
|
8055 |
** function. But there is a bit of a catch. We need to know the
|
8056 |
** correct index to go along with the left one. This gets a bit
|
8057 |
** complicated if the convergent was already in the Farey series.
|
8058 |
** We'll only give the subscript of 0 if the rational number is
|
8059 |
** in the Farey series.
|
8060 |
*/
|
8061 |
if (rnCompare(&conv_h, &conv_k, &neigh_h, &neigh_k) < 0)
|
8062 |
{
|
8063 |
/* Convergent and neighbor are ascending in order. Can
|
8064 |
** leave exactly as is.
|
8065 |
*/
|
8066 |
siCopy(&conv_h, &hleft);
|
8067 |
siCopy(&conv_k, &kleft);
|
8068 |
siCopy(&neigh_h, &hright);
|
8069 |
siCopy(&neigh_k, &kright);
|
8070 |
|
8071 |
if (arg_in_series)
|
8072 |
cur_series_term = 0;
|
8073 |
else
|
8074 |
cur_series_term = -1;
|
8075 |
}
|
8076 |
else
|
8077 |
{
|
8078 |
/* Convergent and neighbor are descending in order.
|
8079 |
** There are two possibilities. If the number
|
8080 |
** is in the rectangular series, need to traverse.
|
8081 |
** Otherwise, will need to swap, as number is in
|
8082 |
** between.
|
8083 |
*/
|
8084 |
if (arg_in_series)
|
8085 |
{
|
8086 |
siCopy(&neigh_h, &hleft);
|
8087 |
siCopy(&neigh_k, &kleft);
|
8088 |
siCopy(&conv_h, &hright);
|
8089 |
siCopy(&conv_k, &kright);
|
8090 |
|
8091 |
rnFareyTraverse(&kright, &hright, &kleft, &hleft, &hmax, -1);
|
8092 |
|
8093 |
cur_series_term = 0;
|
8094 |
}
|
8095 |
else
|
8096 |
{
|
8097 |
siCopy(&neigh_h, &hleft);
|
8098 |
siCopy(&neigh_k, &kleft);
|
8099 |
siCopy(&conv_h, &hright);
|
8100 |
siCopy(&conv_k, &kright);
|
8101 |
|
8102 |
cur_series_term = -1;
|
8103 |
}
|
8104 |
}
|
8105 |
}
|
8106 |
else if (rnCompare(&hmax, &kmax, &h, &k) == 0)
|
8107 |
{
|
8108 |
/* printf("Reached equality case.\n"); */
|
8109 |
|
8110 |
/* h/k = hmax/kmax
|
8111 |
** The left neighbor is h/k, the right is an adjacent point to the
|
8112 |
** corner point.
|
8113 |
*/
|
8114 |
/* This is a much simpler case. Can just assign, as we have calculated everything
|
8115 |
** of interest about the corner point already.
|
8116 |
*/
|
8117 |
gfBannerHeading("h_in/k_in == hmax/kmax", 0);
|
8118 |
gfHline();
|
8119 |
gfBannerHeading("Point To Right Of Corner Point", 0);
|
8120 |
gfHline();
|
8121 |
siDump(&reciprocal_corner_successor_h, "successor_h");
|
8122 |
siDump(&reciprocal_corner_successor_k, "successor_k");
|
8123 |
gfHline();
|
8124 |
|
8125 |
siCopy(&canonical_hmax, &hleft);
|
8126 |
siCopy(&canonical_kmax, &kleft);
|
8127 |
siCopy(&reciprocal_corner_successor_h, &hright);
|
8128 |
siCopy(&reciprocal_corner_successor_k, &kright);
|
8129 |
|
8130 |
cur_series_term = 0; /* Left member is exactly equal to h/k. */
|
8131 |
}
|
8132 |
else
|
8133 |
{
|
8134 |
/* 0 <= h/k < hmax/kmax
|
8135 |
** The neighbors can be found by searching in the normal Farey
|
8136 |
** series.
|
8137 |
*/
|
8138 |
pqBapp(&rn_expansion,
|
8139 |
&kmax,
|
8140 |
&conv_h,
|
8141 |
&conv_k,
|
8142 |
&neigh_h,
|
8143 |
&neigh_k,
|
8144 |
&convergent_number);
|
8145 |
|
8146 |
/* Print out the information generated by the call above
|
8147 |
*/
|
8148 |
gfBannerHeading("0 <= h_in/k_in < hmax/kmax", 0);
|
8149 |
gfHline();
|
8150 |
gfBannerHeading("Highest-Order Convergent With q(i)<=N", 0);
|
8151 |
gfHline();
|
8152 |
sprintf(buf, "p(%d)", convergent_number);
|
8153 |
siDump(&conv_h, buf);
|
8154 |
sprintf(buf, "q(%d)", convergent_number);
|
8155 |
siDump(&conv_k, buf);
|
8156 |
gfHline();
|
8157 |
gfBannerHeading("Accompanying Intermediate Fraction", 0);
|
8158 |
gfHline();
|
8159 |
siDump(&neigh_h, "intermediate_h");
|
8160 |
siDump(&neigh_k, "intermediate_k");
|
8161 |
gfHline();
|
8162 |
|
8163 |
/* We need to sort the convergent and neighbor back from the cfBapp()
|
8164 |
** function. But there is a bit of a catch. We need to know the
|
8165 |
** correct index to go along with the left one. This gets a bit
|
8166 |
** complicated if the convergent was already in the Farey series.
|
8167 |
** We'll only give the subscript of 0 if the rational number is
|
8168 |
** in the Farey series.
|
8169 |
*/
|
8170 |
if (rnCompare(&conv_h, &conv_k, &neigh_h, &neigh_k) < 0)
|
8171 |
{
|
8172 |
siCopy(&conv_h, &hleft);
|
8173 |
siCopy(&conv_k, &kleft);
|
8174 |
siCopy(&neigh_h, &hright);
|
8175 |
siCopy(&neigh_k, &kright);
|
8176 |
|
8177 |
if (arg_in_series)
|
8178 |
cur_series_term = 0;
|
8179 |
else
|
8180 |
cur_series_term = -1;
|
8181 |
}
|
8182 |
else
|
8183 |
{
|
8184 |
siCopy(&neigh_h, &hleft);
|
8185 |
siCopy(&neigh_k, &kleft);
|
8186 |
siCopy(&conv_h, &hright);
|
8187 |
siCopy(&conv_k, &kright);
|
8188 |
|
8189 |
if (arg_in_series)
|
8190 |
rnFareyTraverse(&hleft, &kleft, &hright, &kright, &kmax, 1);
|
8191 |
|
8192 |
if (arg_in_series)
|
8193 |
cur_series_term = 0;
|
8194 |
else
|
8195 |
cur_series_term = -1;
|
8196 |
}
|
8197 |
}
|
8198 |
|
8199 |
#if 0
|
8200 |
printf ("Past Bap\n");
|
8201 |
siDump(&hleft, "hleft");
|
8202 |
siDump(&kleft, "kleft");
|
8203 |
siDump(&hright, "hright");
|
8204 |
siDump(&kright, "kright");
|
8205 |
printf("cur_series_term: %d\n", cur_series_term);
|
8206 |
#endif
|
8207 |
|
8208 |
/* At this point we know the neighbors of the corner point, and the neighbors
|
8209 |
** of the h/k. We want to search downward until we exhaust the number of
|
8210 |
** neighbors required or until we hit zero. The complicated thing is that
|
8211 |
** in the rectangular case, there are special cases, especially as we round
|
8212 |
** the corner.
|
8213 |
*/
|
8214 |
while ((hleft->len) && (cur_series_term > -nneighbors))
|
8215 |
{
|
8216 |
if (rnCompare(&hleft,&kleft,&canonical_hmax,&canonical_kmax)==0)
|
8217 |
{
|
8218 |
/* The left term is the corner point. Need to "round the corner".
|
8219 |
*/
|
8220 |
siCopy(&hleft, &hright);
|
8221 |
siCopy(&kleft, &kright);
|
8222 |
siCopy(&normal_corner_predecessor_h, &hleft);
|
8223 |
siCopy(&normal_corner_predecessor_k, &kleft);
|
8224 |
cur_series_term--;
|
8225 |
}
|
8226 |
else if (rnCompare(&hleft, &kleft, &hmax, &constant_1) == 0)
|
8227 |
{
|
8228 |
/* The left term is hmax/1. Need to get the correct right neighbor
|
8229 |
** and go backwards by 1 in the inverted Farey series.
|
8230 |
*/
|
8231 |
siSetToLong(&hright, 1);
|
8232 |
siSetToLong(&kright, 0);
|
8233 |
rnFareyTraverse(&kright, &hright, &kleft, &hleft, &hmax, 1);
|
8234 |
cur_series_term--;
|
8235 |
}
|
8236 |
else if (rnCompare(&hleft, &kleft, &hmax, &kmax) > 0)
|
8237 |
{
|
8238 |
/* We are to the right of the corner point. Need to progress
|
8239 |
** in the inverted Farey series.
|
8240 |
*/
|
8241 |
rnFareyTraverse(&kright, &hright, &kleft, &hleft, &hmax, 1);
|
8242 |
cur_series_term--;
|
8243 |
}
|
8244 |
else
|
8245 |
{
|
8246 |
/* We are to the left of the corner point. Simply go
|
8247 |
** backwards in the Farey series.
|
8248 |
*/
|
8249 |
rnFareyTraverse(&hleft, &kleft, &hright, &kright, &kmax, -1);
|
8250 |
cur_series_term--;
|
8251 |
}
|
8252 |
}
|
8253 |
|
8254 |
#if 0
|
8255 |
printf("Past reverse traversal.\n");
|
8256 |
siDump(&hleft, "hleft");
|
8257 |
siDump(&kleft, "kleft");
|
8258 |
siDump(&hright, "hright");
|
8259 |
siDump(&kright, "kright");
|
8260 |
printf("cur_series_term: %d\n", cur_series_term);
|
8261 |
#endif
|
8262 |
|
8263 |
/* Now, go forward. If the rational number specified was already in
|
8264 |
** the series, we use the subscript zero, otherwise not.
|
8265 |
*/
|
8266 |
while ((cur_series_term <= nneighbors) && !done)
|
8267 |
{
|
8268 |
/* Heading */
|
8269 |
sprintf(buf, "Rectangular Farey Neighbor Index %d", cur_series_term);
|
8270 |
gfBannerHeading(buf, 0);
|
8271 |
gfHline();
|
8272 |
|
8273 |
/* The actual term. */
|
8274 |
sprintf(buf, "h(%d)", cur_series_term);
|
8275 |
siDump(&hleft, buf);
|
8276 |
gfHline();
|
8277 |
buf[0] = 'k';
|
8278 |
siDump(&kleft, buf);
|
8279 |
gfHline();
|
8280 |
|
8281 |
/* Also present the rational number as a decimal.
|
8282 |
*/
|
8283 |
siCopy(&D, &dap_k);
|
8284 |
rnDap(&hleft, &kleft, &dap_h, &dap_k);
|
8285 |
sprintf(buf, "DAP_N(%d)", cur_series_term);
|
8286 |
siDump(&dap_h, buf);
|
8287 |
gfHline();
|
8288 |
sprintf(buf, "DAP_D(%d)", cur_series_term);
|
8289 |
siDump(&dap_k, buf);
|
8290 |
gfHline();
|
8291 |
|
8292 |
/* Rational difference between the rational number we're trying
|
8293 |
** to approximate and the approximation we have. Canonically, we
|
8294 |
** want a larger approximation to have a positive error, so we
|
8295 |
** define error as (approximation - actual).
|
8296 |
*/
|
8297 |
/* Calculate the difference as a rational number.
|
8298 |
*/
|
8299 |
rnDifference(&hleft, &kleft, &h, &k, &error_h, &error_k);
|
8300 |
|
8301 |
/* Present it as a rational number. */
|
8302 |
sprintf(buf, "error_h(%d)", cur_series_term);
|
8303 |
siDump(&error_h, buf);
|
8304 |
gfHline();
|
8305 |
sprintf(buf, "error_k(%d)", cur_series_term);
|
8306 |
siDump(&error_k, buf);
|
8307 |
gfHline();
|
8308 |
|
8309 |
/* Present it as a DAP. */
|
8310 |
siCopy(&D, &dap_k);
|
8311 |
rnDap(&error_h, &error_k, &dap_h, &dap_k);
|
8312 |
sprintf(buf, "ERROR_DAP_N(%d)", cur_series_term);
|
8313 |
siDump(&dap_h, buf);
|
8314 |
gfHline();
|
8315 |
sprintf(buf, "ERROR_DAP_D(%d)", cur_series_term);
|
8316 |
siDump(&dap_k, buf);
|
8317 |
gfHline();
|
8318 |
|
8319 |
/* Advance the series counter. We need to skip zero if the
|
8320 |
** number ain't in the series.
|
8321 |
*/
|
8322 |
if (arg_in_series)
|
8323 |
{
|
8324 |
cur_series_term++;
|
8325 |
}
|
8326 |
else
|
8327 |
{
|
8328 |
if (cur_series_term == -1)
|
8329 |
cur_series_term = 1;
|
8330 |
else
|
8331 |
cur_series_term++;
|
8332 |
}
|
8333 |
|
8334 |
/* Advance the rectangular series forward. There are special cases
|
8335 |
** as we "round the corner", plus need to set a "done" flag if can
|
8336 |
** go no further.
|
8337 |
*/
|
8338 |
if (rnCompare(&hleft, &kleft, &hmax, &constant_1) == 0)
|
8339 |
{
|
8340 |
/* The left term is hmax/1. Can't go any further.
|
8341 |
*/
|
8342 |
done = TRUE;
|
8343 |
}
|
8344 |
else if (rnCompare(&hright,&kright,&canonical_hmax,&canonical_kmax)==0)
|
8345 |
{
|
8346 |
/* The right term is the corner point. Need to "round the corner".
|
8347 |
*/
|
8348 |
siCopy(&hright, &hleft);
|
8349 |
siCopy(&kright, &kleft);
|
8350 |
siCopy(&reciprocal_corner_successor_h, &hright);
|
8351 |
siCopy(&reciprocal_corner_successor_k, &kright);
|
8352 |
}
|
8353 |
else if (rnCompare(&hleft, &kleft, &hmax, &kmax) >= 0)
|
8354 |
{
|
8355 |
/* We are to the right of the corner point. Need to progress
|
8356 |
** in the inverted Farey series.
|
8357 |
*/
|
8358 |
#if 0
|
8359 |
printf("Before.\n");
|
8360 |
siDump(&kright, "kright");
|
8361 |
siDump(&hright, "hright");
|
8362 |
siDump(&kleft, "kleft");
|
8363 |
siDump(&hleft, "hleft");
|
8364 |
siDump(&hmax, "hmax");
|
8365 |
#endif
|
8366 |
rnFareyTraverse(&kright, &hright, &kleft, &hleft, &hmax, -1);
|
8367 |
#if 0
|
8368 |
printf("After.\n");
|
8369 |
siDump(&kright, "kright");
|
8370 |
siDump(&hright, "hright");
|
8371 |
siDump(&kleft, "kleft");
|
8372 |
siDump(&hleft, "hleft");
|
8373 |
siDump(&hmax, "hmax");
|
8374 |
#endif
|
8375 |
}
|
8376 |
else
|
8377 |
{
|
8378 |
/* We are left of the corner point. Normal Farey progression.
|
8379 |
*/
|
8380 |
rnFareyTraverse(&hleft, &kleft, &hright, &kright, &kmax, 1);
|
8381 |
}
|
8382 |
}
|
8383 |
|
8384 |
/* Destroy CF expansions.
|
8385 |
*/
|
8386 |
if (rn_expansion)
|
8387 |
pqDestroy(&rn_expansion);
|
8388 |
if (rn_reciprocal_expansion)
|
8389 |
pqDestroy(&rn_reciprocal_expansion);
|
8390 |
if (corner_point_expansion)
|
8391 |
pqDestroy(&corner_point_expansion);
|
8392 |
if (corner_point_reciprocal_expansion);
|
8393 |
pqDestroy(&corner_point_reciprocal_expansion);
|
8394 |
|
8395 |
/* Destroy all local variables.
|
8396 |
*/
|
8397 |
siDestroy(&D);
|
8398 |
siDestroy(&h);
|
8399 |
siDestroy(&k);
|
8400 |
siDestroy(&hmax);
|
8401 |
siDestroy(&kmax);
|
8402 |
siDestroy(&canonical_hmax);
|
8403 |
siDestroy(&canonical_kmax);
|
8404 |
siDestroy(&normal_corner_predecessor_h);
|
8405 |
siDestroy(&normal_corner_predecessor_k);
|
8406 |
siDestroy(&reciprocal_corner_successor_h);
|
8407 |
siDestroy(&reciprocal_corner_successor_k);
|
8408 |
siDestroy(&constant_1);
|
8409 |
siDestroy(&constant_0);
|
8410 |
siDestroy(&conv_h);
|
8411 |
siDestroy(&conv_k);
|
8412 |
siDestroy(&neigh_h);
|
8413 |
siDestroy(&neigh_k);
|
8414 |
siDestroy(&hleft);
|
8415 |
siDestroy(&kleft);
|
8416 |
siDestroy(&hright);
|
8417 |
siDestroy(&kright);
|
8418 |
siDestroy(&error_h);
|
8419 |
siDestroy(&error_k);
|
8420 |
siDestroy(&dap_h);
|
8421 |
siDestroy(&dap_k);
|
8422 |
siDestroy(&t1);
|
8423 |
siDestroy(&t2);
|
8424 |
}
|
8425 |
|
8426 |
|
8427 |
/****************************************************************************/
|
8428 |
/* cfFndmax(): */
|
8429 |
/*--------------------------------------------------------------------------*/
|
8430 |
/* DESCRIPTION */
|
8431 |
/* Calculates an upper bound between the terms in the Farey series of */
|
8432 |
/* a certain order in an interval. */
|
8433 |
/****************************************************************************/
|
8434 |
void cfFndmax(void)
|
8435 |
{
|
8436 |
SYNTHETIC_INTEGER
|
8437 |
*r1_h, *r1_k,
|
8438 |
/* Left interval endpoint.
|
8439 |
*/
|
8440 |
*r2_h, *r2_k,
|
8441 |
/* Right interval endpoint.
|
8442 |
*/
|
8443 |
*result_h, *result_k,
|
8444 |
/* The fraction in the interval with the
|
8445 |
** smallest denominator.
|
8446 |
*/
|
8447 |
*D,
|
8448 |
/* The DAP denominator to be used.
|
8449 |
*/
|
8450 |
*kmax,
|
8451 |
/* The maximum denominator (i.e. the order of the
|
8452 |
** Farey series of interest).
|
8453 |
*/
|
8454 |
*kmax_minus_qmin,
|
8455 |
/* The order of the Farey series minus the minimum
|
8456 |
** denominator.
|
8457 |
*/
|
8458 |
*error_h, *error_k,
|
8459 |
/* The error bound, expressed as a rational
|
8460 |
** number.
|
8461 |
*/
|
8462 |
*dap_N;
|
8463 |
/* The DAP numerator.
|
8464 |
*/
|
8465 |
|
8466 |
/* Allocate all of our local variables.
|
8467 |
*/
|
8468 |
siCreate(&r1_h);
|
8469 |
siCreate(&r1_k);
|
8470 |
siCreate(&r2_h);
|
8471 |
siCreate(&r2_k);
|
8472 |
siCreate(&result_h);
|
8473 |
siCreate(&result_k);
|
8474 |
siCreate(&D);
|
8475 |
siCreate(&kmax);
|
8476 |
siCreate(&kmax_minus_qmin);
|
8477 |
siCreate(&error_h);
|
8478 |
siCreate(&error_k);
|
8479 |
siCreate(&dap_N);
|
8480 |
|
8481 |
/* Record the order of the series in which we are operating.
|
8482 |
*/
|
8483 |
asAssert(par_block.pars[3].canonical_numerator != NULL, __LINE__);
|
8484 |
siCopy(&(par_block.pars[3].canonical_numerator), &kmax);
|
8485 |
|
8486 |
/* If a different DAP denominator is specified, record that.
|
8487 |
*/
|
8488 |
if (par_block.pars[4].canonical_numerator)
|
8489 |
{
|
8490 |
siCopy(&(par_block.pars[4].canonical_numerator), &D);
|
8491 |
}
|
8492 |
else
|
8493 |
{
|
8494 |
siSetToPowerOfTen(&D, DIGITS_PER_LINE * 4);
|
8495 |
}
|
8496 |
|
8497 |
/* State the two interval endpoints as rational numbers, in case
|
8498 |
** one or both are integers.
|
8499 |
*/
|
8500 |
asAssert(par_block.pars[1].canonical_numerator != NULL, __LINE__);
|
8501 |
asAssert(par_block.pars[2].canonical_numerator != NULL, __LINE__);
|
8502 |
siCopy(&(par_block.pars[1].canonical_numerator), &r1_h);
|
8503 |
siCopy(&(par_block.pars[2].canonical_numerator), &r2_h);
|
8504 |
if (par_block.pars[1].canonical_denominator)
|
8505 |
siCopy(&(par_block.pars[1].canonical_denominator), &r1_k);
|
8506 |
else
|
8507 |
siSetToLong(&r1_k, 1);
|
8508 |
if (par_block.pars[2].canonical_denominator)
|
8509 |
siCopy(&(par_block.pars[2].canonical_denominator), &r2_k);
|
8510 |
else
|
8511 |
siSetToLong(&r2_k, 1);
|
8512 |
|
8513 |
/* Echo back the parameters for the caller.
|
8514 |
*/
|
8515 |
siDump(&r1_h, "l_h");
|
8516 |
gfHline();
|
8517 |
siDump(&r1_k, "l_k");
|
8518 |
gfHline();
|
8519 |
siDump(&r2_h, "r_h");
|
8520 |
gfHline();
|
8521 |
siDump(&r2_k, "r_k");
|
8522 |
gfHline();
|
8523 |
siDump(&kmax, "k_max");
|
8524 |
gfHline();
|
8525 |
siDump(&D, "dap_D");
|
8526 |
gfHline();
|
8527 |
|
8528 |
/* If the parameters for the interval are out of order,
|
8529 |
** declare an error. This probably means that the
|
8530 |
** user of the command is doing something unintended.
|
8531 |
*/
|
8532 |
if (rnCompare(&r1_h, &r1_k, &r2_h, &r2_k) >= 0)
|
8533 |
{
|
8534 |
asFatal("interval endpoints equal or out of order");
|
8535 |
}
|
8536 |
|
8537 |
/* Be sure that both endpoints are in the Farey series
|
8538 |
** of interest.
|
8539 |
*/
|
8540 |
if ((siCompare(&r1_k, &kmax) > 0) || (siCompare(&r2_k, &kmax) > 0))
|
8541 |
{
|
8542 |
asFatal("interval endpoints must be in Farey series of interest");
|
8543 |
}
|
8544 |
|
8545 |
/* Do the calculation proper.
|
8546 |
*/
|
8547 |
naMind(&r1_h,
|
8548 |
&r1_k,
|
8549 |
&r2_h,
|
8550 |
&r2_k,
|
8551 |
&result_h,
|
8552 |
&result_k,
|
8553 |
TRUE,
|
8554 |
TRUE,
|
8555 |
FALSE
|
8556 |
);
|
8557 |
|
8558 |
/* If both endpoints are in the interval, the fraction with
|
8559 |
** the smallest denominator must be in the interval. However,
|
8560 |
** let's just be sure ...
|
8561 |
*/
|
8562 |
asAssert(siCompare(&result_k, &kmax) <= 0, __LINE__);
|
8563 |
|
8564 |
/* Emit the results from determining the rational number with
|
8565 |
** the smallest denominator.
|
8566 |
*/
|
8567 |
gfBannerHeading("A Rational Number With Smallest Denominator In Interval", 0);
|
8568 |
gfHline();
|
8569 |
siDump(&result_h, "result_h");
|
8570 |
gfHline();
|
8571 |
siDump(&result_k, "result_k");
|
8572 |
gfHline();
|
8573 |
|
8574 |
/* Apply the formula in the paper to get the error result
|
8575 |
** as a rational number.
|
8576 |
*/
|
8577 |
siUnrestrictedSubtraction(&kmax, &result_k, &kmax_minus_qmin);
|
8578 |
|
8579 |
siSetToLong(&error_h, 1);
|
8580 |
|
8581 |
if (siCompare(&result_k, &kmax_minus_qmin) > 0)
|
8582 |
{
|
8583 |
SYNTHETIC_INTEGER *temp;
|
8584 |
|
8585 |
siCreate(&temp);
|
8586 |
|
8587 |
siCopy(&result_k, &temp);
|
8588 |
siUnrestrictedMultiplication(&result_k, &temp, &error_k);
|
8589 |
|
8590 |
siDestroy(&temp);
|
8591 |
}
|
8592 |
else
|
8593 |
{
|
8594 |
siUnrestrictedMultiplication(&result_k, &kmax_minus_qmin, &error_k);
|
8595 |
}
|
8596 |
|
8597 |
/* Print out these results. */
|
8598 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Rational Number", 0);
|
8599 |
gfHline();
|
8600 |
siDump(&error_h, "error_ub_h");
|
8601 |
gfHline();
|
8602 |
siDump(&error_k, "error_up_k");
|
8603 |
gfHline();
|
8604 |
|
8605 |
/* Calculate and display DAP results. */
|
8606 |
rnDap(&error_h, &error_k, &dap_N, &D);
|
8607 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Decimal Approximation", 0);
|
8608 |
gfHline();
|
8609 |
siDump(&dap_N, "dap_h");
|
8610 |
gfHline();
|
8611 |
siDump(&D, "dap_k");
|
8612 |
gfHline();
|
8613 |
|
8614 |
/* Destroy the locals.
|
8615 |
*/
|
8616 |
siDestroy(&r1_h);
|
8617 |
siDestroy(&r1_k);
|
8618 |
siDestroy(&r2_h);
|
8619 |
siDestroy(&r2_k);
|
8620 |
siDestroy(&result_h);
|
8621 |
siDestroy(&result_k);
|
8622 |
siDestroy(&D);
|
8623 |
siDestroy(&kmax);
|
8624 |
siDestroy(&kmax_minus_qmin);
|
8625 |
siDestroy(&error_h);
|
8626 |
siDestroy(&error_k);
|
8627 |
siDestroy(&dap_N);
|
8628 |
}
|
8629 |
|
8630 |
|
8631 |
/****************************************************************************/
|
8632 |
/* cfFabdmax(): */
|
8633 |
/*--------------------------------------------------------------------------*/
|
8634 |
/* DESCRIPTION */
|
8635 |
/* Calculates an upper bound between the terms in the "rectangular" Farey */
|
8636 |
/* series of a certain order (2 constrints) in an interval. */
|
8637 |
/****************************************************************************/
|
8638 |
void cfFabdmax(void)
|
8639 |
{
|
8640 |
int case_1_applies = FALSE,
|
8641 |
case_2_applies = FALSE,
|
8642 |
case_3_applies = FALSE,
|
8643 |
/* Boolean variables to record which cases apply.
|
8644 |
*/
|
8645 |
highest = 0;
|
8646 |
/* Integer representing the case with the largest error.
|
8647 |
** This should always be the highest-numbered case
|
8648 |
** evaluated. 1=Case I, 2=Case II, 3=Case III.
|
8649 |
*/
|
8650 |
|
8651 |
SYNTHETIC_INTEGER
|
8652 |
*r1_h, *r1_k,
|
8653 |
/* Left interval endpoint.
|
8654 |
*/
|
8655 |
*r2_h, *r2_k,
|
8656 |
/* Right interval endpoint.
|
8657 |
*/
|
8658 |
*min_k_h, *min_k_k,
|
8659 |
/* The fraction in the interval with the
|
8660 |
** smallest denominator.
|
8661 |
*/
|
8662 |
*D,
|
8663 |
/* The DAP denominator to be used.
|
8664 |
*/
|
8665 |
*constant_1h,
|
8666 |
/* The constant 1, useful for comparisons.
|
8667 |
*/
|
8668 |
*constant_1k,
|
8669 |
/* Second copy of the constant 1, useful for comparisons.
|
8670 |
** The reason for requiring a second copy is that some of the
|
8671 |
** internal functions won't accept two operands which are physically
|
8672 |
** the same.
|
8673 |
*/
|
8674 |
*hmax,
|
8675 |
/* The maximum numerator for the "rectangular"
|
8676 |
** Farey series.
|
8677 |
*/
|
8678 |
*kmax,
|
8679 |
/* The maximum denominator (i.e. the order of the
|
8680 |
** Farey series of interest).
|
8681 |
*/
|
8682 |
*kmax_minus_qmin,
|
8683 |
/* The order of the Farey series minus the minimum
|
8684 |
** denominator.
|
8685 |
*/
|
8686 |
*case_1_error_h,
|
8687 |
*case_1_error_k,
|
8688 |
/* The error bound from the Case I calculation,
|
8689 |
** expressed as a rational number.
|
8690 |
*/
|
8691 |
*dap_N,
|
8692 |
/* The DAP numerator.
|
8693 |
*/
|
8694 |
*case_1_right_h,
|
8695 |
*case_1_right_k,
|
8696 |
/* The right interval endpoint for application of Case I. Case I
|
8697 |
** does not apply any further than hmax/kmax, so this may be
|
8698 |
** different than the right point of the interval.
|
8699 |
*/
|
8700 |
*case_2_right_limit_h,
|
8701 |
*case_2_right_limit_k,
|
8702 |
/* The right limit for application of Case II. This is
|
8703 |
** the lesser of 1 and the interval right endpoint.
|
8704 |
*/
|
8705 |
*case_2_error_h,
|
8706 |
*case_2_error_k,
|
8707 |
/* The error bound from the Case II calculation
|
8708 |
** expressed as a rational number.
|
8709 |
*/
|
8710 |
*case_3_error_h,
|
8711 |
*case_3_error_k,
|
8712 |
/* The error bound from the Case III calculation
|
8713 |
** expressed as a rational number.
|
8714 |
*/
|
8715 |
*t0, *t1, *t2, *t3, *t4, *t5, *t6, *t7, *t8, *t9;
|
8716 |
/* Temporary integers.
|
8717 |
*/
|
8718 |
|
8719 |
/* Allocate all of our local variables.
|
8720 |
*/
|
8721 |
siCreate(&r1_h);
|
8722 |
siCreate(&r1_k);
|
8723 |
siCreate(&r2_h);
|
8724 |
siCreate(&r2_k);
|
8725 |
siCreate(&min_k_h);
|
8726 |
siCreate(&min_k_k);
|
8727 |
siCreate(&D);
|
8728 |
siCreate(&constant_1h);
|
8729 |
siSetToLong(&constant_1h, 1);
|
8730 |
siCreate(&constant_1k);
|
8731 |
siSetToLong(&constant_1k, 1);
|
8732 |
siCreate(&hmax);
|
8733 |
siCreate(&kmax);
|
8734 |
siCreate(&kmax_minus_qmin);
|
8735 |
siCreate(&case_1_error_h);
|
8736 |
siCreate(&case_1_error_k);
|
8737 |
siCreate(&dap_N);
|
8738 |
siCreate(&case_1_right_h);
|
8739 |
siCreate(&case_1_right_k);
|
8740 |
siCreate(&case_2_right_limit_h);
|
8741 |
siCreate(&case_2_right_limit_k);
|
8742 |
siCreate(&case_2_error_h);
|
8743 |
siCreate(&case_2_error_k);
|
8744 |
siCreate(&case_3_error_h);
|
8745 |
siCreate(&case_3_error_k);
|
8746 |
siCreate(&t0);
|
8747 |
siCreate(&t1);
|
8748 |
siCreate(&t2);
|
8749 |
siCreate(&t3);
|
8750 |
siCreate(&t4);
|
8751 |
siCreate(&t5);
|
8752 |
siCreate(&t6);
|
8753 |
siCreate(&t7);
|
8754 |
siCreate(&t8);
|
8755 |
siCreate(&t9);
|
8756 |
|
8757 |
/****************************************************************************/
|
8758 |
/***************** PROCESS INPUTS *******************************************/
|
8759 |
/****************************************************************************/
|
8760 |
/* Record the numerator order of the series in which we are
|
8761 |
** operating.
|
8762 |
*/
|
8763 |
asAssert(par_block.pars[3].canonical_numerator != NULL, __LINE__);
|
8764 |
siCopy(&(par_block.pars[3].canonical_numerator), &hmax);
|
8765 |
|
8766 |
/* Record the denominator order of the series in which we are
|
8767 |
** operating.
|
8768 |
*/
|
8769 |
asAssert(par_block.pars[4].canonical_numerator != NULL, __LINE__);
|
8770 |
siCopy(&(par_block.pars[4].canonical_numerator), &kmax);
|
8771 |
|
8772 |
/* If a different DAP denominator is specified, record that.
|
8773 |
*/
|
8774 |
if (par_block.pars[5].canonical_numerator)
|
8775 |
{
|
8776 |
siCopy(&(par_block.pars[5].canonical_numerator), &D);
|
8777 |
}
|
8778 |
else
|
8779 |
{
|
8780 |
siSetToPowerOfTen(&D, DIGITS_PER_LINE * 4);
|
8781 |
}
|
8782 |
|
8783 |
/* State the two interval endpoints as rational numbers, in case
|
8784 |
** one or both are integers.
|
8785 |
*/
|
8786 |
asAssert(par_block.pars[1].canonical_numerator != NULL, __LINE__);
|
8787 |
asAssert(par_block.pars[2].canonical_numerator != NULL, __LINE__);
|
8788 |
siCopy(&(par_block.pars[1].canonical_numerator), &r1_h);
|
8789 |
siCopy(&(par_block.pars[2].canonical_numerator), &r2_h);
|
8790 |
if (par_block.pars[1].canonical_denominator)
|
8791 |
siCopy(&(par_block.pars[1].canonical_denominator), &r1_k);
|
8792 |
else
|
8793 |
siSetToLong(&r1_k, 1);
|
8794 |
if (par_block.pars[2].canonical_denominator)
|
8795 |
siCopy(&(par_block.pars[2].canonical_denominator), &r2_k);
|
8796 |
else
|
8797 |
siSetToLong(&r2_k, 1);
|
8798 |
|
8799 |
/* Echo back the parameters for the caller.
|
8800 |
*/
|
8801 |
gfBannerHeading("Input Parameters", 2);
|
8802 |
gfHline();
|
8803 |
siDump(&r1_h, "l_h");
|
8804 |
gfHline();
|
8805 |
siDump(&r1_k, "l_k");
|
8806 |
gfHline();
|
8807 |
siDump(&r2_h, "r_h");
|
8808 |
gfHline();
|
8809 |
siDump(&r2_k, "r_k");
|
8810 |
gfHline();
|
8811 |
siDump(&hmax, "h_max");
|
8812 |
gfHline();
|
8813 |
siDump(&kmax, "k_max");
|
8814 |
gfHline();
|
8815 |
siDump(&D, "dap_D");
|
8816 |
gfHline();
|
8817 |
|
8818 |
/* If the parameters for the interval are out of order,
|
8819 |
** declare an error. This probably means that the
|
8820 |
** user of the command is doing something unintended.
|
8821 |
*/
|
8822 |
if (rnCompare(&r1_h, &r1_k, &r2_h, &r2_k) >= 0)
|
8823 |
{
|
8824 |
asFatal("interval endpoints equal or out of order");
|
8825 |
}
|
8826 |
|
8827 |
/* Be sure that both endpoints are in the Farey series
|
8828 |
** of interest.
|
8829 |
*/
|
8830 |
if ((siCompare(&r1_k, &kmax) > 0) || (siCompare(&r2_k, &kmax) > 0)
|
8831 |
||
|
8832 |
(siCompare(&r1_h, &hmax) > 0) || (siCompare(&r2_h, &hmax) > 0))
|
8833 |
{
|
8834 |
asFatal("interval endpoints must be in Farey series of interest");
|
8835 |
}
|
8836 |
|
8837 |
/****************************************************************************/
|
8838 |
/***************** DECIDE WHICH CASES APPLY *********************************/
|
8839 |
/****************************************************************************/
|
8840 |
/* For Case I to apply, the interval must protrude below HMAX/KMAX.
|
8841 |
*/
|
8842 |
if (rnCompare(&r1_h, &r1_k, &hmax, &kmax) < 0)
|
8843 |
case_1_applies = TRUE;
|
8844 |
else
|
8845 |
case_1_applies = FALSE;
|
8846 |
|
8847 |
/* For Case II to apply, the HMAX/KMAX must be less than 1, and the
|
8848 |
** interval must protrude into [HMAX/KMAX, 1].
|
8849 |
*/
|
8850 |
if ((rnCompare(&hmax, &kmax, &constant_1h, &constant_1k) < 0) &&
|
8851 |
(rnCompare(&r2_h, &r2_k, &hmax, &kmax) > 0) &&
|
8852 |
(rnCompare(&r1_h, &r1_k, &constant_1h, &constant_1k) < 0))
|
8853 |
case_2_applies = TRUE;
|
8854 |
else
|
8855 |
case_2_applies = FALSE;
|
8856 |
|
8857 |
/* For Case III to apply, the interval must protrude above 1 and
|
8858 |
** above hmax/kmax.
|
8859 |
*/
|
8860 |
if ((rnCompare(&r2_h, &r2_k, &constant_1h, &constant_1k) > 0)
|
8861 |
&& (rnCompare(&r2_h, &r2_k, &hmax, &kmax) > 0))
|
8862 |
case_3_applies = TRUE;
|
8863 |
else
|
8864 |
case_3_applies = FALSE;
|
8865 |
|
8866 |
/* Announce what applies.
|
8867 |
*/
|
8868 |
gfBannerHeading("Case Selection Results", 2);
|
8869 |
gfHline();
|
8870 |
if (case_1_applies)
|
8871 |
printf("Case I applies and will be evaluated.\n");
|
8872 |
else
|
8873 |
printf("Case I does not apply and will not be evaluated.\n");
|
8874 |
|
8875 |
if (case_2_applies)
|
8876 |
printf("Case II applies and will be evaluated.\n");
|
8877 |
else
|
8878 |
printf("Case II does not apply and will not be evaluated.\n");
|
8879 |
|
8880 |
if (case_3_applies)
|
8881 |
printf("Case III applies and will be evaluated.\n");
|
8882 |
else
|
8883 |
printf("Case III does not apply and will not be evaluated.\n");
|
8884 |
|
8885 |
gfHline();
|
8886 |
|
8887 |
/* At this point I'm too lazy to go through the Boolean algebra to make
|
8888 |
** sure that for any interval at least one case applies. I *believe* I got
|
8889 |
** it right, but just in case, let's assert that at least one case applies.
|
8890 |
*/
|
8891 |
asAssert(case_1_applies || case_2_applies || case_3_applies, __LINE__);
|
8892 |
|
8893 |
/****************************************************************************/
|
8894 |
/***************** CASE I ***************************************************/
|
8895 |
/****************************************************************************/
|
8896 |
if (case_1_applies)
|
8897 |
{
|
8898 |
gfBannerHeading("Start Of Case I Results", 2);
|
8899 |
gfHline();
|
8900 |
|
8901 |
/* Must select an interval over which to operate for Case I. If the
|
8902 |
** right endpoint of the interval is > hmax/kmax, must knock it back
|
8903 |
** to hmax/kmax for evaluation of Case I. For Case I, can only evaluate
|
8904 |
** to the left of hmax/kmax.
|
8905 |
*/
|
8906 |
if (rnCompare(&r2_h, &r2_k, &hmax, &kmax) > 0)
|
8907 |
{
|
8908 |
siCopy(&hmax, &case_1_right_h);
|
8909 |
siCopy(&kmax, &case_1_right_k);
|
8910 |
}
|
8911 |
else
|
8912 |
{
|
8913 |
siCopy(&r2_h, &case_1_right_h);
|
8914 |
siCopy(&r2_k, &case_1_right_k);
|
8915 |
}
|
8916 |
|
8917 |
gfBannerHeading("Possibly Truncated Interval For Case I", 0);
|
8918 |
gfHline();
|
8919 |
siDump(&r1_h, "l_h");
|
8920 |
gfHline();
|
8921 |
siDump(&r1_k, "l_k");
|
8922 |
gfHline();
|
8923 |
siDump(&case_1_right_h, "r_h");
|
8924 |
gfHline();
|
8925 |
siDump(&case_1_right_k, "r_k");
|
8926 |
gfHline();
|
8927 |
|
8928 |
/* Do the calculation proper.
|
8929 |
*/
|
8930 |
naMind(&r1_h,
|
8931 |
&r1_k,
|
8932 |
&case_1_right_h,
|
8933 |
&case_1_right_k,
|
8934 |
&min_k_h,
|
8935 |
&min_k_k,
|
8936 |
TRUE,
|
8937 |
TRUE,
|
8938 |
FALSE
|
8939 |
);
|
8940 |
|
8941 |
/* If both endpoints are in the Farey series, the fraction with
|
8942 |
** the smallest denominator must be in the Farey series. However,
|
8943 |
** let's just be sure ...
|
8944 |
*/
|
8945 |
asAssert(siCompare(&min_k_k, &kmax) <= 0, __LINE__);
|
8946 |
|
8947 |
/* Emit the results from determining the rational number with
|
8948 |
** the smallest denominator.
|
8949 |
*/
|
8950 |
gfBannerHeading("A Rational Number With Smallest Denominator In Interval", 0);
|
8951 |
gfHline();
|
8952 |
siDump(&min_k_h, "result_h");
|
8953 |
gfHline();
|
8954 |
siDump(&min_k_k, "result_k");
|
8955 |
gfHline();
|
8956 |
|
8957 |
/* Apply the formula in the paper to get the error result
|
8958 |
** as a rational number.
|
8959 |
*/
|
8960 |
siUnrestrictedSubtraction(&kmax, &min_k_k, &kmax_minus_qmin);
|
8961 |
|
8962 |
siSetToLong(&case_1_error_h, 1);
|
8963 |
|
8964 |
if (siCompare(&min_k_k, &kmax_minus_qmin) > 0)
|
8965 |
{
|
8966 |
SYNTHETIC_INTEGER *temp;
|
8967 |
|
8968 |
siCreate(&temp);
|
8969 |
|
8970 |
siCopy(&min_k_k, &temp);
|
8971 |
siUnrestrictedMultiplication(&min_k_k, &temp, &case_1_error_k);
|
8972 |
|
8973 |
siDestroy(&temp);
|
8974 |
}
|
8975 |
else
|
8976 |
{
|
8977 |
siUnrestrictedMultiplication(&min_k_k, &kmax_minus_qmin, &case_1_error_k);
|
8978 |
}
|
8979 |
|
8980 |
/* Print out these results. */
|
8981 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Rational Number", 0);
|
8982 |
gfHline();
|
8983 |
siDump(&case_1_error_h, "error_ub_h");
|
8984 |
gfHline();
|
8985 |
siDump(&case_1_error_k, "error_up_k");
|
8986 |
gfHline();
|
8987 |
|
8988 |
/* Calculate and display DAP results. */
|
8989 |
rnDap(&case_1_error_h, &case_1_error_k, &dap_N, &D);
|
8990 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Decimal Approximation", 0);
|
8991 |
gfHline();
|
8992 |
siDump(&dap_N, "dap_h");
|
8993 |
gfHline();
|
8994 |
siDump(&D, "dap_k");
|
8995 |
gfHline();
|
8996 |
}
|
8997 |
|
8998 |
/****************************************************************************/
|
8999 |
/***************** CASE II **************************************************/
|
9000 |
/****************************************************************************/
|
9001 |
if (case_2_applies)
|
9002 |
{
|
9003 |
gfBannerHeading("Start Of Case II Results", 2);
|
9004 |
gfHline();
|
9005 |
|
9006 |
/* If Case II applies, the maximum error will occur at the
|
9007 |
** right limit of the interval or at 1, whichever is less. Can
|
9008 |
** just evaluate the error at this point.
|
9009 |
*/
|
9010 |
if (rnCompare(&r2_h, &r2_k,
|
9011 |
&constant_1h, &constant_1k) > 0)
|
9012 |
{
|
9013 |
siSetToLong(&case_2_right_limit_h, 1);
|
9014 |
siSetToLong(&case_2_right_limit_k, 1);
|
9015 |
}
|
9016 |
else
|
9017 |
{
|
9018 |
siCopy(&r2_h, &case_2_right_limit_h);
|
9019 |
siCopy(&r2_k, &case_2_right_limit_k);
|
9020 |
}
|
9021 |
|
9022 |
/* We know the upper limit to apply. Announce it.
|
9023 |
*/
|
9024 |
gfBannerHeading("Case II Right Limit", 0);
|
9025 |
gfHline();
|
9026 |
siDump(&case_2_right_limit_h, "case_2_right_h");
|
9027 |
gfHline();
|
9028 |
siDump(&case_2_right_limit_k, "case_2_right_k");
|
9029 |
gfHline();
|
9030 |
|
9031 |
/* Now evaluate the maximum error per the equations
|
9032 |
** in the TOMS paper, and give that error
|
9033 |
** and the DAP approximation as output.
|
9034 |
*/
|
9035 |
/* Calculate the expression:
|
9036 |
** floor(HMAX/RI)
|
9037 |
** This will require a little fancy footwork.
|
9038 |
*/
|
9039 |
siUnrestrictedMultiplication(&hmax, &case_2_right_limit_k, &t1);
|
9040 |
siUnrestrictedDivision(&t1, &case_2_right_limit_h,
|
9041 |
&t0, &t2);
|
9042 |
|
9043 |
/* This quantity should now be in t0. Now square it and add,
|
9044 |
** leave in t1. This is the denominator on the error expression.
|
9045 |
*/
|
9046 |
siCopy(&t0, &t1);
|
9047 |
siUnrestrictedMultiplication(&t0, &t1, &t2);
|
9048 |
siUnrestrictedAddition(&t0, &t2, &t1);
|
9049 |
siCopy(&t1, &case_2_error_k);
|
9050 |
|
9051 |
/* The numerator is HMAX. */
|
9052 |
siCopy(&hmax, &case_2_error_h);
|
9053 |
|
9054 |
/* Put the rational number in lowest terms.
|
9055 |
*/
|
9056 |
rnCanonize(&case_2_error_h, &case_2_error_k);
|
9057 |
|
9058 |
/* Print out these results. */
|
9059 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Rational Number", 0);
|
9060 |
gfHline();
|
9061 |
siDump(&case_2_error_h, "error_ub_h");
|
9062 |
gfHline();
|
9063 |
siDump(&case_2_error_k, "error_up_k");
|
9064 |
gfHline();
|
9065 |
|
9066 |
/* Calculate and display DAP results. */
|
9067 |
rnDap(&case_2_error_h, &case_2_error_k, &dap_N, &D);
|
9068 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Decimal Approximation", 0);
|
9069 |
gfHline();
|
9070 |
siDump(&dap_N, "dap_h");
|
9071 |
gfHline();
|
9072 |
siDump(&D, "dap_k");
|
9073 |
gfHline();
|
9074 |
}
|
9075 |
|
9076 |
/****************************************************************************/
|
9077 |
/***************** CASE III *************************************************/
|
9078 |
/****************************************************************************/
|
9079 |
if (case_3_applies)
|
9080 |
{
|
9081 |
gfBannerHeading("Start Of Case III Results", 2);
|
9082 |
gfHline();
|
9083 |
|
9084 |
/* Case III is pretty simple. Just 1/(simple_expression).
|
9085 |
** For r_I we should use the upper limit on the interval, if
|
9086 |
** Case III applies at all.
|
9087 |
*/
|
9088 |
/* Calculate the expression:
|
9089 |
** floor(HMAX/RI)
|
9090 |
** This will require a little fancy footwork.
|
9091 |
*/
|
9092 |
siUnrestrictedMultiplication(&hmax, &r2_k, &t1);
|
9093 |
siUnrestrictedDivision(&t1, &r2_h,
|
9094 |
&t0, &t2);
|
9095 |
|
9096 |
/* t0 now contains the denominator, and the numerator is 1.
|
9097 |
*/
|
9098 |
siSetToLong(&case_3_error_h, 1);
|
9099 |
siCopy(&t0, &case_3_error_k);
|
9100 |
|
9101 |
/* Present that result and the DAP result.
|
9102 |
*/
|
9103 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Rational Number", 0);
|
9104 |
gfHline();
|
9105 |
siDump(&case_3_error_h, "error_ub_h");
|
9106 |
gfHline();
|
9107 |
siDump(&case_3_error_k, "error_up_k");
|
9108 |
gfHline();
|
9109 |
|
9110 |
/* Calculate and display DAP results. */
|
9111 |
rnDap(&case_3_error_h, &case_3_error_k, &dap_N, &D);
|
9112 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Decimal Approximation", 0);
|
9113 |
gfHline();
|
9114 |
siDump(&dap_N, "dap_h");
|
9115 |
gfHline();
|
9116 |
siDump(&D, "dap_k");
|
9117 |
gfHline();
|
9118 |
}
|
9119 |
|
9120 |
/****************************************************************************/
|
9121 |
/***************** CUMULATIVE RESULTS ***************************************/
|
9122 |
/****************************************************************************/
|
9123 |
/* At this point, can compare the results to see which of the active
|
9124 |
** cases generated the largest error. It should always be the
|
9125 |
** highest-numbered case, but can compare anyway.
|
9126 |
*/
|
9127 |
gfBannerHeading("Start Of Cumulative Results", 2);
|
9128 |
gfHline();
|
9129 |
siSetToLong(&t0, 0);
|
9130 |
siSetToLong(&t1, 0);
|
9131 |
|
9132 |
if (case_1_applies)
|
9133 |
{
|
9134 |
siCopy(&case_1_error_h, &t0);
|
9135 |
siCopy(&case_1_error_k, &t1);
|
9136 |
highest = 1;
|
9137 |
}
|
9138 |
else if (case_2_applies)
|
9139 |
{
|
9140 |
siCopy(&case_2_error_h, &t0);
|
9141 |
siCopy(&case_2_error_k, &t1);
|
9142 |
highest = 2;
|
9143 |
}
|
9144 |
else if (case_3_applies)
|
9145 |
{
|
9146 |
siCopy(&case_3_error_h, &t0);
|
9147 |
siCopy(&case_3_error_k, &t1);
|
9148 |
highest = 3;
|
9149 |
}
|
9150 |
else
|
9151 |
{
|
9152 |
asAssert(0, __LINE__);
|
9153 |
}
|
9154 |
|
9155 |
/* OK, one case has been copied to t0/t1. Compare
|
9156 |
** to see if there is a larger one.
|
9157 |
*/
|
9158 |
if (case_2_applies)
|
9159 |
{
|
9160 |
if (rnCompare(&case_2_error_h, &case_2_error_k,
|
9161 |
&t0, &t1) > 0)
|
9162 |
{
|
9163 |
siCopy(&case_2_error_h, &t0);
|
9164 |
siCopy(&case_2_error_k, &t1);
|
9165 |
highest = 2;
|
9166 |
}
|
9167 |
}
|
9168 |
if (case_3_applies)
|
9169 |
{
|
9170 |
if (rnCompare(&case_3_error_h, &case_3_error_k,
|
9171 |
&t0, &t1) > 0)
|
9172 |
{
|
9173 |
siCopy(&case_3_error_h, &t0);
|
9174 |
siCopy(&case_3_error_k, &t1);
|
9175 |
highest = 3;
|
9176 |
}
|
9177 |
}
|
9178 |
|
9179 |
/* Announce the results.
|
9180 |
*/
|
9181 |
{
|
9182 |
char buf1[100], buf2[100];
|
9183 |
|
9184 |
switch (highest)
|
9185 |
{
|
9186 |
case 1 : strcpy(buf1, "I"); break;
|
9187 |
case 2 : strcpy(buf1, "II"); break;
|
9188 |
case 3 : strcpy(buf1, "III"); break;
|
9189 |
default: strcpy(buf1, "???"); break;
|
9190 |
}
|
9191 |
|
9192 |
sprintf(buf2, "Largest Error (Case %s)", buf1);
|
9193 |
|
9194 |
gfBannerHeading(buf2, 2);
|
9195 |
gfHline();
|
9196 |
}
|
9197 |
|
9198 |
/* Present that result and the DAP result.
|
9199 |
*/
|
9200 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Rational Number", 0);
|
9201 |
gfHline();
|
9202 |
siDump(&t0, "error_ub_h");
|
9203 |
gfHline();
|
9204 |
siDump(&t1, "error_up_k");
|
9205 |
gfHline();
|
9206 |
|
9207 |
/* Calculate and display DAP results. */
|
9208 |
rnDap(&t0, &t1, &dap_N, &D);
|
9209 |
gfBannerHeading("Upper Bound On Distance Between Farey Terms As Decimal Approximation", 0);
|
9210 |
gfHline();
|
9211 |
siDump(&dap_N, "dap_h");
|
9212 |
gfHline();
|
9213 |
siDump(&D, "dap_k");
|
9214 |
gfHline();
|
9215 |
|
9216 |
/* Destroy the locals.
|
9217 |
*/
|
9218 |
siDestroy(&r1_h);
|
9219 |
siDestroy(&r1_k);
|
9220 |
siDestroy(&r2_h);
|
9221 |
siDestroy(&r2_k);
|
9222 |
siDestroy(&min_k_h);
|
9223 |
siDestroy(&min_k_k);
|
9224 |
siDestroy(&D);
|
9225 |
siDestroy(&constant_1h);
|
9226 |
siDestroy(&constant_1k);
|
9227 |
siDestroy(&hmax);
|
9228 |
siDestroy(&kmax);
|
9229 |
siDestroy(&kmax_minus_qmin);
|
9230 |
siDestroy(&case_1_error_h);
|
9231 |
siDestroy(&case_1_error_k);
|
9232 |
siDestroy(&dap_N);
|
9233 |
siDestroy(&case_1_right_h);
|
9234 |
siDestroy(&case_1_right_k);
|
9235 |
siDestroy(&case_2_right_limit_h);
|
9236 |
siDestroy(&case_2_right_limit_k);
|
9237 |
siDestroy(&case_2_error_h);
|
9238 |
siDestroy(&case_2_error_k);
|
9239 |
siDestroy(&case_3_error_h);
|
9240 |
siDestroy(&case_3_error_k);
|
9241 |
siDestroy(&t0);
|
9242 |
siDestroy(&t1);
|
9243 |
siDestroy(&t2);
|
9244 |
siDestroy(&t3);
|
9245 |
siDestroy(&t4);
|
9246 |
siDestroy(&t5);
|
9247 |
siDestroy(&t6);
|
9248 |
siDestroy(&t7);
|
9249 |
siDestroy(&t8);
|
9250 |
siDestroy(&t9);
|
9251 |
}
|
9252 |
|
9253 |
|
9254 |
/****************************************************************************/
|
9255 |
/****************************************************************************/
|
9256 |
/********** I N P U T P A R A M E T E R F U N C T I O N S *********/
|
9257 |
/****************************************************************************/
|
9258 |
/****************************************************************************/
|
9259 |
/* This section is reserved for functions which process the input parameters
|
9260 |
** and get them properly arranged in a data structure for the program
|
9261 |
** internals to process.
|
9262 |
*/
|
9263 |
|
9264 |
|
9265 |
/* A simple structure to implement a linked list of strings. This is used
|
9266 |
** to hold the tokens of both the command-line or the processing from the
|
9267 |
** standard input.
|
9268 |
*/
|
9269 |
struct ipSimpleStringLlNodeStruct
|
9270 |
{
|
9271 |
char *s;
|
9272 |
/* Dynamically allocated string.
|
9273 |
*/
|
9274 |
struct ipSimpleStringLlNodeStruct *next;
|
9275 |
/* Link to next, or NULL if end of list.
|
9276 |
*/
|
9277 |
};
|
9278 |
|
9279 |
|
9280 |
/****************************************************************************/
|
9281 |
/* ipBufferStandardInputStream(): */
|
9282 |
/*--------------------------------------------------------------------------*/
|
9283 |
/* DESCRIPTION */
|
9284 |
/* Buffers the entire standard input stream into an array of characters, */
|
9285 |
/* up to a maximum of STDIN_MAX_CHARS. */
|
9286 |
/* */
|
9287 |
/* OUTPUTS */
|
9288 |
/* <-- : Pointer to allocated array, terminated with '\0'. Should */
|
9289 |
/* be deallocated at some point. */
|
9290 |
/****************************************************************************/
|
9291 |
char *ipBufferStandardInputStream(void)
|
9292 |
{
|
9293 |
char *rv;
|
9294 |
char c;
|
9295 |
unsigned i;
|
9296 |
|
9297 |
rv = maMalloc(((unsigned long)(sizeof(char))) * (STDIN_MAX_CHARS + 1));
|
9298 |
|
9299 |
i = 0;
|
9300 |
rv[0] = '\0';
|
9301 |
|
9302 |
while ((c = getchar()) != EOF)
|
9303 |
{
|
9304 |
if (i >= STDIN_MAX_CHARS)
|
9305 |
{
|
9306 |
asFatal("standard input exceeds 32000 characters");
|
9307 |
}
|
9308 |
|
9309 |
rv[i] = c;
|
9310 |
rv[i+1] = '\0';
|
9311 |
i++;
|
9312 |
}
|
9313 |
|
9314 |
return(rv);
|
9315 |
}
|
9316 |
|
9317 |
|
9318 |
/****************************************************************************/
|
9319 |
/* ipTranslateStdinToRawTokens(): */
|
9320 |
/*--------------------------------------------------------------------------*/
|
9321 |
/* DESCRIPTION */
|
9322 |
/* Translates from the array of characters buffered from the standard */
|
9323 |
/* input to a linked list of raw tokens. By "raw" I mean that the */
|
9324 |
/* possibility of concatenation has not been handled. */
|
9325 |
/****************************************************************************/
|
9326 |
void ipTranslateStdinToRawTokens(
|
9327 |
char *stdin_array,
|
9328 |
struct ipSimpleStringLlNodeStruct **ptr_to_callers_ptr
|
9329 |
)
|
9330 |
{
|
9331 |
/* Make sure the caller isn't doing anything silly.
|
9332 |
*/
|
9333 |
asAssert(stdin_array != NULL, __LINE__);
|
9334 |
asAssert(ptr_to_callers_ptr != NULL, __LINE__);
|
9335 |
|
9336 |
/* Scan the buffer for unexpected characters that can't be handled.
|
9337 |
** If one exists, generate a fatal error and message.
|
9338 |
*/
|
9339 |
{
|
9340 |
char *p;
|
9341 |
unsigned i;
|
9342 |
char buf[100];
|
9343 |
|
9344 |
i = 0;
|
9345 |
p = stdin_array;
|
9346 |
|
9347 |
while (*p)
|
9348 |
{
|
9349 |
if (!ddIsInfoChar(*p) && !ddIsDiscardChar(*p) && !ddIsWhitespaceChar(*p))
|
9350 |
{
|
9351 |
sprintf( buf,
|
9352 |
"illegal char in stdin at offset=%u, val=%u, char=%c",
|
9353 |
i,
|
9354 |
(int)(*p),
|
9355 |
(unsigned)(*p));
|
9356 |
asFatal(buf);
|
9357 |
}
|
9358 |
i++;
|
9359 |
p++;
|
9360 |
}
|
9361 |
}
|
9362 |
|
9363 |
|
9364 |
/* Convert the entire buffer to lower case.
|
9365 |
*/
|
9366 |
{
|
9367 |
unsigned len = strlen(stdin_array);
|
9368 |
unsigned i;
|
9369 |
|
9370 |
for (i=0; i<len; i++)
|
9371 |
stdin_array[i] = ddCharToLower(stdin_array[i]);
|
9372 |
}
|
9373 |
|
9374 |
/* Delete all the characters from the buffer that are the "ignore"
|
9375 |
** characters.
|
9376 |
*/
|
9377 |
{
|
9378 |
char *srcptr, *dstptr;
|
9379 |
|
9380 |
srcptr = dstptr = stdin_array;
|
9381 |
|
9382 |
while (*srcptr)
|
9383 |
{
|
9384 |
if (!ddIsDiscardChar(*srcptr))
|
9385 |
{
|
9386 |
*dstptr = *srcptr;
|
9387 |
dstptr++;
|
9388 |
}
|
9389 |
|
9390 |
srcptr++;
|
9391 |
}
|
9392 |
|
9393 |
*dstptr = '\0';
|
9394 |
}
|
9395 |
|
9396 |
|
9397 |
/* Break the stream into tokens, ignoring any concatenation. What will be
|
9398 |
** formed is a linked list.
|
9399 |
*/
|
9400 |
{
|
9401 |
char *srcptr;
|
9402 |
struct ipSimpleStringLlNodeStruct **insert_point = NULL;
|
9403 |
struct ipSimpleStringLlNodeStruct *newnode;
|
9404 |
|
9405 |
/* Set up to build a linked list. */
|
9406 |
*ptr_to_callers_ptr = NULL;
|
9407 |
|
9408 |
srcptr = stdin_array;
|
9409 |
|
9410 |
/* Advance pointer past any initial whitespace. */
|
9411 |
while ((*srcptr) && (ddIsWhitespaceChar(*srcptr)))
|
9412 |
srcptr++;
|
9413 |
|
9414 |
/* While we're not at the end, get us a new token and put it
|
9415 |
** into the linked list.
|
9416 |
*/
|
9417 |
while (*srcptr)
|
9418 |
{
|
9419 |
unsigned memblocklen;
|
9420 |
char *snipleftptr;
|
9421 |
unsigned i;
|
9422 |
|
9423 |
/* Snapshot the start of the token so we don't forget it. */
|
9424 |
snipleftptr = srcptr;
|
9425 |
|
9426 |
/* Advance the source pointer so that it points one past the
|
9427 |
** last character of the token.
|
9428 |
*/
|
9429 |
while (ddIsInfoChar(*srcptr))
|
9430 |
srcptr++;
|
9431 |
|
9432 |
/* Calculate the size of the memory block to hold the token's string
|
9433 |
** representation. We must add one to include the '\0' terminator.
|
9434 |
*/
|
9435 |
memblocklen = srcptr - snipleftptr + 1;
|
9436 |
|
9437 |
/* Allocate a new node to be put into the linked list. */
|
9438 |
newnode = maMalloc(sizeof(struct ipSimpleStringLlNodeStruct));
|
9439 |
|
9440 |
/* For now, NEXT points nowhere. */
|
9441 |
newnode->next = NULL;
|
9442 |
|
9443 |
/* Allocate the space to hold the string for the token. */
|
9444 |
newnode->s = maMalloc(memblocklen * sizeof(char));
|
9445 |
|
9446 |
/* Copy the token, not including a terminator. */
|
9447 |
for (i=0; i<(memblocklen - 1); i++)
|
9448 |
newnode->s[i] = snipleftptr[i];
|
9449 |
|
9450 |
/* Insert the string terminator. */
|
9451 |
newnode->s[memblocklen-1] = '\0';
|
9452 |
|
9453 |
/* Insert the newly created node into the linked list. There
|
9454 |
** are two different ways to do it, depending on if this is our
|
9455 |
** first element or not.
|
9456 |
*/
|
9457 |
if (*ptr_to_callers_ptr)
|
9458 |
{
|
9459 |
/* Head of list is not NULL. This is not our first element. */
|
9460 |
*insert_point = newnode;
|
9461 |
insert_point = &(newnode->next);
|
9462 |
}
|
9463 |
else
|
9464 |
{
|
9465 |
/* Head of list is NULL. This is our first element. */
|
9466 |
*ptr_to_callers_ptr = newnode;
|
9467 |
insert_point = &(newnode->next);
|
9468 |
}
|
9469 |
|
9470 |
/* Advance pointer past any whitespace until next token or end of string. */
|
9471 |
while ((*srcptr) && (ddIsWhitespaceChar(*srcptr)))
|
9472 |
srcptr++;
|
9473 |
} /* End while() */
|
9474 |
} /* End block. */
|
9475 |
} /* End function. */
|
9476 |
|
9477 |
|
9478 |
/****************************************************************************/
|
9479 |
/* ipPackCmdLineArgsIntoLinkedList(): */
|
9480 |
/*--------------------------------------------------------------------------*/
|
9481 |
/* DESCRIPTION */
|
9482 |
/* Translates the command-line arguments into a linked list of strings. */
|
9483 |
/* The first argument (the program name) is omitted. */
|
9484 |
/****************************************************************************/
|
9485 |
void ipPackCmdLineArgsIntoLinkedList(
|
9486 |
int argc,
|
9487 |
char * argv[],
|
9488 |
struct ipSimpleStringLlNodeStruct **ptr_to_callers_ptr)
|
9489 |
{
|
9490 |
int i;
|
9491 |
struct ipSimpleStringLlNodeStruct *newnode;
|
9492 |
unsigned len;
|
9493 |
struct ipSimpleStringLlNodeStruct **insert_point = NULL;
|
9494 |
|
9495 |
/* Be sure that the caller isn't doing anything silly. */
|
9496 |
asAssert(argv != NULL, __LINE__);
|
9497 |
asAssert(ptr_to_callers_ptr != NULL, __LINE__);
|
9498 |
|
9499 |
/* NULL out the caller's pointer, consistent with an empty linked list. */
|
9500 |
*ptr_to_callers_ptr = NULL;
|
9501 |
|
9502 |
/* For each command-line argument, add it to the linked list. Slightly
|
9503 |
** different actions are necessary if the linked list is empty versus
|
9504 |
** if it has at least one element.
|
9505 |
*/
|
9506 |
|
9507 |
for (i=1; i<argc; i++)
|
9508 |
{
|
9509 |
/* Figure out how long the string will be. */
|
9510 |
len = strlen(argv[i]);
|
9511 |
|
9512 |
/* Allocate the memory for the new node. */
|
9513 |
newnode = maMalloc(sizeof(struct ipSimpleStringLlNodeStruct));
|
9514 |
|
9515 |
/* For now, the node points nowhere. */
|
9516 |
newnode->next = NULL;
|
9517 |
|
9518 |
/* Allocate space for the string. */
|
9519 |
newnode->s = maMalloc((len + 1) * sizeof(char));
|
9520 |
|
9521 |
/* Copy from the argument list to the string. */
|
9522 |
strcpy(newnode->s, argv[i]);
|
9523 |
|
9524 |
/* Insert the node into the list. */
|
9525 |
if (*ptr_to_callers_ptr)
|
9526 |
{
|
9527 |
/* Head of list is not NULL. This is not our first element. */
|
9528 |
*insert_point = newnode;
|
9529 |
insert_point = &(newnode->next);
|
9530 |
}
|
9531 |
else
|
9532 |
{
|
9533 |
/* Head of list is NULL. This is our first element. */
|
9534 |
*ptr_to_callers_ptr = newnode;
|
9535 |
insert_point = &(newnode->next);
|
9536 |
}
|
9537 |
}
|
9538 |
|
9539 |
/* printf("Into check for illegals.\n"); */
|
9540 |
/* There are two tasks still to be performed to make the treatment
|
9541 |
** of command-line args consistent with the treatment of the stdin
|
9542 |
** stream. First, check for illegal characters. Second, remove the
|
9543 |
** "ignore" characters.
|
9544 |
*/
|
9545 |
{
|
9546 |
struct ipSimpleStringLlNodeStruct *p;
|
9547 |
unsigned i;
|
9548 |
|
9549 |
p = *ptr_to_callers_ptr;
|
9550 |
i = 1;
|
9551 |
|
9552 |
while(p)
|
9553 |
{
|
9554 |
char *cp;
|
9555 |
|
9556 |
cp = p->s;
|
9557 |
|
9558 |
while(*cp)
|
9559 |
{
|
9560 |
char buf[100];
|
9561 |
|
9562 |
if (ddIsWhitespaceChar(*cp) || (!ddIsInfoChar(*cp) && !ddIsDiscardChar(*cp)))
|
9563 |
{
|
9564 |
sprintf( buf,
|
9565 |
"illegal char in cmdline arg #%u, val=%u, char=%c",
|
9566 |
i,
|
9567 |
(unsigned)(*cp),
|
9568 |
*cp);
|
9569 |
asFatal(buf);
|
9570 |
}
|
9571 |
|
9572 |
cp++;
|
9573 |
}
|
9574 |
|
9575 |
i++;
|
9576 |
p = p->next;
|
9577 |
}
|
9578 |
}
|
9579 |
|
9580 |
/* printf("into discards\n"); */
|
9581 |
/* Now, remove any of the "discard" characters. */
|
9582 |
{
|
9583 |
struct ipSimpleStringLlNodeStruct *p;
|
9584 |
|
9585 |
p = *ptr_to_callers_ptr;
|
9586 |
|
9587 |
while(p)
|
9588 |
{
|
9589 |
char *srcptr, *dstptr;
|
9590 |
|
9591 |
srcptr = dstptr = p->s;
|
9592 |
|
9593 |
while (*srcptr)
|
9594 |
{
|
9595 |
*srcptr = ddCharToLower(*srcptr);
|
9596 |
|
9597 |
if (!ddIsDiscardChar(*srcptr))
|
9598 |
{
|
9599 |
*dstptr = *srcptr;
|
9600 |
dstptr++;
|
9601 |
}
|
9602 |
|
9603 |
srcptr++;
|
9604 |
}
|
9605 |
|
9606 |
*dstptr = '\0';
|
9607 |
|
9608 |
p = p->next;
|
9609 |
}
|
9610 |
}
|
9611 |
}
|
9612 |
|
9613 |
|
9614 |
/****************************************************************************/
|
9615 |
/* ipProcessLinkedListParameterContinuationCharacters(): */
|
9616 |
/*--------------------------------------------------------------------------*/
|
9617 |
/* DESCRIPTION */
|
9618 |
/* Processes the continuation characters. If any token ends with a '\', */
|
9619 |
/* combines it with next token. */
|
9620 |
/****************************************************************************/
|
9621 |
void ipProcessLinkedListParameterContinuationCharacters
|
9622 |
(struct ipSimpleStringLlNodeStruct **ptr_to_callers_ptr)
|
9623 |
{
|
9624 |
struct ipSimpleStringLlNodeStruct **p, *removed_node;
|
9625 |
unsigned len_a, len_b;
|
9626 |
|
9627 |
/* Be sure that the caller isn't doing anything silly. */
|
9628 |
asAssert(ptr_to_callers_ptr != NULL, __LINE__);
|
9629 |
|
9630 |
p = ptr_to_callers_ptr;
|
9631 |
|
9632 |
while (*p)
|
9633 |
{
|
9634 |
asAssert((*p)->s != NULL, __LINE__);
|
9635 |
|
9636 |
len_a = strlen((*p)->s);
|
9637 |
if (len_a)
|
9638 |
{
|
9639 |
if ((*p)->s[len_a-1] == '\\')
|
9640 |
{
|
9641 |
/* Final character of this token is a backslash. Must concatenate it with
|
9642 |
** next token.
|
9643 |
*/
|
9644 |
if (!((*p)->next))
|
9645 |
asFatal("final parameter ends in continuation character ('\\')");
|
9646 |
|
9647 |
removed_node = (*p)->next;
|
9648 |
|
9649 |
(*p)->next = removed_node->next;
|
9650 |
|
9651 |
len_b = strlen(removed_node->s);
|
9652 |
|
9653 |
(*p)->s = maRealloc((*p)->s, (len_a + len_b) * sizeof(char));
|
9654 |
|
9655 |
(*p)->s[len_a-1] = '\0';
|
9656 |
/* Trash the terminating continuation character. This also
|
9657 |
** makes the Realloc() just above valid, don't need to add
|
9658 |
** "+1", because have shorted string containing termination
|
9659 |
** character by 1.
|
9660 |
*/
|
9661 |
|
9662 |
strcat((*p)->s, removed_node->s);
|
9663 |
|
9664 |
maFree(removed_node->s);
|
9665 |
|
9666 |
maFree(removed_node);
|
9667 |
}
|
9668 |
}
|
9669 |
|
9670 |
len_a = strlen((*p)->s);
|
9671 |
if (len_a)
|
9672 |
{
|
9673 |
if ((*p)->s[len_a-1] != '\\')
|
9674 |
p = &((*p)->next);
|
9675 |
}
|
9676 |
}
|
9677 |
}
|
9678 |
|
9679 |
|
9680 |
/****************************************************************************/
|
9681 |
/* ipParseAsRationalNumber(): */
|
9682 |
/*--------------------------------------------------------------------------*/
|
9683 |
/* DESCRIPTION */
|
9684 |
/* Attempts to parse a string (subscript in par_block passed) as a */
|
9685 |
/* rational number. Looks for errors, fills in the raw values, converts */
|
9686 |
/* to canonical form, and fills in the ftype fields. */
|
9687 |
/****************************************************************************/
|
9688 |
void ipParseAsRationalNumber(int i)
|
9689 |
{
|
9690 |
SYNTHETIC_INTEGER *constant_1 = NULL,
|
9691 |
*h_raw = NULL,
|
9692 |
*k_raw = NULL,
|
9693 |
*h_canonical = NULL,
|
9694 |
*k_canonical = NULL,
|
9695 |
*si_temp1 = NULL,
|
9696 |
*si_temp2 = NULL,
|
9697 |
*si_temp3 = NULL,
|
9698 |
*si_temp4 = NULL;
|
9699 |
int is_neg = FALSE;
|
9700 |
char *s, *t;
|
9701 |
|
9702 |
/* Make sure the caller isn't doing anything silly. */
|
9703 |
asAssert(i >= 0, __LINE__);
|
9704 |
asAssert(i < MAX_CMDLINE_PARS, __LINE__);
|
9705 |
|
9706 |
/* Allocate all of the temporary synthetic integers that we'll
|
9707 |
** use, and assign the constant 1.
|
9708 |
*/
|
9709 |
siCreate(&constant_1);
|
9710 |
siSetToLong(&constant_1, 1);
|
9711 |
siCreate(&h_raw);
|
9712 |
siCreate(&k_raw);
|
9713 |
siCreate(&h_canonical);
|
9714 |
siCreate(&k_canonical);
|
9715 |
siCreate(&si_temp1);
|
9716 |
siCreate(&si_temp2);
|
9717 |
siCreate(&si_temp3);
|
9718 |
siCreate(&si_temp4);
|
9719 |
|
9720 |
/* There are two parsing cases to cover. Either the user is trying to
|
9721 |
** specify a rational number as integer/integer, or as a floating point
|
9722 |
** number. The two cases can be differentiated by the presence of a
|
9723 |
** forward slash in the input.
|
9724 |
*/
|
9725 |
if (ddStringContains(par_block.pars[i].orig_string, "/"))
|
9726 |
{
|
9727 |
/* Integer/Integer Case */
|
9728 |
/* Parse off any leading minus sign. */
|
9729 |
|
9730 |
/* Form a pointer to the start of the string. */
|
9731 |
s = par_block.pars[i].orig_string;
|
9732 |
|
9733 |
/* Process any leading '-' sign. */
|
9734 |
if (*s == '-')
|
9735 |
{
|
9736 |
s++;
|
9737 |
is_neg = TRUE;
|
9738 |
}
|
9739 |
|
9740 |
/* Parse off a group of digits, up to any non-digit character.
|
9741 |
** We'll come to rest one past the last digit.
|
9742 |
*/
|
9743 |
t = s;
|
9744 |
while (*t && ddIsDigit(*t))
|
9745 |
{
|
9746 |
t++;
|
9747 |
}
|
9748 |
|
9749 |
/* Guard against the case where we could find no digits.
|
9750 |
*/
|
9751 |
if (s == t)
|
9752 |
{
|
9753 |
asFatal("missing numerator in rational number");
|
9754 |
}
|
9755 |
|
9756 |
/* Guard against the case where we have a leading zero on a string
|
9757 |
** of digits that contains more than a zero.
|
9758 |
*/
|
9759 |
if ((*s == '0') && ((t-s) > 1))
|
9760 |
{
|
9761 |
asFatal("leading zeros on non-zero integers not allowed");
|
9762 |
}
|
9763 |
|
9764 |
/* If we've made it this far, we have a contiguous group of digits,
|
9765 |
** with no leading zeroes. Process it.
|
9766 |
*/
|
9767 |
if (*s=='0')
|
9768 |
{
|
9769 |
/* Our digit was zero. */
|
9770 |
siSetToLong(&h_raw, 0);
|
9771 |
if (is_neg)
|
9772 |
asFatal("can't negate zero");
|
9773 |
}
|
9774 |
else if ((t-s) > INPUT_INTEGER_MAX_DIGITS)
|
9775 |
{
|
9776 |
asFatal("numerator too long");
|
9777 |
}
|
9778 |
else
|
9779 |
{
|
9780 |
char *u, *v;
|
9781 |
|
9782 |
u = s;
|
9783 |
v = &(h_raw->digits[0]);
|
9784 |
while (u != t)
|
9785 |
{
|
9786 |
*v = *u;
|
9787 |
u++;
|
9788 |
v++;
|
9789 |
}
|
9790 |
*v = '\0';
|
9791 |
ddStringReverse(h_raw->digits);
|
9792 |
h_raw->len = strlen(h_raw->digits);
|
9793 |
h_raw->neg = is_neg;
|
9794 |
}
|
9795 |
|
9796 |
/* OK, the first group of digits is done. Now advance
|
9797 |
** past the slash.
|
9798 |
*/
|
9799 |
s = t;
|
9800 |
if (*s != '/')
|
9801 |
asFatal("missing '/' in rational number");
|
9802 |
s++;
|
9803 |
|
9804 |
/* Guard against case of being at end of string. */
|
9805 |
if (!(*s))
|
9806 |
asFatal("missing denominator in rational number");
|
9807 |
|
9808 |
/* Be sure nothing else left in the string except digits.
|
9809 |
*/
|
9810 |
if (!ddStringContainsOnly(s, "0123456789"))
|
9811 |
asFatal("unexpected non-digit character in rational number denominator");
|
9812 |
|
9813 |
/* As before, parse past digits, copy, etc., except that no
|
9814 |
** '-' sign is allowed.
|
9815 |
*/
|
9816 |
/* Parse off a group of digits, up to any non-digit character.
|
9817 |
** We'll come to rest one past the last digit.
|
9818 |
*/
|
9819 |
t = s;
|
9820 |
while (*t && ddIsDigit(*t))
|
9821 |
{
|
9822 |
t++;
|
9823 |
}
|
9824 |
|
9825 |
/* Guard against the case where we could find no digits.
|
9826 |
*/
|
9827 |
if (s == t)
|
9828 |
{
|
9829 |
asFatal("missing denominator in rational number");
|
9830 |
}
|
9831 |
|
9832 |
/* Guard against the case where we have a leading zero on a string
|
9833 |
** of digits that contains more than a zero.
|
9834 |
*/
|
9835 |
if ((*s == '0') && ((t-s) > 1))
|
9836 |
{
|
9837 |
asFatal("leading zeros on non-zero integers not allowed");
|
9838 |
}
|
9839 |
|
9840 |
/* If we've made it this far, we have a contiguous group of digits,
|
9841 |
** with no deading zeroes. Process it.
|
9842 |
*/
|
9843 |
if (*s=='0')
|
9844 |
{
|
9845 |
/* Our digit was zero. */
|
9846 |
asFatal("zero denominator in rational number");
|
9847 |
}
|
9848 |
else if ((t-s) > INPUT_INTEGER_MAX_DIGITS)
|
9849 |
{
|
9850 |
asFatal("denominator too long");
|
9851 |
}
|
9852 |
else
|
9853 |
{
|
9854 |
char *u, *v;
|
9855 |
|
9856 |
u = s;
|
9857 |
v = &(k_raw->digits[0]);
|
9858 |
while (u != t)
|
9859 |
{
|
9860 |
*v = *u;
|
9861 |
u++;
|
9862 |
v++;
|
9863 |
}
|
9864 |
*v = '\0';
|
9865 |
ddStringReverse(k_raw->digits);
|
9866 |
k_raw->len = strlen(k_raw->digits);
|
9867 |
}
|
9868 |
#if 0
|
9869 |
siDump(&h_raw, "h_raw");
|
9870 |
siDump(&k_raw, "k_raw");
|
9871 |
#endif
|
9872 |
}
|
9873 |
else
|
9874 |
{
|
9875 |
char *before_decimal = NULL;
|
9876 |
int decimal_found = FALSE;
|
9877 |
char *after_decimal = NULL;
|
9878 |
int e_found = FALSE;
|
9879 |
char e_sign = '+';
|
9880 |
char *exponent_mag = NULL;
|
9881 |
char *concat_mantissa = NULL;
|
9882 |
int effective_exponent = 0;
|
9883 |
|
9884 |
/* Floating-Point Constant Case */
|
9885 |
/* We've identified this number as a floating point constant of
|
9886 |
** some kind. Parse it out. It will be re-expressed as a rational
|
9887 |
** number.
|
9888 |
*/
|
9889 |
s = par_block.pars[i].orig_string;
|
9890 |
|
9891 |
/* Process any leading '-' sign. */
|
9892 |
if (*s == '-')
|
9893 |
{
|
9894 |
s++;
|
9895 |
is_neg = TRUE;
|
9896 |
}
|
9897 |
|
9898 |
/* Parse off the first group of digits. Keep parsing until hit a
|
9899 |
** non-digit. Form into a string.
|
9900 |
*/
|
9901 |
/* Parse off a group of digits, up to any non-digit character.
|
9902 |
** We'll come to rest one past the last digit.
|
9903 |
*/
|
9904 |
t = s;
|
9905 |
while (*t && ddIsDigit(*t))
|
9906 |
{
|
9907 |
t++;
|
9908 |
}
|
9909 |
|
9910 |
if (t != s)
|
9911 |
{
|
9912 |
int i;
|
9913 |
|
9914 |
before_decimal = maMalloc((sizeof(char)) * (t-s+1));
|
9915 |
|
9916 |
for (i=0; i<(t-s); i++)
|
9917 |
before_decimal[i] = s[i];
|
9918 |
|
9919 |
before_decimal[i] = '\0';
|
9920 |
}
|
9921 |
else
|
9922 |
{
|
9923 |
before_decimal = maMalloc((sizeof(char)) * (1));
|
9924 |
strcpy(before_decimal, "");
|
9925 |
}
|
9926 |
|
9927 |
s = t;
|
9928 |
|
9929 |
/* Now, rip off any decimal point that exists. */
|
9930 |
if (*s == '.')
|
9931 |
{
|
9932 |
decimal_found = TRUE;
|
9933 |
s++;
|
9934 |
t++;
|
9935 |
}
|
9936 |
|
9937 |
/* Rip off any remaining group of digits before
|
9938 |
** the 'e' character.
|
9939 |
*/
|
9940 |
while (*t && ddIsDigit(*t))
|
9941 |
{
|
9942 |
t++;
|
9943 |
}
|
9944 |
|
9945 |
if (t != s)
|
9946 |
{
|
9947 |
int i;
|
9948 |
|
9949 |
after_decimal = maMalloc((sizeof(char)) * (t-s+1));
|
9950 |
|
9951 |
for (i=0; i<(t-s); i++)
|
9952 |
after_decimal[i] = s[i];
|
9953 |
|
9954 |
after_decimal[i] = '\0';
|
9955 |
}
|
9956 |
else
|
9957 |
{
|
9958 |
after_decimal = maMalloc((sizeof(char)) * (1));
|
9959 |
strcpy(after_decimal, "");
|
9960 |
}
|
9961 |
|
9962 |
s = t;
|
9963 |
|
9964 |
/* Rip off any e-character, should it exist. */
|
9965 |
if (*s == 'e')
|
9966 |
{
|
9967 |
e_found = TRUE;
|
9968 |
s++;
|
9969 |
t++;
|
9970 |
}
|
9971 |
|
9972 |
/* Rip any sign off the e, should it exist. */
|
9973 |
if ((*s == '+') || (*s == '-'))
|
9974 |
{
|
9975 |
e_sign = *s;
|
9976 |
s++;
|
9977 |
t++;
|
9978 |
}
|
9979 |
|
9980 |
/* Finally, rip off any final digits, which are
|
9981 |
** the exponent.
|
9982 |
*/
|
9983 |
while (*t && ddIsDigit(*t))
|
9984 |
{
|
9985 |
t++;
|
9986 |
}
|
9987 |
|
9988 |
if (t != s)
|
9989 |
{
|
9990 |
int i;
|
9991 |
|
9992 |
exponent_mag = maMalloc((sizeof(char)) * (t-s+1));
|
9993 |
|
9994 |
for (i=0; i<(t-s); i++)
|
9995 |
exponent_mag[i] = s[i];
|
9996 |
|
9997 |
exponent_mag[i] = '\0';
|
9998 |
}
|
9999 |
else
|
10000 |
{
|
10001 |
exponent_mag = maMalloc((sizeof(char)) * (1));
|
10002 |
strcpy(exponent_mag, "");
|
10003 |
}
|
10004 |
|
10005 |
s = t;
|
10006 |
|
10007 |
/* If we're not at the end of the string, something
|
10008 |
** is wrong.
|
10009 |
*/
|
10010 |
if (*s)
|
10011 |
asFatal("unable to parse floating-point number");
|
10012 |
|
10013 |
/* If "e" was specified but no exponent was captured, this is an error.
|
10014 |
*/
|
10015 |
if (!strlen(exponent_mag) && e_found)
|
10016 |
asFatal("missing floating-point exponent digits");
|
10017 |
|
10018 |
/* Parse the exponent into a number. The exponent is about the
|
10019 |
** only place where leading zeros are allowed. Start off believing
|
10020 |
** the exponent is zero.
|
10021 |
*/
|
10022 |
effective_exponent = 0;
|
10023 |
while (exponent_mag[0] == '0')
|
10024 |
ddStringDeleteLeadingChar(exponent_mag);
|
10025 |
|
10026 |
if (strlen(exponent_mag) > 3)
|
10027 |
asFatal("floating-point exponent magnitude too large");
|
10028 |
|
10029 |
if (strlen(exponent_mag))
|
10030 |
sscanf(exponent_mag, "%d", &effective_exponent);
|
10031 |
|
10032 |
if (e_sign == '-')
|
10033 |
effective_exponent = -effective_exponent;
|
10034 |
|
10035 |
/* If there was a decimal point but no digits before or no digits
|
10036 |
** after, this is an error.
|
10037 |
*/
|
10038 |
if (decimal_found && (!strlen(before_decimal) || !strlen(after_decimal)))
|
10039 |
asFatal("improper floating-point mantissa");
|
10040 |
|
10041 |
/* If there were no digits at all, this is an error */
|
10042 |
if (!strlen(before_decimal) && !strlen(after_decimal))
|
10043 |
asFatal("missing floating-point mantissa");
|
10044 |
|
10045 |
/* Concatenate the before decimal and after decimal
|
10046 |
** parts.
|
10047 |
*/
|
10048 |
concat_mantissa = maMalloc((sizeof(char)) * (strlen(before_decimal) + strlen(after_decimal) + 1));
|
10049 |
strcpy(concat_mantissa, before_decimal);
|
10050 |
strcat(concat_mantissa, after_decimal);
|
10051 |
|
10052 |
/* Delete all leading zeroes. */
|
10053 |
while (concat_mantissa[0] == '0')
|
10054 |
ddStringDeleteLeadingChar(concat_mantissa);
|
10055 |
|
10056 |
/* If we've depleted the concatenated string, then
|
10057 |
** there are two possibilities. Either the number is zero,
|
10058 |
** or there is an error of a '-' sign was specified.
|
10059 |
*/
|
10060 |
if (!strlen(concat_mantissa))
|
10061 |
{
|
10062 |
if (is_neg)
|
10063 |
{
|
10064 |
asFatal("zero cannot be negated");
|
10065 |
}
|
10066 |
else
|
10067 |
{
|
10068 |
siSetToLong(&h_raw, 0);
|
10069 |
siSetToLong(&k_raw, 1);
|
10070 |
goto float_parsing_end;
|
10071 |
}
|
10072 |
}
|
10073 |
|
10074 |
/* We start off believing that the exponent is the one given in the
|
10075 |
** exponent field. But we also need to adjust downward for the
|
10076 |
** number of digits after the decimal point.
|
10077 |
*/
|
10078 |
effective_exponent -= strlen(after_decimal);
|
10079 |
|
10080 |
/* We are now poised to resolve what we have into a
|
10081 |
** rational number. Assign the concatenated string
|
10082 |
** to h_raw, and 1 to k_raw. For each negative
|
10083 |
** count in the exponent, we multiply the denominator
|
10084 |
** by 10. For each postive count in the exponent,
|
10085 |
** we multiply the numerator by 10.
|
10086 |
*/
|
10087 |
if (strlen(concat_mantissa) > INPUT_INTEGER_MAX_DIGITS)
|
10088 |
{
|
10089 |
asFatal("floating-point mantissa too long");
|
10090 |
}
|
10091 |
|
10092 |
ddStringReverse(concat_mantissa);
|
10093 |
strcpy(h_raw->digits, concat_mantissa);
|
10094 |
h_raw->len = strlen(h_raw->digits);
|
10095 |
h_raw->neg = is_neg;
|
10096 |
|
10097 |
siSetToLong(&k_raw, 1);
|
10098 |
siSetToLong(&si_temp1, 10);
|
10099 |
|
10100 |
while (effective_exponent)
|
10101 |
{
|
10102 |
if (effective_exponent < 0)
|
10103 |
{
|
10104 |
siUnrestrictedMultiplication(&k_raw, &si_temp1, &si_temp2);
|
10105 |
if (si_temp2->nan || (si_temp2->len > INPUT_INTEGER_MAX_DIGITS))
|
10106 |
asFatal("floating-point number magnitude too small");
|
10107 |
siCopy(&si_temp2, &k_raw);
|
10108 |
effective_exponent++;
|
10109 |
}
|
10110 |
else
|
10111 |
{
|
10112 |
siUnrestrictedMultiplication(&h_raw, &si_temp1, &si_temp2);
|
10113 |
if (si_temp2->nan || (si_temp2->len > INPUT_INTEGER_MAX_DIGITS))
|
10114 |
asFatal("floating-point number magnitude too large");
|
10115 |
siCopy(&si_temp2, &h_raw);
|
10116 |
effective_exponent--;
|
10117 |
}
|
10118 |
}
|
10119 |
|
10120 |
float_parsing_end: ;
|
10121 |
/* Print out information for debugging. */
|
10122 |
#if 0
|
10123 |
if (before_decimal)
|
10124 |
printf("before_decimal: %s\n", before_decimal);
|
10125 |
else
|
10126 |
printf("before_decimal: NULL\n");
|
10127 |
|
10128 |
printf("decimal_found: %d\n", decimal_found);
|
10129 |
|
10130 |
if (after_decimal)
|
10131 |
printf("after_decimal: %s\n", after_decimal);
|
10132 |
else
|
10133 |
printf("after_decimal: NULL\n");
|
10134 |
|
10135 |
printf("e_found: %d\n", e_found);
|
10136 |
|
10137 |
printf("e_sign: %c\n", e_sign);
|
10138 |
|
10139 |
if (exponent_mag)
|
10140 |
printf("exponent_mag: %s\n", exponent_mag);
|
10141 |
else
|
10142 |
printf("exponent_mag: NULL\n");
|
10143 |
|
10144 |
if (concat_mantissa)
|
10145 |
printf("concat_mantissa: %s\n", concat_mantissa);
|
10146 |
else
|
10147 |
printf("concat_mantissa: NULL\n");
|
10148 |
#endif
|
10149 |
|
10150 |
/* Free all of the memory that was potentially allocated.
|
10151 |
*/
|
10152 |
if (before_decimal)
|
10153 |
maFree(before_decimal);
|
10154 |
if (after_decimal)
|
10155 |
maFree(after_decimal);
|
10156 |
if (exponent_mag)
|
10157 |
maFree(exponent_mag);
|
10158 |
if (concat_mantissa)
|
10159 |
maFree(concat_mantissa);
|
10160 |
}
|
10161 |
|
10162 |
/* At this point h_raw and k_raw contain a viable rational number. Now
|
10163 |
** we need to bring it into a normalized form. This involves these steps.
|
10164 |
**
|
10165 |
** a)If the number specified was negative, the rational number must
|
10166 |
** have a neg numerator and pos denominator (this is done for us earlier).
|
10167 |
**
|
10168 |
** b)If the number is zero, the canonical form of 0 must be used.
|
10169 |
**
|
10170 |
** c)If the number is actually an integer, it must be stored in that
|
10171 |
** form (NULL denominator SI).
|
10172 |
**
|
10173 |
** d)Any gcd() must be factored out.
|
10174 |
*/
|
10175 |
/* The zero test first. */
|
10176 |
if (!(h_raw->len))
|
10177 |
{
|
10178 |
siSetToLong(&h_canonical, 0);
|
10179 |
siDestroy(&k_canonical);
|
10180 |
}
|
10181 |
else
|
10182 |
{
|
10183 |
/* The number is not zero. Remove any gcd(). This will have the added
|
10184 |
** benefit of identifying any integers easily.
|
10185 |
*/
|
10186 |
siCopy(&h_raw, &si_temp1);
|
10187 |
siCopy(&k_raw, &si_temp2);
|
10188 |
si_temp1->neg = FALSE;
|
10189 |
siGcd(&si_temp1, &si_temp2, &si_temp3);
|
10190 |
|
10191 |
#if 0
|
10192 |
siDump(&si_temp3, "gcd");
|
10193 |
#endif
|
10194 |
|
10195 |
siUnrestrictedDivision(&h_raw, &si_temp3, &h_canonical, &si_temp4);
|
10196 |
siUnrestrictedDivision(&k_raw, &si_temp3, &k_canonical, &si_temp4);
|
10197 |
|
10198 |
/* The gcd is removed. If the denominator is "1", trash the denominator.
|
10199 |
*/
|
10200 |
if (!siCompare(&constant_1, &k_canonical))
|
10201 |
{
|
10202 |
siDestroy(&k_canonical);
|
10203 |
}
|
10204 |
}
|
10205 |
|
10206 |
/* Assign the raw values and canonical values to the four variables involved.
|
10207 |
** Must NULL any moved pointers to prevent a subsequent FREE of something that
|
10208 |
** now does not belong to us.
|
10209 |
*/
|
10210 |
par_block.pars[i].raw_numerator = h_raw;
|
10211 |
h_raw = NULL;
|
10212 |
par_block.pars[i].raw_denominator = k_raw;
|
10213 |
k_raw = NULL;
|
10214 |
par_block.pars[i].canonical_numerator = h_canonical;
|
10215 |
h_canonical = NULL;
|
10216 |
par_block.pars[i].canonical_denominator = k_canonical;
|
10217 |
k_canonical = NULL;
|
10218 |
|
10219 |
/* Now set the ftype. This is easy to determine. The sign comes from the
|
10220 |
** canonical numerator, and the type comes from the NULLness of the
|
10221 |
** canonical denominator.
|
10222 |
*/
|
10223 |
if (par_block.pars[i].canonical_numerator->neg)
|
10224 |
{
|
10225 |
/* Neg */
|
10226 |
if (par_block.pars[i].canonical_denominator)
|
10227 |
{
|
10228 |
/* Rational number negative */
|
10229 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_RATNEG;
|
10230 |
}
|
10231 |
else
|
10232 |
{
|
10233 |
/* Integral */
|
10234 |
if (par_block.pars[i].canonical_numerator->len)
|
10235 |
{
|
10236 |
/* Integer negative. */
|
10237 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_INTNEG;
|
10238 |
}
|
10239 |
else
|
10240 |
{
|
10241 |
/* Invalid case. */
|
10242 |
asAssert(FALSE, __LINE__);
|
10243 |
}
|
10244 |
}
|
10245 |
}
|
10246 |
else
|
10247 |
{
|
10248 |
/* Pos */
|
10249 |
if (par_block.pars[i].canonical_denominator)
|
10250 |
{
|
10251 |
/* Rational number positive */
|
10252 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_RATPOS;
|
10253 |
}
|
10254 |
else
|
10255 |
{
|
10256 |
/* Integral */
|
10257 |
if (par_block.pars[i].canonical_numerator->len)
|
10258 |
{
|
10259 |
/* Integer positive */
|
10260 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_INTPOS;
|
10261 |
}
|
10262 |
else
|
10263 |
{
|
10264 |
/* Integer zero. */
|
10265 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_INTZERO;
|
10266 |
}
|
10267 |
}
|
10268 |
}
|
10269 |
|
10270 |
/* Destroy all of the temporary synthetic integers that were not
|
10271 |
** otherwise destroyed or reassigned.
|
10272 |
*/
|
10273 |
if (constant_1)
|
10274 |
siDestroy(&constant_1);
|
10275 |
if (h_raw)
|
10276 |
siDestroy(&h_raw);
|
10277 |
if (k_raw)
|
10278 |
siDestroy(&k_raw);
|
10279 |
if (h_canonical)
|
10280 |
siDestroy(&h_canonical);
|
10281 |
if (k_canonical)
|
10282 |
siDestroy(&k_canonical);
|
10283 |
if (si_temp1)
|
10284 |
siDestroy(&si_temp1);
|
10285 |
if (si_temp2)
|
10286 |
siDestroy(&si_temp2);
|
10287 |
if (si_temp3)
|
10288 |
siDestroy(&si_temp3);
|
10289 |
if (si_temp4)
|
10290 |
siDestroy(&si_temp4);
|
10291 |
|
10292 |
/* Print out diagnostic information */
|
10293 |
#if 0
|
10294 |
if(par_block.pars[i].raw_numerator)
|
10295 |
siDump(&(par_block.pars[i].raw_numerator), "raw_num");
|
10296 |
else
|
10297 |
printf("raw_num is NULL\n");
|
10298 |
|
10299 |
if(par_block.pars[i].raw_denominator)
|
10300 |
siDump(&(par_block.pars[i].raw_denominator), "raw_den");
|
10301 |
else
|
10302 |
printf("raw_den is NULL\n");
|
10303 |
|
10304 |
if(par_block.pars[i].canonical_numerator)
|
10305 |
siDump(&(par_block.pars[i].canonical_numerator), "can_num");
|
10306 |
else
|
10307 |
printf("can_num is NULL\n");
|
10308 |
|
10309 |
if(par_block.pars[i].canonical_denominator)
|
10310 |
siDump(&(par_block.pars[i].canonical_denominator), "can_den");
|
10311 |
else
|
10312 |
printf("can_den is NULL\n");
|
10313 |
|
10314 |
printf("ftype is : %d\n", par_block.pars[i].ftype);
|
10315 |
#endif
|
10316 |
}
|
10317 |
|
10318 |
|
10319 |
/****************************************************************************/
|
10320 |
/* ipParseAsSimpleInteger(): */
|
10321 |
/*--------------------------------------------------------------------------*/
|
10322 |
/* DESCRIPTION */
|
10323 |
/* Attempts to parse a string (subscript in par_block passed) as a */
|
10324 |
/* simple integer. Looks for errors and fills in the raw integer. There */
|
10325 |
/* isn't much to think about with a raw integer, so fills in ftype. */
|
10326 |
/****************************************************************************/
|
10327 |
void ipParseAsSimpleInteger(int i)
|
10328 |
{
|
10329 |
int int_is_neg = FALSE;
|
10330 |
char *s;
|
10331 |
|
10332 |
/* Make sure the caller isn't doing anything silly. */
|
10333 |
asAssert(i >= 0, __LINE__);
|
10334 |
asAssert(i < MAX_CMDLINE_PARS, __LINE__);
|
10335 |
|
10336 |
s = par_block.pars[i].orig_string;
|
10337 |
|
10338 |
/* Process any leading '-' sign. */
|
10339 |
if (*s == '-')
|
10340 |
{
|
10341 |
s++;
|
10342 |
int_is_neg = TRUE;
|
10343 |
}
|
10344 |
|
10345 |
/* The remainder of the string must a)exist, and b)contain only digits.
|
10346 |
*/
|
10347 |
if (!(*s))
|
10348 |
asFatal("bad parameter while expecting simple integer");
|
10349 |
|
10350 |
if (!ddStringContainsOnly(s, "0123456789"))
|
10351 |
asFatal("unexpected non-digit character while expecting simple integer");
|
10352 |
|
10353 |
/* If there is a leading zero, that must be the only character, and then
|
10354 |
** we can know we have zero.
|
10355 |
*/
|
10356 |
if (*s == '0')
|
10357 |
{
|
10358 |
if (s[1])
|
10359 |
asFatal("leading zeroes not allowed on integers");
|
10360 |
|
10361 |
if (int_is_neg)
|
10362 |
asFatal("can't negate zero");
|
10363 |
|
10364 |
/* Beavis, we have a zero. Form it.
|
10365 |
*/
|
10366 |
siCreate(&(par_block.pars[i].raw_numerator));
|
10367 |
/* Zero is created by default, so no need to go further.
|
10368 |
*/
|
10369 |
}
|
10370 |
else
|
10371 |
{
|
10372 |
/* String contains a non-zero integer, which may or may not be
|
10373 |
** negated. We know it contains only digits and no leading
|
10374 |
** 0.
|
10375 |
*/
|
10376 |
if (strlen(s) > INPUT_INTEGER_MAX_DIGITS)
|
10377 |
asFatal("input integer too long");
|
10378 |
|
10379 |
/* If we're here, we're clean. The string is ready to go as is,
|
10380 |
** except the order must be reversed.
|
10381 |
*/
|
10382 |
siCreate(&(par_block.pars[i].raw_numerator));
|
10383 |
par_block.pars[i].raw_numerator->neg = int_is_neg;
|
10384 |
strcpy(par_block.pars[i].raw_numerator->digits, s);
|
10385 |
par_block.pars[i].raw_numerator->len
|
10386 |
= strlen(par_block.pars[i].raw_numerator->digits);
|
10387 |
|
10388 |
{
|
10389 |
/* Reverse the digits. */
|
10390 |
int len, idx;
|
10391 |
char temp;
|
10392 |
|
10393 |
len = par_block.pars[i].raw_numerator->len;
|
10394 |
|
10395 |
for (idx=0; idx < (len/2); idx++)
|
10396 |
{
|
10397 |
temp = par_block.pars[i].raw_numerator->digits[idx];
|
10398 |
par_block.pars[i].raw_numerator->digits[idx]
|
10399 |
= par_block.pars[i].raw_numerator->digits[len - 1 - idx];
|
10400 |
par_block.pars[i].raw_numerator->digits[len - 1 - idx] = temp;
|
10401 |
}
|
10402 |
}
|
10403 |
}
|
10404 |
|
10405 |
/* Can also fill in the ftype field.
|
10406 |
*/
|
10407 |
if (!(par_block.pars[i].raw_numerator->len))
|
10408 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_INTZERO;
|
10409 |
else if (par_block.pars[i].raw_numerator->neg)
|
10410 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_INTNEG;
|
10411 |
else
|
10412 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_INTPOS;
|
10413 |
|
10414 |
/* In parsing a simple integer, there is no distinction between
|
10415 |
** the raw and the canonical forms. Still, should copy all over
|
10416 |
** to the canonical area.
|
10417 |
*/
|
10418 |
|
10419 |
siCreate(&(par_block.pars[i].canonical_numerator));
|
10420 |
siCopy(&(par_block.pars[i].raw_numerator), &(par_block.pars[i].canonical_numerator));
|
10421 |
|
10422 |
/* We know the denominator is NULL, because of the way the parameter block
|
10423 |
** is initialized.
|
10424 |
*/
|
10425 |
}
|
10426 |
|
10427 |
|
10428 |
/****************************************************************************/
|
10429 |
/* ipParseCommandLineParameters(): */
|
10430 |
/*--------------------------------------------------------------------------*/
|
10431 |
/* DESCRIPTION */
|
10432 |
/* Parses the command line parameters, as passed in the linked list. */
|
10433 |
/* This includes: */
|
10434 |
/* a)Checking for an excessive number of parameters. */
|
10435 |
/* b)Deciding on the type of the parameters, and converting them to */
|
10436 |
/* integers, rational numbers, etc. */
|
10437 |
/* c)Placing the quantities into canonical form. */
|
10438 |
/****************************************************************************/
|
10439 |
void ipParseCommandLineParameters
|
10440 |
(
|
10441 |
struct ipSimpleStringLlNodeStruct **ptr_to_callers_ptr
|
10442 |
)
|
10443 |
{
|
10444 |
/* Make sure the caller isn't doing anything silly. */
|
10445 |
asAssert(ptr_to_callers_ptr != NULL, __LINE__);
|
10446 |
|
10447 |
/* Completely initialize the array of command-line parameters.
|
10448 |
*/
|
10449 |
{
|
10450 |
int i;
|
10451 |
|
10452 |
par_block.n = 0;
|
10453 |
|
10454 |
for(i=0; i<MAX_CMDLINE_PARS; i++)
|
10455 |
{
|
10456 |
par_block.pars[i].ftype = CMDLINE_PAR_TYPE_UNASSIGNED;
|
10457 |
par_block.pars[i].orig_string = NULL;
|
10458 |
par_block.pars[i].raw_numerator = NULL;
|
10459 |
par_block.pars[i].raw_denominator = NULL;
|
10460 |
par_block.pars[i].canonical_numerator = NULL;
|
10461 |
par_block.pars[i].canonical_denominator = NULL;
|
10462 |
}
|
10463 |
}
|
10464 |
|
10465 |
/* Count up the total number of parameters. Crap out of too
|
10466 |
** many.
|
10467 |
*/
|
10468 |
{
|
10469 |
unsigned i;
|
10470 |
struct ipSimpleStringLlNodeStruct *p;
|
10471 |
char buf[100];
|
10472 |
|
10473 |
p = *ptr_to_callers_ptr;
|
10474 |
i = 0;
|
10475 |
|
10476 |
while(p)
|
10477 |
{
|
10478 |
p = p->next;
|
10479 |
i++;
|
10480 |
}
|
10481 |
|
10482 |
if (i > MAX_CMDLINE_PARS)
|
10483 |
{
|
10484 |
sprintf(buf, "too many cmd line pars, actual=%u, max=%u",
|
10485 |
i,
|
10486 |
MAX_CMDLINE_PARS);
|
10487 |
asFatal(buf);
|
10488 |
}
|
10489 |
}
|
10490 |
|
10491 |
/* Loop through the linked list of parameters, assigning each
|
10492 |
** string into the parameter block, and dismantle the linked list
|
10493 |
** in the process. The strings are kept.
|
10494 |
*/
|
10495 |
{
|
10496 |
struct ipSimpleStringLlNodeStruct *node_to_destroy;
|
10497 |
|
10498 |
par_block.n = 0;
|
10499 |
|
10500 |
while(*ptr_to_callers_ptr)
|
10501 |
{
|
10502 |
par_block.pars[par_block.n].orig_string = (*ptr_to_callers_ptr)->s;
|
10503 |
node_to_destroy = *ptr_to_callers_ptr;
|
10504 |
*ptr_to_callers_ptr = node_to_destroy->next;
|
10505 |
maFree(node_to_destroy);
|
10506 |
(par_block.n)++;
|
10507 |
}
|
10508 |
}
|
10509 |
|
10510 |
/* Parse the first parameter specially. The first parameter must be one of
|
10511 |
** the commands. There must be at least a command.
|
10512 |
*/
|
10513 |
{
|
10514 |
static struct
|
10515 |
{
|
10516 |
char *s;
|
10517 |
unsigned v;
|
10518 |
} cmdtable[] =
|
10519 |
{
|
10520 |
{"+", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS },
|
10521 |
{"-", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS },
|
10522 |
{"*", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES },
|
10523 |
{"/", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT },
|
10524 |
{"%", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO },
|
10525 |
{"**", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER },
|
10526 |
{"gcd", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_GCD },
|
10527 |
{"dap", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP },
|
10528 |
{"mind", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND },
|
10529 |
{"cf", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_CF },
|
10530 |
{"fn", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN },
|
10531 |
{"fndmax", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX },
|
10532 |
{"fab", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB },
|
10533 |
{"fabdmax", CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX }
|
10534 |
};
|
10535 |
unsigned i;
|
10536 |
char buf[100];
|
10537 |
|
10538 |
if (par_block.n < 1)
|
10539 |
asFatal("too few parameters--at least a command required");
|
10540 |
|
10541 |
/* Try to match the first parameter against the table above. */
|
10542 |
for (i=0; i<sizeof(cmdtable)/sizeof(cmdtable[0]); i++)
|
10543 |
{
|
10544 |
if (!strcmp(cmdtable[i].s, par_block.pars[0].orig_string))
|
10545 |
{
|
10546 |
break;
|
10547 |
}
|
10548 |
}
|
10549 |
|
10550 |
if (i == sizeof(cmdtable)/sizeof(cmdtable[0]))
|
10551 |
{
|
10552 |
sprintf(buf, "unknown command \"%s\"", par_block.pars[0].orig_string);
|
10553 |
asFatal(buf);
|
10554 |
}
|
10555 |
|
10556 |
par_block.pars[0].ftype = cmdtable[i].v;
|
10557 |
}
|
10558 |
|
10559 |
/* For the remaining parameters, parse them as numbers. The rules are
|
10560 |
** easy. If the number contains a '/', a '.', or an 'e', we must attempt
|
10561 |
** to parse it as a rational number, otherwise we attempt as an
|
10562 |
** integer.
|
10563 |
*/
|
10564 |
{
|
10565 |
int i;
|
10566 |
|
10567 |
for (i=1; i<par_block.n; i++)
|
10568 |
{
|
10569 |
if (ddStringContains(par_block.pars[i].orig_string, "e/."))
|
10570 |
{
|
10571 |
/* Attempt to parse as a rational number. */
|
10572 |
ipParseAsRationalNumber(i);
|
10573 |
}
|
10574 |
else
|
10575 |
{
|
10576 |
/* Attempt to parse as a simple integer. */
|
10577 |
ipParseAsSimpleInteger(i);
|
10578 |
}
|
10579 |
}
|
10580 |
}
|
10581 |
}
|
10582 |
|
10583 |
|
10584 |
/****************************************************************************/
|
10585 |
/* ipExecuteCommand(): */
|
10586 |
/*--------------------------------------------------------------------------*/
|
10587 |
/* DESCRIPTION */
|
10588 |
/* Matches a command against the built-in templates and executes a */
|
10589 |
/* command iff the inputs match a template that a command will accept. */
|
10590 |
/****************************************************************************/
|
10591 |
void ipExecuteCommand(void)
|
10592 |
{
|
10593 |
/* The structure below gives the "templates" for commands--what is allowed
|
10594 |
** to be passed as parameters, and how it maps to commands. In retrospect,
|
10595 |
** the system for classification could be optimized (it is necessary to
|
10596 |
** spell out too may cases), but the template-matching happens only
|
10597 |
** once.
|
10598 |
*/
|
10599 |
static struct
|
10600 |
{
|
10601 |
void (*fptr)(void);
|
10602 |
/* Function pointer to execute.
|
10603 |
*/
|
10604 |
int template[MAX_CMDLINE_PARS];
|
10605 |
/* Template to match.
|
10606 |
*/
|
10607 |
} cmd_templates[]
|
10608 |
=
|
10609 |
{
|
10610 |
/* Simple addition of two integers. Multiple templates are
|
10611 |
** required.
|
10612 |
*/
|
10613 |
{
|
10614 |
cfSimple2ParIntegerAddition,
|
10615 |
{
|
10616 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10617 |
CMDLINE_PAR_TYPE_INTNEG,
|
10618 |
CMDLINE_PAR_TYPE_INTNEG,
|
10619 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10620 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10621 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10622 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10623 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10624 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10625 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10626 |
}
|
10627 |
},
|
10628 |
{
|
10629 |
cfSimple2ParIntegerAddition,
|
10630 |
{
|
10631 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10632 |
CMDLINE_PAR_TYPE_INTNEG,
|
10633 |
CMDLINE_PAR_TYPE_INTZERO,
|
10634 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10635 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10636 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10637 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10638 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10639 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10640 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10641 |
}
|
10642 |
},
|
10643 |
{
|
10644 |
cfSimple2ParIntegerAddition,
|
10645 |
{
|
10646 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10647 |
CMDLINE_PAR_TYPE_INTNEG,
|
10648 |
CMDLINE_PAR_TYPE_INTPOS,
|
10649 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10650 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10651 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10652 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10653 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10654 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10655 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10656 |
}
|
10657 |
},
|
10658 |
{
|
10659 |
cfSimple2ParIntegerAddition,
|
10660 |
{
|
10661 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10662 |
CMDLINE_PAR_TYPE_INTZERO,
|
10663 |
CMDLINE_PAR_TYPE_INTNEG,
|
10664 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10665 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10666 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10667 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10668 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10669 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10670 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10671 |
}
|
10672 |
},
|
10673 |
{
|
10674 |
cfSimple2ParIntegerAddition,
|
10675 |
{
|
10676 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10677 |
CMDLINE_PAR_TYPE_INTZERO,
|
10678 |
CMDLINE_PAR_TYPE_INTZERO,
|
10679 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10680 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10681 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10682 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10683 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10684 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10685 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10686 |
}
|
10687 |
},
|
10688 |
{
|
10689 |
cfSimple2ParIntegerAddition,
|
10690 |
{
|
10691 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10692 |
CMDLINE_PAR_TYPE_INTZERO,
|
10693 |
CMDLINE_PAR_TYPE_INTPOS,
|
10694 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10695 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10696 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10697 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10698 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10699 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10700 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10701 |
}
|
10702 |
},
|
10703 |
{
|
10704 |
cfSimple2ParIntegerAddition,
|
10705 |
{
|
10706 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10707 |
CMDLINE_PAR_TYPE_INTPOS,
|
10708 |
CMDLINE_PAR_TYPE_INTNEG,
|
10709 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10710 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10711 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10712 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10713 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10714 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10715 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10716 |
}
|
10717 |
},
|
10718 |
{
|
10719 |
cfSimple2ParIntegerAddition,
|
10720 |
{
|
10721 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10722 |
CMDLINE_PAR_TYPE_INTPOS,
|
10723 |
CMDLINE_PAR_TYPE_INTZERO,
|
10724 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10725 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10726 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10727 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10728 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10729 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10730 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10731 |
}
|
10732 |
},
|
10733 |
{
|
10734 |
cfSimple2ParIntegerAddition,
|
10735 |
{
|
10736 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10737 |
CMDLINE_PAR_TYPE_INTPOS,
|
10738 |
CMDLINE_PAR_TYPE_INTPOS,
|
10739 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10740 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10741 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10742 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10743 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10744 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10745 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10746 |
}
|
10747 |
},
|
10748 |
/* Simple addition of two rational numbers.
|
10749 |
** Multiple templates are required.
|
10750 |
*/
|
10751 |
{
|
10752 |
cfSimple2ParRationalRationalAddition,
|
10753 |
{
|
10754 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10755 |
CMDLINE_PAR_TYPE_RATNEG,
|
10756 |
CMDLINE_PAR_TYPE_RATNEG,
|
10757 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10758 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10759 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10760 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10761 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10762 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10763 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10764 |
}
|
10765 |
},
|
10766 |
{
|
10767 |
cfSimple2ParRationalRationalAddition,
|
10768 |
{
|
10769 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10770 |
CMDLINE_PAR_TYPE_RATNEG,
|
10771 |
CMDLINE_PAR_TYPE_RATZERO,
|
10772 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10773 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10774 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10775 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10776 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10777 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10778 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10779 |
}
|
10780 |
},
|
10781 |
{
|
10782 |
cfSimple2ParRationalRationalAddition,
|
10783 |
{
|
10784 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10785 |
CMDLINE_PAR_TYPE_RATNEG,
|
10786 |
CMDLINE_PAR_TYPE_RATPOS,
|
10787 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10788 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10789 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10790 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10791 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10792 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10793 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10794 |
}
|
10795 |
},
|
10796 |
{
|
10797 |
cfSimple2ParRationalRationalAddition,
|
10798 |
{
|
10799 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10800 |
CMDLINE_PAR_TYPE_RATZERO,
|
10801 |
CMDLINE_PAR_TYPE_RATNEG,
|
10802 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10803 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10804 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10805 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10806 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10807 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10808 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10809 |
}
|
10810 |
},
|
10811 |
{
|
10812 |
cfSimple2ParRationalRationalAddition,
|
10813 |
{
|
10814 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10815 |
CMDLINE_PAR_TYPE_RATZERO,
|
10816 |
CMDLINE_PAR_TYPE_RATZERO,
|
10817 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10818 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10819 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10820 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10821 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10822 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10823 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10824 |
}
|
10825 |
},
|
10826 |
{
|
10827 |
cfSimple2ParRationalRationalAddition,
|
10828 |
{
|
10829 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10830 |
CMDLINE_PAR_TYPE_RATZERO,
|
10831 |
CMDLINE_PAR_TYPE_RATPOS,
|
10832 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10833 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10834 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10835 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10836 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10837 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10838 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10839 |
}
|
10840 |
},
|
10841 |
{
|
10842 |
cfSimple2ParRationalRationalAddition,
|
10843 |
{
|
10844 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10845 |
CMDLINE_PAR_TYPE_RATPOS,
|
10846 |
CMDLINE_PAR_TYPE_RATNEG,
|
10847 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10848 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10849 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10850 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10851 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10852 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10853 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10854 |
}
|
10855 |
},
|
10856 |
{
|
10857 |
cfSimple2ParRationalRationalAddition,
|
10858 |
{
|
10859 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10860 |
CMDLINE_PAR_TYPE_RATPOS,
|
10861 |
CMDLINE_PAR_TYPE_RATZERO,
|
10862 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10863 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10864 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10865 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10866 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10867 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10868 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10869 |
}
|
10870 |
},
|
10871 |
{
|
10872 |
cfSimple2ParRationalRationalAddition,
|
10873 |
{
|
10874 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10875 |
CMDLINE_PAR_TYPE_RATPOS,
|
10876 |
CMDLINE_PAR_TYPE_RATPOS,
|
10877 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10878 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10879 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10880 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10881 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10882 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10883 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10884 |
}
|
10885 |
},
|
10886 |
{
|
10887 |
cfSimple2ParRationalRationalAddition,
|
10888 |
{
|
10889 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10890 |
CMDLINE_PAR_TYPE_INTNEG,
|
10891 |
CMDLINE_PAR_TYPE_RATNEG,
|
10892 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10893 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10894 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10895 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10896 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10897 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10898 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10899 |
}
|
10900 |
},
|
10901 |
{
|
10902 |
cfSimple2ParRationalRationalAddition,
|
10903 |
{
|
10904 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10905 |
CMDLINE_PAR_TYPE_INTNEG,
|
10906 |
CMDLINE_PAR_TYPE_RATZERO,
|
10907 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10908 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10909 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10910 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10911 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10912 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10913 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10914 |
}
|
10915 |
},
|
10916 |
{
|
10917 |
cfSimple2ParRationalRationalAddition,
|
10918 |
{
|
10919 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10920 |
CMDLINE_PAR_TYPE_INTNEG,
|
10921 |
CMDLINE_PAR_TYPE_RATPOS,
|
10922 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10923 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10924 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10925 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10926 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10927 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10928 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10929 |
}
|
10930 |
},
|
10931 |
{
|
10932 |
cfSimple2ParRationalRationalAddition,
|
10933 |
{
|
10934 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10935 |
CMDLINE_PAR_TYPE_INTZERO,
|
10936 |
CMDLINE_PAR_TYPE_RATNEG,
|
10937 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10938 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10939 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10940 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10941 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10942 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10943 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10944 |
}
|
10945 |
},
|
10946 |
{
|
10947 |
cfSimple2ParRationalRationalAddition,
|
10948 |
{
|
10949 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10950 |
CMDLINE_PAR_TYPE_INTZERO,
|
10951 |
CMDLINE_PAR_TYPE_RATZERO,
|
10952 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10953 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10954 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10955 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10956 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10957 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10958 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10959 |
}
|
10960 |
},
|
10961 |
{
|
10962 |
cfSimple2ParRationalRationalAddition,
|
10963 |
{
|
10964 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10965 |
CMDLINE_PAR_TYPE_INTZERO,
|
10966 |
CMDLINE_PAR_TYPE_RATPOS,
|
10967 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10968 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10969 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10970 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10971 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10972 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10973 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10974 |
}
|
10975 |
},
|
10976 |
{
|
10977 |
cfSimple2ParRationalRationalAddition,
|
10978 |
{
|
10979 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10980 |
CMDLINE_PAR_TYPE_INTPOS,
|
10981 |
CMDLINE_PAR_TYPE_RATNEG,
|
10982 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10983 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10984 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10985 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10986 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10987 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10988 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
10989 |
}
|
10990 |
},
|
10991 |
{
|
10992 |
cfSimple2ParRationalRationalAddition,
|
10993 |
{
|
10994 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
10995 |
CMDLINE_PAR_TYPE_INTPOS,
|
10996 |
CMDLINE_PAR_TYPE_RATZERO,
|
10997 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10998 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
10999 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11000 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11001 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11002 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11003 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11004 |
}
|
11005 |
},
|
11006 |
{
|
11007 |
cfSimple2ParRationalRationalAddition,
|
11008 |
{
|
11009 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11010 |
CMDLINE_PAR_TYPE_INTPOS,
|
11011 |
CMDLINE_PAR_TYPE_RATPOS,
|
11012 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11013 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11014 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11015 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11016 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11017 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11018 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11019 |
}
|
11020 |
},
|
11021 |
{
|
11022 |
cfSimple2ParRationalRationalAddition,
|
11023 |
{
|
11024 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11025 |
CMDLINE_PAR_TYPE_RATNEG,
|
11026 |
CMDLINE_PAR_TYPE_INTNEG,
|
11027 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11028 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11029 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11030 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11031 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11032 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11033 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11034 |
}
|
11035 |
},
|
11036 |
{
|
11037 |
cfSimple2ParRationalRationalAddition,
|
11038 |
{
|
11039 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11040 |
CMDLINE_PAR_TYPE_RATNEG,
|
11041 |
CMDLINE_PAR_TYPE_INTZERO,
|
11042 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11043 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11044 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11045 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11046 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11047 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11048 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11049 |
}
|
11050 |
},
|
11051 |
{
|
11052 |
cfSimple2ParRationalRationalAddition,
|
11053 |
{
|
11054 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11055 |
CMDLINE_PAR_TYPE_RATNEG,
|
11056 |
CMDLINE_PAR_TYPE_INTPOS,
|
11057 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11058 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11059 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11060 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11061 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11062 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11063 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11064 |
}
|
11065 |
},
|
11066 |
{
|
11067 |
cfSimple2ParRationalRationalAddition,
|
11068 |
{
|
11069 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11070 |
CMDLINE_PAR_TYPE_RATZERO,
|
11071 |
CMDLINE_PAR_TYPE_INTNEG,
|
11072 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11073 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11074 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11075 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11076 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11077 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11078 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11079 |
}
|
11080 |
},
|
11081 |
{
|
11082 |
cfSimple2ParRationalRationalAddition,
|
11083 |
{
|
11084 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11085 |
CMDLINE_PAR_TYPE_RATZERO,
|
11086 |
CMDLINE_PAR_TYPE_INTZERO,
|
11087 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11088 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11089 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11090 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11091 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11092 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11093 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11094 |
}
|
11095 |
},
|
11096 |
{
|
11097 |
cfSimple2ParRationalRationalAddition,
|
11098 |
{
|
11099 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11100 |
CMDLINE_PAR_TYPE_RATZERO,
|
11101 |
CMDLINE_PAR_TYPE_INTPOS,
|
11102 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11103 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11104 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11105 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11106 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11107 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11108 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11109 |
}
|
11110 |
},
|
11111 |
{
|
11112 |
cfSimple2ParRationalRationalAddition,
|
11113 |
{
|
11114 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11115 |
CMDLINE_PAR_TYPE_RATPOS,
|
11116 |
CMDLINE_PAR_TYPE_INTNEG,
|
11117 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11118 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11119 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11120 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11121 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11122 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11123 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11124 |
}
|
11125 |
},
|
11126 |
{
|
11127 |
cfSimple2ParRationalRationalAddition,
|
11128 |
{
|
11129 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11130 |
CMDLINE_PAR_TYPE_RATPOS,
|
11131 |
CMDLINE_PAR_TYPE_INTZERO,
|
11132 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11133 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11134 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11135 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11136 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11137 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11138 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11139 |
}
|
11140 |
},
|
11141 |
{
|
11142 |
cfSimple2ParRationalRationalAddition,
|
11143 |
{
|
11144 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_PLUS,
|
11145 |
CMDLINE_PAR_TYPE_RATPOS,
|
11146 |
CMDLINE_PAR_TYPE_INTPOS,
|
11147 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11148 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11149 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11150 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11151 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11152 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11153 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11154 |
}
|
11155 |
},
|
11156 |
/* Simple subtraction of two integers. Multiple templates are
|
11157 |
** required.
|
11158 |
*/
|
11159 |
{
|
11160 |
cfSimple2ParIntegerSubtraction,
|
11161 |
{
|
11162 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11163 |
CMDLINE_PAR_TYPE_INTNEG,
|
11164 |
CMDLINE_PAR_TYPE_INTNEG,
|
11165 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11166 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11167 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11168 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11169 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11170 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11171 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11172 |
}
|
11173 |
},
|
11174 |
{
|
11175 |
cfSimple2ParIntegerSubtraction,
|
11176 |
{
|
11177 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11178 |
CMDLINE_PAR_TYPE_INTNEG,
|
11179 |
CMDLINE_PAR_TYPE_INTZERO,
|
11180 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11181 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11182 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11183 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11184 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11185 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11186 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11187 |
}
|
11188 |
},
|
11189 |
{
|
11190 |
cfSimple2ParIntegerSubtraction,
|
11191 |
{
|
11192 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11193 |
CMDLINE_PAR_TYPE_INTNEG,
|
11194 |
CMDLINE_PAR_TYPE_INTPOS,
|
11195 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11196 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11197 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11198 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11199 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11200 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11201 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11202 |
}
|
11203 |
},
|
11204 |
{
|
11205 |
cfSimple2ParIntegerSubtraction,
|
11206 |
{
|
11207 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11208 |
CMDLINE_PAR_TYPE_INTZERO,
|
11209 |
CMDLINE_PAR_TYPE_INTNEG,
|
11210 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11211 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11212 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11213 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11214 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11215 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11216 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11217 |
}
|
11218 |
},
|
11219 |
{
|
11220 |
cfSimple2ParIntegerSubtraction,
|
11221 |
{
|
11222 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11223 |
CMDLINE_PAR_TYPE_INTZERO,
|
11224 |
CMDLINE_PAR_TYPE_INTZERO,
|
11225 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11226 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11227 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11228 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11229 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11230 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11231 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11232 |
}
|
11233 |
},
|
11234 |
{
|
11235 |
cfSimple2ParIntegerSubtraction,
|
11236 |
{
|
11237 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11238 |
CMDLINE_PAR_TYPE_INTZERO,
|
11239 |
CMDLINE_PAR_TYPE_INTPOS,
|
11240 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11241 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11242 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11243 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11244 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11245 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11246 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11247 |
}
|
11248 |
},
|
11249 |
{
|
11250 |
cfSimple2ParIntegerSubtraction,
|
11251 |
{
|
11252 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11253 |
CMDLINE_PAR_TYPE_INTPOS,
|
11254 |
CMDLINE_PAR_TYPE_INTNEG,
|
11255 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11256 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11257 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11258 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11259 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11260 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11261 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11262 |
}
|
11263 |
},
|
11264 |
{
|
11265 |
cfSimple2ParIntegerSubtraction,
|
11266 |
{
|
11267 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11268 |
CMDLINE_PAR_TYPE_INTPOS,
|
11269 |
CMDLINE_PAR_TYPE_INTZERO,
|
11270 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11271 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11272 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11273 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11274 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11275 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11276 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11277 |
}
|
11278 |
},
|
11279 |
{
|
11280 |
cfSimple2ParIntegerSubtraction,
|
11281 |
{
|
11282 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11283 |
CMDLINE_PAR_TYPE_INTPOS,
|
11284 |
CMDLINE_PAR_TYPE_INTPOS,
|
11285 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11286 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11287 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11288 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11289 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11290 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11291 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11292 |
}
|
11293 |
},
|
11294 |
/* Simple subtraction of two rational numbers.
|
11295 |
** Multiple templates are required.
|
11296 |
*/
|
11297 |
{
|
11298 |
cfSimple2ParRationalRationalSubtraction,
|
11299 |
{
|
11300 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11301 |
CMDLINE_PAR_TYPE_RATNEG,
|
11302 |
CMDLINE_PAR_TYPE_RATNEG,
|
11303 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11304 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11305 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11306 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11307 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11308 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11309 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11310 |
}
|
11311 |
},
|
11312 |
{
|
11313 |
cfSimple2ParRationalRationalSubtraction,
|
11314 |
{
|
11315 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11316 |
CMDLINE_PAR_TYPE_RATNEG,
|
11317 |
CMDLINE_PAR_TYPE_RATZERO,
|
11318 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11319 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11320 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11321 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11322 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11323 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11324 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11325 |
}
|
11326 |
},
|
11327 |
{
|
11328 |
cfSimple2ParRationalRationalSubtraction,
|
11329 |
{
|
11330 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11331 |
CMDLINE_PAR_TYPE_RATNEG,
|
11332 |
CMDLINE_PAR_TYPE_RATPOS,
|
11333 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11334 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11335 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11336 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11337 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11338 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11339 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11340 |
}
|
11341 |
},
|
11342 |
{
|
11343 |
cfSimple2ParRationalRationalSubtraction,
|
11344 |
{
|
11345 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11346 |
CMDLINE_PAR_TYPE_RATZERO,
|
11347 |
CMDLINE_PAR_TYPE_RATNEG,
|
11348 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11349 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11350 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11351 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11352 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11353 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11354 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11355 |
}
|
11356 |
},
|
11357 |
{
|
11358 |
cfSimple2ParRationalRationalSubtraction,
|
11359 |
{
|
11360 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11361 |
CMDLINE_PAR_TYPE_RATZERO,
|
11362 |
CMDLINE_PAR_TYPE_RATZERO,
|
11363 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11364 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11365 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11366 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11367 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11368 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11369 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11370 |
}
|
11371 |
},
|
11372 |
{
|
11373 |
cfSimple2ParRationalRationalSubtraction,
|
11374 |
{
|
11375 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11376 |
CMDLINE_PAR_TYPE_RATZERO,
|
11377 |
CMDLINE_PAR_TYPE_RATPOS,
|
11378 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11379 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11380 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11381 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11382 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11383 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11384 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11385 |
}
|
11386 |
},
|
11387 |
{
|
11388 |
cfSimple2ParRationalRationalSubtraction,
|
11389 |
{
|
11390 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11391 |
CMDLINE_PAR_TYPE_RATPOS,
|
11392 |
CMDLINE_PAR_TYPE_RATNEG,
|
11393 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11394 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11395 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11396 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11397 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11398 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11399 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11400 |
}
|
11401 |
},
|
11402 |
{
|
11403 |
cfSimple2ParRationalRationalSubtraction,
|
11404 |
{
|
11405 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11406 |
CMDLINE_PAR_TYPE_RATPOS,
|
11407 |
CMDLINE_PAR_TYPE_RATZERO,
|
11408 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11409 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11410 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11411 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11412 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11413 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11414 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11415 |
}
|
11416 |
},
|
11417 |
{
|
11418 |
cfSimple2ParRationalRationalSubtraction,
|
11419 |
{
|
11420 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11421 |
CMDLINE_PAR_TYPE_RATPOS,
|
11422 |
CMDLINE_PAR_TYPE_RATPOS,
|
11423 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11424 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11425 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11426 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11427 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11428 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11429 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11430 |
}
|
11431 |
},
|
11432 |
{
|
11433 |
cfSimple2ParRationalRationalSubtraction,
|
11434 |
{
|
11435 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11436 |
CMDLINE_PAR_TYPE_INTNEG,
|
11437 |
CMDLINE_PAR_TYPE_RATNEG,
|
11438 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11439 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11440 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11441 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11442 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11443 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11444 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11445 |
}
|
11446 |
},
|
11447 |
{
|
11448 |
cfSimple2ParRationalRationalSubtraction,
|
11449 |
{
|
11450 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11451 |
CMDLINE_PAR_TYPE_INTNEG,
|
11452 |
CMDLINE_PAR_TYPE_RATZERO,
|
11453 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11454 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11455 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11456 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11457 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11458 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11459 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11460 |
}
|
11461 |
},
|
11462 |
{
|
11463 |
cfSimple2ParRationalRationalSubtraction,
|
11464 |
{
|
11465 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11466 |
CMDLINE_PAR_TYPE_INTNEG,
|
11467 |
CMDLINE_PAR_TYPE_RATPOS,
|
11468 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11469 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11470 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11471 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11472 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11473 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11474 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11475 |
}
|
11476 |
},
|
11477 |
{
|
11478 |
cfSimple2ParRationalRationalSubtraction,
|
11479 |
{
|
11480 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11481 |
CMDLINE_PAR_TYPE_INTZERO,
|
11482 |
CMDLINE_PAR_TYPE_RATNEG,
|
11483 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11484 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11485 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11486 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11487 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11488 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11489 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11490 |
}
|
11491 |
},
|
11492 |
{
|
11493 |
cfSimple2ParRationalRationalSubtraction,
|
11494 |
{
|
11495 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11496 |
CMDLINE_PAR_TYPE_INTZERO,
|
11497 |
CMDLINE_PAR_TYPE_RATZERO,
|
11498 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11499 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11500 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11501 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11502 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11503 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11504 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11505 |
}
|
11506 |
},
|
11507 |
{
|
11508 |
cfSimple2ParRationalRationalSubtraction,
|
11509 |
{
|
11510 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11511 |
CMDLINE_PAR_TYPE_INTZERO,
|
11512 |
CMDLINE_PAR_TYPE_RATPOS,
|
11513 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11514 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11515 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11516 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11517 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11518 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11519 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11520 |
}
|
11521 |
},
|
11522 |
{
|
11523 |
cfSimple2ParRationalRationalSubtraction,
|
11524 |
{
|
11525 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11526 |
CMDLINE_PAR_TYPE_INTPOS,
|
11527 |
CMDLINE_PAR_TYPE_RATNEG,
|
11528 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11529 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11530 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11531 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11532 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11533 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11534 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11535 |
}
|
11536 |
},
|
11537 |
{
|
11538 |
cfSimple2ParRationalRationalSubtraction,
|
11539 |
{
|
11540 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11541 |
CMDLINE_PAR_TYPE_INTPOS,
|
11542 |
CMDLINE_PAR_TYPE_RATZERO,
|
11543 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11544 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11545 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11546 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11547 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11548 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11549 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11550 |
}
|
11551 |
},
|
11552 |
{
|
11553 |
cfSimple2ParRationalRationalSubtraction,
|
11554 |
{
|
11555 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11556 |
CMDLINE_PAR_TYPE_INTPOS,
|
11557 |
CMDLINE_PAR_TYPE_RATPOS,
|
11558 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11559 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11560 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11561 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11562 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11563 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11564 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11565 |
}
|
11566 |
},
|
11567 |
{
|
11568 |
cfSimple2ParRationalRationalSubtraction,
|
11569 |
{
|
11570 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11571 |
CMDLINE_PAR_TYPE_RATNEG,
|
11572 |
CMDLINE_PAR_TYPE_INTNEG,
|
11573 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11574 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11575 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11576 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11577 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11578 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11579 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11580 |
}
|
11581 |
},
|
11582 |
{
|
11583 |
cfSimple2ParRationalRationalSubtraction,
|
11584 |
{
|
11585 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11586 |
CMDLINE_PAR_TYPE_RATNEG,
|
11587 |
CMDLINE_PAR_TYPE_INTZERO,
|
11588 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11589 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11590 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11591 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11592 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11593 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11594 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11595 |
}
|
11596 |
},
|
11597 |
{
|
11598 |
cfSimple2ParRationalRationalSubtraction,
|
11599 |
{
|
11600 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11601 |
CMDLINE_PAR_TYPE_RATNEG,
|
11602 |
CMDLINE_PAR_TYPE_INTPOS,
|
11603 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11604 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11605 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11606 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11607 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11608 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11609 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11610 |
}
|
11611 |
},
|
11612 |
{
|
11613 |
cfSimple2ParRationalRationalSubtraction,
|
11614 |
{
|
11615 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11616 |
CMDLINE_PAR_TYPE_RATZERO,
|
11617 |
CMDLINE_PAR_TYPE_INTNEG,
|
11618 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11619 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11620 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11621 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11622 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11623 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11624 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11625 |
}
|
11626 |
},
|
11627 |
{
|
11628 |
cfSimple2ParRationalRationalSubtraction,
|
11629 |
{
|
11630 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11631 |
CMDLINE_PAR_TYPE_RATZERO,
|
11632 |
CMDLINE_PAR_TYPE_INTZERO,
|
11633 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11634 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11635 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11636 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11637 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11638 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11639 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11640 |
}
|
11641 |
},
|
11642 |
{
|
11643 |
cfSimple2ParRationalRationalSubtraction,
|
11644 |
{
|
11645 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11646 |
CMDLINE_PAR_TYPE_RATZERO,
|
11647 |
CMDLINE_PAR_TYPE_INTPOS,
|
11648 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11649 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11650 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11651 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11652 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11653 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11654 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11655 |
}
|
11656 |
},
|
11657 |
{
|
11658 |
cfSimple2ParRationalRationalSubtraction,
|
11659 |
{
|
11660 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11661 |
CMDLINE_PAR_TYPE_RATPOS,
|
11662 |
CMDLINE_PAR_TYPE_INTNEG,
|
11663 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11664 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11665 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11666 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11667 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11668 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11669 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11670 |
}
|
11671 |
},
|
11672 |
{
|
11673 |
cfSimple2ParRationalRationalSubtraction,
|
11674 |
{
|
11675 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11676 |
CMDLINE_PAR_TYPE_RATPOS,
|
11677 |
CMDLINE_PAR_TYPE_INTZERO,
|
11678 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11679 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11680 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11681 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11682 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11683 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11684 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11685 |
}
|
11686 |
},
|
11687 |
{
|
11688 |
cfSimple2ParRationalRationalSubtraction,
|
11689 |
{
|
11690 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MINUS,
|
11691 |
CMDLINE_PAR_TYPE_RATPOS,
|
11692 |
CMDLINE_PAR_TYPE_INTPOS,
|
11693 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11694 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11695 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11696 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11697 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11698 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11699 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11700 |
}
|
11701 |
},
|
11702 |
/* Simple multiplication of two integers. Multiple templates are
|
11703 |
** required.
|
11704 |
*/
|
11705 |
{
|
11706 |
cfSimple2ParIntegerMultiplication,
|
11707 |
{
|
11708 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11709 |
CMDLINE_PAR_TYPE_INTNEG,
|
11710 |
CMDLINE_PAR_TYPE_INTNEG,
|
11711 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11712 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11713 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11714 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11715 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11716 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11717 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11718 |
}
|
11719 |
},
|
11720 |
{
|
11721 |
cfSimple2ParIntegerMultiplication,
|
11722 |
{
|
11723 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11724 |
CMDLINE_PAR_TYPE_INTNEG,
|
11725 |
CMDLINE_PAR_TYPE_INTZERO,
|
11726 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11727 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11728 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11729 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11730 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11731 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11732 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11733 |
}
|
11734 |
},
|
11735 |
{
|
11736 |
cfSimple2ParIntegerMultiplication,
|
11737 |
{
|
11738 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11739 |
CMDLINE_PAR_TYPE_INTNEG,
|
11740 |
CMDLINE_PAR_TYPE_INTPOS,
|
11741 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11742 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11743 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11744 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11745 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11746 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11747 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11748 |
}
|
11749 |
},
|
11750 |
{
|
11751 |
cfSimple2ParIntegerMultiplication,
|
11752 |
{
|
11753 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11754 |
CMDLINE_PAR_TYPE_INTZERO,
|
11755 |
CMDLINE_PAR_TYPE_INTNEG,
|
11756 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11757 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11758 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11759 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11760 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11761 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11762 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11763 |
}
|
11764 |
},
|
11765 |
{
|
11766 |
cfSimple2ParIntegerMultiplication,
|
11767 |
{
|
11768 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11769 |
CMDLINE_PAR_TYPE_INTZERO,
|
11770 |
CMDLINE_PAR_TYPE_INTZERO,
|
11771 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11772 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11773 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11774 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11775 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11776 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11777 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11778 |
}
|
11779 |
},
|
11780 |
{
|
11781 |
cfSimple2ParIntegerMultiplication,
|
11782 |
{
|
11783 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11784 |
CMDLINE_PAR_TYPE_INTZERO,
|
11785 |
CMDLINE_PAR_TYPE_INTPOS,
|
11786 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11787 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11788 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11789 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11790 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11791 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11792 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11793 |
}
|
11794 |
},
|
11795 |
{
|
11796 |
cfSimple2ParIntegerMultiplication,
|
11797 |
{
|
11798 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11799 |
CMDLINE_PAR_TYPE_INTPOS,
|
11800 |
CMDLINE_PAR_TYPE_INTNEG,
|
11801 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11802 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11803 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11804 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11805 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11806 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11807 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11808 |
}
|
11809 |
},
|
11810 |
{
|
11811 |
cfSimple2ParIntegerMultiplication,
|
11812 |
{
|
11813 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11814 |
CMDLINE_PAR_TYPE_INTPOS,
|
11815 |
CMDLINE_PAR_TYPE_INTZERO,
|
11816 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11817 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11818 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11819 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11820 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11821 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11822 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11823 |
}
|
11824 |
},
|
11825 |
{
|
11826 |
cfSimple2ParIntegerMultiplication,
|
11827 |
{
|
11828 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11829 |
CMDLINE_PAR_TYPE_INTPOS,
|
11830 |
CMDLINE_PAR_TYPE_INTPOS,
|
11831 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11832 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11833 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11834 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11835 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11836 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11837 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11838 |
}
|
11839 |
},
|
11840 |
/* Simple multiplication of two rational numbers.
|
11841 |
** Multiple templates are required.
|
11842 |
*/
|
11843 |
{
|
11844 |
cfSimple2ParRationalRationalMultiplication,
|
11845 |
{
|
11846 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11847 |
CMDLINE_PAR_TYPE_RATNEG,
|
11848 |
CMDLINE_PAR_TYPE_RATNEG,
|
11849 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11850 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11851 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11852 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11853 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11854 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11855 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11856 |
}
|
11857 |
},
|
11858 |
{
|
11859 |
cfSimple2ParRationalRationalMultiplication,
|
11860 |
{
|
11861 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11862 |
CMDLINE_PAR_TYPE_RATNEG,
|
11863 |
CMDLINE_PAR_TYPE_RATZERO,
|
11864 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11865 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11866 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11867 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11868 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11869 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11870 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11871 |
}
|
11872 |
},
|
11873 |
{
|
11874 |
cfSimple2ParRationalRationalMultiplication,
|
11875 |
{
|
11876 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11877 |
CMDLINE_PAR_TYPE_RATNEG,
|
11878 |
CMDLINE_PAR_TYPE_RATPOS,
|
11879 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11880 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11881 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11882 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11883 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11884 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11885 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11886 |
}
|
11887 |
},
|
11888 |
{
|
11889 |
cfSimple2ParRationalRationalMultiplication,
|
11890 |
{
|
11891 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11892 |
CMDLINE_PAR_TYPE_RATZERO,
|
11893 |
CMDLINE_PAR_TYPE_RATNEG,
|
11894 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11895 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11896 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11897 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11898 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11899 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11900 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11901 |
}
|
11902 |
},
|
11903 |
{
|
11904 |
cfSimple2ParRationalRationalMultiplication,
|
11905 |
{
|
11906 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11907 |
CMDLINE_PAR_TYPE_RATZERO,
|
11908 |
CMDLINE_PAR_TYPE_RATZERO,
|
11909 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11910 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11911 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11912 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11913 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11914 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11915 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11916 |
}
|
11917 |
},
|
11918 |
{
|
11919 |
cfSimple2ParRationalRationalMultiplication,
|
11920 |
{
|
11921 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11922 |
CMDLINE_PAR_TYPE_RATZERO,
|
11923 |
CMDLINE_PAR_TYPE_RATPOS,
|
11924 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11925 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11926 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11927 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11928 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11929 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11930 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11931 |
}
|
11932 |
},
|
11933 |
{
|
11934 |
cfSimple2ParRationalRationalMultiplication,
|
11935 |
{
|
11936 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11937 |
CMDLINE_PAR_TYPE_RATPOS,
|
11938 |
CMDLINE_PAR_TYPE_RATNEG,
|
11939 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11940 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11941 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11942 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11943 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11944 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11945 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11946 |
}
|
11947 |
},
|
11948 |
{
|
11949 |
cfSimple2ParRationalRationalMultiplication,
|
11950 |
{
|
11951 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11952 |
CMDLINE_PAR_TYPE_RATPOS,
|
11953 |
CMDLINE_PAR_TYPE_RATZERO,
|
11954 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11955 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11956 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11957 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11958 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11959 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11960 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11961 |
}
|
11962 |
},
|
11963 |
{
|
11964 |
cfSimple2ParRationalRationalMultiplication,
|
11965 |
{
|
11966 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11967 |
CMDLINE_PAR_TYPE_RATPOS,
|
11968 |
CMDLINE_PAR_TYPE_RATPOS,
|
11969 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11970 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11971 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11972 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11973 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11974 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11975 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11976 |
}
|
11977 |
},
|
11978 |
{
|
11979 |
cfSimple2ParRationalRationalMultiplication,
|
11980 |
{
|
11981 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11982 |
CMDLINE_PAR_TYPE_INTNEG,
|
11983 |
CMDLINE_PAR_TYPE_RATNEG,
|
11984 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11985 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11986 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11987 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11988 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11989 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
11990 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
11991 |
}
|
11992 |
},
|
11993 |
{
|
11994 |
cfSimple2ParRationalRationalMultiplication,
|
11995 |
{
|
11996 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
11997 |
CMDLINE_PAR_TYPE_INTNEG,
|
11998 |
CMDLINE_PAR_TYPE_RATZERO,
|
11999 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12000 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12001 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12002 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12003 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12004 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12005 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12006 |
}
|
12007 |
},
|
12008 |
{
|
12009 |
cfSimple2ParRationalRationalMultiplication,
|
12010 |
{
|
12011 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12012 |
CMDLINE_PAR_TYPE_INTNEG,
|
12013 |
CMDLINE_PAR_TYPE_RATPOS,
|
12014 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12015 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12016 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12017 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12018 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12019 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12020 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12021 |
}
|
12022 |
},
|
12023 |
{
|
12024 |
cfSimple2ParRationalRationalMultiplication,
|
12025 |
{
|
12026 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12027 |
CMDLINE_PAR_TYPE_INTZERO,
|
12028 |
CMDLINE_PAR_TYPE_RATNEG,
|
12029 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12030 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12031 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12032 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12033 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12034 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12035 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12036 |
}
|
12037 |
},
|
12038 |
{
|
12039 |
cfSimple2ParRationalRationalMultiplication,
|
12040 |
{
|
12041 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12042 |
CMDLINE_PAR_TYPE_INTZERO,
|
12043 |
CMDLINE_PAR_TYPE_RATZERO,
|
12044 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12045 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12046 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12047 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12048 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12049 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12050 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12051 |
}
|
12052 |
},
|
12053 |
{
|
12054 |
cfSimple2ParRationalRationalMultiplication,
|
12055 |
{
|
12056 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12057 |
CMDLINE_PAR_TYPE_INTZERO,
|
12058 |
CMDLINE_PAR_TYPE_RATPOS,
|
12059 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12060 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12061 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12062 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12063 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12064 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12065 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12066 |
}
|
12067 |
},
|
12068 |
{
|
12069 |
cfSimple2ParRationalRationalMultiplication,
|
12070 |
{
|
12071 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12072 |
CMDLINE_PAR_TYPE_INTPOS,
|
12073 |
CMDLINE_PAR_TYPE_RATNEG,
|
12074 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12075 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12076 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12077 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12078 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12079 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12080 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12081 |
}
|
12082 |
},
|
12083 |
{
|
12084 |
cfSimple2ParRationalRationalMultiplication,
|
12085 |
{
|
12086 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12087 |
CMDLINE_PAR_TYPE_INTPOS,
|
12088 |
CMDLINE_PAR_TYPE_RATZERO,
|
12089 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12090 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12091 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12092 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12093 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12094 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12095 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12096 |
}
|
12097 |
},
|
12098 |
{
|
12099 |
cfSimple2ParRationalRationalMultiplication,
|
12100 |
{
|
12101 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12102 |
CMDLINE_PAR_TYPE_INTPOS,
|
12103 |
CMDLINE_PAR_TYPE_RATPOS,
|
12104 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12105 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12106 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12107 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12108 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12109 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12110 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12111 |
}
|
12112 |
},
|
12113 |
{
|
12114 |
cfSimple2ParRationalRationalMultiplication,
|
12115 |
{
|
12116 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12117 |
CMDLINE_PAR_TYPE_RATNEG,
|
12118 |
CMDLINE_PAR_TYPE_INTNEG,
|
12119 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12120 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12121 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12122 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12123 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12124 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12125 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12126 |
}
|
12127 |
},
|
12128 |
{
|
12129 |
cfSimple2ParRationalRationalMultiplication,
|
12130 |
{
|
12131 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12132 |
CMDLINE_PAR_TYPE_RATNEG,
|
12133 |
CMDLINE_PAR_TYPE_INTZERO,
|
12134 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12135 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12136 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12137 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12138 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12139 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12140 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12141 |
}
|
12142 |
},
|
12143 |
{
|
12144 |
cfSimple2ParRationalRationalMultiplication,
|
12145 |
{
|
12146 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12147 |
CMDLINE_PAR_TYPE_RATNEG,
|
12148 |
CMDLINE_PAR_TYPE_INTPOS,
|
12149 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12150 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12151 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12152 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12153 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12154 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12155 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12156 |
}
|
12157 |
},
|
12158 |
{
|
12159 |
cfSimple2ParRationalRationalMultiplication,
|
12160 |
{
|
12161 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12162 |
CMDLINE_PAR_TYPE_RATZERO,
|
12163 |
CMDLINE_PAR_TYPE_INTNEG,
|
12164 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12165 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12166 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12167 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12168 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12169 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12170 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12171 |
}
|
12172 |
},
|
12173 |
{
|
12174 |
cfSimple2ParRationalRationalMultiplication,
|
12175 |
{
|
12176 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12177 |
CMDLINE_PAR_TYPE_RATZERO,
|
12178 |
CMDLINE_PAR_TYPE_INTZERO,
|
12179 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12180 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12181 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12182 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12183 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12184 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12185 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12186 |
}
|
12187 |
},
|
12188 |
{
|
12189 |
cfSimple2ParRationalRationalMultiplication,
|
12190 |
{
|
12191 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12192 |
CMDLINE_PAR_TYPE_RATZERO,
|
12193 |
CMDLINE_PAR_TYPE_INTPOS,
|
12194 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12195 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12196 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12197 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12198 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12199 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12200 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12201 |
}
|
12202 |
},
|
12203 |
{
|
12204 |
cfSimple2ParRationalRationalMultiplication,
|
12205 |
{
|
12206 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12207 |
CMDLINE_PAR_TYPE_RATPOS,
|
12208 |
CMDLINE_PAR_TYPE_INTNEG,
|
12209 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12210 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12211 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12212 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12213 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12214 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12215 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12216 |
}
|
12217 |
},
|
12218 |
{
|
12219 |
cfSimple2ParRationalRationalMultiplication,
|
12220 |
{
|
12221 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12222 |
CMDLINE_PAR_TYPE_RATPOS,
|
12223 |
CMDLINE_PAR_TYPE_INTZERO,
|
12224 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12225 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12226 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12227 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12228 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12229 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12230 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12231 |
}
|
12232 |
},
|
12233 |
{
|
12234 |
cfSimple2ParRationalRationalMultiplication,
|
12235 |
{
|
12236 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_TIMES,
|
12237 |
CMDLINE_PAR_TYPE_RATPOS,
|
12238 |
CMDLINE_PAR_TYPE_INTPOS,
|
12239 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12240 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12241 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12242 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12243 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12244 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12245 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12246 |
}
|
12247 |
},
|
12248 |
/* Simple exponentiation of two integers. Multiple templates are
|
12249 |
** required.
|
12250 |
*/
|
12251 |
{
|
12252 |
cfSimple2ParIntegerExponentiation,
|
12253 |
{
|
12254 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12255 |
CMDLINE_PAR_TYPE_INTNEG,
|
12256 |
CMDLINE_PAR_TYPE_INTZERO,
|
12257 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12258 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12259 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12260 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12261 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12262 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12263 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12264 |
}
|
12265 |
},
|
12266 |
{
|
12267 |
cfSimple2ParIntegerExponentiation,
|
12268 |
{
|
12269 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12270 |
CMDLINE_PAR_TYPE_INTNEG,
|
12271 |
CMDLINE_PAR_TYPE_INTPOS,
|
12272 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12273 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12274 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12275 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12276 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12277 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12278 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12279 |
}
|
12280 |
},
|
12281 |
{
|
12282 |
cfSimple2ParIntegerExponentiation,
|
12283 |
{
|
12284 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12285 |
CMDLINE_PAR_TYPE_INTZERO,
|
12286 |
CMDLINE_PAR_TYPE_INTPOS,
|
12287 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12288 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12289 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12290 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12291 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12292 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12293 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12294 |
}
|
12295 |
},
|
12296 |
{
|
12297 |
cfSimple2ParIntegerExponentiation,
|
12298 |
{
|
12299 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12300 |
CMDLINE_PAR_TYPE_INTPOS,
|
12301 |
CMDLINE_PAR_TYPE_INTZERO,
|
12302 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12303 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12304 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12305 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12306 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12307 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12308 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12309 |
}
|
12310 |
},
|
12311 |
{
|
12312 |
cfSimple2ParIntegerExponentiation,
|
12313 |
{
|
12314 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12315 |
CMDLINE_PAR_TYPE_INTPOS,
|
12316 |
CMDLINE_PAR_TYPE_INTPOS,
|
12317 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12318 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12319 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12320 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12321 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12322 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12323 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12324 |
}
|
12325 |
},
|
12326 |
/* Simple exponentiation of rational number to an
|
12327 |
** integer power. Multiple templates are
|
12328 |
** required.
|
12329 |
*/
|
12330 |
{
|
12331 |
cfSimple2ParIntegerExponentiationOfRational,
|
12332 |
{
|
12333 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12334 |
CMDLINE_PAR_TYPE_RATNEG,
|
12335 |
CMDLINE_PAR_TYPE_INTZERO,
|
12336 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12337 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12338 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12339 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12340 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12341 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12342 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12343 |
}
|
12344 |
},
|
12345 |
{
|
12346 |
cfSimple2ParIntegerExponentiationOfRational,
|
12347 |
{
|
12348 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12349 |
CMDLINE_PAR_TYPE_RATNEG,
|
12350 |
CMDLINE_PAR_TYPE_INTPOS,
|
12351 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12352 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12353 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12354 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12355 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12356 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12357 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12358 |
}
|
12359 |
},
|
12360 |
{
|
12361 |
cfSimple2ParIntegerExponentiationOfRational,
|
12362 |
{
|
12363 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12364 |
CMDLINE_PAR_TYPE_RATZERO, /* Can't happen because will
|
12365 |
** be converted to integer
|
12366 |
** zero, but no harm in
|
12367 |
** including in table.
|
12368 |
*/
|
12369 |
CMDLINE_PAR_TYPE_INTPOS,
|
12370 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12371 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12372 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12373 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12374 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12375 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12376 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12377 |
}
|
12378 |
},
|
12379 |
{
|
12380 |
cfSimple2ParIntegerExponentiationOfRational,
|
12381 |
{
|
12382 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12383 |
CMDLINE_PAR_TYPE_RATPOS,
|
12384 |
CMDLINE_PAR_TYPE_INTZERO,
|
12385 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12386 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12387 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12388 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12389 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12390 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12391 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12392 |
}
|
12393 |
},
|
12394 |
{
|
12395 |
cfSimple2ParIntegerExponentiationOfRational,
|
12396 |
{
|
12397 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_POWER,
|
12398 |
CMDLINE_PAR_TYPE_RATPOS,
|
12399 |
CMDLINE_PAR_TYPE_INTPOS,
|
12400 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12401 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12402 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12403 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12404 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12405 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12406 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12407 |
}
|
12408 |
},
|
12409 |
/* Simple division of two integers. Multiple templates are
|
12410 |
** required.
|
12411 |
*/
|
12412 |
{
|
12413 |
cfSimple2ParIntegerQuotient,
|
12414 |
{
|
12415 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12416 |
CMDLINE_PAR_TYPE_INTNEG,
|
12417 |
CMDLINE_PAR_TYPE_INTNEG,
|
12418 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12419 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12420 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12421 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12422 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12423 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12424 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12425 |
}
|
12426 |
},
|
12427 |
{
|
12428 |
cfSimple2ParIntegerQuotient,
|
12429 |
{
|
12430 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12431 |
CMDLINE_PAR_TYPE_INTNEG,
|
12432 |
CMDLINE_PAR_TYPE_INTZERO,
|
12433 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12434 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12435 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12436 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12437 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12438 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12439 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12440 |
}
|
12441 |
},
|
12442 |
{
|
12443 |
cfSimple2ParIntegerQuotient,
|
12444 |
{
|
12445 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12446 |
CMDLINE_PAR_TYPE_INTNEG,
|
12447 |
CMDLINE_PAR_TYPE_INTPOS,
|
12448 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12449 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12450 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12451 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12452 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12453 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12454 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12455 |
}
|
12456 |
},
|
12457 |
{
|
12458 |
cfSimple2ParIntegerQuotient,
|
12459 |
{
|
12460 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12461 |
CMDLINE_PAR_TYPE_INTZERO,
|
12462 |
CMDLINE_PAR_TYPE_INTNEG,
|
12463 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12464 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12465 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12466 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12467 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12468 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12469 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12470 |
}
|
12471 |
},
|
12472 |
{
|
12473 |
cfSimple2ParIntegerQuotient,
|
12474 |
{
|
12475 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12476 |
CMDLINE_PAR_TYPE_INTZERO,
|
12477 |
CMDLINE_PAR_TYPE_INTZERO,
|
12478 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12479 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12480 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12481 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12482 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12483 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12484 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12485 |
}
|
12486 |
},
|
12487 |
{
|
12488 |
cfSimple2ParIntegerQuotient,
|
12489 |
{
|
12490 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12491 |
CMDLINE_PAR_TYPE_INTZERO,
|
12492 |
CMDLINE_PAR_TYPE_INTPOS,
|
12493 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12494 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12495 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12496 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12497 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12498 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12499 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12500 |
}
|
12501 |
},
|
12502 |
{
|
12503 |
cfSimple2ParIntegerQuotient,
|
12504 |
{
|
12505 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12506 |
CMDLINE_PAR_TYPE_INTPOS,
|
12507 |
CMDLINE_PAR_TYPE_INTNEG,
|
12508 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12509 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12510 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12511 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12512 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12513 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12514 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12515 |
}
|
12516 |
},
|
12517 |
{
|
12518 |
cfSimple2ParIntegerQuotient,
|
12519 |
{
|
12520 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12521 |
CMDLINE_PAR_TYPE_INTPOS,
|
12522 |
CMDLINE_PAR_TYPE_INTZERO,
|
12523 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12524 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12525 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12526 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12527 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12528 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12529 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12530 |
}
|
12531 |
},
|
12532 |
{
|
12533 |
cfSimple2ParIntegerQuotient,
|
12534 |
{
|
12535 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12536 |
CMDLINE_PAR_TYPE_INTPOS,
|
12537 |
CMDLINE_PAR_TYPE_INTPOS,
|
12538 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12539 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12540 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12541 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12542 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12543 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12544 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12545 |
}
|
12546 |
},
|
12547 |
/* Simple modulo of two integers. Multiple templates are
|
12548 |
** required.
|
12549 |
*/
|
12550 |
{
|
12551 |
cfSimple2ParIntegerRemainder,
|
12552 |
{
|
12553 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12554 |
CMDLINE_PAR_TYPE_INTNEG,
|
12555 |
CMDLINE_PAR_TYPE_INTNEG,
|
12556 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12557 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12558 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12559 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12560 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12561 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12562 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12563 |
}
|
12564 |
},
|
12565 |
{
|
12566 |
cfSimple2ParIntegerRemainder,
|
12567 |
{
|
12568 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12569 |
CMDLINE_PAR_TYPE_INTNEG,
|
12570 |
CMDLINE_PAR_TYPE_INTZERO,
|
12571 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12572 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12573 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12574 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12575 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12576 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12577 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12578 |
}
|
12579 |
},
|
12580 |
{
|
12581 |
cfSimple2ParIntegerRemainder,
|
12582 |
{
|
12583 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12584 |
CMDLINE_PAR_TYPE_INTNEG,
|
12585 |
CMDLINE_PAR_TYPE_INTPOS,
|
12586 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12587 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12588 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12589 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12590 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12591 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12592 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12593 |
}
|
12594 |
},
|
12595 |
{
|
12596 |
cfSimple2ParIntegerRemainder,
|
12597 |
{
|
12598 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12599 |
CMDLINE_PAR_TYPE_INTZERO,
|
12600 |
CMDLINE_PAR_TYPE_INTNEG,
|
12601 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12602 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12603 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12604 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12605 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12606 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12607 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12608 |
}
|
12609 |
},
|
12610 |
{
|
12611 |
cfSimple2ParIntegerRemainder,
|
12612 |
{
|
12613 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12614 |
CMDLINE_PAR_TYPE_INTZERO,
|
12615 |
CMDLINE_PAR_TYPE_INTZERO,
|
12616 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12617 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12618 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12619 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12620 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12621 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12622 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12623 |
}
|
12624 |
},
|
12625 |
{
|
12626 |
cfSimple2ParIntegerRemainder,
|
12627 |
{
|
12628 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12629 |
CMDLINE_PAR_TYPE_INTZERO,
|
12630 |
CMDLINE_PAR_TYPE_INTPOS,
|
12631 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12632 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12633 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12634 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12635 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12636 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12637 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12638 |
}
|
12639 |
},
|
12640 |
{
|
12641 |
cfSimple2ParIntegerRemainder,
|
12642 |
{
|
12643 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12644 |
CMDLINE_PAR_TYPE_INTPOS,
|
12645 |
CMDLINE_PAR_TYPE_INTNEG,
|
12646 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12647 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12648 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12649 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12650 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12651 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12652 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12653 |
}
|
12654 |
},
|
12655 |
{
|
12656 |
cfSimple2ParIntegerRemainder,
|
12657 |
{
|
12658 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12659 |
CMDLINE_PAR_TYPE_INTPOS,
|
12660 |
CMDLINE_PAR_TYPE_INTZERO,
|
12661 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12662 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12663 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12664 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12665 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12666 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12667 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12668 |
}
|
12669 |
},
|
12670 |
{
|
12671 |
cfSimple2ParIntegerRemainder,
|
12672 |
{
|
12673 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MODULO,
|
12674 |
CMDLINE_PAR_TYPE_INTPOS,
|
12675 |
CMDLINE_PAR_TYPE_INTPOS,
|
12676 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12677 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12678 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12679 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12680 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12681 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12682 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12683 |
}
|
12684 |
},
|
12685 |
/* Simple division of two rational numbers.
|
12686 |
** Multiple templates are required.
|
12687 |
*/
|
12688 |
{
|
12689 |
cfSimple2ParRationalRationalQuotient,
|
12690 |
{
|
12691 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12692 |
CMDLINE_PAR_TYPE_RATNEG,
|
12693 |
CMDLINE_PAR_TYPE_RATNEG,
|
12694 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12695 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12696 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12697 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12698 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12699 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12700 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12701 |
}
|
12702 |
},
|
12703 |
{
|
12704 |
cfSimple2ParRationalRationalQuotient,
|
12705 |
{
|
12706 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12707 |
CMDLINE_PAR_TYPE_RATNEG,
|
12708 |
CMDLINE_PAR_TYPE_RATPOS,
|
12709 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12710 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12711 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12712 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12713 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12714 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12715 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12716 |
}
|
12717 |
},
|
12718 |
{
|
12719 |
cfSimple2ParRationalRationalQuotient,
|
12720 |
{
|
12721 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12722 |
CMDLINE_PAR_TYPE_RATZERO,
|
12723 |
CMDLINE_PAR_TYPE_RATNEG,
|
12724 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12725 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12726 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12727 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12728 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12729 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12730 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12731 |
}
|
12732 |
},
|
12733 |
{
|
12734 |
cfSimple2ParRationalRationalQuotient,
|
12735 |
{
|
12736 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12737 |
CMDLINE_PAR_TYPE_RATZERO,
|
12738 |
CMDLINE_PAR_TYPE_RATPOS,
|
12739 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12740 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12741 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12742 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12743 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12744 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12745 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12746 |
}
|
12747 |
},
|
12748 |
{
|
12749 |
cfSimple2ParRationalRationalQuotient,
|
12750 |
{
|
12751 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12752 |
CMDLINE_PAR_TYPE_RATPOS,
|
12753 |
CMDLINE_PAR_TYPE_RATNEG,
|
12754 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12755 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12756 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12757 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12758 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12759 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12760 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12761 |
}
|
12762 |
},
|
12763 |
{
|
12764 |
cfSimple2ParRationalRationalQuotient,
|
12765 |
{
|
12766 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12767 |
CMDLINE_PAR_TYPE_RATPOS,
|
12768 |
CMDLINE_PAR_TYPE_RATPOS,
|
12769 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12770 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12771 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12772 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12773 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12774 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12775 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12776 |
}
|
12777 |
},
|
12778 |
{
|
12779 |
cfSimple2ParRationalRationalQuotient,
|
12780 |
{
|
12781 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12782 |
CMDLINE_PAR_TYPE_INTNEG,
|
12783 |
CMDLINE_PAR_TYPE_RATNEG,
|
12784 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12785 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12786 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12787 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12788 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12789 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12790 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12791 |
}
|
12792 |
},
|
12793 |
{
|
12794 |
cfSimple2ParRationalRationalQuotient,
|
12795 |
{
|
12796 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12797 |
CMDLINE_PAR_TYPE_INTNEG,
|
12798 |
CMDLINE_PAR_TYPE_RATPOS,
|
12799 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12800 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12801 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12802 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12803 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12804 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12805 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12806 |
}
|
12807 |
},
|
12808 |
{
|
12809 |
cfSimple2ParRationalRationalQuotient,
|
12810 |
{
|
12811 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12812 |
CMDLINE_PAR_TYPE_INTZERO,
|
12813 |
CMDLINE_PAR_TYPE_RATNEG,
|
12814 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12815 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12816 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12817 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12818 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12819 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12820 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12821 |
}
|
12822 |
},
|
12823 |
{
|
12824 |
cfSimple2ParRationalRationalQuotient,
|
12825 |
{
|
12826 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12827 |
CMDLINE_PAR_TYPE_INTZERO,
|
12828 |
CMDLINE_PAR_TYPE_RATPOS,
|
12829 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12830 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12831 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12832 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12833 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12834 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12835 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12836 |
}
|
12837 |
},
|
12838 |
{
|
12839 |
cfSimple2ParRationalRationalQuotient,
|
12840 |
{
|
12841 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12842 |
CMDLINE_PAR_TYPE_INTPOS,
|
12843 |
CMDLINE_PAR_TYPE_RATNEG,
|
12844 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12845 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12846 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12847 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12848 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12849 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12850 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12851 |
}
|
12852 |
},
|
12853 |
{
|
12854 |
cfSimple2ParRationalRationalQuotient,
|
12855 |
{
|
12856 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12857 |
CMDLINE_PAR_TYPE_INTPOS,
|
12858 |
CMDLINE_PAR_TYPE_RATPOS,
|
12859 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12860 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12861 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12862 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12863 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12864 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12865 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12866 |
}
|
12867 |
},
|
12868 |
{
|
12869 |
cfSimple2ParRationalRationalQuotient,
|
12870 |
{
|
12871 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12872 |
CMDLINE_PAR_TYPE_RATNEG,
|
12873 |
CMDLINE_PAR_TYPE_INTNEG,
|
12874 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12875 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12876 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12877 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12878 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12879 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12880 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12881 |
}
|
12882 |
},
|
12883 |
{
|
12884 |
cfSimple2ParRationalRationalQuotient,
|
12885 |
{
|
12886 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12887 |
CMDLINE_PAR_TYPE_RATNEG,
|
12888 |
CMDLINE_PAR_TYPE_INTPOS,
|
12889 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12890 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12891 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12892 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12893 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12894 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12895 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12896 |
}
|
12897 |
},
|
12898 |
{
|
12899 |
cfSimple2ParRationalRationalQuotient,
|
12900 |
{
|
12901 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12902 |
CMDLINE_PAR_TYPE_RATZERO,
|
12903 |
CMDLINE_PAR_TYPE_INTNEG,
|
12904 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12905 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12906 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12907 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12908 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12909 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12910 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12911 |
}
|
12912 |
},
|
12913 |
{
|
12914 |
cfSimple2ParRationalRationalQuotient,
|
12915 |
{
|
12916 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12917 |
CMDLINE_PAR_TYPE_RATZERO,
|
12918 |
CMDLINE_PAR_TYPE_INTPOS,
|
12919 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12920 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12921 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12922 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12923 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12924 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12925 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12926 |
}
|
12927 |
},
|
12928 |
{
|
12929 |
cfSimple2ParRationalRationalQuotient,
|
12930 |
{
|
12931 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12932 |
CMDLINE_PAR_TYPE_RATPOS,
|
12933 |
CMDLINE_PAR_TYPE_INTNEG,
|
12934 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12935 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12936 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12937 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12938 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12939 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12940 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12941 |
}
|
12942 |
},
|
12943 |
{
|
12944 |
cfSimple2ParRationalRationalQuotient,
|
12945 |
{
|
12946 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_QUOTIENT,
|
12947 |
CMDLINE_PAR_TYPE_RATPOS,
|
12948 |
CMDLINE_PAR_TYPE_INTPOS,
|
12949 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12950 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12951 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12952 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12953 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12954 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12955 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12956 |
}
|
12957 |
},
|
12958 |
/* GCD
|
12959 |
*/
|
12960 |
{
|
12961 |
cfSimple2ParIntegerGcd,
|
12962 |
{
|
12963 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_GCD,
|
12964 |
CMDLINE_PAR_TYPE_INTPOS,
|
12965 |
CMDLINE_PAR_TYPE_INTPOS,
|
12966 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12967 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12968 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12969 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12970 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12971 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12972 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12973 |
}
|
12974 |
},
|
12975 |
/* DAP */
|
12976 |
{
|
12977 |
cfDap,
|
12978 |
{
|
12979 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
12980 |
CMDLINE_PAR_TYPE_RATNEG,
|
12981 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12982 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12983 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12984 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12985 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12986 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12987 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12988 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
12989 |
}
|
12990 |
},
|
12991 |
{
|
12992 |
cfDap,
|
12993 |
{
|
12994 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
12995 |
CMDLINE_PAR_TYPE_RATNEG,
|
12996 |
CMDLINE_PAR_TYPE_INTPOS,
|
12997 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12998 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
12999 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13000 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13001 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13002 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13003 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13004 |
}
|
13005 |
},
|
13006 |
{
|
13007 |
cfDap,
|
13008 |
{
|
13009 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13010 |
CMDLINE_PAR_TYPE_RATZERO,
|
13011 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13012 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13013 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13014 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13015 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13016 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13017 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13018 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13019 |
}
|
13020 |
},
|
13021 |
{
|
13022 |
cfDap,
|
13023 |
{
|
13024 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13025 |
CMDLINE_PAR_TYPE_RATZERO,
|
13026 |
CMDLINE_PAR_TYPE_INTPOS,
|
13027 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13028 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13029 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13030 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13031 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13032 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13033 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13034 |
}
|
13035 |
},
|
13036 |
{
|
13037 |
cfDap,
|
13038 |
{
|
13039 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13040 |
CMDLINE_PAR_TYPE_RATPOS,
|
13041 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13042 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13043 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13044 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13045 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13046 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13047 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13048 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13049 |
}
|
13050 |
},
|
13051 |
{
|
13052 |
cfDap,
|
13053 |
{
|
13054 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13055 |
CMDLINE_PAR_TYPE_RATPOS,
|
13056 |
CMDLINE_PAR_TYPE_INTPOS,
|
13057 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13058 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13059 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13060 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13061 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13062 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13063 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13064 |
}
|
13065 |
},
|
13066 |
{
|
13067 |
cfDap,
|
13068 |
{
|
13069 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13070 |
CMDLINE_PAR_TYPE_INTNEG,
|
13071 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13072 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13073 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13074 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13075 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13076 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13077 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13078 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13079 |
}
|
13080 |
},
|
13081 |
{
|
13082 |
cfDap,
|
13083 |
{
|
13084 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13085 |
CMDLINE_PAR_TYPE_INTNEG,
|
13086 |
CMDLINE_PAR_TYPE_INTPOS,
|
13087 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13088 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13089 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13090 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13091 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13092 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13093 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13094 |
}
|
13095 |
},
|
13096 |
{
|
13097 |
cfDap,
|
13098 |
{
|
13099 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13100 |
CMDLINE_PAR_TYPE_INTZERO,
|
13101 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13102 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13103 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13104 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13105 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13106 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13107 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13108 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13109 |
}
|
13110 |
},
|
13111 |
{
|
13112 |
cfDap,
|
13113 |
{
|
13114 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13115 |
CMDLINE_PAR_TYPE_INTZERO,
|
13116 |
CMDLINE_PAR_TYPE_INTPOS,
|
13117 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13118 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13119 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13120 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13121 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13122 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13123 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13124 |
}
|
13125 |
},
|
13126 |
{
|
13127 |
cfDap,
|
13128 |
{
|
13129 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13130 |
CMDLINE_PAR_TYPE_INTPOS,
|
13131 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13132 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13133 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13134 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13135 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13136 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13137 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13138 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13139 |
}
|
13140 |
},
|
13141 |
{
|
13142 |
cfDap,
|
13143 |
{
|
13144 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_DAP,
|
13145 |
CMDLINE_PAR_TYPE_INTPOS,
|
13146 |
CMDLINE_PAR_TYPE_INTPOS,
|
13147 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13148 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13149 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13150 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13151 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13152 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13153 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13154 |
}
|
13155 |
},
|
13156 |
/* CF--forming the continued fraction partial quotients and
|
13157 |
** convergents of a non-negative rational number.
|
13158 |
*/
|
13159 |
{
|
13160 |
cfCf,
|
13161 |
{
|
13162 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_CF,
|
13163 |
CMDLINE_PAR_TYPE_RATZERO,
|
13164 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13165 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13166 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13167 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13168 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13169 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13170 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13171 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13172 |
}
|
13173 |
},
|
13174 |
{
|
13175 |
cfCf,
|
13176 |
{
|
13177 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_CF,
|
13178 |
CMDLINE_PAR_TYPE_RATPOS,
|
13179 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13180 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13181 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13182 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13183 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13184 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13185 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13186 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13187 |
}
|
13188 |
},
|
13189 |
{
|
13190 |
cfCf,
|
13191 |
{
|
13192 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_CF,
|
13193 |
CMDLINE_PAR_TYPE_INTZERO,
|
13194 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13195 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13196 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13197 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13198 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13199 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13200 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13201 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13202 |
}
|
13203 |
},
|
13204 |
{
|
13205 |
cfCf,
|
13206 |
{
|
13207 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_CF,
|
13208 |
CMDLINE_PAR_TYPE_INTPOS,
|
13209 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13210 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13211 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13212 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13213 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13214 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13215 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13216 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13217 |
}
|
13218 |
},
|
13219 |
/* Farey series neighbor functionality. Multiple
|
13220 |
** templates required.
|
13221 |
*/
|
13222 |
{
|
13223 |
cfFn,
|
13224 |
{
|
13225 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13226 |
CMDLINE_PAR_TYPE_INTZERO,
|
13227 |
CMDLINE_PAR_TYPE_INTPOS,
|
13228 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13229 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13230 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13231 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13232 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13233 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13234 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13235 |
}
|
13236 |
},
|
13237 |
{
|
13238 |
cfFn,
|
13239 |
{
|
13240 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13241 |
CMDLINE_PAR_TYPE_INTPOS,
|
13242 |
CMDLINE_PAR_TYPE_INTPOS,
|
13243 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13244 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13245 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13246 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13247 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13248 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13249 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13250 |
}
|
13251 |
},
|
13252 |
{
|
13253 |
cfFn,
|
13254 |
{
|
13255 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13256 |
CMDLINE_PAR_TYPE_RATZERO,
|
13257 |
CMDLINE_PAR_TYPE_INTPOS,
|
13258 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13259 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13260 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13261 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13262 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13263 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13264 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13265 |
}
|
13266 |
},
|
13267 |
{
|
13268 |
cfFn,
|
13269 |
{
|
13270 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13271 |
CMDLINE_PAR_TYPE_RATPOS,
|
13272 |
CMDLINE_PAR_TYPE_INTPOS,
|
13273 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13274 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13275 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13276 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13277 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13278 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13279 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13280 |
}
|
13281 |
},
|
13282 |
{
|
13283 |
cfFn,
|
13284 |
{
|
13285 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13286 |
CMDLINE_PAR_TYPE_INTZERO,
|
13287 |
CMDLINE_PAR_TYPE_INTPOS,
|
13288 |
CMDLINE_PAR_TYPE_INTPOS,
|
13289 |
CMDLINE_PAR_TYPE_INTPOS,
|
13290 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13291 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13292 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13293 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13294 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13295 |
}
|
13296 |
},
|
13297 |
{
|
13298 |
cfFn,
|
13299 |
{
|
13300 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13301 |
CMDLINE_PAR_TYPE_INTPOS,
|
13302 |
CMDLINE_PAR_TYPE_INTPOS,
|
13303 |
CMDLINE_PAR_TYPE_INTPOS,
|
13304 |
CMDLINE_PAR_TYPE_INTPOS,
|
13305 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13306 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13307 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13308 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13309 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13310 |
}
|
13311 |
},
|
13312 |
{
|
13313 |
cfFn,
|
13314 |
{
|
13315 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13316 |
CMDLINE_PAR_TYPE_RATZERO,
|
13317 |
CMDLINE_PAR_TYPE_INTPOS,
|
13318 |
CMDLINE_PAR_TYPE_INTPOS,
|
13319 |
CMDLINE_PAR_TYPE_INTPOS,
|
13320 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13321 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13322 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13323 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13324 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13325 |
}
|
13326 |
},
|
13327 |
{
|
13328 |
cfFn,
|
13329 |
{
|
13330 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FN,
|
13331 |
CMDLINE_PAR_TYPE_RATPOS,
|
13332 |
CMDLINE_PAR_TYPE_INTPOS,
|
13333 |
CMDLINE_PAR_TYPE_INTPOS,
|
13334 |
CMDLINE_PAR_TYPE_INTPOS,
|
13335 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13336 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13337 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13338 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13339 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13340 |
}
|
13341 |
},
|
13342 |
{
|
13343 |
cfMind,
|
13344 |
{
|
13345 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13346 |
CMDLINE_PAR_TYPE_INTZERO,
|
13347 |
CMDLINE_PAR_TYPE_INTZERO,
|
13348 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13349 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13350 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13351 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13352 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13353 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13354 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13355 |
}
|
13356 |
},
|
13357 |
{
|
13358 |
cfMind,
|
13359 |
{
|
13360 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13361 |
CMDLINE_PAR_TYPE_INTZERO,
|
13362 |
CMDLINE_PAR_TYPE_INTPOS,
|
13363 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13364 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13365 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13366 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13367 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13368 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13369 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13370 |
}
|
13371 |
},
|
13372 |
{
|
13373 |
cfMind,
|
13374 |
{
|
13375 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13376 |
CMDLINE_PAR_TYPE_INTZERO,
|
13377 |
CMDLINE_PAR_TYPE_RATZERO,
|
13378 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13379 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13380 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13381 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13382 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13383 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13384 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13385 |
}
|
13386 |
},
|
13387 |
{
|
13388 |
cfMind,
|
13389 |
{
|
13390 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13391 |
CMDLINE_PAR_TYPE_INTZERO,
|
13392 |
CMDLINE_PAR_TYPE_RATPOS,
|
13393 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13394 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13395 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13396 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13397 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13398 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13399 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13400 |
}
|
13401 |
},
|
13402 |
{
|
13403 |
cfMind,
|
13404 |
{
|
13405 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13406 |
CMDLINE_PAR_TYPE_INTPOS,
|
13407 |
CMDLINE_PAR_TYPE_INTZERO,
|
13408 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13409 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13410 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13411 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13412 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13413 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13414 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13415 |
}
|
13416 |
},
|
13417 |
{
|
13418 |
cfMind,
|
13419 |
{
|
13420 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13421 |
CMDLINE_PAR_TYPE_INTPOS,
|
13422 |
CMDLINE_PAR_TYPE_INTPOS,
|
13423 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13424 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13425 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13426 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13427 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13428 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13429 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13430 |
}
|
13431 |
},
|
13432 |
{
|
13433 |
cfMind,
|
13434 |
{
|
13435 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13436 |
CMDLINE_PAR_TYPE_INTPOS,
|
13437 |
CMDLINE_PAR_TYPE_RATZERO,
|
13438 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13439 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13440 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13441 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13442 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13443 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13444 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13445 |
}
|
13446 |
},
|
13447 |
{
|
13448 |
cfMind,
|
13449 |
{
|
13450 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13451 |
CMDLINE_PAR_TYPE_INTPOS,
|
13452 |
CMDLINE_PAR_TYPE_RATPOS,
|
13453 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13454 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13455 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13456 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13457 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13458 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13459 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13460 |
}
|
13461 |
},
|
13462 |
{
|
13463 |
cfMind,
|
13464 |
{
|
13465 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13466 |
CMDLINE_PAR_TYPE_RATZERO,
|
13467 |
CMDLINE_PAR_TYPE_INTZERO,
|
13468 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13469 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13470 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13471 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13472 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13473 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13474 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13475 |
}
|
13476 |
},
|
13477 |
{
|
13478 |
cfMind,
|
13479 |
{
|
13480 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13481 |
CMDLINE_PAR_TYPE_RATZERO,
|
13482 |
CMDLINE_PAR_TYPE_INTPOS,
|
13483 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13484 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13485 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13486 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13487 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13488 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13489 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13490 |
}
|
13491 |
},
|
13492 |
{
|
13493 |
cfMind,
|
13494 |
{
|
13495 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13496 |
CMDLINE_PAR_TYPE_RATZERO,
|
13497 |
CMDLINE_PAR_TYPE_RATZERO,
|
13498 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13499 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13500 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13501 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13502 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13503 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13504 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13505 |
}
|
13506 |
},
|
13507 |
{
|
13508 |
cfMind,
|
13509 |
{
|
13510 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13511 |
CMDLINE_PAR_TYPE_RATZERO,
|
13512 |
CMDLINE_PAR_TYPE_RATPOS,
|
13513 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13514 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13515 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13516 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13517 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13518 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13519 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13520 |
}
|
13521 |
},
|
13522 |
{
|
13523 |
cfMind,
|
13524 |
{
|
13525 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13526 |
CMDLINE_PAR_TYPE_RATPOS,
|
13527 |
CMDLINE_PAR_TYPE_INTZERO,
|
13528 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13529 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13530 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13531 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13532 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13533 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13534 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13535 |
}
|
13536 |
},
|
13537 |
{
|
13538 |
cfMind,
|
13539 |
{
|
13540 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13541 |
CMDLINE_PAR_TYPE_RATPOS,
|
13542 |
CMDLINE_PAR_TYPE_INTPOS,
|
13543 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13544 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13545 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13546 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13547 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13548 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13549 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13550 |
}
|
13551 |
},
|
13552 |
{
|
13553 |
cfMind,
|
13554 |
{
|
13555 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13556 |
CMDLINE_PAR_TYPE_RATPOS,
|
13557 |
CMDLINE_PAR_TYPE_RATZERO,
|
13558 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13559 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13560 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13561 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13562 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13563 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13564 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13565 |
}
|
13566 |
},
|
13567 |
{
|
13568 |
cfMind,
|
13569 |
{
|
13570 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_MIND,
|
13571 |
CMDLINE_PAR_TYPE_RATPOS,
|
13572 |
CMDLINE_PAR_TYPE_RATPOS,
|
13573 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13574 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13575 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13576 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13577 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13578 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13579 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13580 |
}
|
13581 |
},
|
13582 |
/* Farey series double-constrained neighbor functionality.
|
13583 |
** Multiple templates required.
|
13584 |
*/
|
13585 |
{
|
13586 |
cfFab,
|
13587 |
{
|
13588 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13589 |
CMDLINE_PAR_TYPE_INTZERO,
|
13590 |
CMDLINE_PAR_TYPE_INTPOS,
|
13591 |
CMDLINE_PAR_TYPE_INTPOS,
|
13592 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13593 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13594 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13595 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13596 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13597 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13598 |
}
|
13599 |
},
|
13600 |
{
|
13601 |
cfFab,
|
13602 |
{
|
13603 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13604 |
CMDLINE_PAR_TYPE_INTPOS,
|
13605 |
CMDLINE_PAR_TYPE_INTPOS,
|
13606 |
CMDLINE_PAR_TYPE_INTPOS,
|
13607 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13608 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13609 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13610 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13611 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13612 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13613 |
}
|
13614 |
},
|
13615 |
{
|
13616 |
cfFab,
|
13617 |
{
|
13618 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13619 |
CMDLINE_PAR_TYPE_RATZERO,
|
13620 |
CMDLINE_PAR_TYPE_INTPOS,
|
13621 |
CMDLINE_PAR_TYPE_INTPOS,
|
13622 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13623 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13624 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13625 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13626 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13627 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13628 |
}
|
13629 |
},
|
13630 |
{
|
13631 |
cfFab,
|
13632 |
{
|
13633 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13634 |
CMDLINE_PAR_TYPE_RATPOS,
|
13635 |
CMDLINE_PAR_TYPE_INTPOS,
|
13636 |
CMDLINE_PAR_TYPE_INTPOS,
|
13637 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13638 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13639 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13640 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13641 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13642 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13643 |
}
|
13644 |
},
|
13645 |
{
|
13646 |
cfFab,
|
13647 |
{
|
13648 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13649 |
CMDLINE_PAR_TYPE_INTZERO,
|
13650 |
CMDLINE_PAR_TYPE_INTPOS,
|
13651 |
CMDLINE_PAR_TYPE_INTPOS,
|
13652 |
CMDLINE_PAR_TYPE_INTPOS,
|
13653 |
CMDLINE_PAR_TYPE_INTPOS,
|
13654 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13655 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13656 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13657 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13658 |
}
|
13659 |
},
|
13660 |
{
|
13661 |
cfFab,
|
13662 |
{
|
13663 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13664 |
CMDLINE_PAR_TYPE_INTPOS,
|
13665 |
CMDLINE_PAR_TYPE_INTPOS,
|
13666 |
CMDLINE_PAR_TYPE_INTPOS,
|
13667 |
CMDLINE_PAR_TYPE_INTPOS,
|
13668 |
CMDLINE_PAR_TYPE_INTPOS,
|
13669 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13670 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13671 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13672 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13673 |
}
|
13674 |
},
|
13675 |
{
|
13676 |
cfFab,
|
13677 |
{
|
13678 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13679 |
CMDLINE_PAR_TYPE_RATZERO,
|
13680 |
CMDLINE_PAR_TYPE_INTPOS,
|
13681 |
CMDLINE_PAR_TYPE_INTPOS,
|
13682 |
CMDLINE_PAR_TYPE_INTPOS,
|
13683 |
CMDLINE_PAR_TYPE_INTPOS,
|
13684 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13685 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13686 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13687 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13688 |
}
|
13689 |
},
|
13690 |
{
|
13691 |
cfFab,
|
13692 |
{
|
13693 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FAB,
|
13694 |
CMDLINE_PAR_TYPE_RATPOS,
|
13695 |
CMDLINE_PAR_TYPE_INTPOS,
|
13696 |
CMDLINE_PAR_TYPE_INTPOS,
|
13697 |
CMDLINE_PAR_TYPE_INTPOS,
|
13698 |
CMDLINE_PAR_TYPE_INTPOS,
|
13699 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13700 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13701 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13702 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13703 |
}
|
13704 |
},
|
13705 |
/* Maximum distance between terms of Farey series.
|
13706 |
** Only two forms possible, one with DAP alternate
|
13707 |
** denominator, one without.
|
13708 |
*/
|
13709 |
{
|
13710 |
cfFndmax,
|
13711 |
{
|
13712 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13713 |
CMDLINE_PAR_TYPE_INTZERO,
|
13714 |
CMDLINE_PAR_TYPE_INTZERO,
|
13715 |
CMDLINE_PAR_TYPE_INTPOS,
|
13716 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13717 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13718 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13719 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13720 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13721 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13722 |
}
|
13723 |
},
|
13724 |
{
|
13725 |
cfFndmax,
|
13726 |
{
|
13727 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13728 |
CMDLINE_PAR_TYPE_INTZERO,
|
13729 |
CMDLINE_PAR_TYPE_INTPOS,
|
13730 |
CMDLINE_PAR_TYPE_INTPOS,
|
13731 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13732 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13733 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13734 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13735 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13736 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13737 |
}
|
13738 |
},
|
13739 |
{
|
13740 |
cfFndmax,
|
13741 |
{
|
13742 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13743 |
CMDLINE_PAR_TYPE_INTZERO,
|
13744 |
CMDLINE_PAR_TYPE_RATZERO,
|
13745 |
CMDLINE_PAR_TYPE_INTPOS,
|
13746 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13747 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13748 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13749 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13750 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13751 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13752 |
}
|
13753 |
},
|
13754 |
{
|
13755 |
cfFndmax,
|
13756 |
{
|
13757 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13758 |
CMDLINE_PAR_TYPE_INTZERO,
|
13759 |
CMDLINE_PAR_TYPE_RATPOS,
|
13760 |
CMDLINE_PAR_TYPE_INTPOS,
|
13761 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13762 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13763 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13764 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13765 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13766 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13767 |
}
|
13768 |
},
|
13769 |
{
|
13770 |
cfFndmax,
|
13771 |
{
|
13772 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13773 |
CMDLINE_PAR_TYPE_INTZERO,
|
13774 |
CMDLINE_PAR_TYPE_INTZERO,
|
13775 |
CMDLINE_PAR_TYPE_INTPOS,
|
13776 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13777 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13778 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13779 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13780 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13781 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13782 |
}
|
13783 |
},
|
13784 |
{
|
13785 |
cfFndmax,
|
13786 |
{
|
13787 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13788 |
CMDLINE_PAR_TYPE_INTZERO,
|
13789 |
CMDLINE_PAR_TYPE_INTPOS,
|
13790 |
CMDLINE_PAR_TYPE_INTPOS,
|
13791 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13792 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13793 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13794 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13795 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13796 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13797 |
}
|
13798 |
},
|
13799 |
{
|
13800 |
cfFndmax,
|
13801 |
{
|
13802 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13803 |
CMDLINE_PAR_TYPE_INTZERO,
|
13804 |
CMDLINE_PAR_TYPE_RATZERO,
|
13805 |
CMDLINE_PAR_TYPE_INTPOS,
|
13806 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13807 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13808 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13809 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13810 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13811 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13812 |
}
|
13813 |
},
|
13814 |
{
|
13815 |
cfFndmax,
|
13816 |
{
|
13817 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13818 |
CMDLINE_PAR_TYPE_INTZERO,
|
13819 |
CMDLINE_PAR_TYPE_RATPOS,
|
13820 |
CMDLINE_PAR_TYPE_INTPOS,
|
13821 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13822 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13823 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13824 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13825 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13826 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13827 |
}
|
13828 |
},
|
13829 |
{
|
13830 |
cfFndmax,
|
13831 |
{
|
13832 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13833 |
CMDLINE_PAR_TYPE_INTPOS,
|
13834 |
CMDLINE_PAR_TYPE_INTZERO,
|
13835 |
CMDLINE_PAR_TYPE_INTPOS,
|
13836 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13837 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13838 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13839 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13840 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13841 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13842 |
}
|
13843 |
},
|
13844 |
{
|
13845 |
cfFndmax,
|
13846 |
{
|
13847 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13848 |
CMDLINE_PAR_TYPE_INTPOS,
|
13849 |
CMDLINE_PAR_TYPE_INTPOS,
|
13850 |
CMDLINE_PAR_TYPE_INTPOS,
|
13851 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13852 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13853 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13854 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13855 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13856 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13857 |
}
|
13858 |
},
|
13859 |
{
|
13860 |
cfFndmax,
|
13861 |
{
|
13862 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13863 |
CMDLINE_PAR_TYPE_INTPOS,
|
13864 |
CMDLINE_PAR_TYPE_RATZERO,
|
13865 |
CMDLINE_PAR_TYPE_INTPOS,
|
13866 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13867 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13868 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13869 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13870 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13871 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13872 |
}
|
13873 |
},
|
13874 |
{
|
13875 |
cfFndmax,
|
13876 |
{
|
13877 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13878 |
CMDLINE_PAR_TYPE_INTPOS,
|
13879 |
CMDLINE_PAR_TYPE_RATPOS,
|
13880 |
CMDLINE_PAR_TYPE_INTPOS,
|
13881 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13882 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13883 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13884 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13885 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13886 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13887 |
}
|
13888 |
},
|
13889 |
{
|
13890 |
cfFndmax,
|
13891 |
{
|
13892 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13893 |
CMDLINE_PAR_TYPE_RATZERO,
|
13894 |
CMDLINE_PAR_TYPE_INTZERO,
|
13895 |
CMDLINE_PAR_TYPE_INTPOS,
|
13896 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13897 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13898 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13899 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13900 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13901 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13902 |
}
|
13903 |
},
|
13904 |
{
|
13905 |
cfFndmax,
|
13906 |
{
|
13907 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13908 |
CMDLINE_PAR_TYPE_RATZERO,
|
13909 |
CMDLINE_PAR_TYPE_INTPOS,
|
13910 |
CMDLINE_PAR_TYPE_INTPOS,
|
13911 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13912 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13913 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13914 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13915 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13916 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13917 |
}
|
13918 |
},
|
13919 |
{
|
13920 |
cfFndmax,
|
13921 |
{
|
13922 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13923 |
CMDLINE_PAR_TYPE_RATZERO,
|
13924 |
CMDLINE_PAR_TYPE_RATZERO,
|
13925 |
CMDLINE_PAR_TYPE_INTPOS,
|
13926 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13927 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13928 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13929 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13930 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13931 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13932 |
}
|
13933 |
},
|
13934 |
{
|
13935 |
cfFndmax,
|
13936 |
{
|
13937 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13938 |
CMDLINE_PAR_TYPE_RATZERO,
|
13939 |
CMDLINE_PAR_TYPE_RATPOS,
|
13940 |
CMDLINE_PAR_TYPE_INTPOS,
|
13941 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13942 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13943 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13944 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13945 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13946 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13947 |
}
|
13948 |
},
|
13949 |
{
|
13950 |
cfFndmax,
|
13951 |
{
|
13952 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13953 |
CMDLINE_PAR_TYPE_RATPOS,
|
13954 |
CMDLINE_PAR_TYPE_INTZERO,
|
13955 |
CMDLINE_PAR_TYPE_INTPOS,
|
13956 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13957 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13958 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13959 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13960 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13961 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13962 |
}
|
13963 |
},
|
13964 |
{
|
13965 |
cfFndmax,
|
13966 |
{
|
13967 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13968 |
CMDLINE_PAR_TYPE_RATPOS,
|
13969 |
CMDLINE_PAR_TYPE_INTPOS,
|
13970 |
CMDLINE_PAR_TYPE_INTPOS,
|
13971 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13972 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13973 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13974 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13975 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13976 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13977 |
}
|
13978 |
},
|
13979 |
{
|
13980 |
cfFndmax,
|
13981 |
{
|
13982 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13983 |
CMDLINE_PAR_TYPE_RATPOS,
|
13984 |
CMDLINE_PAR_TYPE_RATZERO,
|
13985 |
CMDLINE_PAR_TYPE_INTPOS,
|
13986 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13987 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13988 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13989 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13990 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
13991 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
13992 |
}
|
13993 |
},
|
13994 |
{
|
13995 |
cfFndmax,
|
13996 |
{
|
13997 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
13998 |
CMDLINE_PAR_TYPE_RATPOS,
|
13999 |
CMDLINE_PAR_TYPE_RATPOS,
|
14000 |
CMDLINE_PAR_TYPE_INTPOS,
|
14001 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14002 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14003 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14004 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14005 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14006 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14007 |
}
|
14008 |
},
|
14009 |
{
|
14010 |
cfFndmax,
|
14011 |
{
|
14012 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14013 |
CMDLINE_PAR_TYPE_INTZERO,
|
14014 |
CMDLINE_PAR_TYPE_INTZERO,
|
14015 |
CMDLINE_PAR_TYPE_INTPOS,
|
14016 |
CMDLINE_PAR_TYPE_INTPOS,
|
14017 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14018 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14019 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14020 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14021 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14022 |
}
|
14023 |
},
|
14024 |
{
|
14025 |
cfFndmax,
|
14026 |
{
|
14027 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14028 |
CMDLINE_PAR_TYPE_INTZERO,
|
14029 |
CMDLINE_PAR_TYPE_INTPOS,
|
14030 |
CMDLINE_PAR_TYPE_INTPOS,
|
14031 |
CMDLINE_PAR_TYPE_INTPOS,
|
14032 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14033 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14034 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14035 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14036 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14037 |
}
|
14038 |
},
|
14039 |
{
|
14040 |
cfFndmax,
|
14041 |
{
|
14042 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14043 |
CMDLINE_PAR_TYPE_INTZERO,
|
14044 |
CMDLINE_PAR_TYPE_RATZERO,
|
14045 |
CMDLINE_PAR_TYPE_INTPOS,
|
14046 |
CMDLINE_PAR_TYPE_INTPOS,
|
14047 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14048 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14049 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14050 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14051 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14052 |
}
|
14053 |
},
|
14054 |
{
|
14055 |
cfFndmax,
|
14056 |
{
|
14057 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14058 |
CMDLINE_PAR_TYPE_INTZERO,
|
14059 |
CMDLINE_PAR_TYPE_RATPOS,
|
14060 |
CMDLINE_PAR_TYPE_INTPOS,
|
14061 |
CMDLINE_PAR_TYPE_INTPOS,
|
14062 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14063 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14064 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14065 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14066 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14067 |
}
|
14068 |
},
|
14069 |
{
|
14070 |
cfFndmax,
|
14071 |
{
|
14072 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14073 |
CMDLINE_PAR_TYPE_INTZERO,
|
14074 |
CMDLINE_PAR_TYPE_INTZERO,
|
14075 |
CMDLINE_PAR_TYPE_INTPOS,
|
14076 |
CMDLINE_PAR_TYPE_INTPOS,
|
14077 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14078 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14079 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14080 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14081 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14082 |
}
|
14083 |
},
|
14084 |
{
|
14085 |
cfFndmax,
|
14086 |
{
|
14087 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14088 |
CMDLINE_PAR_TYPE_INTZERO,
|
14089 |
CMDLINE_PAR_TYPE_INTPOS,
|
14090 |
CMDLINE_PAR_TYPE_INTPOS,
|
14091 |
CMDLINE_PAR_TYPE_INTPOS,
|
14092 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14093 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14094 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14095 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14096 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14097 |
}
|
14098 |
},
|
14099 |
{
|
14100 |
cfFndmax,
|
14101 |
{
|
14102 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14103 |
CMDLINE_PAR_TYPE_INTZERO,
|
14104 |
CMDLINE_PAR_TYPE_RATZERO,
|
14105 |
CMDLINE_PAR_TYPE_INTPOS,
|
14106 |
CMDLINE_PAR_TYPE_INTPOS,
|
14107 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14108 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14109 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14110 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14111 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14112 |
}
|
14113 |
},
|
14114 |
{
|
14115 |
cfFndmax,
|
14116 |
{
|
14117 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14118 |
CMDLINE_PAR_TYPE_INTZERO,
|
14119 |
CMDLINE_PAR_TYPE_RATPOS,
|
14120 |
CMDLINE_PAR_TYPE_INTPOS,
|
14121 |
CMDLINE_PAR_TYPE_INTPOS,
|
14122 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14123 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14124 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14125 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14126 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14127 |
}
|
14128 |
},
|
14129 |
{
|
14130 |
cfFndmax,
|
14131 |
{
|
14132 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14133 |
CMDLINE_PAR_TYPE_INTPOS,
|
14134 |
CMDLINE_PAR_TYPE_INTZERO,
|
14135 |
CMDLINE_PAR_TYPE_INTPOS,
|
14136 |
CMDLINE_PAR_TYPE_INTPOS,
|
14137 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14138 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14139 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14140 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14141 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14142 |
}
|
14143 |
},
|
14144 |
{
|
14145 |
cfFndmax,
|
14146 |
{
|
14147 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14148 |
CMDLINE_PAR_TYPE_INTPOS,
|
14149 |
CMDLINE_PAR_TYPE_INTPOS,
|
14150 |
CMDLINE_PAR_TYPE_INTPOS,
|
14151 |
CMDLINE_PAR_TYPE_INTPOS,
|
14152 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14153 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14154 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14155 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14156 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14157 |
}
|
14158 |
},
|
14159 |
{
|
14160 |
cfFndmax,
|
14161 |
{
|
14162 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14163 |
CMDLINE_PAR_TYPE_INTPOS,
|
14164 |
CMDLINE_PAR_TYPE_RATZERO,
|
14165 |
CMDLINE_PAR_TYPE_INTPOS,
|
14166 |
CMDLINE_PAR_TYPE_INTPOS,
|
14167 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14168 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14169 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14170 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14171 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14172 |
}
|
14173 |
},
|
14174 |
{
|
14175 |
cfFndmax,
|
14176 |
{
|
14177 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14178 |
CMDLINE_PAR_TYPE_INTPOS,
|
14179 |
CMDLINE_PAR_TYPE_RATPOS,
|
14180 |
CMDLINE_PAR_TYPE_INTPOS,
|
14181 |
CMDLINE_PAR_TYPE_INTPOS,
|
14182 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14183 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14184 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14185 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14186 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14187 |
}
|
14188 |
},
|
14189 |
{
|
14190 |
cfFndmax,
|
14191 |
{
|
14192 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14193 |
CMDLINE_PAR_TYPE_RATZERO,
|
14194 |
CMDLINE_PAR_TYPE_INTZERO,
|
14195 |
CMDLINE_PAR_TYPE_INTPOS,
|
14196 |
CMDLINE_PAR_TYPE_INTPOS,
|
14197 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14198 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14199 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14200 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14201 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14202 |
}
|
14203 |
},
|
14204 |
{
|
14205 |
cfFndmax,
|
14206 |
{
|
14207 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14208 |
CMDLINE_PAR_TYPE_RATZERO,
|
14209 |
CMDLINE_PAR_TYPE_INTPOS,
|
14210 |
CMDLINE_PAR_TYPE_INTPOS,
|
14211 |
CMDLINE_PAR_TYPE_INTPOS,
|
14212 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14213 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14214 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14215 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14216 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14217 |
}
|
14218 |
},
|
14219 |
{
|
14220 |
cfFndmax,
|
14221 |
{
|
14222 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14223 |
CMDLINE_PAR_TYPE_RATZERO,
|
14224 |
CMDLINE_PAR_TYPE_RATZERO,
|
14225 |
CMDLINE_PAR_TYPE_INTPOS,
|
14226 |
CMDLINE_PAR_TYPE_INTPOS,
|
14227 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14228 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14229 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14230 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14231 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14232 |
}
|
14233 |
},
|
14234 |
{
|
14235 |
cfFndmax,
|
14236 |
{
|
14237 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14238 |
CMDLINE_PAR_TYPE_RATZERO,
|
14239 |
CMDLINE_PAR_TYPE_RATPOS,
|
14240 |
CMDLINE_PAR_TYPE_INTPOS,
|
14241 |
CMDLINE_PAR_TYPE_INTPOS,
|
14242 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14243 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14244 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14245 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14246 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14247 |
}
|
14248 |
},
|
14249 |
{
|
14250 |
cfFndmax,
|
14251 |
{
|
14252 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14253 |
CMDLINE_PAR_TYPE_RATPOS,
|
14254 |
CMDLINE_PAR_TYPE_INTZERO,
|
14255 |
CMDLINE_PAR_TYPE_INTPOS,
|
14256 |
CMDLINE_PAR_TYPE_INTPOS,
|
14257 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14258 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14259 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14260 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14261 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14262 |
}
|
14263 |
},
|
14264 |
{
|
14265 |
cfFndmax,
|
14266 |
{
|
14267 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14268 |
CMDLINE_PAR_TYPE_RATPOS,
|
14269 |
CMDLINE_PAR_TYPE_INTPOS,
|
14270 |
CMDLINE_PAR_TYPE_INTPOS,
|
14271 |
CMDLINE_PAR_TYPE_INTPOS,
|
14272 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14273 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14274 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14275 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14276 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14277 |
}
|
14278 |
},
|
14279 |
{
|
14280 |
cfFndmax,
|
14281 |
{
|
14282 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14283 |
CMDLINE_PAR_TYPE_RATPOS,
|
14284 |
CMDLINE_PAR_TYPE_RATZERO,
|
14285 |
CMDLINE_PAR_TYPE_INTPOS,
|
14286 |
CMDLINE_PAR_TYPE_INTPOS,
|
14287 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14288 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14289 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14290 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14291 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14292 |
}
|
14293 |
},
|
14294 |
{
|
14295 |
cfFndmax,
|
14296 |
{
|
14297 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FNDMAX,
|
14298 |
CMDLINE_PAR_TYPE_RATPOS,
|
14299 |
CMDLINE_PAR_TYPE_RATPOS,
|
14300 |
CMDLINE_PAR_TYPE_INTPOS,
|
14301 |
CMDLINE_PAR_TYPE_INTPOS,
|
14302 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14303 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14304 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14305 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14306 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14307 |
}
|
14308 |
},
|
14309 |
/* Maximum distance between terms of "rectangular" Farey
|
14310 |
** series. Only two forms possible, one with DAP alternate
|
14311 |
** denominator, one without.
|
14312 |
*/
|
14313 |
{
|
14314 |
cfFabdmax,
|
14315 |
{
|
14316 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14317 |
CMDLINE_PAR_TYPE_INTZERO,
|
14318 |
CMDLINE_PAR_TYPE_INTZERO,
|
14319 |
CMDLINE_PAR_TYPE_INTPOS,
|
14320 |
CMDLINE_PAR_TYPE_INTPOS,
|
14321 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14322 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14323 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14324 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14325 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14326 |
}
|
14327 |
},
|
14328 |
{
|
14329 |
cfFabdmax,
|
14330 |
{
|
14331 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14332 |
CMDLINE_PAR_TYPE_INTZERO,
|
14333 |
CMDLINE_PAR_TYPE_INTPOS,
|
14334 |
CMDLINE_PAR_TYPE_INTPOS,
|
14335 |
CMDLINE_PAR_TYPE_INTPOS,
|
14336 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14337 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14338 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14339 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14340 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14341 |
}
|
14342 |
},
|
14343 |
{
|
14344 |
cfFabdmax,
|
14345 |
{
|
14346 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14347 |
CMDLINE_PAR_TYPE_INTZERO,
|
14348 |
CMDLINE_PAR_TYPE_RATZERO,
|
14349 |
CMDLINE_PAR_TYPE_INTPOS,
|
14350 |
CMDLINE_PAR_TYPE_INTPOS,
|
14351 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14352 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14353 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14354 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14355 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14356 |
}
|
14357 |
},
|
14358 |
{
|
14359 |
cfFabdmax,
|
14360 |
{
|
14361 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14362 |
CMDLINE_PAR_TYPE_INTZERO,
|
14363 |
CMDLINE_PAR_TYPE_RATPOS,
|
14364 |
CMDLINE_PAR_TYPE_INTPOS,
|
14365 |
CMDLINE_PAR_TYPE_INTPOS,
|
14366 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14367 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14368 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14369 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14370 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14371 |
}
|
14372 |
},
|
14373 |
{
|
14374 |
cfFabdmax,
|
14375 |
{
|
14376 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14377 |
CMDLINE_PAR_TYPE_INTZERO,
|
14378 |
CMDLINE_PAR_TYPE_INTZERO,
|
14379 |
CMDLINE_PAR_TYPE_INTPOS,
|
14380 |
CMDLINE_PAR_TYPE_INTPOS,
|
14381 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14382 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14383 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14384 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14385 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14386 |
}
|
14387 |
},
|
14388 |
{
|
14389 |
cfFabdmax,
|
14390 |
{
|
14391 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14392 |
CMDLINE_PAR_TYPE_INTZERO,
|
14393 |
CMDLINE_PAR_TYPE_INTPOS,
|
14394 |
CMDLINE_PAR_TYPE_INTPOS,
|
14395 |
CMDLINE_PAR_TYPE_INTPOS,
|
14396 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14397 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14398 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14399 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14400 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14401 |
}
|
14402 |
},
|
14403 |
{
|
14404 |
cfFabdmax,
|
14405 |
{
|
14406 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14407 |
CMDLINE_PAR_TYPE_INTZERO,
|
14408 |
CMDLINE_PAR_TYPE_RATZERO,
|
14409 |
CMDLINE_PAR_TYPE_INTPOS,
|
14410 |
CMDLINE_PAR_TYPE_INTPOS,
|
14411 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14412 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14413 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14414 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14415 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14416 |
}
|
14417 |
},
|
14418 |
{
|
14419 |
cfFabdmax,
|
14420 |
{
|
14421 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14422 |
CMDLINE_PAR_TYPE_INTZERO,
|
14423 |
CMDLINE_PAR_TYPE_RATPOS,
|
14424 |
CMDLINE_PAR_TYPE_INTPOS,
|
14425 |
CMDLINE_PAR_TYPE_INTPOS,
|
14426 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14427 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14428 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14429 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14430 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14431 |
}
|
14432 |
},
|
14433 |
{
|
14434 |
cfFabdmax,
|
14435 |
{
|
14436 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14437 |
CMDLINE_PAR_TYPE_INTPOS,
|
14438 |
CMDLINE_PAR_TYPE_INTZERO,
|
14439 |
CMDLINE_PAR_TYPE_INTPOS,
|
14440 |
CMDLINE_PAR_TYPE_INTPOS,
|
14441 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14442 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14443 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14444 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14445 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14446 |
}
|
14447 |
},
|
14448 |
{
|
14449 |
cfFabdmax,
|
14450 |
{
|
14451 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14452 |
CMDLINE_PAR_TYPE_INTPOS,
|
14453 |
CMDLINE_PAR_TYPE_INTPOS,
|
14454 |
CMDLINE_PAR_TYPE_INTPOS,
|
14455 |
CMDLINE_PAR_TYPE_INTPOS,
|
14456 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14457 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14458 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14459 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14460 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14461 |
}
|
14462 |
},
|
14463 |
{
|
14464 |
cfFabdmax,
|
14465 |
{
|
14466 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14467 |
CMDLINE_PAR_TYPE_INTPOS,
|
14468 |
CMDLINE_PAR_TYPE_RATZERO,
|
14469 |
CMDLINE_PAR_TYPE_INTPOS,
|
14470 |
CMDLINE_PAR_TYPE_INTPOS,
|
14471 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14472 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14473 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14474 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14475 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14476 |
}
|
14477 |
},
|
14478 |
{
|
14479 |
cfFabdmax,
|
14480 |
{
|
14481 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14482 |
CMDLINE_PAR_TYPE_INTPOS,
|
14483 |
CMDLINE_PAR_TYPE_RATPOS,
|
14484 |
CMDLINE_PAR_TYPE_INTPOS,
|
14485 |
CMDLINE_PAR_TYPE_INTPOS,
|
14486 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14487 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14488 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14489 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14490 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14491 |
}
|
14492 |
},
|
14493 |
{
|
14494 |
cfFabdmax,
|
14495 |
{
|
14496 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14497 |
CMDLINE_PAR_TYPE_RATZERO,
|
14498 |
CMDLINE_PAR_TYPE_INTZERO,
|
14499 |
CMDLINE_PAR_TYPE_INTPOS,
|
14500 |
CMDLINE_PAR_TYPE_INTPOS,
|
14501 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14502 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14503 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14504 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14505 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14506 |
}
|
14507 |
},
|
14508 |
{
|
14509 |
cfFabdmax,
|
14510 |
{
|
14511 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14512 |
CMDLINE_PAR_TYPE_RATZERO,
|
14513 |
CMDLINE_PAR_TYPE_INTPOS,
|
14514 |
CMDLINE_PAR_TYPE_INTPOS,
|
14515 |
CMDLINE_PAR_TYPE_INTPOS,
|
14516 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14517 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14518 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14519 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14520 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14521 |
}
|
14522 |
},
|
14523 |
{
|
14524 |
cfFabdmax,
|
14525 |
{
|
14526 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14527 |
CMDLINE_PAR_TYPE_RATZERO,
|
14528 |
CMDLINE_PAR_TYPE_RATZERO,
|
14529 |
CMDLINE_PAR_TYPE_INTPOS,
|
14530 |
CMDLINE_PAR_TYPE_INTPOS,
|
14531 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14532 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14533 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14534 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14535 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14536 |
}
|
14537 |
},
|
14538 |
{
|
14539 |
cfFabdmax,
|
14540 |
{
|
14541 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14542 |
CMDLINE_PAR_TYPE_RATZERO,
|
14543 |
CMDLINE_PAR_TYPE_RATPOS,
|
14544 |
CMDLINE_PAR_TYPE_INTPOS,
|
14545 |
CMDLINE_PAR_TYPE_INTPOS,
|
14546 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14547 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14548 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14549 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14550 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14551 |
}
|
14552 |
},
|
14553 |
{
|
14554 |
cfFabdmax,
|
14555 |
{
|
14556 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14557 |
CMDLINE_PAR_TYPE_RATPOS,
|
14558 |
CMDLINE_PAR_TYPE_INTZERO,
|
14559 |
CMDLINE_PAR_TYPE_INTPOS,
|
14560 |
CMDLINE_PAR_TYPE_INTPOS,
|
14561 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14562 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14563 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14564 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14565 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14566 |
}
|
14567 |
},
|
14568 |
{
|
14569 |
cfFabdmax,
|
14570 |
{
|
14571 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14572 |
CMDLINE_PAR_TYPE_RATPOS,
|
14573 |
CMDLINE_PAR_TYPE_INTPOS,
|
14574 |
CMDLINE_PAR_TYPE_INTPOS,
|
14575 |
CMDLINE_PAR_TYPE_INTPOS,
|
14576 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14577 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14578 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14579 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14580 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14581 |
}
|
14582 |
},
|
14583 |
{
|
14584 |
cfFabdmax,
|
14585 |
{
|
14586 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14587 |
CMDLINE_PAR_TYPE_RATPOS,
|
14588 |
CMDLINE_PAR_TYPE_RATZERO,
|
14589 |
CMDLINE_PAR_TYPE_INTPOS,
|
14590 |
CMDLINE_PAR_TYPE_INTPOS,
|
14591 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14592 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14593 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14594 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14595 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14596 |
}
|
14597 |
},
|
14598 |
{
|
14599 |
cfFabdmax,
|
14600 |
{
|
14601 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14602 |
CMDLINE_PAR_TYPE_RATPOS,
|
14603 |
CMDLINE_PAR_TYPE_RATPOS,
|
14604 |
CMDLINE_PAR_TYPE_INTPOS,
|
14605 |
CMDLINE_PAR_TYPE_INTPOS,
|
14606 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14607 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14608 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14609 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14610 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14611 |
}
|
14612 |
},
|
14613 |
{
|
14614 |
cfFabdmax,
|
14615 |
{
|
14616 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14617 |
CMDLINE_PAR_TYPE_INTZERO,
|
14618 |
CMDLINE_PAR_TYPE_INTZERO,
|
14619 |
CMDLINE_PAR_TYPE_INTPOS,
|
14620 |
CMDLINE_PAR_TYPE_INTPOS,
|
14621 |
CMDLINE_PAR_TYPE_INTPOS,
|
14622 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14623 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14624 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14625 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14626 |
}
|
14627 |
},
|
14628 |
{
|
14629 |
cfFabdmax,
|
14630 |
{
|
14631 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14632 |
CMDLINE_PAR_TYPE_INTZERO,
|
14633 |
CMDLINE_PAR_TYPE_INTPOS,
|
14634 |
CMDLINE_PAR_TYPE_INTPOS,
|
14635 |
CMDLINE_PAR_TYPE_INTPOS,
|
14636 |
CMDLINE_PAR_TYPE_INTPOS,
|
14637 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14638 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14639 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14640 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14641 |
}
|
14642 |
},
|
14643 |
{
|
14644 |
cfFabdmax,
|
14645 |
{
|
14646 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14647 |
CMDLINE_PAR_TYPE_INTZERO,
|
14648 |
CMDLINE_PAR_TYPE_RATZERO,
|
14649 |
CMDLINE_PAR_TYPE_INTPOS,
|
14650 |
CMDLINE_PAR_TYPE_INTPOS,
|
14651 |
CMDLINE_PAR_TYPE_INTPOS,
|
14652 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14653 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14654 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14655 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14656 |
}
|
14657 |
},
|
14658 |
{
|
14659 |
cfFabdmax,
|
14660 |
{
|
14661 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14662 |
CMDLINE_PAR_TYPE_INTZERO,
|
14663 |
CMDLINE_PAR_TYPE_RATPOS,
|
14664 |
CMDLINE_PAR_TYPE_INTPOS,
|
14665 |
CMDLINE_PAR_TYPE_INTPOS,
|
14666 |
CMDLINE_PAR_TYPE_INTPOS,
|
14667 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14668 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14669 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14670 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14671 |
}
|
14672 |
},
|
14673 |
{
|
14674 |
cfFabdmax,
|
14675 |
{
|
14676 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14677 |
CMDLINE_PAR_TYPE_INTZERO,
|
14678 |
CMDLINE_PAR_TYPE_INTZERO,
|
14679 |
CMDLINE_PAR_TYPE_INTPOS,
|
14680 |
CMDLINE_PAR_TYPE_INTPOS,
|
14681 |
CMDLINE_PAR_TYPE_INTPOS,
|
14682 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14683 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14684 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14685 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14686 |
}
|
14687 |
},
|
14688 |
{
|
14689 |
cfFabdmax,
|
14690 |
{
|
14691 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14692 |
CMDLINE_PAR_TYPE_INTZERO,
|
14693 |
CMDLINE_PAR_TYPE_INTPOS,
|
14694 |
CMDLINE_PAR_TYPE_INTPOS,
|
14695 |
CMDLINE_PAR_TYPE_INTPOS,
|
14696 |
CMDLINE_PAR_TYPE_INTPOS,
|
14697 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14698 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14699 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14700 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14701 |
}
|
14702 |
},
|
14703 |
{
|
14704 |
cfFabdmax,
|
14705 |
{
|
14706 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14707 |
CMDLINE_PAR_TYPE_INTZERO,
|
14708 |
CMDLINE_PAR_TYPE_RATZERO,
|
14709 |
CMDLINE_PAR_TYPE_INTPOS,
|
14710 |
CMDLINE_PAR_TYPE_INTPOS,
|
14711 |
CMDLINE_PAR_TYPE_INTPOS,
|
14712 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14713 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14714 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14715 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14716 |
}
|
14717 |
},
|
14718 |
{
|
14719 |
cfFabdmax,
|
14720 |
{
|
14721 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14722 |
CMDLINE_PAR_TYPE_INTZERO,
|
14723 |
CMDLINE_PAR_TYPE_RATPOS,
|
14724 |
CMDLINE_PAR_TYPE_INTPOS,
|
14725 |
CMDLINE_PAR_TYPE_INTPOS,
|
14726 |
CMDLINE_PAR_TYPE_INTPOS,
|
14727 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14728 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14729 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14730 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14731 |
}
|
14732 |
},
|
14733 |
{
|
14734 |
cfFabdmax,
|
14735 |
{
|
14736 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14737 |
CMDLINE_PAR_TYPE_INTPOS,
|
14738 |
CMDLINE_PAR_TYPE_INTZERO,
|
14739 |
CMDLINE_PAR_TYPE_INTPOS,
|
14740 |
CMDLINE_PAR_TYPE_INTPOS,
|
14741 |
CMDLINE_PAR_TYPE_INTPOS,
|
14742 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14743 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14744 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14745 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14746 |
}
|
14747 |
},
|
14748 |
{
|
14749 |
cfFabdmax,
|
14750 |
{
|
14751 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14752 |
CMDLINE_PAR_TYPE_INTPOS,
|
14753 |
CMDLINE_PAR_TYPE_INTPOS,
|
14754 |
CMDLINE_PAR_TYPE_INTPOS,
|
14755 |
CMDLINE_PAR_TYPE_INTPOS,
|
14756 |
CMDLINE_PAR_TYPE_INTPOS,
|
14757 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14758 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14759 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14760 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14761 |
}
|
14762 |
},
|
14763 |
{
|
14764 |
cfFabdmax,
|
14765 |
{
|
14766 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14767 |
CMDLINE_PAR_TYPE_INTPOS,
|
14768 |
CMDLINE_PAR_TYPE_RATZERO,
|
14769 |
CMDLINE_PAR_TYPE_INTPOS,
|
14770 |
CMDLINE_PAR_TYPE_INTPOS,
|
14771 |
CMDLINE_PAR_TYPE_INTPOS,
|
14772 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14773 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14774 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14775 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14776 |
}
|
14777 |
},
|
14778 |
{
|
14779 |
cfFabdmax,
|
14780 |
{
|
14781 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14782 |
CMDLINE_PAR_TYPE_INTPOS,
|
14783 |
CMDLINE_PAR_TYPE_RATPOS,
|
14784 |
CMDLINE_PAR_TYPE_INTPOS,
|
14785 |
CMDLINE_PAR_TYPE_INTPOS,
|
14786 |
CMDLINE_PAR_TYPE_INTPOS,
|
14787 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14788 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14789 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14790 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14791 |
}
|
14792 |
},
|
14793 |
{
|
14794 |
cfFabdmax,
|
14795 |
{
|
14796 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14797 |
CMDLINE_PAR_TYPE_RATZERO,
|
14798 |
CMDLINE_PAR_TYPE_INTZERO,
|
14799 |
CMDLINE_PAR_TYPE_INTPOS,
|
14800 |
CMDLINE_PAR_TYPE_INTPOS,
|
14801 |
CMDLINE_PAR_TYPE_INTPOS,
|
14802 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14803 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14804 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14805 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14806 |
}
|
14807 |
},
|
14808 |
{
|
14809 |
cfFabdmax,
|
14810 |
{
|
14811 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14812 |
CMDLINE_PAR_TYPE_RATZERO,
|
14813 |
CMDLINE_PAR_TYPE_INTPOS,
|
14814 |
CMDLINE_PAR_TYPE_INTPOS,
|
14815 |
CMDLINE_PAR_TYPE_INTPOS,
|
14816 |
CMDLINE_PAR_TYPE_INTPOS,
|
14817 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14818 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14819 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14820 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14821 |
}
|
14822 |
},
|
14823 |
{
|
14824 |
cfFabdmax,
|
14825 |
{
|
14826 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14827 |
CMDLINE_PAR_TYPE_RATZERO,
|
14828 |
CMDLINE_PAR_TYPE_RATZERO,
|
14829 |
CMDLINE_PAR_TYPE_INTPOS,
|
14830 |
CMDLINE_PAR_TYPE_INTPOS,
|
14831 |
CMDLINE_PAR_TYPE_INTPOS,
|
14832 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14833 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14834 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14835 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14836 |
}
|
14837 |
},
|
14838 |
{
|
14839 |
cfFabdmax,
|
14840 |
{
|
14841 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14842 |
CMDLINE_PAR_TYPE_RATZERO,
|
14843 |
CMDLINE_PAR_TYPE_RATPOS,
|
14844 |
CMDLINE_PAR_TYPE_INTPOS,
|
14845 |
CMDLINE_PAR_TYPE_INTPOS,
|
14846 |
CMDLINE_PAR_TYPE_INTPOS,
|
14847 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14848 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14849 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14850 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14851 |
}
|
14852 |
},
|
14853 |
{
|
14854 |
cfFabdmax,
|
14855 |
{
|
14856 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14857 |
CMDLINE_PAR_TYPE_RATPOS,
|
14858 |
CMDLINE_PAR_TYPE_INTZERO,
|
14859 |
CMDLINE_PAR_TYPE_INTPOS,
|
14860 |
CMDLINE_PAR_TYPE_INTPOS,
|
14861 |
CMDLINE_PAR_TYPE_INTPOS,
|
14862 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14863 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14864 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14865 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14866 |
}
|
14867 |
},
|
14868 |
{
|
14869 |
cfFabdmax,
|
14870 |
{
|
14871 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14872 |
CMDLINE_PAR_TYPE_RATPOS,
|
14873 |
CMDLINE_PAR_TYPE_INTPOS,
|
14874 |
CMDLINE_PAR_TYPE_INTPOS,
|
14875 |
CMDLINE_PAR_TYPE_INTPOS,
|
14876 |
CMDLINE_PAR_TYPE_INTPOS,
|
14877 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14878 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14879 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14880 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14881 |
}
|
14882 |
},
|
14883 |
{
|
14884 |
cfFabdmax,
|
14885 |
{
|
14886 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14887 |
CMDLINE_PAR_TYPE_RATPOS,
|
14888 |
CMDLINE_PAR_TYPE_RATZERO,
|
14889 |
CMDLINE_PAR_TYPE_INTPOS,
|
14890 |
CMDLINE_PAR_TYPE_INTPOS,
|
14891 |
CMDLINE_PAR_TYPE_INTPOS,
|
14892 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14893 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14894 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14895 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14896 |
}
|
14897 |
},
|
14898 |
{
|
14899 |
cfFabdmax,
|
14900 |
{
|
14901 |
CMDLINE_PAR_TYPE_CMD_KEYTOKEN_FABDMAX,
|
14902 |
CMDLINE_PAR_TYPE_RATPOS,
|
14903 |
CMDLINE_PAR_TYPE_RATPOS,
|
14904 |
CMDLINE_PAR_TYPE_INTPOS,
|
14905 |
CMDLINE_PAR_TYPE_INTPOS,
|
14906 |
CMDLINE_PAR_TYPE_INTPOS,
|
14907 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14908 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14909 |
CMDLINE_PAR_TYPE_UNASSIGNED,
|
14910 |
CMDLINE_PAR_TYPE_UNASSIGNED
|
14911 |
}
|
14912 |
},
|
14913 |
};
|
14914 |
|
14915 |
int i;
|
14916 |
int j;
|
14917 |
|
14918 |
/* Try to match the par_block against the templates, and call the first
|
14919 |
** function that gives a match. If there isn't a match in the table,
|
14920 |
** this is an error, as the user has specified something that the program
|
14921 |
** isn't prepared to handle.
|
14922 |
*/
|
14923 |
|
14924 |
for (i=0; i<sizeof(cmd_templates)/sizeof(cmd_templates[0]); i++)
|
14925 |
/* For each template.
|
14926 |
*/
|
14927 |
{
|
14928 |
/* printf("Processing table entry: %d\n", i); */
|
14929 |
|
14930 |
for (j=0; j<MAX_CMDLINE_PARS; j++)
|
14931 |
{
|
14932 |
|
14933 |
/* printf(" Processing template entry: %d, tbl: %d, pars: %d\n", j,
|
14934 |
cmd_templates[i].template[j],
|
14935 |
par_block.pars[j].ftype); */
|
14936 |
|
14937 |
if ((cmd_templates[i].template[j]) != (par_block.pars[j].ftype))
|
14938 |
break;
|
14939 |
}
|
14940 |
|
14941 |
if (j==MAX_CMDLINE_PARS)
|
14942 |
{
|
14943 |
(cmd_templates[i].fptr)();
|
14944 |
break;
|
14945 |
}
|
14946 |
}
|
14947 |
|
14948 |
if (i==sizeof(cmd_templates)/sizeof(cmd_templates[0]))
|
14949 |
{
|
14950 |
asFatal("no match of command and pars to cmd template");
|
14951 |
}
|
14952 |
}
|
14953 |
|
14954 |
|
14955 |
/****************************************************************************/
|
14956 |
/****************************************************************************/
|
14957 |
/**************** U N I T T E S T F U N C T I O N S ***************/
|
14958 |
/****************************************************************************/
|
14959 |
/****************************************************************************/
|
14960 |
/* These functions constitute a crude unit test. This code will be
|
14961 |
** preprocessed out before this is released to the ACM.
|
14962 |
*/
|
14963 |
|
14964 |
#if 0
|
14965 |
/****************************************************************************/
|
14966 |
/* utFunc1(): */
|
14967 |
/*--------------------------------------------------------------------------*/
|
14968 |
/* DESCRIPTION */
|
14969 |
/* Double-checks the way that integers are presented (titles, commas, */
|
14970 |
/* etc.). */
|
14971 |
/****************************************************************************/
|
14972 |
void utFunc1(void)
|
14973 |
{
|
14974 |
long vectors[] = {-876437264, -10, -9, -2, -1, 0, 1, 2, 3, 10, 99, 29343432};
|
14975 |
unsigned i;
|
14976 |
SYNTHETIC_INTEGER *si1;
|
14977 |
char buf[100];
|
14978 |
|
14979 |
/* Create a synthetic integer.
|
14980 |
*/
|
14981 |
siCreate(&si1);
|
14982 |
|
14983 |
/* Run through each of the test vectors.
|
14984 |
*/
|
14985 |
for (i=0; i<sizeof(vectors)/sizeof(vectors[0]); i++)
|
14986 |
{
|
14987 |
/* Assign it to be the integer 0. */
|
14988 |
siSetToLong(&si1, vectors[i]);
|
14989 |
|
14990 |
/* Print the value. */
|
14991 |
sprintf(buf, "Vector[%u]", i);
|
14992 |
siDump(&si1, buf);
|
14993 |
|
14994 |
/* Add a horizontal line. */
|
14995 |
gfHline();
|
14996 |
}
|
14997 |
|
14998 |
/* Destroy the synthetic integer. */
|
14999 |
siDestroy(&si1 );
|
15000 |
}
|
15001 |
|
15002 |
|
15003 |
/****************************************************************************/
|
15004 |
/* utFunc2(): */
|
15005 |
/*--------------------------------------------------------------------------*/
|
15006 |
/* DESCRIPTION */
|
15007 |
/* Double-checks the way that integers are added, and also the NAN which */
|
15008 |
/* should occur on overflow. Powers of two are generated by doubling. */
|
15009 |
/****************************************************************************/
|
15010 |
void utFunc2(void)
|
15011 |
{
|
15012 |
SYNTHETIC_INTEGER *arg1, *arg2, *result;
|
15013 |
int i;
|
15014 |
char buf[100];
|
15015 |
|
15016 |
siCreate(&arg1);
|
15017 |
siCreate(&arg2);
|
15018 |
siCreate(&result);
|
15019 |
|
15020 |
siSetToLong(&arg1, 0);
|
15021 |
siSetToLong(&arg2, 1);
|
15022 |
/* Ln(2)/Ln(10) is 0.30, so we should run out of space
|
15023 |
** in around 4000/0.30 = 13,300 or so iterations.
|
15024 |
*/
|
15025 |
|
15026 |
for (i=0; i<13300; i++)
|
15027 |
{
|
15028 |
siAddTwoNonnegative(&arg1, &arg2, &result);
|
15029 |
siCopy(&result, &arg1);
|
15030 |
siCopy(&result, &arg2);
|
15031 |
sprintf(buf, "Iteration %d", i);
|
15032 |
siDump(&result, buf);
|
15033 |
gfHline();
|
15034 |
}
|
15035 |
|
15036 |
siDestroy(&arg1);
|
15037 |
siDestroy(&arg2);
|
15038 |
siDestroy(&result);
|
15039 |
}
|
15040 |
|
15041 |
|
15042 |
/****************************************************************************/
|
15043 |
/* utFunc3(): */
|
15044 |
/*--------------------------------------------------------------------------*/
|
15045 |
/* DESCRIPTION */
|
15046 |
/* Double-checks the behavior of the non-negative result subtraction */
|
15047 |
/* function. */
|
15048 |
/****************************************************************************/
|
15049 |
void utFunc3(void)
|
15050 |
{
|
15051 |
long vectors[] = { 0, 0, /* zero minus zero should be zero */
|
15052 |
1000, 0,
|
15053 |
9, 0,
|
15054 |
1000, 1,
|
15055 |
99, 33,
|
15056 |
99, 99,
|
15057 |
99, 98,
|
15058 |
99, 97,
|
15059 |
99, 96,
|
15060 |
99, 95,
|
15061 |
99, 94,
|
15062 |
99, 93,
|
15063 |
99, 92,
|
15064 |
99, 91,
|
15065 |
99, 90,
|
15066 |
99, 89,
|
15067 |
99, 88,
|
15068 |
99, 97,
|
15069 |
10101, 101,
|
15070 |
10101, 102,
|
15071 |
10101, 100,
|
15072 |
};
|
15073 |
|
15074 |
unsigned i;
|
15075 |
SYNTHETIC_INTEGER *si1, *si2, *result;
|
15076 |
char buf[100];
|
15077 |
|
15078 |
/* Create the synthetic integers
|
15079 |
*/
|
15080 |
siCreate(&si1);
|
15081 |
siCreate(&si2);
|
15082 |
siCreate(&result);
|
15083 |
|
15084 |
/* Run through each of the test vectors.
|
15085 |
*/
|
15086 |
for (i=0; i< sizeof(vectors)/sizeof(vectors[0]); i+=2)
|
15087 |
{
|
15088 |
/* Assign the value to be subtracted from. */
|
15089 |
siSetToLong(&si1, vectors[i]);
|
15090 |
|
15091 |
/* Assign the value to be subtracted. */
|
15092 |
siSetToLong(&si2, vectors[i+1]);
|
15093 |
|
15094 |
/* Make the subtraction. */
|
15095 |
siSubtractToProduceNonnegativeResult(&si1, &si2, &result);
|
15096 |
|
15097 |
/* Print the values. */
|
15098 |
sprintf(buf, "Vector[%u] Arg 1", i/2);
|
15099 |
siDump(&si1, buf);
|
15100 |
gfHline();
|
15101 |
sprintf(buf, "Vector[%u] Arg 2", i/2);
|
15102 |
siDump(&si2, buf);
|
15103 |
gfHline();
|
15104 |
sprintf(buf, "Vector[%u] Result", i/2);
|
15105 |
siDump(&result, buf);
|
15106 |
gfHline();
|
15107 |
}
|
15108 |
|
15109 |
/* Destroy the synthetic integers. */
|
15110 |
siDestroy(&si1 );
|
15111 |
siDestroy(&si2 );
|
15112 |
siDestroy(&result );
|
15113 |
}
|
15114 |
|
15115 |
|
15116 |
/****************************************************************************/
|
15117 |
/* utFunc4(): */
|
15118 |
/*--------------------------------------------------------------------------*/
|
15119 |
/* DESCRIPTION */
|
15120 |
/* Double-checks the behavior of the general addition function. */
|
15121 |
/****************************************************************************/
|
15122 |
void utFunc4(void)
|
15123 |
{
|
15124 |
long vectors[] = { /* This group is the vectors copied from the
|
15125 |
** table in the function above. These are
|
15126 |
** non-specific, but can do no harm to run them
|
15127 |
** through.
|
15128 |
*/
|
15129 |
0, 0, /* zero minus zero should be zero */
|
15130 |
1000, 0,
|
15131 |
9, 0,
|
15132 |
1000, 1,
|
15133 |
99, 33,
|
15134 |
99, 99,
|
15135 |
99, 98,
|
15136 |
99, 97,
|
15137 |
99, 96,
|
15138 |
99, 95,
|
15139 |
99, 94,
|
15140 |
99, 93,
|
15141 |
99, 92,
|
15142 |
99, 91,
|
15143 |
99, 90,
|
15144 |
99, 89,
|
15145 |
99, 88,
|
15146 |
99, 97,
|
15147 |
10101, 101,
|
15148 |
10101, 102,
|
15149 |
10101, 100,
|
15150 |
/* These are the specific vectors. Want to run them
|
15151 |
** through each of the 12 cases in the function.
|
15152 |
*/
|
15153 |
0, 0,
|
15154 |
0, -583,
|
15155 |
-583, 0,
|
15156 |
0, 583,
|
15157 |
583, 0,
|
15158 |
583, -12,
|
15159 |
-12, 583,
|
15160 |
-609, 11,
|
15161 |
11, -609,
|
15162 |
329, 329,
|
15163 |
-329, -329,
|
15164 |
327, 252,
|
15165 |
252, 329,
|
15166 |
-21, -591,
|
15167 |
321, -321,
|
15168 |
-322, 322,
|
15169 |
-42923, -31998,
|
15170 |
};
|
15171 |
|
15172 |
unsigned i;
|
15173 |
SYNTHETIC_INTEGER *si1, *si2, *result;
|
15174 |
char buf[100];
|
15175 |
|
15176 |
/* Create the synthetic integers
|
15177 |
*/
|
15178 |
siCreate(&si1);
|
15179 |
siCreate(&si2);
|
15180 |
siCreate(&result);
|
15181 |
|
15182 |
/* Run through each of the test vectors.
|
15183 |
*/
|
15184 |
for (i=0; i< sizeof(vectors)/sizeof(vectors[0]); i+=2)
|
15185 |
{
|
15186 |
/* Assign the value to be subtracted from. */
|
15187 |
siSetToLong(&si1, vectors[i]);
|
15188 |
|
15189 |
/* Assign the value to be subtracted. */
|
15190 |
siSetToLong(&si2, vectors[i+1]);
|
15191 |
|
15192 |
/* Make the addition. */
|
15193 |
siUnrestrictedAddition(&si1, &si2, &result);
|
15194 |
|
15195 |
/* Print the values. */
|
15196 |
sprintf(buf, "Vector[%u] Arg 1", i/2);
|
15197 |
siDump(&si1, buf);
|
15198 |
gfHline();
|
15199 |
sprintf(buf, "Vector[%u] Arg 2", i/2);
|
15200 |
siDump(&si2, buf);
|
15201 |
gfHline();
|
15202 |
sprintf(buf, "Vector[%u] Result", i/2);
|
15203 |
siDump(&result, buf);
|
15204 |
gfHline();
|
15205 |
}
|
15206 |
|
15207 |
/* Destroy the synthetic integers. */
|
15208 |
siDestroy(&si1 );
|
15209 |
siDestroy(&si2 );
|
15210 |
siDestroy(&result );
|
15211 |
}
|
15212 |
|
15213 |
|
15214 |
/****************************************************************************/
|
15215 |
/* utUnittestAll(): */
|
15216 |
/*--------------------------------------------------------------------------*/
|
15217 |
/* DESCRIPTION */
|
15218 |
/* Sequentially runs all unit tests. */
|
15219 |
/****************************************************************************/
|
15220 |
void utUnitTestAll(void)
|
15221 |
{
|
15222 |
/* utFunc1(); */
|
15223 |
/* utFunc2(); */
|
15224 |
/* utFunc3(); */
|
15225 |
/* utFunc4(); */
|
15226 |
}
|
15227 |
#endif
|
15228 |
|
15229 |
|
15230 |
/****************************************************************************/
|
15231 |
/****************************************************************************/
|
15232 |
/******************** M A I N F U N C T I O N ************************/
|
15233 |
/****************************************************************************/
|
15234 |
/****************************************************************************/
|
15235 |
|
15236 |
/****************************************************************************/
|
15237 |
/* main_c(): */
|
15238 |
/*--------------------------------------------------------------------------*/
|
15239 |
/* DESCRIPTION */
|
15240 |
/* Main function of the program. If this program is ported, main_c() */
|
15241 |
/* must be renamed to main(). The name of main_c() [different than */
|
15242 |
/* main()] was chosen because the main() function of Visual C++ is in */
|
15243 |
/* another source file (it is a C++ wrapper), and two functions cannot */
|
15244 |
/* both have the name main(). */
|
15245 |
/* */
|
15246 |
/* INPUTS */
|
15247 |
/* argc, argv : The count of command-line parameters and the command- */
|
15248 |
/* line parameters. */
|
15249 |
/****************************************************************************/
|
15250 |
int main_c(int argc, char* argv[])
|
15251 |
{
|
15252 |
/*************************************************************************/
|
15253 |
char *stdin_array = NULL;
|
15254 |
/* The characters read from the standard input, verbatim, before
|
15255 |
** further parsing. This pointer, if it is assigned, is a
|
15256 |
** dynamically allocated block, terminated with '\0', and should
|
15257 |
** be free'd at some point.
|
15258 |
*/
|
15259 |
/*************************************************************************/
|
15260 |
struct ipSimpleStringLlNodeStruct *raw_tokens_list = NULL;
|
15261 |
/* Linked list of raw tokens from either the command-line or
|
15262 |
** the standard input if running in batch mode.
|
15263 |
*/
|
15264 |
|
15265 |
#if 0
|
15266 |
{
|
15267 |
int idx;
|
15268 |
|
15269 |
SYNTHETIC_INTEGER *h1, *h2, *k1, *k2, *N;
|
15270 |
|
15271 |
siCreate(&h1);
|
15272 |
siCreate(&h2);
|
15273 |
siCreate(&k1);
|
15274 |
siCreate(&k2);
|
15275 |
siCreate(&N);
|
15276 |
|
15277 |
siSetToLong(&h1, 0);
|
15278 |
siSetToLong(&k1, 1);
|
15279 |
siSetToLong(&h2, 1);
|
15280 |
siSetToLong(&k2, 1000);
|
15281 |
siSetToLong(&N, 1000);
|
15282 |
|
15283 |
for (idx=0; idx<10000; idx++)
|
15284 |
{
|
15285 |
rnFareyTraverse(&h1, &k1, &h2, &k2, &N, 1);
|
15286 |
|
15287 |
printf("index: %d\n", idx);
|
15288 |
siDump(&h1, "h1");
|
15289 |
siDump(&k1, "k1");
|
15290 |
siDump(&h2, "h2");
|
15291 |
siDump(&k2, "k2");
|
15292 |
siDump(&N, "N");
|
15293 |
gfHline();
|
15294 |
}
|
15295 |
|
15296 |
for (idx=9999; idx>=0; idx--)
|
15297 |
{
|
15298 |
rnFareyTraverse(&h1, &k1, &h2, &k2, &N, -1);
|
15299 |
|
15300 |
printf("index: %d\n", idx);
|
15301 |
siDump(&h1, "h1");
|
15302 |
siDump(&k1, "k1");
|
15303 |
siDump(&h2, "h2");
|
15304 |
siDump(&k2, "k2");
|
15305 |
siDump(&N, "N");
|
15306 |
gfHline();
|
15307 |
}
|
15308 |
|
15309 |
exit(0);
|
15310 |
}
|
15311 |
|
15312 |
#endif
|
15313 |
#if 0
|
15314 |
{
|
15315 |
int i;
|
15316 |
|
15317 |
for (i=-10; i <= 10; i++)
|
15318 |
{
|
15319 |
printf("i: %d, i mod 3: %d\n", i, i%3);
|
15320 |
}
|
15321 |
|
15322 |
for (i=-10; i <= 10; i++)
|
15323 |
{
|
15324 |
printf("i: %d, i mod -3: %d\n", i, i%(-3));
|
15325 |
}
|
15326 |
|
15327 |
exit(0);
|
15328 |
}
|
15329 |
#endif
|
15330 |
|
15331 |
/*************************************************************************/
|
15332 |
/* Write introductory message, including version control information. */
|
15333 |
gfHline();printf("RAP (");{unsigned i = 0;while (vcGetVcData(i)){printf(
|
15334 |
"%s",vcGetVcData(i));i++;}}printf(") execution begins.\n");gfHline();
|
15335 |
/*************************************************************************/
|
15336 |
/* Run all built-in unit tests (used only for development). */
|
15337 |
/* utUnitTestAll(); */
|
15338 |
/*************************************************************************/
|
15339 |
/* Split into two cases. Either the command-line pars are on the
|
15340 |
** command-line, or they are coming from stdin. In this section get to
|
15341 |
** the point of having an array of tokens, before concatenation is
|
15342 |
** performed.
|
15343 |
*/
|
15344 |
|
15345 |
#if 0
|
15346 |
{
|
15347 |
SYNTHETIC_INTEGER *i, *j, *k;
|
15348 |
|
15349 |
siCreate(&i);
|
15350 |
|
15351 |
siSetToLong(&i, 788);
|
15352 |
|
15353 |
siDump(&i, "788");
|
15354 |
|
15355 |
siMulByDigit(&i, '3');
|
15356 |
|
15357 |
siDump(&i, "3*788");
|
15358 |
|
15359 |
}
|
15360 |
#endif
|
15361 |
|
15362 |
|
15363 |
if (argc==0)
|
15364 |
{
|
15365 |
asFatal("argc can't be zero--runtime environment anomaly");
|
15366 |
}
|
15367 |
if (argc==1)
|
15368 |
{
|
15369 |
/* "rap" used alone on command line. Probably this is a user trying
|
15370 |
** to figure out what this executable on his hard drive is. Print out
|
15371 |
** an informational message and exit.
|
15372 |
*/
|
15373 |
asInfo();
|
15374 |
}
|
15375 |
else if (argc==2)
|
15376 |
{
|
15377 |
/* If there are two arguments, the second one must be "batch" or the
|
15378 |
** program can't process the input.
|
15379 |
*/
|
15380 |
if (_stricmp("batch", argv[1]))
|
15381 |
{
|
15382 |
asFatal("if only one command-line parameter specified, must be \"batch\"");
|
15383 |
}
|
15384 |
else
|
15385 |
{
|
15386 |
/* We're running batch mode. Must take our parameters from a file as if they
|
15387 |
** came from the command line.
|
15388 |
*/
|
15389 |
/* First, buffer the entire standard input stream to a character buffer.
|
15390 |
*/
|
15391 |
stdin_array = ipBufferStandardInputStream();
|
15392 |
/* printf("%d\n", strlen(stdin_array)); */
|
15393 |
/* printf("%s\n", stdin_array); */
|
15394 |
|
15395 |
/* Make the transformation from the buffered standard input array to
|
15396 |
** a linked list of tokens.
|
15397 |
*/
|
15398 |
ipTranslateStdinToRawTokens(stdin_array, &raw_tokens_list);
|
15399 |
|
15400 |
/* At this point, the array of characters taken from the standard
|
15401 |
** input is disposable. Free it up.
|
15402 |
*/
|
15403 |
maFree(stdin_array);
|
15404 |
stdin_array = NULL;
|
15405 |
}
|
15406 |
}
|
15407 |
else
|
15408 |
{
|
15409 |
/* argc > 2. In this case, can take the command-line arguments and
|
15410 |
** pack them into a linked list, same as would do with stdin input.
|
15411 |
*/
|
15412 |
ipPackCmdLineArgsIntoLinkedList(argc, argv, &raw_tokens_list);
|
15413 |
}
|
15414 |
|
15415 |
/* In either case (whether we obtained the linked list from the command-line
|
15416 |
** or from stdin), we must process continuation characters and concatenate tokens.
|
15417 |
*/
|
15418 |
ipProcessLinkedListParameterContinuationCharacters(&raw_tokens_list);
|
15419 |
|
15420 |
/* Parse the command-line or stdin parameters.
|
15421 |
*/
|
15422 |
ipParseCommandLineParameters(&raw_tokens_list);
|
15423 |
|
15424 |
#if 1
|
15425 |
/* Search for a matching command template and execute the command if appropriate
|
15426 |
** or error out if no template match.
|
15427 |
*/
|
15428 |
ipExecuteCommand();
|
15429 |
#endif
|
15430 |
|
15431 |
|
15432 |
#if 0
|
15433 |
/* For diagnostic purposes, print out the linked list. */
|
15434 |
{
|
15435 |
struct ipSimpleStringLlNodeStruct *p;
|
15436 |
|
15437 |
p = raw_tokens_list;
|
15438 |
|
15439 |
while (p)
|
15440 |
{
|
15441 |
printf("%s\n", p->s);
|
15442 |
|
15443 |
p = p->next;
|
15444 |
}
|
15445 |
|
15446 |
}
|
15447 |
#endif
|
15448 |
#if 0
|
15449 |
gfBannerHeading("Test 21", 2);
|
15450 |
#endif
|
15451 |
|
15452 |
/*************************************************************************/
|
15453 |
printf("RAP execution ends.\n");gfHline();
|
15454 |
/*************************************************************************/
|
15455 |
return(0); /* Return value not set for caller--zero used in all cases. */
|
15456 |
/*************************************************************************/
|
15457 |
}
|
15458 |
|
15459 |
|
15460 |
/* $History: rap_c.c $
|
15461 |
*
|
15462 |
* ***************** Version 21 *****************
|
15463 |
* User: Dashley1 Date: 11/13/00 Time: 3:59a
|
15464 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15465 |
* Final versions for submission to the ACM.
|
15466 |
*
|
15467 |
* ***************** Version 20 *****************
|
15468 |
* User: Dashley1 Date: 11/10/00 Time: 10:49a
|
15469 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15470 |
* Completion of FAB functionality.
|
15471 |
*
|
15472 |
* ***************** Version 19 *****************
|
15473 |
* User: Dashley1 Date: 11/09/00 Time: 1:04a
|
15474 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15475 |
* Completion of minimum denominator work.
|
15476 |
*
|
15477 |
* ***************** Version 18 *****************
|
15478 |
* User: Dashley1 Date: 11/01/00 Time: 6:21p
|
15479 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15480 |
* FN functionality completed.
|
15481 |
*
|
15482 |
* ***************** Version 17 *****************
|
15483 |
* User: Dashley1 Date: 11/01/00 Time: 4:42a
|
15484 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15485 |
* FN functionality mostly complete. Throws an OS exception when rational
|
15486 |
* number to approximate is < 1/N, need to proofread and diagnose.
|
15487 |
*
|
15488 |
* ***************** Version 16 *****************
|
15489 |
* User: Dashley1 Date: 10/30/00 Time: 6:40p
|
15490 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15491 |
* Completion of CF expansion functionality.
|
15492 |
*
|
15493 |
* ***************** Version 15 *****************
|
15494 |
* User: Dashley1 Date: 10/29/00 Time: 10:09p
|
15495 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15496 |
* DAP function finished and checked.
|
15497 |
*
|
15498 |
* ***************** Version 14 *****************
|
15499 |
* User: Dashley1 Date: 10/29/00 Time: 4:00a
|
15500 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15501 |
* Safety check-in.
|
15502 |
*
|
15503 |
* ***************** Version 13 *****************
|
15504 |
* User: Dashley1 Date: 10/28/00 Time: 4:23a
|
15505 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15506 |
* Rational number parsing complete.
|
15507 |
*
|
15508 |
* ***************** Version 12 *****************
|
15509 |
* User: Dashley1 Date: 10/27/00 Time: 4:03a
|
15510 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15511 |
* gcd() functionality implemented and tested.
|
15512 |
*
|
15513 |
* ***************** Version 11 *****************
|
15514 |
* User: Dashley1 Date: 10/27/00 Time: 3:18a
|
15515 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15516 |
* Division function checked in and tested. Safety check-in.
|
15517 |
*
|
15518 |
* ***************** Version 10 *****************
|
15519 |
* User: Dashley1 Date: 10/26/00 Time: 3:05a
|
15520 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15521 |
* Safety check-in. Integer exponentiation complete.
|
15522 |
*
|
15523 |
* ***************** Version 9 *****************
|
15524 |
* User: Dashley1 Date: 10/25/00 Time: 3:28a
|
15525 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15526 |
* Safety check-in.
|
15527 |
*
|
15528 |
* ***************** Version 8 *****************
|
15529 |
* User: Dashley1 Date: 10/23/00 Time: 7:18p
|
15530 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15531 |
* Safety check-in.
|
15532 |
*
|
15533 |
* ***************** Version 7 *****************
|
15534 |
* User: Dashley1 Date: 10/23/00 Time: 12:01a
|
15535 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15536 |
* Major progress, safety check-in.
|
15537 |
*
|
15538 |
* ***************** Version 6 *****************
|
15539 |
* User: Dashley1 Date: 10/20/00 Time: 3:30p
|
15540 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15541 |
* Safety check-in.
|
15542 |
*
|
15543 |
* ***************** Version 5 *****************
|
15544 |
* User: Dashley1 Date: 10/20/00 Time: 5:12a
|
15545 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15546 |
* Test of keyword expansion when keywords on same line.
|
15547 |
*
|
15548 |
* ***************** Version 4 *****************
|
15549 |
* User: Dashley1 Date: 10/20/00 Time: 4:35a
|
15550 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15551 |
* Test checkin to test keyword expansion changes.
|
15552 |
*
|
15553 |
* ***************** Version 3 *****************
|
15554 |
* User: Dashley1 Date: 10/18/00 Time: 4:15a
|
15555 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15556 |
* Second check-in to test VC embedding.
|
15557 |
*
|
15558 |
* ***************** Version 2 *****************
|
15559 |
* User: Dashley1 Date: 10/18/00 Time: 4:08a
|
15560 |
* Updated in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15561 |
* Check-in to test version embedding functionality.
|
15562 |
*
|
15563 |
* ***************** Version 1 *****************
|
15564 |
* User: Dashley1 Date: 10/18/00 Time: 3:58a
|
15565 |
* Created in $/ACM Rational Approximation Paper And Algorithms/C-Language Implementation
|
15566 |
* Initial check-in.
|
15567 |
*/
|
15568 |
|
15569 |
/* End of file RAP_C.C */ |