gmpy2-2.1.0b3/0000775000175000017500000000000013530663166012660 5ustar casecase00000000000000gmpy2-2.1.0b3/COPYING0000664000175000017500000010451313105222070013676 0ustar casecase00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . gmpy2-2.1.0b3/COPYING.LESSER0000664000175000017500000001674313105222070014701 0ustar casecase00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. gmpy2-2.1.0b3/INSTALL0000664000175000017500000000560013356026702013705 0ustar casecase00000000000000Installing gmpy2 on Unix/Linux ------------------------------ Many Linux distributions provide gmpy2 in their repositories. Please check your distribution's repositories first. Requirements ------------ gmpy2 requires recent versions of GMP, MPFR and MPC. Specifically, gmpy2 requires GMP 5.0.0 or later, MPFR 3.1.0 or later, and MPC 1.0.0 or later. Quick Instructions ------------------ To manually compile gmpy2, you will need to install the development libraries for Python, GMP, MPFR, and MPC are installed. The package names vary between distributions. "python-dev", "python2-dev", or "python3.4-dev" are typical package names for the Python development files. Installing the MPC development package should automatically install the GMP and MPFR development packages. "libmpc-dev" is a typical name for the MPC development package. Once the required development libraries have been installed, compiling should be as simple as: $ cd $ python setup.py build_ext $ sudo python setup.py install If this fails, read on. Detailed Instructions --------------------- If your Linux distribution does not support recent versions of GMP, MPFR and MPC, you will need to compile your own versions. To avoid any possible conflict with existing libraries on your system, it is recommended to build a statically linked version of gmpy2. The following instructions assume the GMP, MPFR, MPC, and gmpy2 source files are all located in $HOME/src and the static libraries are installed into $HOME/static 1. Create the desired destination directory for the GMP, MPFR, and MPC libraries. $ mkdir $HOME/static 2. Download and un-tar the GMP source code. Change to GMP source directory and compile GMP. $ cd $HOME/src/gmp-6.0.0 $ ./configure --prefix=$HOME/static --enable-static --disable-shared --with-pic $ make $ make check $ make install 3. Download and un-tar the MPFR source code. Change to MPFR source directory and compile MPFR. $ cd $HOME/src/mpfr-3.1.2 $ ./configure --prefix=$HOME/static --enable-static --disable-shared --with-pic --with-gmp=$HOME/static $ make $ make check $ make install 4. Download and un-tar the MPC source code. Change to MPC source directory and compile MPC. $ cd $HOME/src/mpc-1.0.3 $ ./configure --prefix=$HOME/static --enable-static --disable-shared --with-pic --with-gmp=$HOME/static --with-mpfr=$HOME/static $ make $ make check $ make install 5. Compile gmpy2 and specify the location of GMP, MPFR and MPC. $ cd $HOME/src/gmpy2-2.1.0 $ python setup.py build_ext --static=$HOME/static install If you get a "permission denied" error message, you may need to use: $ python setup.py build_ext --static=$HOME/static $ sudo python setup.py install Installing gmpy2 on Windows --------------------------- Please see windows_build.txt (preferred) or msys2_build.txt (alpha). gmpy2-2.1.0b3/MANIFEST.in0000664000175000017500000000023413356026702014410 0ustar casecase00000000000000include README include INSTALL include COPYING include docs/* include test/* include COPYING.LESSER include src/* include gmpy2/gmpy2.h include gmpy2/*.pxd gmpy2-2.1.0b3/PKG-INFO0000664000175000017500000000416313530663166013761 0ustar casecase00000000000000Metadata-Version: 1.1 Name: gmpy2 Version: 2.1.0b3 Summary: gmpy2 interface to GMP, MPFR, and MPC for Python 2.7 and 3.4+ Home-page: https://github.com/aleaxit/gmpy Author: Case Van Horsen Author-email: casevh@gmail.com License: LGPL-3.0+ Description: gmpy2 is an optimized, C-coded Python extension module that supports fast multiple-precision arithmetic. gmpy2 is based on the original gmpy module. gmpy2 adds support for correctly rounded multiple-precision real arithmetic (using the MPFR library) and complex arithmetic (using the MPC library). The gmpy2 2.0.x series is a stable version that is only receiving bug fixes. The main development branch (2.1.x) was extensively refactored. The most significant changes are support for thread-safe contexts and context methods. gmpy2 is available at https://pypi.python.org/pypi/gmpy2/ Documentation is available at https://gmpy2.readthedocs.io/en/latest/ Keywords: gmp mpfr mpc multiple-precision arbitrary-precision precision bignum Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+) Classifier: Natural Language :: English Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: POSIX Classifier: Programming Language :: C Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Scientific/Engineering :: Mathematics Classifier: Topic :: Software Development :: Libraries :: Python Modules gmpy2-2.1.0b3/README0000664000175000017500000000122313356026702013531 0ustar casecase00000000000000gmpy2 is an optimized, C-coded Python extension module that supports fast multiple-precision arithmetic. gmpy2 is based on the original gmpy module. gmpy2 adds support for correctly rounded multiple-precision real arithmetic (using the MPFR library) and complex arithmetic (using the MPC library). The gmpy2 2.0.x series is a stable version that is only receiving bug fixes. The main development branch (2.1.x) was extensively refactored. The most significant changes are support for thread-safe contexts and context methods. gmpy2 is available at https://pypi.python.org/pypi/gmpy2/ Documentation is available at https://gmpy2.readthedocs.io/en/latest/ gmpy2-2.1.0b3/docs/0000775000175000017500000000000013530663166013610 5ustar casecase00000000000000gmpy2-2.1.0b3/docs/Makefile0000664000175000017500000001126313244654531015251 0ustar casecase00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" create_static: if [ ! -d _static ]; then mkdir _static; fi clean: -rm -rf $(BUILDDIR)/* html: create_static $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: create_static $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: create_static $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: create_static $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: create_static $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/GMPY2.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/GMPY2.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/GMPY2" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/GMPY2" @echo "# devhelp" epub: create_static $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: create_static $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: create_static $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." make -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: create_static $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: create_static $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." gmpy2-2.1.0b3/docs/advmpz.rst0000664000175000017500000002022013356026702015632 0ustar casecase00000000000000Multiple-precision Integers (Advanced topics) ============================================= The xmpz type ------------- gmpy2 provides access to an experimental integer type called *xmpz*. The *xmpz* type is a mutable integer type. In-place operations (+=, //=, etc.) modify the original object and do not create a new object. Instances of *xmpz* cannot be used as dictionary keys. :: >>> import gmpy2 >>> from gmpy2 import xmpz >>> a = xmpz(123) >>> b = a >>> a += 1 >>> a xmpz(124) >>> b xmpz(124) The ability to change an *xmpz* object in-place allows for efficient and rapid bit manipulation. Individual bits can be set or cleared:: >>> a[10]=1 >>> a xmpz(1148) Slice notation is supported. The bits referenced by a slice can be either 'read from' or 'written to'. To clear a slice of bits, use a source value of 0. In 2s-complement format, 0 is represented by an arbitrary number of 0-bits. To set a slice of bits, use a source value of ~0. The *tilde* operator inverts, or complements the bits in an integer. (~0 is -1 so you can also use -1.) In 2s-complement format, -1 is represented by an arbitrary number of 1-bits. If a value for *stop* is specified in a slice assignment and the actual bit-length of the *xmpz* is less than *stop*, then the destination *xmpz* is logically padded with 0-bits to length *stop*. :: >>> a=xmpz(0) >>> a[8:16] = ~0 >>> bin(a) '0b1111111100000000' >>> a[4:12] = ~a[4:12] >>> bin(a) '0b1111000011110000' Bits can be reversed:: >>> bin(a) '0b10001111100' >>> a[::] = a[::-1] >>> bin(a) '0b111110001' The *iter_bits()* method returns a generator that returns True or False for each bit position. The methods *iter_clear()*, and *iter_set()* return generators that return the bit positions that are 1 or 0. The methods support arguments *start* and *stop* that define the beginning and ending bit positions that are used. To mimic the behavior of slices. the bit positions checked include *start* but the last position checked is *stop* - 1. :: >>> a=xmpz(117) >>> bin(a) '0b1110101' >>> list(a.iter_bits()) [True, False, True, False, True, True, True] >>> list(a.iter_clear()) [1, 3] >>> list(a.iter_set()) [0, 2, 4, 5, 6] >>> list(a.iter_bits(stop=12)) [True, False, True, False, True, True, True, False, False, False, False, False] The following program uses the Sieve of Eratosthenes to generate a list of prime numbers. :: from __future__ import print_function import time import gmpy2 def sieve(limit=1000000): '''Returns a generator that yields the prime numbers up to limit.''' # Increment by 1 to account for the fact that slices do not include # the last index value but we do want to include the last value for # calculating a list of primes. sieve_limit = gmpy2.isqrt(limit) + 1 limit += 1 # Mark bit positions 0 and 1 as not prime. bitmap = gmpy2.xmpz(3) # Process 2 separately. This allows us to use p+p for the step size # when sieving the remaining primes. bitmap[4 : limit : 2] = -1 # Sieve the remaining primes. for p in bitmap.iter_clear(3, sieve_limit): bitmap[p*p : limit : p+p] = -1 return bitmap.iter_clear(2, limit) if __name__ == "__main__": start = time.time() result = list(sieve()) print(time.time() - start) print(len(result)) Advanced Number Theory Functions -------------------------------- The following functions are based on mpz_lucas.c and mpz_prp.c by David Cleaver. A good reference for probable prime testing is http://www.pseudoprime.com/pseudo.html **is_bpsw_prp(...)** is_bpsw_prp(n) will return True if *n* is a Baillie-Pomerance-Selfridge-Wagstaff probable prime. A BPSW probable prime passes the is_strong_prp() test with base 2 and the is_selfridge_prp() test. **is_euler_prp(...)** is_euler_prp(n,a) will return True if *n* is an Euler (also known as Solovay-Strassen) probable prime to the base *a*. | Assuming: | gcd(n, a) == 1 | n is odd | | Then an Euler probable prime requires: | a**((n-1)/2) == 1 (mod n) **is_extra_strong_lucas_prp(...)** is_extra_strong_lucas_prp(n,p) will return True if *n* is an extra strong Lucas probable prime with parameters (p,1). | Assuming: | n is odd | D = p*p - 4, D != 0 | gcd(n, 2*D) == 1 | n = s*(2**r) + Jacobi(D,n), s odd | | Then an extra strong Lucas probable prime requires: | lucasu(p,1,s) == 0 (mod n) | or | lucasv(p,1,s) == +/-2 (mod n) | or | lucasv(p,1,s*(2**t)) == 0 (mod n) for some t, 0 <= t < r **is_fermat_prp(...)** is_fermat_prp(n,a) will return True if *n* is a Fermat probable prime to the base a. | Assuming: | gcd(n,a) == 1 | | Then a Fermat probable prime requires: | a**(n-1) == 1 (mod n) **is_fibonacci_prp(...)** is_fibonacci_prp(n,p,q) will return True if *n* is a Fibonacci probable prime with parameters (p,q). | Assuming: | n is odd | p > 0, q = +/-1 | p*p - 4*q != 0 | | Then a Fibonacci probable prime requires: | lucasv(p,q,n) == p (mod n). **is_lucas_prp(...)** is_lucas_prp(n,p,q) will return True if *n* is a Lucas probable prime with parameters (p,q). | Assuming: | n is odd | D = p*p - 4*q, D != 0 | gcd(n, 2*q*D) == 1 | | Then a Lucas probable prime requires: | lucasu(p,q,n - Jacobi(D,n)) == 0 (mod n) **is_selfridge_prp(...)** is_selfridge_prp(n) will return True if *n* is a Lucas probable prime with Selfidge parameters (p,q). The Selfridge parameters are chosen by finding the first element D in the sequence {5, -7, 9, -11, 13, ...} such that Jacobi(D,n) == -1. Let p=1 and q = (1-D)/4 and then perform a Lucas probable prime test. **is_strong_bpsw_prp(...)** is_strong_bpsw_prp(n) will return True if *n* is a strong Baillie-Pomerance-Selfridge-Wagstaff probable prime. A strong BPSW probable prime passes the is_strong_prp() test with base 2 and the is_strongselfridge_prp() test. **is_strong_lucas_prp(...)** is_strong_lucas_prp(n,p,q) will return True if *n* is a strong Lucas probable prime with parameters (p,q). | Assuming: | n is odd | D = p*p - 4*q, D != 0 | gcd(n, 2*q*D) == 1 | n = s*(2**r) + Jacobi(D,n), s odd | | Then a strong Lucas probable prime requires: | lucasu(p,q,s) == 0 (mod n) | or | lucasv(p,q,s*(2**t)) == 0 (mod n) for some t, 0 <= t < r **is_strong_prp(...)** is_strong_prp(n,a) will return True if *n* is a strong (also known as Miller-Rabin) probable prime to the base a. | Assuming: | gcd(n,a) == 1 | n is odd | n = s*(2**r) + 1, with s odd | | Then a strong probable prime requires one of the following is true: | a**s == 1 (mod n) | or | a**(s*(2**t)) == -1 (mod n) for some t, 0 <= t < r. **is_strong_selfridge_prp(...)** is_strong_selfridge_prp(n) will return True if *n* is a strong Lucas probable prime with Selfidge parameters (p,q). The Selfridge parameters are chosen by finding the first element D in the sequence {5, -7, 9, -11, 13, ...} such that Jacobi(D,n) == -1. Let p=1 and q = (1-D)/4 and then perform a strong Lucas probable prime test. **lucasu(...)** lucasu(p,q,k) will return the k-th element of the Lucas U sequence defined by p,q. p*p - 4*q must not equal 0; k must be greater than or equal to 0. **lucasu_mod(...)** lucasu_mod(p,q,k,n) will return the k-th element of the Lucas U sequence defined by p,q (mod n). p*p - 4*q must not equal 0; k must be greater than or equal to 0; n must be greater than 0. **lucasv(...)** lucasv(p,q,k) will return the k-th element of the Lucas V sequence defined by parameters (p,q). p*p - 4*q must not equal 0; k must be greater than or equal to 0. **lucasv_mod(...)** lucasv_mod(p,q,k,n) will return the k-th element of the Lucas V sequence defined by parameters (p,q) (mod n). p*p - 4*q must not equal 0; k must be greater than or equal to 0; n must be greater than 0. gmpy2-2.1.0b3/docs/conf.py0000664000175000017500000001557713463454541015126 0ustar casecase00000000000000# -*- coding: utf-8 -*- # # gmpy2 documentation build configuration file, created by # sphinx-quickstart on Fri Feb 24 19:56:16 2012. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.imgmath'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'gmpy2' copyright = u'2012, 2013, 2014, 2017, 2018, 2019 Case Van Horsen' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '2.1' # The full version, including alpha/beta/rc tags. release = '2.1.0b1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'gmpy2doc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'gmpy2.tex', 'gmpy2 Documentation', 'Case Van Horsen', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'gmpy2', 'gmpy2 Documentation', ['Case Van Horsen'], 3) ] gmpy2-2.1.0b3/docs/conversion.rst0000664000175000017500000000316213441640452016523 0ustar casecase00000000000000Conversion methods and gmpy2's numbers ====================================== Conversion methods ------------------ A python object could interact with gmpy2 if it implements one of the following methods: - **__mpz__** : return an object of . - **__mpq__** : return an object of . - **__mpfr__** : return an object of . - **__mpc__** : return an object of . | Implementing on of these methods allow gmpy2 to convert a python object into a gmpy2 type. | Example:: >>> from gmpy2 import mpz >>> class CustInt: ... def __init__(self, x): ... self.x = x ... def __mpz__(self): ... return mpz(self.x) ... >>> ci = CustInt(5) >>> z = mpz(ci); z mpz(5) >>> type(z) Arithmetic operations --------------------- | gmpy2 allow arithmetic operations between gmpy2 numbers and objects with conversion methods. | Operation with object that implements floating conversion and exact conversion methods are not supported. | That means that only the following cases are supported: - An integer type have to implement **__mpz__** - A rational type have to implement **__mpq__** and can implement **__mpz__** - A real type have to implement **__mpfr__** - A complex type have to implement **__mpc__** and can implement **__mpfr__** Examples:: >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> class Q: ... def __mpz__(self): return mpz(1) ... def __mpq__(self): return mpq(3,2) >>> q = Q() >>> mpz(2) + q mpq(7,2) >>> mpq(1,2) * q mpq(3,4) >>> mpfr(10) * q mpfr('15.0') gmpy2-2.1.0b3/docs/cython.rst0000664000175000017500000001014213244654531015642 0ustar casecase00000000000000Cython usage ============ The gmpy2 module provides a C-API that can be conveniently used from Cython. All types and functions are declared in the header gmpy2.pxd that is installed automatically in your Python path together with the library. Initialization -------------- In order to use the C-API you need to make one call to the function **void import_gmpy2(void)**. Types ----- The types **mpz**, **mpq**, **mpfr** and **mpc** are declared as extension types in gmpy2.pxd. They correspond respectively to the C structures **MPZ_Object**, **MPQ_Object**, **MPFR_Object** and **MPC_Object**. Fast type checking can be done with the following C functions **bint MPZ_Check(object)** equivalent to **isinstance(obj, mpz)** **bint MPQ_Check(object)** equivalent to **isinstance(obj, mpq)** **bint MPFR_Check(object)** equivalent to **isinstance(obj, mpfr)** **bint MPC_Check(object)** equivalent to **isinstance(obj, mpc)** Object creation --------------- To create a new gmpy2 types there are four basic functions **mpz GMPy_MPZ_New(void * ctx)** create a new mpz object from a given context ctx **mpq GMPy_MPQ_New(void * ctx)** create a new mpq object from a given context ctx **mpfr MPFR_New(void * ctx, mpfr_prec_t prec)** create a new mpfr object with given context ctx and precision prec **mpc MPC_New(void * ctx, mpfr_prec_t rprec, mpfr_prec_t iprec)** create a new mpc object with given context ctx, precisions rprec and iprec of respectively real and imaginary parts The context can be set to **NULL** and controls the default behavior (e.g. precision). The gmpy2.pxd header also provides convenience macro to wrap a (copy of) a mpz_t, mpq_t, mpfr_t or a mpc_t object into the corresponding gmpy2 type. **mpz GMPy_MPZ_From_mpz(mpz_srcptr z)** return a new mpz object with a given mpz_t value z **mpq GMPy_MPQ_From_mpq(mpq_srcptr q)** return a new mpq object from a given mpq_t value q **mpq GMPy_MPQ_From_mpz(mpz_srcptr num, mpz_srcptr den)** return a new mpq object with a given mpz_t numerator num and mpz_t denominator den **mpfr GMPy_MPFR_From_mpfr(mpfr_srcptr x)** return a new mpfr object with a given mpfr_t value x **mpc GMPy_MPC_From_mpc(mpc_srcptr c)** return a new mpc object with a given mpc_t value c **mpc GMPy_MPC_From_mpfr(mpfr_srcptr re, mpfr_srcptr im)** return a new mpc object with a given mpfr_t real part re and mpfr_t imaginary part im Access to the underlying C type -------------------------------- Each of the gmpy2 objects has a field corresponding to the underlying C type. The following functions give access to this field **mpz_t MPZ(mpz)** **mpq_t MPQ(mpq)** **mpfr_t MPFR(mpfr)** **mpc_t MPC(mpc)** Compilation ------------ The header gmpy2.pxd as well as the C header gmpy2.h from which it depends are installed in the Python path. In order to make Cython and the C compiler aware of the existence of these files, the Python path should be part of the include directories. Recall that **import_gmpy2()** needs to be called *before* any other function of the C-API. Here is a minimal example of a Cython file test_gmpy2.pyx :: "A minimal setup.py for compiling test_gmpy2.pyx" from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize import sys ext = Extension("test_gmpy2", ["test_gmpy2.pyx"], include_dirs=sys.path, libraries=['gmp', 'mpfr', 'mpc']) setup( name="cython_gmpy_test", ext_modules=cythonize([ext], include_path=sys.path) ) The corresponding setup.py is given below. :: "A minimal cython file test_gmpy2.pyx" from gmpy2 cimport * cdef extern from "gmp.h": void mpz_set_si(mpz_t, long) import_gmpy2() # needed to initialize the C-API cdef mpz z = GMPy_MPZ_New(NULL) mpz_set_si(MPZ(z), -7) print(z + 3) With these two files in the same repository, you should be able to compile your module using :: $ python setup.py build_ext --inplace For more about compilation and installation of cython files and extension modules, please refer to the official documentation of Cython and distutils. gmpy2-2.1.0b3/docs/history.rst0000664000175000017500000001773013463456636016062 0ustar casecase00000000000000Changes for gmpy2 releases ========================== Changes in gmpy2 2.1.0b1 ------------------------ * Added cmp() and cmp_abs(). * Improved compatibility with _numbers_ protocol. * Many bug fixes. Changes in gmpy2 2.1.a05 ------------------------ * Fix qdiv() not returning mpz() when it should. * Added root_of_unity(). Changes in gmpy2 2.1.0a4 ------------------------ * Fix issue 204; missing file for Cython. * Additional support for MPFR 4 - Add fmma() and fmms() Changes in gmpy2 2.1.0a3 ------------------------ * Updates to setup.py. * Initial support for MPFR4 - Add nrandom() - grandom() now calls nrandom twice; may return different values versus MPFR3 - Add rootn(); same as root() except different sign when taking even root of -0.0 Changes in gmpy2 2.1.0a2 ------------------------ * Revised build process. * Removal of unused code/macros. * Cleanup of Cython interface. Changes in gmpy2 2.1.0a1 ------------------------ * Thread-safe contexts are now supported. Properly integrating thread-safe contexts required an extensive rewrite of almost all internal functions. * MPFR and MPC are now required. It is no longer possible to build a version of gmpy2 that only supports the GMP library. * The function inverse() now raises an exception if the inverse does not exist. * Context methods have been added for MPFR/MPC related functions. * A new context option (*rational_division*) has been added that changes the behavior of integer division involving *mpz* instances to return a rational result instead of a floating point result. * gmpy2 types are now registered in the numeric tower. * In previous versions of gmpy2, *gmpy2.mpz* was a factory function that returned an *mpz* instance. *gmpy2.mpz* is now an actual type. The same is true for the other gmpy2 types. * If a Python object has an __mpz__ method, it will be called bye *mpz()* to allow an unrecognized type to be converted to an mpz instance. The same is true for the other gmpy2 types. * A new C-API and Cython interface has been added. Changes in gmpy2 2.0.4 ---------------------- * Fix bit_scan0() for negative values. * Changes to setup.py to allow static linking. * Fix performance regression with mpmath and Python 3. Changes in gmpy2 2.0.3 ---------------------- * Fix lucas2() and atanh(); they were returning incorrect values. Changes in gmpy2 2.0.2 ---------------------- * Rebuild Windows binary installers due to MPIR 2.6.0 bug in next_prime(). * Another fix for is_extra_strong_lucas_prp(). Changes in gmpy2 2.0.1 ---------------------- * Updated setup.py to work in more situations. * Corrected exception handling in basic operations with mpfr type. * Correct InvalidOperation exception not raised in certain circumstances. * invert() now raises an exception if the modular inverse does not exist. * Fixed internal exception in is_bpsw_prp() and is_strong_bpsw_prp(). * Updated is_extra_strong_lucas_prp() to latest version. Changes in gmpy2 2.0.0 ---------------------- * Fix segmentation fault in _mpmath_normalize (an undocumented helper function specifically for mpmath.) * Improved setup.py See below for documentation on the changes. * Fix issues when compiled without support for MPFR. * Conversion of too large an mpz to float now raises OverflowError instead of returning *inf*. * Renamed min2()/max2() to minnum()/maxnum() * The build and install process (i.e. setup.py) has been completely rewritten. See the Installation section for more information. * get_context() no longer accepts keyword arguments. Known issues in gmpy2 2.0.0 ----------------------------- * The test suite is still incomplete. Changes in gmpy2 2.0.0b4 ------------------------ * Added __ceil__, __floor__, __trunc__, and __round__ methods to mpz and mpq types. * Added __complex__ to mpc type. * round(mpfr) now correctly returns an mpz type. * If no arguments are given to mpz, mpq, mpfr, mpc, and xmpz, return 0 of the appropriate type. * Fix broken comparison between mpz and mpq when mpz is on the left. * Added __sizeof__ to all types. *Note: sys.getsizeof() calls __sizeof__ to get the memory size of a gmpy2 object. The returned value reflects the size of the allocated memory which may be larger than the actual minimum memory required by the object.* Known issues in gmpy2 2.0.0b4 ----------------------------- * The new test suite (test/runtest.py) is incomplete and some tests fail on Python 2.x due to formatting issues. Changes in gmpy2 2.0.0b3 ------------------------ * mp_version(), mpc_version(), and mpfr_version() now return normal strings on Python 2.x instead of Unicode strings. * Faster conversion of the standard library Fraction type to mpq. * Improved conversion of the Decimal type to mpfr. * Consistently return OverflowError when converting "inf". * Fix mpz.__format__() when the format code includes "#". * Add is_infinite() and deprecate is_inf(). * Add is_finite() and deprecate is_number(). * Fixed the various is_XXX() tests when used with mpc. * Added caching for mpc objects. * Faster code path for basic operation is both operands are mpfr or mpc. * Fix mpfr + float segmentation fault. Changes in gmpy2 2.0.0b2 ------------------------ * Allow xmpz slice assignment to increase length of xmpz instance by specifying a value for stop. * Fixed reference counting bug in several is_xxx_prp() tests. * Added iter_bits(), iter_clear(), iter_set() methods to xmpz. * Added powmod() for easy access to three argument pow(). * Removed addmul() and submul() which were added in 2.0.0b1 since they are slower than just using Python code. * Bug fix in gcd_ext when both arguments are not mpz. * Added ieee() to create contexts for 32, 64, or 128 bit floats. * Bug fix in context() not setting emax/emin correctly if they had been changed earlier. * Contexts can be directly used in with statement without requiring set_context()/local_context() sequence. * local_context() now accepts an optional context. Changes in gmpy2 2.0.0b1 and earlier ------------------------------------ * Renamed functions that manipulate individual bits to bit_XXX() to align with bit_length(). * Added caching for mpq. * Added rootrem(), fib2(), lucas(), lucas2(). * Support changed hash function in Python 3.2. * Added is_even(), is_odd(). * Add caching of the calculated hash value. * Add xmpz (mutable mpz) type. * Fix mpq formatting issue. * Add read/write bit access using slices to xmpz. * Add read-only bit access using slices to mpz. * Add pack()/unpack() methods to split/join an integer into n-bit chunks. * Add support for MPFR (casevh) * Removed fcoform float conversion modifier. * Add support for MPC. * Added context manager. * Allow building with just GMP/MPIR if MPFR not available. * Allow building with GMP/MPIR and MPFR if MPC not available. * Removed most instance methods in favor of gmpy2.function. The general guideline is that *properties* of an instance can be done via instance methods but *functions* that return a new result are done using gmpy2.function. * Added __ceil__, __floor__, and __trunc__ methods since they are called by math.ceil(), math.floor(), and math.trunc(). * Removed gmpy2.pow() to avoid conflicts. * Removed gmpy2._copy and added xmpz.copy. * Added support for __format__. * Added as_integer_ratio, as_mantissa_exp, as_simple_fraction. * Updated rich_compare. * Require MPFR 3.1.0+ to get divby0 support. * Added fsum(), degrees(), radians(). * Updated random number generation support. * Changed license to LGPL 3+. * Added lucasu, lucasu_mod, lucasv, and lucasv_mod. *Based on code contributed by David Cleaver.* * Added probable-prime tests. *Based on code contributed by David Cleaver.* * Added to_binary()/from_binary. * Renamed numdigits() to num_digits(). * Added keyword precision to constants. * Added addmul() and submul(). * Added __round__(), round2(), round_away() for mpfr. * round() is no longer a module level function. * Renamed module functions min()/max() to min2()/max2(). * No longer conflicts with builtin min() and max() * Removed set_debug() and related functionality. gmpy2-2.1.0b3/docs/index.rst0000664000175000017500000000100213441640452015434 0ustar casecase00000000000000.. gmpy2 documentation master file, created by sphinx-quickstart on Fri Feb 24 19:56:16 2012. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to gmpy2's documentation! ================================= Contents: .. toctree:: :maxdepth: 2 intro overview mpz advmpz mpq mpfr mpc cython conversion history Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` gmpy2-2.1.0b3/docs/intro.rst0000664000175000017500000001356613463457612015512 0ustar casecase00000000000000Introduction to gmpy2 ===================== gmpy2 is a C-coded Python extension module that supports multiple-precision arithmetic. gmpy2 is the successor to the original gmpy module. The gmpy module only supported the GMP multiple-precision library. gmpy2 adds support for the MPFR (correctly rounded real floating-point arithmetic) and MPC (correctly rounded complex floating-point arithmetic) libraries. gmpy2 also updates the API and naming conventions to be more consistent and support the additional functionality. The following libraries are supported: * GMP for integer and rational arithmetic Home page: http://gmplib.org * MPIR is based on the GMP library but adds support for Microsoft's Visual Studio compiler. It is used to create the Windows binaries. Home page: http://www.mpir.org * MPFR for correctly rounded real floating-point arithmetic Home page: http://www.mpfr.org * MPC for correctly rounded complex floating-point arithmetic Home page: http://mpc.multiprecision.org * Generalized Lucas sequences and primality tests are based on the following code: mpz_lucas: http://sourceforge.net/projects/mpzlucas/ mpz_prp: http://sourceforge.net/projects/mpzprp/ gmpy2 Versions -------------- This manual documents the two major versions of gmpy2. Sections that are specific to a particular version will be identified as such. The 2.0 version is the stable release that only receives bug fixes and very minor updates. Version 2.1 is currently under active development and includes several new capabilities. Most gmpy2 2.0 code should run unchanged with gmpy2 2.1. The most significant change in gmpy2 2.1 is support for thread-safe contexts. This change required extensive refactoring of almost all internal functions. Please see the History chapter for a detail list of the changes. Installation ============ Installing gmpy2 on Windows --------------------------- Pre-compiled versions of gmpy2 2.0.8 are available at `https://pypi.org/project/gmpy2/`. A pre-compiled version of gmpy2 2.1.0a1 is available at `https://pypi.org/project/gmpy2/2.1.0a1/`. Updated Windows versions should be available again beginning with version 2.1.0b1. Installing gmpy2 on Unix/Linux ------------------------------ Requirements ^^^^^^^^^^^^ gmpy2 has only been tested with the most recent versions of GMP, MPFR and MPC. Specifically, for integer and rational support, gmpy2 requires GMP 5.0.x or later. To support multiple-precision floating point arithmetic, MPFR 3.1.x or later is required. MPC 1.0.1 or later is required for complex arithmetic. Short Instructions ^^^^^^^^^^^^^^^^^^ gmpy2 requires the development files for GMP, MPFR, and MPC. The actual package that provides these files varies between Linux distributions. Installing "libmpc-dev" (or its equivalent) is usually sufficient. If your system has the development libraries installed, compiling should be as simple as: :: cd python setup.py build_ext --force install --force If this fails, read on. Detailed Instructions ^^^^^^^^^^^^^^^^^^^^^ Note: You really shouldn't need to do this. Unless you need the capabilities provided a newer GMP/MPFR/MPC, you should use the versions provided by your distribution. If your Linux distribution does not support recent versions of GMP, MPFR and MPC, you will need to compile your own versions. To avoid any possible conflict with existing libraries on your system, it is recommended to use a directory not normally used by your distribution. Create the desired destination directory for GMP, MPFR, and MPC. :: $ mkdir /home/<>/local Download and un-tar the GMP source code. Change to the GMP source directory and compile GMP. :: $ cd /home/<>/local/src/gmp-6.1.2 $ ./configure --prefix=/home/<>/local $ make $ make check $ make install Download and un-tar the MPFR source code. Change to the MPFR source directory and compile MPFR. :: $ cd /home/<>/local/src/mpfr-4.0.1 $ ./configure --prefix=/home/<>/local --with-gmp=/home/<>/local $ make $ make check $ make install Download and un-tar the MPC source code. Change to the MPC source directory and compile MPC. :: $ cd /home/<>/local/src/mpc-1.1.0 $ ./configure --prefix=/home/<>/local --with-gmp=/home/<>/local --with-mpfr=/home/<>/local $ make $ make check $ make install Compile gmpy2 and specify the location of GMP, MPFR and MPC. The location of the GMP, MPFR, and MPC libraries is embedded into the gmpy2 library so the new versions of GMP, MPFR, and MPC do not need to be installed the system library directories. The prefix directory is added to the beginning of the directories that are checked so it will be found first. :: $ python setup.py install --prefix=/home/case/local If you get a "permission denied" error message, you may need to use:: $ python setup.py build --prefix=/home/case/local $ sudo python setup.py install --prefix=/home/case/local Options for setup.py ^^^^^^^^^^^^^^^^^^^^ **--force** Ignore the timestamps on all files and recompile. Normally, the results of a previous compile are cached. To force gmpy2 to recognize external changes (updated version of GMP, etc.), you will need to use this option. **--mpir** Force the use of MPIR instead of GMP. GMP is the default library on non-Windows operating systems. **--gmp** Force the use of GMP instead of MPIR. MPIR is the default library on Windows operating systems. **--shared=<...>** Add the specified directory prefix to the beginning of the list of directories that are searched for GMP, MPFR, and MPC shared libraries. **--static=<...>** Create a statically linked library using libraries from the specified path, or from the operating system's default library location if no path is specified gmpy2-2.1.0b3/docs/make.bat0000775000175000017500000001063513170047220015210 0ustar casecase00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\GMPY2.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\GMPY2.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end gmpy2-2.1.0b3/docs/mpc.rst0000664000175000017500000002351513433671427015130 0ustar casecase00000000000000Multiple-precision Complex ========================== gmpy2 adds a multiple-precision complex type called *mpc* that is based on the MPC library. The context manager settings for *mpfr* arithmetic are applied to *mpc* arithmetic by default. It is possible to specify different precision and rounding modes for both the real and imaginary components of an *mpc*. :: >>> import gmpy2 >>> from gmpy2 import mpc >>> gmpy2.sqrt(mpc("1+2j")) mpc('1.272019649514069+0.78615137775742328j') >>> gmpy2.get_context(real_prec=100,imag_prec=200) context(precision=53, real_prec=100, imag_prec=200, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, trap_expbound=False, allow_complex=False) >>> gmpy2.sqrt(mpc("1+2j")) mpc('1.2720196495140689642524224617376+0.78615137775742328606955858584295892952312205783772323766490213j',(100,200)) Exceptions are normally raised in Python when the result of a real operation is not defined over the reals; for example, ``sqrt(-4)`` will raise an exception. The default context in gmpy2 implements the same behavior but by setting allow_complex to True, complex results will be returned. :: >>> import gmpy2 >>> from gmpy2 import mpc >>> gmpy2.sqrt(-4) mpfr('nan') >>> gmpy2.get_context(allow_complex=True) context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=True, trap_erange=False, erange=False, trap_divzero=False, divzero=False, trap_expbound=False, allow_complex=True) >>> gmpy2.sqrt(-4) mpc('0.0+2.0j') mpc Methods ----------- **conjugate()** Returns the complex conjugate. **digits()** Returns a two element tuple where each element represents the real and imaginary components as a 3-tuple containing the mantissa, the exponent, and the number of bits of precision. The mantissa is represented as a string in the specified base with up to 'prec' digits. If 'prec' is 0, as many digits that are available are returned. No more digits than available given x's precision are returned. 'base' must be between 2 and 62, inclusive. mpc Attributes -------------- **imag** Returns the imaginary component. **precision** Returns a 2-tuple containing the precision of the real and imaginary components. **rc** Returns a 2-tuple containing the ternary value of the real and imaginary components. The ternary value is 0 if the value of the component is exactly equal to the exact, infinite precision value. If the result code is 1, then the value of the component is greater than the exact value. If the result code is -1, then the value of the component is less than the exact, infinite precision value. **real** Returns the real component. mpc Functions ------------- **acos(...)** acos(x) returns the arc-cosine of x. **acosh(...)** acosh(x) returns the inverse hyperbolic cosine of x. **add(...)** add(x, y) returns x + y. The type of the result is based on the types of the arguments. **asin(...)** asin(x) returns the arc-sine of x. **asinh(...)** asinh(x) return the inverse hyperbolic sine of x. **atan(...)** atan(x) returns the arc-tangent of x. **atanh(...)** atanh(x) returns the inverse hyperbolic tangent of x. **cos(...)** cos(x) returns the cosine of x. **cosh(...)** cosh(x) returns the hyperbolic cosine of x. **div(...)** div(x, y) returns x / y. The type of the result is based on the types of the arguments. **div_2exp(...)** div_2exp(x, n) returns an 'mpfr' or 'mpc' divided by 2**n. **exp(...)** exp(x) returns e**x. **fma(...)** fma(x, y, z) returns correctly rounded result of (x * y) + z. **fms(...)** fms(x, y, z) returns correctly rounded result of (x * y) - z. **is_inf(...)** is_inf(x) returns True if either the real or imaginary component of x is Infinity or -Infinity. **is_nan(...)** is_nan(x) returns True if either the real or imaginary component of x is NaN (Not-A-Number). **is_zero(...)** is_zero(x) returns True if x is zero. **log(...)** log(x) returns the natural logarithm of x. **log10(...)** log10(x) returns the base-10 logarithm of x. **mpc(...)** mpc() returns an *mpc* object set to 0.0+0.0j. mpc(c[, precision=0]) returns a new 'mpc' object from an existing complex number (either a Python complex object or another 'mpc' object). If the precision is not specified, then the precision is taken from the current context. The rounding mode is always taken from the current context. mpc(r[, i=0[, precision=0]]) returns a new 'mpc' object by converting two non-complex numbers into the real and imaginary components of an 'mpc' object. If the precision is not specified, then the precision is taken from the current context. The rounding mode is always taken from the current context. mpc(s[, [precision=0[, base=10]]) returns a new 'mpc' object by converting a string s into a complex number. If base is omitted, then a base-10 representation is assumed otherwise a base between 2 and 36 can be specified. If the precision is not specified, then the precision is taken from the current context. The rounding mode is always taken from the current context. In addition to the standard Python string representation of a complex number: ``"1+2j"``, the string representation used by the MPC library: ``"(1 2)"`` is also supported. .. note:: The precision can be specified either a single number that is used for both the real and imaginary components, or as a 2-tuple that can specify different precisions for the real and imaginary components. **mpc_random(...)** mpfc_random(random_state) returns a uniformly distributed number in the unit square [0,1]x[0,1]. The parameter *random_state* must be created by random_state() first. **mul(...)** mul(x, y) returns x * y. The type of the result is based on the types of the arguments. **mul_2exp(...)** mul_2exp(x, n) returns 'mpfr' or 'mpc' multiplied by 2**n. **norm(...)** norm(x) returns the norm of a complex x. The norm(x) is defined as x.real**2 + x.imag**2. abs(x) is the square root of norm(x). **phase(...)** phase(x) returns the phase angle, also known as argument, of a complex x. **polar(...)** polar(x) returns the polar coordinate form of a complex x that is in rectangular form. **proj(...)** proj(x) returns the projection of a complex x on to the Riemann sphere. **rect(...)** rect(x) returns the polar coordinate form of a complex x that is in rectangular form. **root_of_unity(...)** root_of_unity(n, k) returns the n-th root of mpc(1) raised to the k-th power. Requires MPC 1.1.0 or greater. **sin(...)** sin(x) returns the sine of x. **sinh(...)** sinh(x) returns the hyberbolic sine of x. **sqrt(...)** sqrt(x) returns the square root of x. If x is integer, rational, or real, then an *mpfr* will be returned. If x is complex, then an *mpc* will be returned. If context.allow_complex is True, negative values of x will return an *mpc*. **square(...)** square(x) returns x * x. The type of the result is based on the types of the arguments. **sub(...)** sub(x, y) returns x - y. The type of the result is based on the types of the arguments. **tan(...)** tan(x) returns the tangent of x. x is measured in radians. **tanh(...)** tanh(x) returns the hyperbolic tangent of x. mpc Formatting -------------- The *mpc* type supports the __format__() special method to allow custom output formatting. **__format__(...)** x.__format__(fmt) returns a Python string by formatting 'x' using the format string 'fmt'. A valid format string consists of: | optional alignment code: | '<' -> left shifted in field | '>' -> right shifted in field | '^' -> centered in field | optional leading sign code | '+' -> always display leading sign | '-' -> only display minus for negative values | ' ' -> minus for negative values, space for positive values | optional width.real_precision.imag_precision | optional rounding mode: | 'U' -> round toward plus infinity | 'D' -> round toward minus infinity | 'Z' -> round toward zero | 'N' -> round to nearest | optional output style: | 'P' -> Python style, 1+2j, (default) | 'M' -> MPC style, (1 2) | optional conversion code: | 'a','A' -> hex format | 'b' -> binary format | 'e','E' -> scientific format | 'f','F' -> fixed point format | 'g','G' -> fixed or scientific format .. note:: The formatting codes must be specified in the order shown above. :: >>> import gmpy2 >>> from gmpy2 import mpc >>> a=gmpy2.sqrt(mpc("1+2j")) >>> a mpc('1.272019649514069+0.78615137775742328j') >>> "{0:.4.4Mf}".format(a) '(1.2720 0.7862)' >>> "{0:.4.4f}".format(a) '1.2720+0.7862j' >>> "{0:^20.4.4U}".format(a) ' 1.2721+0.7862j ' >>> "{0:^20.4.4D}".format(a) ' 1.2720+0.7861j ' gmpy2-2.1.0b3/docs/mpfr.rst0000664000175000017500000006647213372302125015312 0ustar casecase00000000000000Multiple-precision Reals ======================== gmpy2 replaces the *mpf* type from gmpy 1.x with a new *mpfr* type based on the MPFR library. The new *mpfr* type supports correct rounding, selectable rounding modes, and many trigonometric, exponential, and special functions. A *context manager* is used to control precision, rounding modes, and the behavior of exceptions. The default precision of an *mpfr* is 53 bits - the same precision as Python's *float* type. If the precision is changed, then ``mpfr(float('1.2'))`` differs from ``mpfr('1.2')``. To take advantage of the higher precision provided by the *mpfr* type, always pass constants as strings. :: >>> import gmpy2 >>> from gmpy2 import mpfr >>> mpfr('1.2') mpfr('1.2') >>> mpfr(float('1.2')) mpfr('1.2') >>> gmpy2.get_context().precision=100 >>> mpfr('1.2') mpfr('1.2000000000000000000000000000006',100) >>> mpfr(float('1.2')) mpfr('1.1999999999999999555910790149937',100) >>> Contexts -------- .. warning:: Contexts and context managers are not thread-safe! Modifying the context in one thread will impact all other threads. A *context* is used to control the behavior of *mpfr* and *mpc* arithmetic. In addition to controlling the precision, the rounding mode can be specified, minimum and maximum exponent values can be changed, various exceptions can be raised or ignored, gradual underflow can be enabled, and returning complex results can be enabled. ``gmpy2.context()`` creates a new context with all options set to default. ``gmpy2.set_context(ctx)`` will set the active context to *ctx*. ``gmpy2.get_context()`` will return a reference to the active context. Note that contexts are mutable: modifying the reference returned by get_context() will modify the active context until a new context is enabled with set_context(). The ``copy()`` method of a context will return a copy of the context. The following example just modifies the precision. The remaining options will be discussed later. :: >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.get_context() context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, trap_expbound=False, allow_complex=False) >>> gmpy2.sqrt(5) mpfr('2.2360679774997898') >>> gmpy2.get_context().precision=100 >>> gmpy2.sqrt(5) mpfr('2.2360679774997896964091736687316',100) >>> gmpy2.get_context().precision+=20 >>> gmpy2.sqrt(5) mpfr('2.2360679774997896964091736687312762351',120) >>> ctx=gmpy2.get_context() >>> ctx.precision+=20 >>> gmpy2.sqrt(5) mpfr('2.2360679774997896964091736687312762354406182',140) >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.sqrt(5) mpfr('2.2360679774997898') >>> ctx.precision+=20 >>> gmpy2.sqrt(5) mpfr('2.2360679774997898') >>> gmpy2.set_context(ctx) >>> gmpy2.sqrt(5) mpfr('2.2360679774997896964091736687312762354406183596116',160) >>> Context Attributes ------------------ **precision** This attribute controls the precision of an *mpfr* result. The precision is specified in bits, not decimal digits. The maximum precision that can be specified is platform dependent and can be retrieved with **get_max_precision()**. .. note:: Specifying a value for precision that is too close to the maximum precision will cause the MPFR library to fail. **real_prec** This attribute controls the precision of the real part of an *mpc* result. If the value is ``Default``, then the value of the precision attribute is used. **imag_prec** This attribute controls the precision of the imaginary part of an *mpc* result. If the value is ``Default``, then the value of real_prec is used. **round** There are five rounding modes available to *mpfr* types: ``RoundAwayZero`` The result is rounded away from 0.0. ``RoundDown`` The result is rounded towards -Infinity. ``RoundToNearest`` Round to the nearest value; ties are rounded to an even value. ``RoundToZero`` The result is rounded towards 0.0. ``RoundUp`` The result is rounded towards +Infinity. **real_round** This attribute controls the rounding mode for the real part of an *mpc* result. If the value is ``Default``, then the value of the round attribute is used. Note: ``RoundAwayZero`` is not a valid rounding mode for *mpc*. **imag_round** This attribute controls the rounding mode for the imaginary part of an *mpc* result. If the value is ``Default``, then the value of the real_round attribute is used. Note: ``RoundAwayZero`` is not a valid rounding mode for *mpc*. **emax** This attribute controls the maximum allowed exponent of an *mpfr* result. The maximum exponent is platform dependent and can be retrieved with **get_emax_max()**. **emin** This attribute controls the minimum allowed exponent of an *mpfr* result. The minimum exponent is platform dependent and can be retrieved with **get_emin_min()**. .. note:: It is possible to change the values of emin/emax such that previous *mpfr* values are no longer valid numbers but should either underflow to +/-0.0 or overflow to +/-Infinity. To raise an exception if this occurs, see **trap_expbound**. **subnormalize** The usual IEEE-754 floating point representation supports gradual underflow when the minimum exponent is reached. The MFPR library does not enable gradual underflow by default but it can be enabled to precisely mimic the results of IEEE-754 floating point operations. **trap_underflow** If set to ``False``, a result that is smaller than the smallest possible *mpfr* given the current exponent range will be replaced by +/-0.0. If set to ``True``, an ``UnderflowResultError`` exception is raised. **underflow** This flag is not user controllable. It is automatically set if a result underflowed to +/-0.0 and trap_underflow is ``False``. **trap_overflow** If set to ``False``, a result that is larger than the largest possible *mpfr* given the current exponent range will be replaced by +/-Infinity. If set to ``True``, an ``OverflowResultError`` exception is raised. **overflow** This flag is not user controllable. It is automatically set if a result overflowed to +/-Infinity and trap_overflow is ``False``. **trap_inexact** This attribute controls whether or not an ``InexactResultError`` exception is raised if an inexact result is returned. To check if the result is greater or less than the exact result, check the **rc** attribute of the *mpfr* result. **inexact** This flag is not user controllable. It is automatically set if an inexact result is returned. **trap_invalid** This attribute controls whether or not an ``InvalidOperationError`` exception is raised if a numerical result is not defined. A special NaN (Not-A-Number) value will be returned if an exception is not raised. The ``InvalidOperationError`` is a sub-class of Python's ``ValueError``. For example, ``gmpy2.sqrt(-2)`` will normally return *mpfr('nan')*. However, if allow_complex is set to ``True``, then an *mpc* result will be returned. **invalid** This flag is not user controllable. It is automatically set if an invalid (Not-A-Number) result is returned. **trap_erange** This attribute controls whether or not a ``RangeError`` exception is raised when certain operations are performed on NaN and/or Infinity values. Setting trap_erange to ``True`` can be used to raise an exception if comparisons are attempted with a NaN. :: >>> gmpy2.set_context(gmpy2.context()) >>> mpfr('nan') == mpfr('nan') False >>> gmpy2.get_context().trap_erange=True >>> mpfr('nan') == mpfr('nan') Traceback (most recent call last): File "", line 1, in gmpy2.RangeError: comparison with NaN >>> **erange** This flag is not user controllable. It is automatically set if an erange error occurred. **trap_divzero** This attribute controls whether or not a ``DivisionByZeroError`` exception is raised if division by 0 occurs. The ``DivisionByZeroError`` is a sub-class of Python's ``ZeroDivisionError``. **divzero** This flag is not user controllable. It is automatically set if a division by zero occurred and NaN result was returned. **trap_expbound** This attribute controls whether or not an ``ExponentOutOfBoundsError`` exception is raised if exponents in an operand are outside the current emin/emax limits. **allow_complex** This attribute controls whether or not an *mpc* result can be returned if an *mpfr* result would normally not be possible. Context Methods --------------- **clear_flags()** Clear the underflow, overflow, inexact, invalid, erange, and divzero flags. **copy()** Return a copy of the context. Contexts and the with statement ------------------------------- Contexts can also be used in conjunction with Python's ``with ...`` statement to temporarily change the context settings for a block of code and then restore the original settings when the block of code exits. ``gmpy2.local_context()`` first save the current context and then creates a new context based on a context passed as the first argument, or the current context if no context is passed. The new context is modified if any optional keyword arguments are given. The original active context is restored when the block completes. In the following example, the current context is saved by ``gmpy2.local_context()`` and then the block begins with a copy of the default context and the precision set to 100. When the block is finished, the original context is restored. :: >>> with gmpy2.local_context(gmpy2.context(), precision=100) as ctx: ... print(gmpy2.sqrt(2)) ... ctx.precision += 100 ... print(gmpy2.sqrt(2)) ... 1.4142135623730950488016887242092 1.4142135623730950488016887242096980785696718753769480731766796 >>> A context object can also be used directly to create a context manager block. However, instead of restoring the context to the active context when the ``with ...`` statement is executed, the restored context is the context used before any keyword argument modifications. The code: :: with gmpy2.ieee(64) as ctx: is equivalent to: :: gmpy2.set_context(gmpy2.ieee(64)) with gmpy2.local_context() as ctx: Contexts that implement the standard *single*, *double*, and *quadruple* precision floating point types can be created using **ieee()**. mpfr Methods ------------ **as_integer_ratio()** Returns a 2-tuple containing the numerator and denominator after converting the *mpfr* object into the exact rational equivalent. The return 2-tuple is equivalent to Python's as_integer_ratio() method of built-in float objects. **as_mantissa_exp()** Returns a 2-tuple containing the mantissa and exponent. **as_simple_fraction()** Returns an *mpq* containing the simplest rational value that approximates the *mpfr* value with an error less than 1/(2**precision). **conjugate()** Returns the complex conjugate. For *mpfr* objects, returns a copy of the original object. **digits()** Returns a 3-tuple containing the mantissa, the exponent, and the number of bits of precision. The mantissa is represented as a string in the specified base with up to 'prec' digits. If 'prec' is 0, as many digits that are available are returned. No more digits than available given x's precision are returned. 'base' must be between 2 and 62, inclusive. **is_integer()** Returns True if the *mpfr* object is an integer. mpfr Attributes --------------- **imag** Returns the imaginary component. For *mpfr* objects, returns 0. **precision** Returns the precision of the *mpfr* object. **rc** The result code (also known as ternary value in the MPFR documentation) is 0 if the value of the *mpfr* object is exactly equal to the exact, infinite precision value. If the result code is 1, then the value of the *mpfr* object is greater than the exact value. If the result code is -1, then the value of the *mpfr* object is less than the exact, infinite precision value. **real** Returns the real component. For *mpfr* objects, returns a copy of the original object. mpfr Functions -------------- **acos(...)** acos(x) returns the arc-cosine of x. x is measured in radians. If context.allow_complex is True, then an *mpc* result will be returned for abs(x) > 1. **acosh(...)** acosh(x) returns the inverse hyperbolic cosine of x. **add(...)** add(x, y) returns x + y. The type of the result is based on the types of the arguments. **agm(...)** agm(x, y) returns the arithmetic-geometric mean of x and y. **ai(...)** ai(x) returns the Airy function of x. **asin(...)** asin(x) returns the arc-sine of x. x is measured in radians. If context.allow_complex is True, then an *mpc* result will be returned for abs(x) > 1. **asinh(...)** asinh(x) return the inverse hyperbolic sine of x. **atan(...)** atan(x) returns the arc-tangent of x. x is measured in radians. **atan2(...)** atan2(y, x) returns the arc-tangent of (y/x). **atanh(...)** atanh(x) returns the inverse hyperbolic tangent of x. If context.allow_complex is True, then an *mpc* result will be returned for abs(x) > 1. **cbrt(...)** cbrt(x) returns the cube root of x. **ceil(...)** ceil(x) returns the 'mpfr' that is the smallest integer >= x. **check_range(...)** check_range(x) return a new 'mpfr' with exponent that lies within the current range of emin and emax. **const_catalan(...)** const_catalan([precision=0]) returns the Catalan's constant using the specified precision. If no precision is specified, the default precision is used. **const_euler(...)** const_euler([precision=0]) returns the Euler's constant using the specified precision. If no precision is specified, the default precision is used. **const_log2(...)** const_log2([precision=0]) returns the log2 constant using the specified precision. If no precision is specified, the default precision is used. **const_pi(...)** const_pi([precision=0]) returns the constant pi using the specified precision. If no precision is specified, the default precision is used. **context(...)** context() returns a new context manager controlling MPFR and MPC arithmetic. **cos(...)** cos(x) returns the cosine of x. x is measured in radians. **cosh(...)** cosh(x) returns the hyperbolic cosine of x. **cot(...)** cot(x) returns the cotangent of x. x is measured in radians. **coth(...)** coth(x) returns the hyperbolic cotangent of x. **csc(...)** csc(x) returns the cosecant of x. x is measured in radians. **csch(...)** csch(x) returns the hyperbolic cosecant of x. **degrees(...)** degrees(x) converts an angle measurement x from radians to degrees. **digamma(...)** digamma(x) returns the digamma of x. **div(...)** div(x, y) returns x / y. The type of the result is based on the types of the arguments. **div_2exp(...)** div_2exp(x, n) returns an 'mpfr' or 'mpc' divided by 2**n. **eint(...)** eint(x) returns the exponential integral of x. **erf(...)** erf(x) returns the error function of x. **erfc(...)** erfc(x) returns the complementary error function of x. **exp(...)** exp(x) returns e**x. **exp10(...)** exp10(x) returns 10**x. **exp2(...)** exp2(x) returns 2**x. **expm1(...)** expm1(x) returns e**x - 1. expm1() is more accurate than exp(x) - 1 when x is small. **f2q(...)** f2q(x[,err]) returns the simplest *mpq* approximating x to within relative error err. Default is the precision of x. Uses Stern-Brocot tree to find the simplest approximation. An *mpz* is returned if the denominator is 1. If err<0, error sought is 2.0 ** err. **factorial(...)** factorial(n) returns the floating-point approximation to the factorial of n. See fac(n) to get the exact integer result. **floor(...)** floor(x) returns the 'mpfr' that is the smallest integer <= x. **fma(...)** fma(x, y, z) returns correctly rounded result of (x * y) + z. **fmma(...)** fmma(x, y, z, t) returns correctly rounded result of (x * y) + (z * t). Requires MPFR 4. **fmms(...)** fmms(x, y, z, t) returns correctly rounded result of (x * y) - (z * t). Requires MPFR 4. **fmod(...)** fmod(x, y) returns x - n*y where n is the integer quotient of x/y, rounded to 0. **fms(...)** fms(x, y, z) returns correctly rounded result of (x * y) - z. **frac(...)** frac(x) returns the fractional part of x. **frexp(...)** frexp(x) returns a tuple containing the exponent and mantissa of x. **fsum(...)** fsum(iterable) returns the accurate sum of the values in the iterable. **gamma(...)** gamma(x) returns the gamma of x. **get_exp(...)** get_exp(mpfr) returns the exponent of an *mpfr*. Returns 0 for NaN or Infinity and sets the erange flag and will raise an exception if trap_erange is set. **hypot(...)** hypot(y, x) returns square root of (x**2 + y**2). **ieee(...)** ieee(bitwidth) returns a context with settings for 32-bit (aka single), 64-bit (aka double), or 128-bit (aka quadruple) precision floating point types. **inf(...)** inf(n) returns an *mpfr* initialized to Infinity with the same sign as n. If n is not given, +Infinity is returned. **is_finite(...)** is_finite(x) returns True if x is an actual number (i.e. not NaN or Infinity). **is_inf(...)** is_inf(x) returns True if x is Infinity or -Infinity. .. note:: **is_inf()** is deprecated; please use **if_infinite()**. **is_infinite(...)** is_infinite(x) returns True if x Infinity or -Infinity. **is_nan(...)** is_nan(x) returns True if x is NaN (Not-A-Number). **is_number(...)** is_number(x) returns True if x is an actual number (i.e. not NaN or Infinity). .. note:: **is_number()** is deprecated; please use **is_finite()**. **is_regular(...)** is_regular(x) returns True if x is not zero, NaN, or Infinity. **is_signed(...)** is_signed(x) returns True if the sign bit of x is set. **is_unordered(...)** is_unordered(x,y) returns True if either x and/or y is NaN. **is_zero(...)** is_zero(x) returns True if x is zero. **j0(...)** j0(x) returns the Bessel function of the first kind of order 0 of x. **j1(...)** j1(x) returns the Bessel function of the first kind of order 1 of x. **jn(...)** jn(x,n) returns the Bessel function of the first kind of order n of x. **lgamma(...)** lgamma(x) returns a tuple containing the logarithm of the absolute value of gamma(x) and the sign of gamma(x) **li2(...)** li2(x) returns the real part of dilogarithm of x. **lngamma(...)** lngamma(x) returns the logarithm of gamma(x). **log(...)** log(x) returns the natural logarithm of x. **log10(...)** log10(x) returns the base-10 logarithm of x. **log1p(...)** log1p(x) returns the natural logarithm of (1+x). **log2(...)** log2(x) returns the base-2 logarithm of x. **max2(...)** max2(x, y) returns the maximum of x and y. The result may be rounded to match the current context. Use the builtin max() to get an exact copy of the largest object without any rounding. **min2(...)** min2(x, y) returns the minimum of x and y. The result may be rounded to match the current context. Use the builtin min() to get an exact copy of the smallest object without any rounding. **modf(...)** modf(x) returns a tuple containing the integer and fractional portions of x. **mpfr(...)** mpfr() returns and *mpfr* object set to 0.0. mpfr(n[, precision=0]) returns an *mpfr* object after converting a numeric value n. If no precision, or a precision of 0, is specified; the precision is taken from the current context. mpfr(s[, precision=0[, [base=0]]) returns an *mpfr* object after converting a string 's' made up of digits in the given base, possibly with fractional part (with period as a separator) and/or exponent (with exponent marker 'e' for base<=10, else '@'). If no precision, or a precision of 0, is specified; the precision is taken from the current context. The base of the string representation must be 0 or in the interval 2 ... 62. If the base is 0, the leading digits of the string are used to identify the base: 0b implies base=2, 0x implies base=16, otherwise base=10 is assumed. **mpfr_from_old_binary(...)** mpfr_from_old_binary(string) returns an *mpfr* from a GMPY 1.x binary mpf format. Please use to_binary()/from_binary() to convert GMPY2 objects to or from a binary format. **mpfr_grandom(...)** mpfr_grandom(random_state) returns two random numbers with Gaussian distribution. The parameter *random_state* must be created by random_state() first. **mpfr_random(...)** mpfr_random(random_state) returns a uniformly distributed number between [0,1]. The parameter *random_state* must be created by random_state() first. **mul(...)** mul(x, y) returns x * y. The type of the result is based on the types of the arguments. **mul_2exp(...)** mul_2exp(x, n) returns 'mpfr' or 'mpc' multiplied by 2**n. **nan(...)** nan() returns an 'mpfr' initialized to NaN (Not-A-Number). **next_above(...)** next_above(x) returns the next 'mpfr' from x toward +Infinity. **next_below(...)** next_below(x) returns the next 'mpfr' from x toward -Infinity. **radians(...)** radians(x) converts an angle measurement x from degrees to radians. **rec_sqrt(...)** rec_sqrt(x) returns the reciprocal of the square root of x. **reldiff(...)** reldiff(x, y) returns the relative difference between x and y. Result is equal to abs(x-y)/x. **remainder(...)** remainder(x, y) returns x - n*y where n is the integer quotient of x/y, rounded to the nearest integer and ties rounded to even. **remquo(...)** remquo(x, y) returns a tuple containing the remainder(x,y) and the low bits of the quotient. **rint(...)** rint(x) returns x rounded to the nearest integer using the current rounding mode. **rint_ceil(...)** rint_ceil(x) returns x rounded to the nearest integer by first rounding to the next higher or equal integer and then, if needed, using the current rounding mode. **rint_floor(...)** rint_floor(x) returns x rounded to the nearest integer by first rounding to the next lower or equal integer and then, if needed, using the current rounding mode. **rint_round(...)** rint_round(x) returns x rounded to the nearest integer by first rounding to the nearest integer (ties away from 0) and then, if needed, using the current rounding mode. **rint_trunc(...)** rint_trunc(x) returns x rounded to the nearest integer by first rounding towards zero and then, if needed, using the current rounding mode. **root(...)** root(x, n) returns n-th root of x. The result always an *mpfr*. **round2(...)** round2(x[, n]) returns x rounded to n bits. Uses default precision if n is not specified. See round_away() to access the mpfr_round() function. Use the builtin round() to round x to n decimal digits. **round_away(...)** round_away(x) returns an *mpfr* by rounding x the nearest integer, with ties rounded away from 0. **sec(...)** sec(x) returns the secant of x. x is measured in radians. **sech(...)** sech(x) returns the hyperbolic secant of x. **set_exp(...)** set_exp(x, n) sets the exponent of a given *mpfr* to n. If n is outside the range of valid exponents, set_exp() will set the erange flag and either return the original value or raise an exception if trap_erange is set. **set_sign(...)** set_sign(x, bool) returns a copy of x with it's sign bit set if *bool* evaluates to True. **sign(...)** sign(x) returns -1 if x < 0, 0 if x == 0, or +1 if x >0. **sin(...)** sin(x) returns the sine of x. x is measured in radians. **sin_cos(...)** sin_cos(x) returns a tuple containing the sine and cosine of x. x is measured in radians. **sinh(...)** sinh(x) returns the hyberbolic sine of x. **sinh_cosh(...)** sinh_cosh(x) returns a tuple containing the hyperbolic sine and cosine of x. **sqrt(...)** sqrt(x) returns the square root of x. If x is integer, rational, or real, then an *mpfr* will be returned. If x is complex, then an *mpc* will be returned. If context.allow_complex is True, negative values of x will return an *mpc*. **square(...)** square(x) returns x * x. The type of the result is based on the types of the arguments. **sub(...)** sub(x, y) returns x - y. The type of the result is based on the types of the arguments. **tan(...)** tan(x) returns the tangent of x. x is measured in radians. **tanh(...)** tanh(x) returns the hyperbolic tangent of x. **trunc(...)** trunc(x) returns an 'mpfr' that is x truncated towards 0. Same as x.floor() if x>=0 or x.ceil() if x<0. **y0(...)** y0(x) returns the Bessel function of the second kind of order 0 of x. **y1(...)** y1(x) returns the Bessel function of the second kind of order 1 of x. **yn(...)** yn(x,n) returns the Bessel function of the second kind of order n of x. **zero(...)** zero(n) returns an *mpfr* initialized to 0.0 with the same sign as n. If n is not given, +0.0 is returned. **zeta(...)** zeta(x) returns the Riemann zeta of x. mpfr Formatting --------------- The *mpfr* type supports the __format__() special method to allow custom output formatting. **__format__(...)** x.__format__(fmt) returns a Python string by formatting 'x' using the format string 'fmt'. A valid format string consists of: | optional alignment code: | '<' -> left shifted in field | '>' -> right shifted in field | '^' -> centered in field | optional leading sign code | '+' -> always display leading sign | '-' -> only display minus for negative values | ' ' -> minus for negative values, space for positive values | optional width.precision | optional rounding mode: | 'U' -> round toward plus infinity | 'D' -> round toward minus infinity | 'Y' -> round away from zero | 'Z' -> round toward zero | 'N' -> round to nearest | optional conversion code: | 'a','A' -> hex format | 'b' -> binary format | 'e','E' -> scientific format | 'f','F' -> fixed point format | 'g','G' -> fixed or scientific format .. note:: The formatting codes must be specified in the order shown above. :: >>> import gmpy2 >>> from gmpy2 import mpfr >>> a=mpfr("1.23456") >>> "{0:15.3f}".format(a) ' 1.235' >>> "{0:15.3Uf}".format(a) ' 1.235' >>> "{0:15.3Df}".format(a) ' 1.234' >>> "{0:.3Df}".format(a) '1.234' >>> "{0:+.3Df}".format(a) '+1.234' gmpy2-2.1.0b3/docs/mpq.rst0000664000175000017500000000417113356026702015135 0ustar casecase00000000000000Multiple-precision Rationals ============================ gmpy2 provides a rational type call *mpq*. It should be a replacement for Python's fractions.Fraction module. :: >>> import gmpy2 >>> from gmpy2 import mpq >>> mpq(1,7) mpq(1,7) >>> mpq(1,7) * 11 mpq(11,7) >>> mpq(11,7)/13 mpq(11,91) mpq Methods ----------- **digits(...)** x.digits([base=10]) returns a Python string representing *x* in the given base (2 to 62, default is 10). A leading '-' is present if *x* < 0, but no leading '+' is present if *x* >= 0. mpq Attributes -------------- **denominator** x.denominator returns the denominator of *x*. **numerator** x.numerator returns the numerator of *x*. mpq Functions ------------- **add(...)** add(x, y) returns *x* + *y*. The result type depends on the input types. **div(...)** div(x, y) returns *x* / *y*. The result type depends on the input types. **f2q(...)** f2q(x[, err]) returns the best *mpq* approximating *x* to within relative error *err*. Default is the precision of *x*. If *x* is not an *mpfr*, it is converted to an *mpfr*. Uses Stern-Brocot tree to find the best approximation. An *mpz* is returned if the denominator is 1. If *err* < 0, then the relative error sought is 2.0 ** *err*. **mpq(...)** mpq() returns an *mpq* object set to 0/1. mpq(n) returns an *mpq* object with a numeric value *n*. Decimal and Fraction values are converted exactly. mpq(n, m) returns an *mpq* object with a numeric value *n* / *m*. mpq(s[, base=10]) returns an *mpq* object from a string *s* made up of digits in the given base. *s* may be made up of two numbers in the same base separated by a '/' character. If *base* == 10, then an embedded '.' indicates a number with a decimal fractional part. **mul(...)** mul(x, y) returns *x* \* *y*. The result type depends on the input types. **qdiv(...)** qdiv(x[, y=1]) returns *x/y* as *mpz* if possible, or as *mpq* if *x* is not exactly divisible by *y*. **sub(...)** sub(x, y) returns *x* - *y*. The result type depends on the input types. gmpy2-2.1.0b3/docs/mpz.rst0000664000175000017500000003376113466164454015166 0ustar casecase00000000000000Multiple-precision Integers =========================== The gmpy2 *mpz* type supports arbitrary precision integers. It should be a drop-in replacement for Python's *long* type. Depending on the platform and the specific operation, an *mpz* will be faster than Python's *long* once the precision exceeds 20 to 50 digits. All the special integer functions in GMP are supported. Examples -------- :: >>> import gmpy2 >>> from gmpy2 import mpz >>> mpz('123') + 1 mpz(124) >>> 10 - mpz(1) mpz(9) >>> gmpy2.is_prime(17) True .. note:: The use of ``from gmpy2 import *`` is not recommended. The names in gmpy2 have been chosen to avoid conflict with Python's builtin names but gmpy2 does use names that may conflict with other modules or variable names. mpz Methods ----------- **bit_clear(...)** x.bit_clear(n) returns a copy of *x* with bit *n* set to 0. **bit_flip(...)** x.bit_flip(n) returns a copy of *x* with bit *n* inverted. **bit_length(...)** x.bit_length() returns the number of significant bits in the radix-2 representation of *x*. For compatibility with Python, mpz(0).bit_length() returns 0. **bit_scan0(...)** x.bit_scan0(n) returns the index of the first 0-bit of *x* with index >= *n*. If there are no more 0-bits in *x* at or above index *n* (which can only happen for *x* < 0, assuming an infinitely long 2's complement format), then None is returned. *n* must be >= 0. **bit_scan1(...)** x.bit_scan1(n) returns the index of the first 1-bit of *x* with index >= *n*. If there are no more 1-bits in *x* at or above index *n* (which can only happen for *x* >= 0, assuming an infinitely long 2's complement format), then None is returned. *n* must be >= 0. **bit_set(...)** x.bit_set(n) returns a copy of *x* with bit *n* set to 1. **bit_test(...)** x.bit_test(n) returns True if bit *n* of *x* is set, and False if it is not set. **conjugtae(...)** Return the conjugate of x (which is just a new reference to x since x not a complex number). **denominator(...)** x.denominator() returns mpz(1). **digits(...)** x.digits([base=10]) returns a string representing *x* in radix *base*. **imag** Return the imaginary component of an *mpz*. Always *mpz(0)*. **is_congruent(...)** x.is_congruent(y, m) returns True if *x* is congruent to *y* modulo *m*, else returns False. **is_divisible(...)** x.is_divisible(d) returns True if *x* is divisible by *d*, else returns False. **is_even(...)** x.is_even() returns True if *x* is even, else returns False. **is_odd(...)** x.is_odd() returns True if *x* is even, else returns False. **is_power(...)** x.is_power() returns True if *x* is a perfect power (there exists integers *y* and *n* > 1, such that x=y**n), else returns False. **is_prime(...)** x.is_prime() returns True if *x* is _probably_ prime, else False if *x* is definitely composite. See the documentation for *gmpy2.is_prime* for details on the underlaying primality tests that are performed. **is_square(...)** x.is_square() returns True if *x* is a perfect square, else returns False. **num_digits(...)** x.num_digits([base=10]) returns the length of the string representing the absolute value of *x* in radix *base*. The result is correct if base is a power of 2. For other bases, the result is usually correct but may be 1 too large. *base* can range between 2 and 62, inclusive. **numerator(...)** x.numerator() returns a copy of *x*. **real(...)** x.real returns a copy of *x*. mpz Functions ------------- **add(...)** add(x, y) returns *x* + *y*. The result type depends on the input types. **bincoef(...)** bincoef(x, n) returns the binomial coefficient. *n* must be >= 0. **bit_clear(...)** bit_clear(x, n) returns a copy of *x* with bit *n* set to 0. **bit_flip(...)** bit_flip(x, n) returns a copy of *x* with bit *n* inverted. **bit_length(...)** bit_length(x) returns the number of significant bits in the radix-2 representation of *x*. For compatibility with Python, mpz(0).bit_length() returns 0 while mpz(0).num_digits(2) returns 1. **bit_mask(...)** bit_mask(n) returns an *mpz* object exactly *n* bits in length with all bits set. **bit_scan0(...)** bit_scan0(x, n) returns the index of the first 0-bit of *x* with index >= *n*. If there are no more 0-bits in *x* at or above index *n* (which can only happen for *x* < 0, assuming an infinitely long 2's complement format), then None is returned. *n* must be >= 0. **bit_scan1(...)** bit_scan1(x, n) returns the index of the first 1-bit of *x* with index >= *n*. If there are no more 1-bits in *x* at or above index *n* (which can only happen for *x* >= 0, assuming an infinitely long 2's complement format), then None is returned. *n* must be >= 0. **bit_set(...)** bit_set(x, n) returns a copy of *x* with bit *n* set to 1. **bit_test(...)** bit_test(x, n) returns True if bit *n* of *x* is set, and False if it is not set. **c_div(...)** c_div(x, y) returns the quotient of *x* divided by *y*. The quotient is rounded towards +Inf (ceiling rounding). *x* and *y* must be integers. **c_div_2exp(...)** c_div_2exp(x, n) returns the quotient of *x* divided by 2**n. The quotient is rounded towards +Inf (ceiling rounding). *x* must be an integer and *n* must be > 0. **c_divmod(...)** c_divmod(x, y) returns the quotient and remainder of *x* divided by *y*. The quotient is rounded towards +Inf (ceiling rounding) and the remainder will have the opposite sign of *y*. *x* and *y* must be integers. **c_divmod_2exp(...)** c_divmod_2exp(x ,n) returns the quotient and remainder of *x* divided by 2**n. The quotient is rounded towards +Inf (ceiling rounding) and the remainder will be negative or zero. *x* must be an integer and *n* must be > 0. **c_mod(...)** c_mod(x, y) returns the remainder of *x* divided by *y*. The remainder will have the opposite sign of *y*. *x* and *y* must be integers. **c_mod_2exp(...)** c_mod_2exp(x, n) returns the remainder of *x* divided by 2**n. The remainder will be negative. *x* must be an integer and *n* must be > 0. **comb(...)** comb(x, n) returns the number of combinations of *x* things, taking *n* at a time. *n* must be >= 0. **digits(...)** digits(x[, base=10]) returns a string representing *x* in radix *base*. **div(...)** div(x, y) returns *x* / *y*. The result type depends on the input types. **divexact(...)** divexact(x, y) returns the quotient of *x* divided by *y*. Faster than standard division but requires the remainder is zero! **divm(...)** divm(a, b, m) returns *x* such that *b* * *x* == *a* modulo *m*. Raises a ZeroDivisionError exception if no such value *x* exists. **f_div(...)** f_div(x, y) returns the quotient of *x* divided by *y*. The quotient is rounded towards -Inf (floor rounding). *x* and *y* must be integers. **f_div_2exp(...)** f_div_2exp(x, n) returns the quotient of *x* divided by 2**n. The quotient is rounded towards -Inf (floor rounding). *x* must be an integer and *n* must be > 0. **f_divmod(...)** f_divmod(x, y) returns the quotient and remainder of *x* divided by *y*. The quotient is rounded towards -Inf (floor rounding) and the remainder will have the same sign as *y*. *x* and *y* must be integers. **f_divmod_2exp(...)** f_divmod_2exp(x, n) returns quotient and remainder after dividing *x* by 2**n. The quotient is rounded towards -Inf (floor rounding) and the remainder will be positive. *x* must be an integer and *n* must be > 0. **f_mod(...)** f_mod(x, y) returns the remainder of *x* divided by *y*. The remainder will have the same sign as *y*. *x* and *y* must be integers. **f_mod_2exp(...)** f_mod_2exp(x, n) returns remainder of *x* divided by 2**n. The remainder will be positive. *x* must be an integer and *n* must be > 0. **fac(...)** fac(n) returns the exact factorial of *n*. Use factorial() to get the floating-point approximation. **fib(...)** fib(n) returns the *n*-th Fibonacci number. **fib2(...)** fib2(n) returns a 2-tuple with the (*n*-1)-th and *n*-th Fibonacci numbers. **gcd(...)** gcd(a, b) returns the greatest common divisor of integers *a* and *b*. **gcdext(...)** gcdext(a, b) returns a 3-element tuple (*g*, *s*, *t*) such that *g* == gcd(*a*, *b*) and *g* == *a* * *s* + *b* * *t* **hamdist(...)** hamdist(x, y) returns the Hamming distance (number of bit-positions where the bits differ) between integers *x* and *y*. **invert(...)** invert(x, m) returns *y* such that *x* * *y* == 1 modulo *m*, or 0 if no such *y* exists. **iroot(...)** iroot(x,n) returns a 2-element tuple (*y*, *b*) such that *y* is the integer *n*-th root of *x* and *b* is True if the root is exact. *x* must be >= 0 and *n* must be > 0. **iroot_rem(...)** iroot_rem(x,n) returns a 2-element tuple (*y*, *r*) such that *y* is the integer *n*-th root of *x* and *x* = y**n + *r*. *x* must be >= 0 and *n* must be > 0. **is_even(...)** is_even(x) returns True if *x* is even, False otherwise. **is_odd(...)** is_odd(x) returns True if *x* is odd, False otherwise. **is_power(...)** is_power(x) returns True if *x* is a perfect power, False otherwise. **is_prime(...)** is_prime(x[, n=25]) returns True if *x* is **probably** prime. False is returned if *x* is definitely composite. *x* is checked for small divisors and up to *n* Miller-Rabin tests are performed. The actual tests performed may vary based on version of GMP or MPIR used. **is_square(...)** is_square(x) returns True if *x* is a perfect square, False otherwise. **isqrt(...)** isqrt(x) returns the integer square root of an integer *x*. *x* must be >= 0. **isqrt_rem(...)** isqrt_rem(x) returns a 2-tuple (*s*, *t*) such that *s* = isqrt(*x*) and *t* = *x* - *s* * *s*. *x* must be >= 0. **jacobi(...)** jacobi(x, y) returns the Jacobi symbol (*x* | *y*). *y* must be odd and > 0. **kronecker(...)** kronecker(x, y) returns the Kronecker-Jacobi symbol (*x* | *y*). **lcm(...)** lcm(a, b) returns the lowest common multiple of integers *a* and *b*. **legendre(...)** legendre(x, y) returns the Legendre symbol (*x* | *y*). *y* is assumed to be an odd prime. **lucas(...)** lucas(n) returns the *n*-th Lucas number. **lucas2(...)** lucas2(n) returns a 2-tuple with the (*n*-1)-th and *n*-th Lucas numbers. **mpz(...)** mpz() returns a new *mpz* object set to 0. mpz(n) returns a new *mpz* object from a numeric value *n*. If *n* is not an integer, it will be truncated to an integer. mpz(s[, base=0]) returns a new *mpz* object from a string *s* made of digits in the given base. If base = 0, then binary, octal, or hex Python strings are recognized by leading 0b, 0o, or 0x characters. Otherwise the string is assumed to be decimal. Values for base can range between 2 and 62. **mpz_random(...)** mpz_random(random_state, n) returns a uniformly distributed random integer between 0 and *n*-1. The parameter *random_state* must be created by random_state() first. **mpz_rrandomb(...)** mpz_rrandomb(random_state, b) returns a random integer between 0 and 2**b - 1 with long sequences of zeros and one in its binary representation. The parameter *random_state* must be created by random_state() first. **mpz_urandomb(...)** mpz_urandomb(random_state, b) returns a uniformly distributed random integer between 0 and 2**b - 1. The parameter *random_state* must be created by random_state() first. **mul(...)** mul(x, y) returns *x* \* *y*. The result type depends on the input types. **next_prime(...)** next_prime(x) returns the next **probable** prime number > *x*. **num_digits(...)** num_digits(x[, base=10]) returns the length of the string representing the absolute value of *x* in radix *base*. The result is correct if base is a power of 2. For other bases, the result is usually correct but may be 1 too large. *base* can range between 2 and 62, inclusive. **popcount(...)** popcount(x) returns the number of bits with value 1 in *x*. If *x* < 0, the number of bits with value 1 is infinite so -1 is returned in that case. **powmod(...)** powmod(x, y, m) returns (*x* ** *y*) mod *m*. The exponent *y* can be negative, and the correct result will be returned if the inverse of *x* mod *m* exists. Otherwise, a ValueError is raised. **remove(...)** remove(x, f) will remove the factor *f* from *x* as many times as possible and return a 2-tuple (*y*, *m*) where *y* = *x* // (*f* ** *m*). *f* does not divide *y*. *m* is the multiplicity of the factor *f* in *x*. *f* must be > 1. **sub(...)** sub(x, y) returns *x* - *y*. The result type depends on the input types. **t_div(...)** t_div(x, y) returns the quotient of *x* divided by *y*. The quotient is rounded towards zero (truncation). *x* and *y* must be integers. **t_div_2exp(...)** t_div_2exp(x, n) returns the quotient of *x* divided by 2**n. The quotient is rounded towards zero (truncation). *n* must be > 0. **t_divmod(...)** t_divmod(x, y) returns the quotient and remainder of *x* divided by *y*. The quotient is rounded towards zero (truncation) and the remainder will have the same sign as *x*. *x* and *y* must be integers. **t_divmod_2exp(...)** t_divmod_2exp(x, n) returns the quotient and remainder of *x* divided by 2**n. The quotient is rounded towards zero (truncation) and the remainder will have the same sign as *x*. *x* must be an integer and *n* must be > 0. **t_mod(...)** t_mod(x, y) returns the remainder of *x* divided by *y*. The remainder will have the same sign as *x*. *x* and *y* must be integers. **t_mod_2exp(...)** t_mod_2exp(x, n) returns the remainder of *x* divided by 2**n. The remainder will have the same sign as *x*. *x* must be an integer and *n* must be > 0. gmpy2-2.1.0b3/docs/overview.rst0000664000175000017500000001224013356026702016202 0ustar casecase00000000000000Overview of gmpy2 ================= Tutorial -------- The *mpz* type is compatible with Python's built-in int/long type but is significantly faster for large values. The cutover point for performance varies, but can be as low as 20 to 40 digits. A variety of additional integer functions are provided. :: >>> import gmpy2 >>> from gmpy2 import mpz,mpq,mpfr,mpc >>> mpz(99) * 43 mpz(4257) >>> pow(mpz(99), 37, 59) mpz(18) >>> gmpy2.isqrt(99) mpz(9) >>> gmpy2.isqrt_rem(99) (mpz(9), mpz(18)) >>> gmpy2.gcd(123,27) mpz(3) >>> gmpy2.lcm(123,27) mpz(1107) The *mpq* type is compatible with the *fractions.Fraction* type included with Python. :: >>> mpq(3,7)/7 mpq(3,49) >>> mpq(45,3) * mpq(11,8) mpq(165,8) The most significant new features in gmpy2 are support for correctly rounded arbitrary precision real and complex arithmetic based on the MPFR and MPC libraries. Floating point contexts are used to control exceptional conditions. For example, division by zero can either return an Infinity or raise an exception. :: >>> mpfr(1)/7 mpfr('0.14285714285714285') >>> gmpy2.get_context().precision=200 >>> mpfr(1)/7 mpfr('0.1428571428571428571428571428571428571428571428571428571428571',200) >>> gmpy2.get_context() context(precision=200, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, trap_expbound=False, allow_complex=False) >>> mpfr(1)/0 mpfr('inf') >>> gmpy2.get_context().trap_divzero=True >>> mpfr(1)/0 Traceback (most recent call last): File "", line 1, in gmpy2.DivisionByZeroError: 'mpfr' division by zero in division >>> gmpy2.get_context() context(precision=200, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=True, divzero=True, trap_expbound=False, allow_complex=False) >>> gmpy2.sqrt(mpfr(-2)) mpfr('nan') >>> gmpy2.get_context().allow_complex=True >>> gmpy2.get_context().precision=53 >>> gmpy2.sqrt(mpfr(-2)) mpc('0.0+1.4142135623730951j') >>> >>> gmpy2.set_context(gmpy2.context()) >>> with gmpy2.local_context() as ctx: ... print(gmpy2.const_pi()) ... ctx.precision+=20 ... print(gmpy2.const_pi()) ... ctx.precision+=20 ... print(gmpy2.const_pi()) ... 3.1415926535897931 3.1415926535897932384628 3.1415926535897932384626433831 >>> print(gmpy2.const_pi()) 3.1415926535897931 >>> Miscellaneous gmpy2 Functions ----------------------------- **from_binary(...)** from_binary(bytes) returns a gmpy2 object from a byte sequence created by to_binary(). **get_cache(...)** get_cache() returns the current cache size (number of objects) and the maximum size per object (number of limbs). gmpy2 maintains an internal list of freed *mpz*, *xmpz*, *mpq*, *mpfr*, and *mpc* objects for reuse. The cache significantly improves performance but also increases the memory footprint. **license(...)** license() returns the gmpy2 license information. **mp_limbsize(...)** mp_limbsize() returns the number of bits per limb used by the GMP or MPIR library. **mp_version(...)** mp_version() returns the version of the GMP or MPIR library. **mpc_version(...)** mpc_version() returns the version of the MPC library. **mpfr_version(...)** mpfr_version() returns the version of the MPFR library. **random_state(...)** random_state([seed]) returns a new object containing state information for the random number generator. An optional integer argument can be specified as the seed value. Only the Mersenne Twister random number generator is supported. **set_cache(...)** set_cache(number, size) updates the maximum number of freed objects of each type that are cached and the maximum size (in limbs) of each object. The maximum number of objects of each type that can be cached is 1000. The maximum size of an object is 16384. The maximum size of an object is approximately 64K on 32-bit systems and 128K on 64-bit systems. .. note:: The caching options are global to gmpy2. Changes are not thread-safe. A change in one thread will impact all threads. **to_binary(...)** to_binary(x) returns a byte sequence from a gmpy2 object. All object types are supported. **version(...)** version() returns the version of gmpy2. gmpy2-2.1.0b3/gmpy2/0000775000175000017500000000000013530663166013716 5ustar casecase00000000000000gmpy2-2.1.0b3/gmpy2/__init__.pxd0000664000175000017500000000003313356026702016161 0ustar casecase00000000000000from gmpy2.gmpy2 cimport * gmpy2-2.1.0b3/gmpy2/__init__.py0000664000175000017500000000057513425750522016032 0ustar casecase00000000000000from .gmpy2 import * # Internal variables/functions are not imported by * above. # These are used by some python level functions and are needed # at the top level. # Use try...except to for static builds were _C_API is not available. try: from .gmpy2 import _C_API, _mpmath_normalize, _mpmath_create except ImportError: from .gmpy2 import _mpmath_normalize, _mpmath_create gmpy2-2.1.0b3/gmpy2/gmpy2.h0000664000175000017500000005100713525427233015125 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* gmpy C API extension header file. Part of Python's gmpy module since version 0.4 Created by Pearu Peterson , November 2000. Edited by A. Martelli , December 2000. Edited by Case Van Horsen , 2009, 2010, 2011. Version 1.02, February 2007. Version 1.03, June 2008 Version 1.04, June 2008 (no changes) Version 1.05, February 2009 (support MPIR) Version 1.20, January 2010 (remove obsolete MS hacks) casevh Version 2.00, April 2010 (change to gmpy2) casevh October 2010 (added Py_hash_t) casevh December 2010 (added mpfr, mpc) casevh January 2011 (add Pygmpy_context) casevh April 2011 (split into multiple files) casevh Version 2.10 August 2014 (reflect major rewrite during 2013/2014) casevh */ #ifndef Py_GMPYMODULE_H #define Py_GMPYMODULE_H #ifdef __cplusplus extern "C" { #endif /* Structure of gmpy2.h * * Revised 17-APR-2017 casevh * * 1. Checks for specific Python versions. * 2. Include headers for GMP/MPIR, MPFR, and MPC. * 3. Define public C-API. * 1. Define gmpy2 types. * 2. Define the public API. * */ /* Check for minimum Python version requirements. */ #if PY_VERSION_HEX < 0x02060000 # error "GMPY2 requires Python 2.6 or later." #endif /* Include headers for GMP/MPIR, MPFR, and MPC. */ #ifdef MPIR # include #else # include #endif #include #include /* Check MPFR and MPC versions. */ #if (!defined(MPC_VERSION) || (MPC_VERSION < MPC_VERSION_NUM(1,0,3))) # error "GMPY2 requires MPC 1.0.3 or later." #endif #if (defined(MPC_VERSION) && (MPC_VERSION >= MPC_VERSION_NUM(1,1,0))) # define MPC_110 #endif #if PY_VERSION_HEX < 0x030200A4 typedef long Py_hash_t; typedef unsigned long Py_uhash_t; # define _PyHASH_IMAG 1000003 #endif /* The native_si and native_ui types correspond to long long on Windows 64. They * should only be used with the MPIR library (not MPFR/MPC). */ #if defined(MPIR) && defined(_WIN64) typedef long long native_si; typedef unsigned long long native_ui; #define GMPy_Integer_AsNative_siAndError GMPy_Integer_AsLongLongAndError #define GMPy_Integer_AsNative_uiAndError GMPy_Integer_AsUnsignedLongLongAndError #else typedef long native_si; typedef unsigned long native_ui; #define GMPy_Integer_AsNative_siAndError GMPy_Integer_AsLongAndError #define GMPy_Integer_AsNative_uiAndError GMPy_Integer_AsUnsignedLongAndError #endif /* GMPY2 Public API */ /* Types * MPZ_Object * XMPZ_Object (mutable version of MPZ_Object) * MPQ_Object * XMPQ_Object (mutable version of MPQ_Object) * MPFR_Object * XMPFR_Object (mutable version of MPFR_Object) * MPC_Object * XMPC_Object (mutable version of MPC_Object) * CTXT_Object * CTXT_Manager_Object * RandomState_Object */ typedef struct { PyObject_HEAD mpz_t z; Py_hash_t hash_cache; } MPZ_Object; typedef struct { PyObject_HEAD mpz_t z; } XMPZ_Object; typedef struct { PyObject_HEAD mpq_t q; Py_hash_t hash_cache; } MPQ_Object; typedef struct { PyObject_HEAD mpfr_t f; Py_hash_t hash_cache; int rc; } MPFR_Object; typedef struct { PyObject_HEAD mpc_t c; Py_hash_t hash_cache; int rc; } MPC_Object; typedef struct { PyObject_HEAD gmp_randstate_t state; } RandomState_Object; typedef struct { mpfr_prec_t mpfr_prec; /* current precision in bits, for MPFR */ mpfr_rnd_t mpfr_round; /* current rounding mode for float (MPFR) */ mpfr_exp_t emax; /* maximum exponent */ mpfr_exp_t emin; /* minimum exponent */ int subnormalize; /* if 1, subnormalization is performed */ int underflow; /* did an underflow occur? */ int overflow; /* did an overflow occur? */ int inexact; /* was the result inexact? */ int invalid; /* invalid operation (i.e. NaN)? */ int erange; /* did a range error occur? */ int divzero; /* divided by zero? */ int traps; /* if 0, do not trap any exceptions */ /* if not 0, then raise traps per bits above */ mpfr_prec_t real_prec; /* current precision in bits, for Re(MPC) */ mpfr_prec_t imag_prec; /* current precision in bits, for Im(MPC) */ mpfr_rnd_t real_round; /* current rounding mode for Re(MPC) */ mpfr_rnd_t imag_round; /* current rounding mode for Im(MPC) */ int allow_complex; /* if 1, allow mpfr functions to return an mpc */ int rational_division; /* if 1, mpz/mpz returns an mpq result */ } gmpy_context; typedef struct { PyObject_HEAD gmpy_context ctx; #ifndef WITHOUT_THREADS PyThreadState *tstate; #endif } CTXT_Object; typedef struct { PyObject_HEAD CTXT_Object *new_context; /* Context that will be returned when * __enter__ is called. */ CTXT_Object *old_context; /* Context that will restored when * __exit__ is called. */ } CTXT_Manager_Object; #define MPZ(obj) (((MPZ_Object*)(obj))->z) #define MPQ(obj) (((MPQ_Object*)(obj))->q) #define MPFR(obj) (((MPFR_Object*)(obj))->f) #define MPC(obj) (((MPC_Object*)(obj))->c) /* Start of the C-API definitions */ #define MPZ_Type_NUM 0 #define XMPZ_Type_NUM 1 #define MPQ_Type_NUM 2 #define XMPQ_Type_NUM 3 #define MPFR_Type_NUM 4 #define XMPFR_Type_NUM 5 #define MPC_Type_NUM 6 #define XMPC_Type_NUM 7 #define CTXT_Type_NUM 8 #define CTXT_Manager_Type_NUM 9 #define RandomState_Type_NUM 10 /* The following functions are found in gmpy2_cache. */ #define GMPy_MPZ_New_NUM 11 #define GMPy_MPZ_New_RETURN MPZ_Object * #define GMPy_MPZ_New_PROTO (CTXT_Object *context) #define GMPy_MPZ_NewInit_NUM 12 #define GMPy_MPZ_NewInit_RETURN PyObject * #define GMPy_MPZ_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPZ_Dealloc_NUM 13 #define GMPy_MPZ_Dealloc_RETURN void #define GMPy_MPZ_Dealloc_PROTO (MPZ_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPZ_ConvertArg_NUM 14 #define GMPy_MPZ_ConvertArg_RETURN int #define GMPy_MPZ_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* The following functions are found in gmpy2_cache. */ #define GMPy_XMPZ_New_NUM 15 #define GMPy_XMPZ_New_RETURN XMPZ_Object * #define GMPy_XMPZ_New_PROTO (CTXT_Object *context) #define GMPy_XMPZ_NewInit_NUM 16 #define GMPy_XMPZ_NewInit_RETURN PyObject * #define GMPy_XMPZ_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_XMPZ_Dealloc_NUM 17 #define GMPy_XMPZ_Dealloc_RETURN void #define GMPy_XMPZ_Dealloc_PROTO (XMPZ_Object *self) /* The following functions are found in gmpy2_cache. */ #define GMPy_MPQ_New_NUM 18 #define GMPy_MPQ_New_RETURN MPQ_Object * #define GMPy_MPQ_New_PROTO (CTXT_Object *context) #define GMPy_MPQ_NewInit_NUM 19 #define GMPy_MPQ_NewInit_RETURN PyObject * #define GMPy_MPQ_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPQ_Dealloc_NUM 20 #define GMPy_MPQ_Dealloc_RETURN void #define GMPy_MPQ_Dealloc_PROTO (MPQ_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPQ_ConvertArg_NUM 21 #define GMPy_MPQ_ConvertArg_RETURN int #define GMPy_MPQ_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* The following functions are found in gmpy2_cache. */ #define GMPy_MPFR_New_NUM 22 #define GMPy_MPFR_New_RETURN MPFR_Object * #define GMPy_MPFR_New_PROTO (mpfr_prec_t bits, CTXT_Object *context) #define GMPy_MPFR_NewInit_NUM 23 #define GMPy_MPFR_NewInit_RETURN PyObject * #define GMPy_MPFR_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPFR_Dealloc_NUM 24 #define GMPy_MPFR_Dealloc_RETURN void #define GMPy_MPFR_Dealloc_PROTO (MPFR_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPFR_ConvertArg_NUM 25 #define GMPy_MPFR_ConvertArg_RETURN int #define GMPy_MPFR_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* The following functions are found in gmpy2_cache. */ #define GMPy_MPC_New_NUM 26 #define GMPy_MPC_New_RETURN MPC_Object * #define GMPy_MPC_New_PROTO (mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) #define GMPy_MPC_NewInit_NUM 27 #define GMPy_MPC_NewInit_RETURN PyObject * #define GMPy_MPC_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPC_Dealloc_NUM 28 #define GMPy_MPC_Dealloc_RETURN void #define GMPy_MPC_Dealloc_PROTO (MPC_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPC_ConvertArg_NUM 29 #define GMPy_MPC_ConvertArg_RETURN int #define GMPy_MPC_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* Total number of C-API pointers. */ #define GMPy_API_pointers 30 /* End of C-API definitions. */ #ifdef GMPY2_MODULE /* Define various macros to deal with differences between Python 2 and 3. */ #if (PY_MAJOR_VERSION == 3) #define PY3 #define Py2or3String_FromString PyUnicode_FromString #define Py2or3String_FromFormat PyUnicode_FromFormat #define Py2or3String_Check PyUnicode_Check #define Py2or3String_Format PyUnicode_Format #define Py2or3String_AsString PyUnicode_AS_DATA #define PyStrOrUnicode_Check(op) (PyBytes_Check(op) || PyUnicode_Check(op)) #define PyIntOrLong_FromLong PyLong_FromLong #define PyIntOrLong_Check(op) PyLong_Check(op) #define PyIntOrLong_FromSize_t PyLong_FromSize_t #define PyIntOrLong_FromSsize_t PyLong_FromSsize_t #define PyIntOrLong_AsSsize_t PyLong_AsSsize_t #define PyIntOrLong_AsLong PyLong_AsLong #else #define PY2 #define Py2or3String_FromString PyString_FromString #define Py2or3String_FromFormat PyString_FromFormat #define Py2or3String_Check PyString_Check #define Py2or3String_Format PyString_Format #define Py2or3String_AsString PyString_AsString #define PyStrOrUnicode_Check(op) (PyString_Check(op) || PyUnicode_Check(op)) #define PyIntOrLong_FromLong PyInt_FromLong #define PyIntOrLong_Check(op) (PyInt_Check(op) || PyLong_Check(op)) #define PyIntOrLong_FromSize_t PyInt_FromSize_t #define PyIntOrLong_FromSsize_t PyInt_FromSsize_t #define PyIntOrLong_AsSsize_t PyInt_AsSsize_t #define PyIntOrLong_AsLong PyInt_AsLong #endif #ifndef ABS # define ABS(a) (((a) < 0) ? -(a) : (a)) #endif #if defined(MS_WIN32) && defined(_MSC_VER) /* so one won't need to link explicitly to gmp.lib...: */ # if defined(MPIR) # pragma comment(lib,"mpir.lib") # else # pragma comment(lib,"gmp.lib") # endif # define USE_ALLOCA 1 # define inline __inline #endif #ifdef __GNUC__ # define USE_ALLOCA 1 #endif #ifndef alloca # ifdef __GNUC__ # define alloca __builtin_alloca # else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else char *alloca (); # endif # endif # endif #endif #define ALLOC_THRESHOLD 8192 #define INDEX_ERROR(msg) PyErr_SetString(PyExc_IndexError, msg) #define TYPE_ERROR(msg) PyErr_SetString(PyExc_TypeError, msg) #define VALUE_ERROR(msg) PyErr_SetString(PyExc_ValueError, msg) #define ZERO_ERROR(msg) PyErr_SetString(PyExc_ZeroDivisionError, msg) #define SYSTEM_ERROR(msg) PyErr_SetString(PyExc_SystemError, msg) #define OVERFLOW_ERROR(msg) PyErr_SetString(PyExc_OverflowError, msg) #define RUNTIME_ERROR(msg) PyErr_SetString(PyExc_RuntimeError, msg) #define GMPY_DEFAULT -1 /* To prevent excessive memory usage, we don't want to save very large * numbers in the cache. The default value specified in the options * structure is 128 words (512 bytes on 32-bit platforms, 1024 bytes on * 64-bit platforms). */ #define MAX_CACHE_LIMBS 16384 /* The maximum number of objects that can be saved in a cache is specified * here. The default value is 100.*/ #define MAX_CACHE 1000 #ifdef USE_ALLOCA # define TEMP_ALLOC(B, S) \ if(S < ALLOC_THRESHOLD) { \ B = alloca(S); \ } else { \ if(!(B = malloc(S))) { \ PyErr_NoMemory(); \ return NULL; \ } \ } # define TEMP_FREE(B, S) if(S >= ALLOC_THRESHOLD) free(B) #else # define TEMP_ALLOC(B, S) \ if(!(B = malloc(S))) { \ PyErr_NoMemory(); \ return NULL; \ } # define TEMP_FREE(B, S) free(B) #endif /* Various defs to mask differences between Python versions. */ #define Py_RETURN_NOTIMPLEMENTED \ return Py_INCREF(Py_NotImplemented), Py_NotImplemented #ifndef Py_SIZE # define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) #endif #ifndef Py_TYPE # define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #endif /* Import a collection of general purpose macros. */ #include "gmpy2_macros.h" /* Import the files that complete the definition of the types defined above. */ #include "gmpy2_mpz.h" #include "gmpy2_xmpz.h" #include "gmpy2_mpq.h" #include "gmpy2_mpfr.h" #include "gmpy2_mpc.h" #include "gmpy2_context.h" #include "gmpy2_random.h" /* Import the header files that provide the various functions. */ /* Support object caching, creation, and deletion. */ #include "gmpy2_cache.h" /* Suport for miscellaneous functions (ie. version, license, etc.). */ #include "gmpy2_misc.h" /* Support conversion to/from binary format. */ #include "gmpy2_binary.h" /* Support for mpz/xmpz specific functions. */ #include "gmpy2_convert.h" #include "gmpy2_convert_utils.h" #include "gmpy2_convert_gmp.h" #include "gmpy2_convert_mpfr.h" #include "gmpy2_convert_mpc.h" #include "gmpy2_mpz_divmod.h" #include "gmpy2_mpz_divmod2exp.h" #include "gmpy2_mpz_pack.h" #include "gmpy2_mpz_bitops.h" #include "gmpy2_mpz_inplace.h" #include "gmpy2_mpz_misc.h" #include "gmpy2_xmpz_inplace.h" #include "gmpy2_xmpz_misc.h" /* Support for mpq specific functions. */ #include "gmpy2_mpq_misc.h" /* Support for mpfr specific functions. */ #include "gmpy2_mpfr_misc.h" /* Support for mpc specific functions. */ #include "gmpy2_mpc_misc.h" /* Support Lucas sequences. */ #include "gmpy_mpz_lucas.h" /* Support probable-prime tests. */ #include "gmpy_mpz_prp.h" /* Support higher-level Python methods and functions; generally not * specific to a single type. */ #include "gmpy2_abs.h" #include "gmpy2_add.h" #include "gmpy2_divmod.h" #include "gmpy2_floordiv.h" #include "gmpy2_minus.h" #include "gmpy2_mod.h" #include "gmpy2_mul.h" #include "gmpy2_plus.h" #include "gmpy2_pow.h" #include "gmpy2_sub.h" #include "gmpy2_truediv.h" #include "gmpy2_math.h" #include "gmpy2_const.h" #include "gmpy2_square.h" #include "gmpy2_format.h" #include "gmpy2_hash.h" #include "gmpy2_fused.h" #include "gmpy2_muldiv_2exp.h" #include "gmpy2_predicate.h" #include "gmpy2_sign.h" #include "gmpy2_richcompare.h" #include "gmpy2_cmp.h" #ifdef VECTOR # include "gmpy2_vector.h" #endif /* defined(VECTOR) */ #else /* defined(GMPY2_MODULE) */ /* This section is used for other C-coded modules that use gmpy2's API. */ static void **GMPy_C_API; #define MPZ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPZ_Type_NUM]) #define XMPZ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPZ_Type_NUM]) #define MPQ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPQ_Type_NUM]) #define XMPQ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPQ_Type_NUM]) #define MPFR_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPFR_Type_NUM]) #define XMPFR_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPFR_Type_NUM]) #define MPC_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPC_Type_NUM]) #define XMPC_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPC_Type_NUM]) #define GMPy_MPZ_New (*(GMPy_MPZ_New_RETURN (*)GMPy_MPZ_New_PROTO) GMPy_C_API[GMPy_MPZ_New_NUM]) #define GMPy_MPZ_NewInit (*(GMPy_MPZ_NewInit_RETURN (*)GMPy_MPZ_NewInit_PROTO) GMPy_C_API[GMPy_MPZ_NewInit_NUM]) #define GMPy_MPZ_Dealloc (*(GMPy_MPZ_Dealloc_RETURN (*)GMPy_MPZ_Dealloc_PROTO) GMPy_C_API[GMPy_MPZ_Dealloc_NUM]) #define GMPy_MPZ_ConvertArg (*(GMPy_MPZ_ConvertArg_RETURN (*)GMPy_MPZ_ConvertArg_PROTO) GMPy_C_API[GMPy_MPZ_ConvertArg_NUM]) #define GMPy_XMPZ_New (*(GMPy_XMPZ_New_RETURN (*)GMPy_XMPZ_New_PROTO) GMPy_C_API[GMPy_XMPZ_New_NUM]) #define GMPy_XMPZ_NewInit (*(GMPy_XMPZ_NewInit_RETURN (*)GMPy_XMPZ_NewInit_PROTO) GMPy_C_API[GMPy_XMPZ_NewInit_NUM]) #define GMPy_XMPZ_Dealloc (*(GMPy_XMPZ_Dealloc_RETURN (*)GMPy_XMPZ_Dealloc_PROTO) GMPy_C_API[GMPy_XMPZ_Dealloc_NUM]) #define GMPy_MPQ_New (*(GMPy_MPQ_New_RETURN (*)GMPy_MPQ_New_PROTO) GMPy_C_API[GMPy_MPQ_New_NUM]) #define GMPy_MPQ_NewInit (*(GMPy_MPQ_NewInit_RETURN (*)GMPy_MPQ_NewInit_PROTO) GMPy_C_API[GMPy_MPQ_NewInit_NUM]) #define GMPy_MPQ_Dealloc (*(GMPy_MPQ_Dealloc_RETURN (*)GMPy_MPQ_Dealloc_PROTO) GMPy_C_API[GMPy_MPQ_Dealloc_NUM]) #define GMPy_MPQ_ConvertArg (*(GMPy_MPQ_ConvertArg_RETURN (*)GMPy_MPQ_ConvertArg_PROTO) GMPy_C_API[GMPy_MPQ_ConvertArg_NUM]) #define GMPy_MPFR_New (*(GMPy_MPFR_New_RETURN (*)GMPy_MPFR_New_PROTO) GMPy_C_API[GMPy_MPFR_New_NUM]) #define GMPy_MPFR_NewInit (*(GMPy_MPFR_NewInit_RETURN (*)GMPy_MPFR_NewInit_PROTO) GMPy_C_API[GMPy_MPFR_NewInit_NUM]) #define GMPy_MPFR_Dealloc (*(GMPy_MPFR_Dealloc_RETURN (*)GMPy_MPFR_Dealloc_PROTO) GMPy_C_API[GMPy_MPFR_Dealloc_NUM]) #define GMPy_MPFR_ConvertArg (*(GMPy_MPFR_ConvertArg_RETURN (*)GMPy_MPFR_ConvertArg_PROTO) GMPy_C_API[GMPy_MPFR_ConvertArg_NUM]) #define GMPy_MPC_New (*(GMPy_MPC_New_RETURN (*)GMPy_MPC_New_PROTO) GMPy_C_API[GMPy_MPC_New_NUM]) #define GMPy_MPC_NewInit (*(GMPy_MPC_NewInit_RETURN (*)GMPy_MPC_NewInit_PROTO) GMPy_C_API[GMPy_MPC_NewInit_NUM]) #define GMPy_MPC_Dealloc (*(GMPy_MPC_Dealloc_RETURN (*)GMPy_MPC_Dealloc_PROTO) GMPy_C_API[GMPy_MPC_Dealloc_NUM]) #define GMPy_MPC_ConvertArg (*(GMPy_MPC_ConvertArg_RETURN (*)GMPy_MPC_ConvertArg_PROTO) GMPy_C_API[GMPy_MPC_ConvertArg_NUM]) static int import_gmpy2(void) { GMPy_C_API = (void **)PyCapsule_Import("gmpy2._C_API", 0); return (GMPy_C_API != NULL) ? 0 : -1; } #endif /* defined(GMPY2_MODULE) */ #ifdef __cplusplus } #endif /* defined(__cplusplus */ #endif /* !defined(Py_GMPYMODULE_H */ gmpy2-2.1.0b3/gmpy2/gmpy2.pxd0000664000175000017500000001111113356026702015457 0ustar casecase00000000000000cdef extern from "gmp.h": # gmp integers ctypedef long mp_limb_t ctypedef struct __mpz_struct: int _mp_alloc int _mp_size mp_limb_t* _mp_d ctypedef __mpz_struct mpz_t[1] ctypedef __mpz_struct *mpz_ptr ctypedef const __mpz_struct *mpz_srcptr # gmp rationals ctypedef struct __mpq_struct: __mpz_struct _mp_num __mpz_struct _mp_den ctypedef __mpq_struct mpq_t[1] ctypedef __mpq_struct *mpq_ptr ctypedef const __mpq_struct *mpq_srcptr void mpz_set(mpz_t rop, mpz_t op) void mpq_set(mpq_ptr rop, mpq_srcptr op) void mpq_set_num(mpq_t rational, mpz_t numerator) void mpq_set_den(mpq_t rational, mpz_t denominator) cdef extern from "mpfr.h": # mpfr reals ctypedef int mpfr_sign_t ctypedef long mpfr_prec_t ctypedef long mpfr_exp_t ctypedef struct __mpfr_struct: mpfr_prec_t _mpfr_prec mpfr_sign_t _mpfr_sign mpfr_exp_t _mpfr_exp mp_limb_t* _mpfr_d ctypedef __mpfr_struct mpfr_t[1] ctypedef __mpfr_struct *mpfr_ptr ctypedef const __mpfr_struct *mpfr_srcptr ctypedef enum mpfr_rnd_t: MPFR_RNDN MPFR_RNDZ MPFR_RNDU MPFR_RNDD MPFR_RNDA MPFR_RNDF MPFR_RNDNA mpfr_prec_t mpfr_get_prec(mpfr_t x) int mpfr_set(mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd) cdef extern from "mpc.h": # mpc complexes ctypedef struct __mpc_struct: mpfr_t re mpfr_t im ctypedef __mpc_struct mpc_t[1]; ctypedef __mpc_struct *mpc_ptr; ctypedef const __mpc_struct *mpc_srcptr; ctypedef enum mpc_rnd_t: MPC_RNDNN MPC_RNDNZ MPC_RNDNU MPC_RNDND MPC_RNDZN MPC_RNDZZ MPC_RNDZU MPC_RNDZD MPC_RNDUN MPC_RNDUZ MPC_RNDUU MPC_RNDUD MPC_RNDDN MPC_RNDDZ MPC_RNDDU MPC_RNDDD mpfr_prec_t mpc_get_prec(mpc_srcptr x) void mpc_get_prec2(mpfr_prec_t *pr, mpfr_prec_t *pi, mpc_srcptr x) int mpc_set(mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) int mpc_set_fr_fr(mpc_ptr rop, mpfr_srcptr rp, mpfr_srcptr ip, mpc_rnd_t rnd) cdef extern from "gmpy2.h": # Initialize the C-API # This must be called before any other functions, but not to access # the types. cdef int import_gmpy2() except -1 # Object types ctypedef class gmpy2.mpz [object MPZ_Object]: cdef mpz_t z ctypedef class gmpy2.mpq [object MPQ_Object]: cdef mpq_t q ctypedef class gmpy2.mpfr [object MPFR_Object]: cdef mpfr_t f cdef int rc ctypedef class gmpy2.mpc [object MPC_Object]: cdef mpc_t c cdef int rc # Object creation cdef mpz GMPy_MPZ_New(void *) cdef mpq GMPy_MPQ_New(void *) cdef mpfr GMPy_MPFR_New(mpfr_prec_t prec, void *) cdef mpc GMPy_MPC_New(mpfr_prec_t rprec, mpfr_prec_t iprec, void *) # C field access cdef mpz_t MPZ(mpz) cdef mpq_t MPQ(mpq) cdef mpfr_t MPFR(mpfr) cdef mpc_t MPC(mpc) # Type check cdef bint MPZ_Check(object) cdef bint MPQ_Check(object) cdef bint MPFR_Check(object) cdef bint MPC_Check(object) # Build a gmpy2 mpz from a gmp mpz cdef inline mpz GMPy_MPZ_From_mpz(mpz_srcptr z): cdef mpz res = GMPy_MPZ_New(NULL) mpz_set(res.z, z) return res # Build a gmpy2 mpq from a gmp mpq cdef inline mpq GMPy_MPQ_From_mpq(mpq_srcptr q): cdef mpq res = GMPy_MPQ_New(NULL) mpq_set(res.q, q) return res # Build a gmpy2 mpq from gmp mpz numerator and denominator cdef inline mpq GMPy_MPQ_From_mpz(mpz_srcptr num, mpz_srcptr den): cdef mpq res = GMPy_MPQ_New(NULL) mpq_set_num(res.q, num) mpq_set_den(res.q, den) return res # Build a gmpy2 mpfr from a mpfr cdef inline mpfr GMPy_MPFR_From_mpfr(mpfr_srcptr x): cdef mpfr res = GMPy_MPFR_New(mpfr_get_prec(x), NULL) mpfr_set(res.f, x, MPFR_RNDN) return res # Build a gmpy2 mpc from a mpc cdef inline mpc GMPy_MPC_From_mpc(mpc_srcptr c): cdef mpfr_prec_t pr cdef mpfr_prec_t pi mpc_get_prec2(&pr, &pi, c) cdef mpc res = GMPy_MPC_New(pr, pi, NULL) mpc_set(res.c, c, MPC_RNDNN) return res # Build a gmpy2 mpc from a real part mpfr and an imaginary part mpfr cdef inline mpc GMPy_MPC_From_mpfr(mpfr_srcptr re, mpfr_srcptr im): cdef mpc res = GMPy_MPC_New(mpfr_get_prec(re), mpfr_get_prec(im), NULL) # We intentionally use MPFR funtions instead of MPC functions here # in order not to add an unneeded dependency on MPC. It's probably # faster too this way. mpfr_set(res.c.re, re, MPFR_RNDN) mpfr_set(res.c.im, im, MPFR_RNDN) return res gmpy2-2.1.0b3/gmpy2.egg-info/0000775000175000017500000000000013530663166015410 5ustar casecase00000000000000gmpy2-2.1.0b3/gmpy2.egg-info/PKG-INFO0000664000175000017500000000416313530663166016511 0ustar casecase00000000000000Metadata-Version: 1.1 Name: gmpy2 Version: 2.1.0b3 Summary: gmpy2 interface to GMP, MPFR, and MPC for Python 2.7 and 3.4+ Home-page: https://github.com/aleaxit/gmpy Author: Case Van Horsen Author-email: casevh@gmail.com License: LGPL-3.0+ Description: gmpy2 is an optimized, C-coded Python extension module that supports fast multiple-precision arithmetic. gmpy2 is based on the original gmpy module. gmpy2 adds support for correctly rounded multiple-precision real arithmetic (using the MPFR library) and complex arithmetic (using the MPC library). The gmpy2 2.0.x series is a stable version that is only receiving bug fixes. The main development branch (2.1.x) was extensively refactored. The most significant changes are support for thread-safe contexts and context methods. gmpy2 is available at https://pypi.python.org/pypi/gmpy2/ Documentation is available at https://gmpy2.readthedocs.io/en/latest/ Keywords: gmp mpfr mpc multiple-precision arbitrary-precision precision bignum Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+) Classifier: Natural Language :: English Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: Microsoft :: Windows Classifier: Operating System :: POSIX Classifier: Programming Language :: C Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Scientific/Engineering :: Mathematics Classifier: Topic :: Software Development :: Libraries :: Python Modules gmpy2-2.1.0b3/gmpy2.egg-info/SOURCES.txt0000664000175000017500000001101713530663166017274 0ustar casecase00000000000000COPYING COPYING.LESSER INSTALL MANIFEST.in README msys2_build.txt setup.py windows_build.txt docs/Makefile docs/advmpz.rst docs/conf.py docs/conversion.rst docs/cython.rst docs/history.rst docs/index.rst docs/intro.rst docs/make.bat docs/mpc.rst docs/mpfr.rst docs/mpq.rst docs/mpz.rst docs/overview.rst gmpy2/__init__.pxd gmpy2/__init__.py gmpy2/gmpy2.h gmpy2/gmpy2.pxd gmpy2.egg-info/PKG-INFO gmpy2.egg-info/SOURCES.txt gmpy2.egg-info/dependency_links.txt gmpy2.egg-info/not-zip-safe gmpy2.egg-info/top_level.txt src/gmpy2.c src/gmpy2.h src/gmpy2.pxd src/gmpy2_abs.c src/gmpy2_abs.h src/gmpy2_add.c src/gmpy2_add.h src/gmpy2_binary.c src/gmpy2_binary.h src/gmpy2_cache.c src/gmpy2_cache.h src/gmpy2_cmp.c src/gmpy2_cmp.h src/gmpy2_const.c src/gmpy2_const.h src/gmpy2_context.c src/gmpy2_context.h src/gmpy2_convert.c src/gmpy2_convert.h src/gmpy2_convert_gmp.c src/gmpy2_convert_gmp.h src/gmpy2_convert_mpc.c src/gmpy2_convert_mpc.h src/gmpy2_convert_mpfr.c src/gmpy2_convert_mpfr.h src/gmpy2_convert_utils.c src/gmpy2_convert_utils.h src/gmpy2_divmod.c src/gmpy2_divmod.h src/gmpy2_floordiv.c src/gmpy2_floordiv.h src/gmpy2_format.c src/gmpy2_format.h src/gmpy2_fused.c src/gmpy2_fused.h src/gmpy2_hash.c src/gmpy2_hash.h src/gmpy2_macros.h src/gmpy2_math.c src/gmpy2_math.h src/gmpy2_minus.c src/gmpy2_minus.h src/gmpy2_misc.c src/gmpy2_misc.h src/gmpy2_mod.c src/gmpy2_mod.h src/gmpy2_mpc.c src/gmpy2_mpc.h src/gmpy2_mpc_misc.c src/gmpy2_mpc_misc.h src/gmpy2_mpfr.c src/gmpy2_mpfr.h src/gmpy2_mpfr_misc.c src/gmpy2_mpfr_misc.h src/gmpy2_mpmath.c src/gmpy2_mpq.c src/gmpy2_mpq.h src/gmpy2_mpq_misc.c src/gmpy2_mpq_misc.h src/gmpy2_mpz.c src/gmpy2_mpz.h src/gmpy2_mpz_bitops.c src/gmpy2_mpz_bitops.h src/gmpy2_mpz_divmod.c src/gmpy2_mpz_divmod.h src/gmpy2_mpz_divmod2exp.c src/gmpy2_mpz_divmod2exp.h src/gmpy2_mpz_inplace.c src/gmpy2_mpz_inplace.h src/gmpy2_mpz_misc.c src/gmpy2_mpz_misc.h src/gmpy2_mpz_pack.c src/gmpy2_mpz_pack.h src/gmpy2_mul.c src/gmpy2_mul.h src/gmpy2_muldiv_2exp.c src/gmpy2_muldiv_2exp.h src/gmpy2_plus.c src/gmpy2_plus.h src/gmpy2_pow.c src/gmpy2_pow.h src/gmpy2_predicate.c src/gmpy2_predicate.h src/gmpy2_random.c src/gmpy2_random.h src/gmpy2_richcompare.c src/gmpy2_richcompare.h src/gmpy2_sign.c src/gmpy2_sign.h src/gmpy2_square.c src/gmpy2_square.h src/gmpy2_sub.c src/gmpy2_sub.h src/gmpy2_truediv.c src/gmpy2_truediv.h src/gmpy2_types.h src/gmpy2_vector.c src/gmpy2_vector.h src/gmpy2_xmpz.c src/gmpy2_xmpz.h src/gmpy2_xmpz_inplace.c src/gmpy2_xmpz_inplace.h src/gmpy2_xmpz_misc.c src/gmpy2_xmpz_misc.h src/gmpy_mpz_lucas.c src/gmpy_mpz_lucas.h src/gmpy_mpz_prp.c src/gmpy_mpz_prp.h src/mpz_pylong.c test/gmpy_test.py test/runtests.py test/supportclasses.py test/supportclasses.pyc test/test_abs.txt test/test_context.txt test/test_gmpy2_abs.txt test/test_gmpy2_add.txt test/test_gmpy2_binary.txt test/test_gmpy2_cmp.txt test/test_gmpy2_comp.txt test/test_gmpy2_const.txt test/test_gmpy2_constructors.txt test/test_gmpy2_convert.txt test/test_gmpy2_divmod.txt test/test_gmpy2_floordiv.txt test/test_gmpy2_format.txt test/test_gmpy2_fused.txt test/test_gmpy2_lucas.txt test/test_gmpy2_math.txt test/test_gmpy2_minus.txt test/test_gmpy2_mpfr_misc.txt test/test_gmpy2_mpq_misc.txt test/test_gmpy2_mpq_misc_py2.txt test/test_gmpy2_mpq_misc_py3.txt test/test_gmpy2_mpz_bitops.txt test/test_gmpy2_mpz_divmod.txt test/test_gmpy2_mpz_divmod2exp.txt test/test_gmpy2_mpz_inplace.txt test/test_gmpy2_mpz_misc.txt test/test_gmpy2_mpz_misc_py2.txt test/test_gmpy2_mpz_misc_py3.txt test/test_gmpy2_mul.txt test/test_gmpy2_muldiv_2exp.txt test/test_gmpy2_plus.txt test/test_gmpy2_pow.txt test/test_gmpy2_predicate.txt test/test_gmpy2_prp.txt test/test_gmpy2_root.txt test/test_gmpy2_square.txt test/test_gmpy2_sub.txt test/test_gmpy2_xmpz_inplace.txt test/test_gmpy2_xmpz_misc.txt test/test_misc.txt test/test_mpc.txt test/test_mpc_create.txt test/test_mpc_exp_log.txt test/test_mpc_to_from_binary.txt test/test_mpc_trig.txt test/test_mpfr.txt test/test_mpfr4_fused.txt test/test_mpfr4_random.txt test/test_mpfr_create.txt test/test_mpfr_dec.txt test/test_mpfr_exp_log.txt test/test_mpfr_min_max.txt test/test_mpfr_special.txt test/test_mpfr_subnormalize.txt test/test_mpfr_to_from_binary.txt test/test_mpfr_trig.txt test/test_mpq.txt test/test_mpq_to_from_binary.txt test/test_mpz.txt test/test_mpz_args.py test/test_mpz_args.pyc test/test_mpz_bit.txt test/test_mpz_create.txt test/test_mpz_functions.txt test/test_mpz_io.txt test/test_mpz_pack_unpack.txt test/test_mpz_random.txt test/test_mpz_template.txt test/test_mpz_to_from_binary.txt test/test_pack.py test/test_pack.pyc test/test_py32_hash.txtgmpy2-2.1.0b3/gmpy2.egg-info/dependency_links.txt0000664000175000017500000000000113530663166021456 0ustar casecase00000000000000 gmpy2-2.1.0b3/gmpy2.egg-info/not-zip-safe0000664000175000017500000000000113244310701017620 0ustar casecase00000000000000 gmpy2-2.1.0b3/gmpy2.egg-info/top_level.txt0000664000175000017500000000000613530663166020136 0ustar casecase00000000000000gmpy2 gmpy2-2.1.0b3/msys2_build.txt0000664000175000017500000002760513244653673015673 0ustar casecase00000000000000Building gmpy2 with MSYS2 ========================= Note: These instructions are a work in progress! From the MSYS2 home page: http://sourceforge.net/projects/msys2/ MSYS2 is a Cygwin-derived Posix-like environment for Windows. The name is a contraction of Minimal SYStem 2, and aims to provide support to facilitate using the bash shell, Autotools, revision control systems and the like for building native Windows applications using MinGW-w64 toolchains. Installing MSYS2 ================ MSYS2 installation instructions can be found at: http://sourceforge.net/p/msys2/wiki/MSYS2%20installation/ Some of the examples assume the 64-bit version of MSYS2 is installed. If you install the 32-bit version of MSYS2, you will need to change any references of C:\msys64 to C:\msys32. After following the installation and upgrade steps documented above, you will need to install the MinGW compiler toolchain(s). Both toolchains can be installed at the same time. To install the 64-bit toolchain: $ pacman -S mingw-w64-x86_64-toolchain To install the 32-bit toolchain: $ pacman -S mingw-w64-i686-toolchain The following additional packages should also be installed: $ pacman -S patch m4 lzip wget tar make diffutils The MSYS2 build environment =========================== The build process is split into two phases. During phase 1 we use the MSYS2 environment to build statically linked versions of GMP, MPFR, and MPC. Once those libraries are build, we will use the Windows command prompt to build the actual gmpy2 extension (DLL). We do not use the versions of Python included with MSYS2 or MinGW to compile gmpy2. Commands that must be executed from an MSYS2 shell are preceded by "$". Commands that must be executed from a Windows command prompt are preceded by ">". You will need to run the commands *after* "$" or ">". The MSYS2 environment provides three different command line operating environments. * msys2_shell.bat is the general-purpose shell but it does not provide access to the MinGW compiler suite. * mingw64_shell.bat provides access to the 64-bit MinGW compiler suite. * mingw32_shell.bat provides access to the 32-bit MinGW compiler suite. MSYS2 does include versions of GMP, MPFR, and MPC but we will compile our own version directly from the source. We will specify the options that are appropriate for building a statically linked Windows DLL. MSYS2 can support both MinGW32 and MinGW64 toolchains simultaneously. We use /mingw32/opt and /mingw64/opt as the destinations for the 32-bit and 64-bit versions of GMP, MPFR, and MPC. The sources for GMP, MPFR, and MPC will be placed in /mingw32/src or /mingw64/opt. 64-bit Build ============ # Start the appropriate shell: MSYS2 WinGW 64-bit # Create a new directies as the destinations for GMP, MPFR, and MPC. $ mkdir /mingw64/opt $ mkdir /mingw64/src # Download and uncompress GMP, MPFR, and MPC $ cd /mingw64/src # Download GMP $ wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz $ tar xf gmp-6.1.2.tar.lz # Download MPFR and any patches $ wget http://www.mpfr.org/mpfr-current/mpfr-3.1.5.tar.bz2 $ tar xf mpfr-3.1.5.tar.bz2 $ cd mpfr-3.1.5/ $ wget http://www.mpfr.org/mpfr-current/allpatches $ patch -N -Z -p1 < allpatches $ cd .. # Download MPC $ wget ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz $ tar xf mpc-1.0.3.tar.gz # Compile GMP $ cd gmp-6.1.2/ $ ./configure --prefix=/mingw64/opt --enable-static --disable-shared --enable-fat --with-pic *Experimental for mingw64 build* mp_bitcnt_t should really be a 64-bit unsigned integer. The following sed command makes the change. It should only be used for 64-bit builds. This will require changes to gmpy2 source also. See gmpy2_convert_utils.h. $ mv gmp.h gmp.original $ sed 's/typedef\s*unsigned\s*long\s*int\s*mp_bitcnt_t/typedef unsigned long long int mp_bitcnt_t/g' gmp.original > gmp.h $ make $ make check $ make install $ cd .. # Compile MPFR $ cd mpfr-3.1.5/ $ ./configure --prefix=/mingw64/opt --enable-static --disable-shared --disable-thread-safe --enable-gmp-internals --with-pic --with-gmp=/mingw64/opt $ make $ make check $ make install $ cd .. # Compile MPC $ cd mpc-1.0.3/ $ ./configure --prefix=/mingw64/opt --enable-static --disable-shared --with-pic --with-gmp=/mingw64/opt --with-mpfr=/mingw64/opt $ make $ make check $ make install $ cd .. 32-bit Build ============ # Start the appropriate shell: MSYS2 WinGW 32-bit # Create a new directies as the destinations for GMP, MPFR, and MPC/ $ mkdir /mingw32/opt $ mkdir /mingw32/src # Download and uncompress GMP, MPFR, and MPC $ cd /mingw32/src # Download GMP $ wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz $ tar xf gmp-6.1.2.tar.lz # Download MPFR and any patches $ wget http://www.mpfr.org/mpfr-current/mpfr-3.1.5.tar.bz2 $ tar xf mpfr-3.1.5.tar.bz2 $ cd mpfr-3.1.5/ $ wget http://www.mpfr.org/mpfr-current/allpatches $ patch -N -Z -p1 < allpatches $ cd .. # Download MPC $ wget ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz $ tar xf mpc-1.0.3.tar.gz # Compile GMP $ cd gmp-6.1.2/ $ ./configure --prefix=/mingw32/opt --enable-static --disable-shared --enable-fat --with-pic $ make $ make check $ make install $ cd .. # Compile MPFR $ cd mpfr-3.1.5/ $ ./configure --prefix=/mingw32/opt --enable-static --disable-shared --disable-thread-safe --enable-gmp-internals --with-pic --with-gmp=/mingw32/opt $ make $ make check $ make install $ cd .. # Compile MPC $ cd mpc-1.0.3/ $ ./configure --prefix=/mingw32/opt --enable-static --disable-shared --with-pic --with-gmp=/mingw32/opt --with-mpfr=/mingw32/opt $ make $ make check $ make install $ cd .. The Windows build environment ============================= # Configure Windows command prompt - GCC The MinGW toolchain must be accessible by the normal Windows installation of Python. The 64-bit MinGW toolchain is located in C:\msys64\mingw64\bin. The 32-bit MinGW toolchain is located in C:\msys64\mingw32\bin. The MinGW location can be added to the system Path permanently or can be added manually after starting the Windows command prompt. We will do it manually. After starting the Windows command prompt, add either the 64-bit or 32-bit MinGW to the Path with one of the following commands: > set Path=C:\msys64\mingw64\bin;%Path% -- or -- > set Path=C:\msys64\mingw32\bin;%Path% To verfiy the MinGW toolchain is accessible, the command "gcc -v" should return information about the gcc compiler. Note: All the remaining instructions assume this step has been completed and that "gcc -v" returns information for the correct version of gcc. # Configure Windows command prompt - Python The Python interpreter does not need to be accessible via the path. You can specify the full path name to start a particular version. To simplify the compilation of multiple versions of gmpy2, I have adopted the following approach: # 32-bit versions of Python are installed in C:\32 # 64-bit versions of Python are installed in C:\64 # Aliases are defined to create shortcuts for invoking a Python interpreter I use the following batch file to configure a command prompt for 32-bit builds: @echo off doskey py26=C:\32\Python26\python.exe $* doskey py27=C:\32\Python27\python.exe $* doskey py34=C:\32\Python34\python.exe $* doskey py35=C:\32\Python35\python.exe $* doskey py36=C:\32\Python36\python.exe $* set Path=C:\msys64\mingw32\bin;%Path% I use the following batch file to configure a command prompt for 64-bit builds: @echo off doskey py26=C:\64\Python26\python.exe $* doskey py27=C:\64\Python27\python.exe $* doskey py34=C:\64\Python34\python.exe $* doskey py35=C:\64\Python35\python.exe $* doskey py36=C:\64\Python36\python.exe $* set Path=C:\msys64\mingw64\bin;%Path% # Modify distutils library The gmpy2 extension is built using the distutils module. Recent versions of the gcc compiler no longer support an option that is used by older versions of distutils. In the file "cygwincompiler.py", remove all occurences of the "-mno-cygwin" option. The "-mno-cygwin" option was already removed in Python 2.7.8, 3.3.5, and 3.4.1. The option was present in Python 2.6.6 and 3.2.5. You will need to check your specific version. In the file "cygwincompiler.py", find the definition for the class "Mingw32CCompiler". In the "__init__" function comment out the line: "self.dll_libraries = get_msvcr()". In the file "cygwincompiler.py", find the definition for the class "Mingw32CCompiler". Under self.set_executables(...), change -O to -O2 and add "-fno-strict-aliasing" and "-fwrapv". After changes, it should look like self.set_executables(compiler='gcc -O2 -Wall -fno-strict-aliasing -fwrapv', compiler_so='gcc -mdll -O2 -Wall -fno-strict-aliasing -fwrapv', compiler_cxx='g++ -O2 -Wall -fno-strict-aliasing -fwrapv', linker_exe='gcc', linker_so='%s %s %s' % (self.linker_dll, shared_option, entry_point)) # Patch C:\Python27\include\pyconfig.h In that file, search for the text #ifdef _WIN64 and cut out the following three lines: #ifdef _WIN64 #define MS_WIN64 #endif Search for the text #ifdef _MSC_VER earlier in the file. Paste in the cut-out lines, ABOVE the #ifdef _MSC_VER. # Create a libpython.a file MinGW requires a libpythonXX.a file that contains information about the C-API functions that exist in pythonXX.dll. Follow these steps for your version of Python. Note: The DLL locations are from a Windows 10 64-bit system with both 32-bit and 64-bit versions of a Python version installed. Your location may vary. # For a 32-bit versions (with mingw32 on the path) > cd C:\32\Python27\libs > gendef c:\Windows\SysWOW64\python27.dll > dlltool --dllname c:\Windows\SysWOW64\python27.dll --def python27.def --output-lib libpython27.a # For a 64-bit version (with mingw64 on the path) > cd C:\64\Python27\libs > gendef c:\Windows\System32\python27.dll > dlltool --dllname c:\Windows\System32\python27.dll --def python27.def --output-lib libpython27.a # To compile gmpy2 py27 setup.py build_ext --msys2 --prefix=c:\msys64\mingwXX\opt # To install to a local Python installation (after compiling) py27 setup.py install ------------------- misc cd C:\32\Python27\libs gendef c:\Windows\SysWOW64\python27.dll dlltool --dllname c:\Windows\SysWOW64\python27.dll --def python27.def --output-lib libpython27.a cd C:\32\Python32\libs gendef c:\Windows\SysWOW64\python32.dll dlltool --dllname c:\Windows\SysWOW64\python32.dll --def python32.def --output-lib libpython32.a cd C:\32\Python33\libs gendef c:\Windows\SysWOW64\python33.dll dlltool --dllname c:\Windows\SysWOW64\python33.dll --def python33.def --output-lib libpython33.a cd C:\32\Python34\libs gendef c:\Windows\SysWOW64\python34.dll dlltool --dllname c:\Windows\SysWOW64\python34.dll --def python34.def --output-lib libpython34.a cd C:\64\Python27\libs gendef c:\Windows\System32\python27.dll dlltool --dllname c:\Windows\System32\python27.dll --def python27.def --output-lib libpython27.a cd C:\64\Python32\libs gendef c:\Windows\System32\python32.dll dlltool --dllname c:\Windows\System32\python32.dll --def python32.def --output-lib libpython32.a cd C:\64\Python33\libs gendef c:\Windows\System32\python33.dll dlltool --dllname c:\Windows\System32\python33.dll --def python33.def --output-lib libpython33.a cd C:\64\Python34\libs gendef c:\Windows\System32\python34.dll dlltool --dllname c:\Windows\System32\python34.dll --def python34.def --output-lib libpython34.a gmpy2-2.1.0b3/setup.cfg0000664000175000017500000000004613530663166014501 0ustar casecase00000000000000[egg_info] tag_build = tag_date = 0 gmpy2-2.1.0b3/setup.py0000664000175000017500000001224713530662251014372 0ustar casecase00000000000000import platform import os from setuptools import setup, find_packages, Extension from setuptools.command.build_ext import build_ext ON_WINDOWS = platform.system() == 'Windows' _comp_args = ["DSHARED=1"] sources = ['src/gmpy2.c'] # Utility function to read the contents of the README file. def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() class Gmpy2Build(build_ext): description = "Build gmpy2 with custom build options" user_options = build_ext.user_options + [ ('fast', None, "Depend on MPFR and MPC internal implementations details" "(even more than the standard build)"), ('gcov', None, "Enable GCC code coverage collection"), ('vector', None, "Include the vector_XXX() functions;" "they are unstable and under active development"), ('mpir', None, "Enable use of mpir library instead of gmp." "gmp is the default on Posix systems while mpir the default on" "Windows and MSVC. Deprecated; will be removed."), ('static', None, "Enable static linking compile time options."), ('static-dir=', None, "Enable static linking and specify location."), ('gdb', None, "Build with debug symbols."), ] def initialize_options(self): build_ext.initialize_options(self) self.fast = False self.gcov = False self.vector = False self.mpir = False self.static = False self.static_dir = False self.gdb = False def finalize_options(self): build_ext.finalize_options(self) if self.fast: _comp_args.append('DFAST=1') if self.gcov: if ON_WINDOWS: raise ValueError("Cannot enable GCC code coverage on Windows") _comp_args.append('DGCOV=1') _comp_args.append('O0') _comp_args.append('-coverage') self.libraries.append('gcov') if self.vector: _comp_args.append('DVECTOR=1') if self.static: _comp_args.remove('DSHARED=1') _comp_args.append('DSTATIC=1') if self.gdb: _comp_args.append('ggdb') if self.static_dir: _comp_args.remove('DSHARED=1') _comp_args.append('DSTATIC=1') self.include_dirs.append(self.static_dir + '/include') self.library_dirs.append(self.static_dir + '/lib') def build_extensions(self): compiler = self.compiler.compiler_type if compiler == 'mingw32': _comp_args.append('DMSYS2=1') if self.mpir: _comp_args.append('DMPIR=1') self.libraries.append('mpir') if 'gmp' in self.libraries: self.libraries.remove('gmp') elif self.mpir or ON_WINDOWS: # --mpir or on Windows and MSVC _comp_args.append('DMPIR=1') self.libraries.append('mpir') if 'gmp' in self.libraries: self.libraries.remove('gmp') if ON_WINDOWS and not self.static: # MSVC shared build _comp_args.append('DMSC_USE_DLL') _prefix = '-' if compiler != 'msvc' else '/' for i in range(len(_comp_args)): _comp_args[i] = ''.join([_prefix, _comp_args[i]]) build_ext.build_extensions(self) extensions = [ Extension('gmpy2.gmpy2', sources=sources, include_dirs=['./src'], libraries=['mpc','mpfr','gmp'], extra_compile_args=_comp_args, ) ] cmdclass = {'build_ext': Gmpy2Build} setup( name="gmpy2", version="2.1.0b3", author="Case Van Horsen", author_email="casevh@gmail.com", cmdclass=cmdclass, license="LGPL-3.0+", url="https://github.com/aleaxit/gmpy", description="gmpy2 interface to GMP, MPFR, " "and MPC for Python 2.7 and 3.4+", long_description=read('README'), zip_safe=False, include_package_data=True, package_data={'gmpy2': [ '*.pxd', 'gmpy2.h', ]}, packages=find_packages(), classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)', 'Natural Language :: English', 'Operating System :: MacOS :: MacOS X', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX', 'Programming Language :: C', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: Implementation :: CPython', 'Topic :: Scientific/Engineering :: Mathematics', 'Topic :: Software Development :: Libraries :: Python Modules', ], keywords="gmp mpfr mpc multiple-precision arbitrary-precision precision bignum", ext_modules=extensions, ) gmpy2-2.1.0b3/src/0000775000175000017500000000000013530663166013447 5ustar casecase00000000000000gmpy2-2.1.0b3/src/gmpy2.c0000664000175000017500000016503613530662465014665 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Todo list * --------- * Add all MPFR and MPC functions as context methods. * All MPFR and MPC functions need to set exponent range on entry. The * current approach where only set_context() and context.__enter__ set * the exponent range fails for context methods. * Should a read-only (or template) context prevent the setting of * exception flags? * Add context option to control the result of integer division: * integer (mpz), exact (mpq), or true (mpfr). * Add modular arithmetic functions. * Implement Chinese Remainder Theorem. * Update PRP code. */ /* * originally written for GMP-2.0 (by AMK...?) * Rewritten by Niels Möller, May 1996 * * Version for GMP-4, Python 2.X, with support for MSVC++6, * addition of mpf's, &c: Alex Martelli (now aleaxit@gmail.com, Nov 2000). * cleanups & reorgs leading to 1.0: Alex Martelli (until Aug 2003) * further cleanups and bugfixes leading to 1.01, Alex Martelli (Nov 2005) * minor bugfixes+new decimal (&c) support to 1.02, Alex Martelli (Feb 2006) * various bugfixes for 64-bit platforms, 1.03, aleaxit and casevh (Jun 2008) * rich comparisons, 1.04, aleaxit and casevh (Jan 2009) * support for Python 3.x, 1.10, casevh (Oct 2009) * * Some hacks by Gustavo Niemeyer . * * 0.1, pre-alpha; date: 2000-11-06 first placed on sourceforge * * 0.2, still pre-alpha: 2000-11-15: bugfixes re formatting (tx, Peanu!) * no tags on oct() and hex() of mpz's * insert 'tagoff' in options (gmpy.mpz() vs mpz() in repr) (for Peanu!) * speedups for _nonzero & _cmp (tx, Peanu!) * slight speedup (7/8%?) for excess reallocs 4<->8 bytes (Peanu's help!) * added copy/fcopy; bin; fib; remove * * 0.3, still pre-alpha, but...: * performance tweaks via mpz-caching & fixed-constants * added get/set functions for zcache, zco min/max * added get-only function for versions (of gmp, and of gmpy) * removed all 'traces' of mutability (to be re-done... much later!) * cleaned up all of the mpz_cmp_ui(X,0) to mpz_sgn(X) * cleaned up Py_BuildValue usage (N vs O, explicit-() for tuples) * added numdigits, lowbits, root, next_prime, invert, popcount, * hamdist, scan0, scan1 * renamed bin to bincoef * * 0.4: * split gmpy.c/gmpy.h introducing C-API interface (Pearu's suggestion) * cleanup some casts using Pearu's new macros * further cache-tweaks at Pearu's suggestion (macros introduced) * added sign (Pearu's request), getbit, setbit * added docstrings * renamed copy functions to start with _ ('internal, private') * added .comb as a synonym of .bincoef * * 0.5: * added jacobi, legendre, kronecker * added random-number generation, seed set/save, shuffling * added mpq (at last!-) * * 0.6: (lots of good ideas from Pearu once more!-): * fixed silly bugs in kronecker and mpq_abs * gmpy-level workaround for scan0/scan1 bugs (?) in GMP 3.1.1 * added qdiv; anynum->mpq substituted for all such conversions * (also anynum->mpz and anynum->mpf by analogy, with care!) * added global.fcoform for optional use of intermediate string in * float2mpf (used for any float->mpf conversion) * added set_fcoform function for global.fcoform access * general cleanup of sources; added alloca for MSVC++; * many sundry minor bugfixes & uniformization; * a little useful refactoring (more would be good...) * added caching of mpq objects * power for mpq * Stern-Brocot algorithm for mpf->mpq (also exposed as f2q) * also used for float->mpq * with stricter tracking of mpf's requested-precision * added getrprec method to mpf, getrprec module-function * exposed ceil, floor and trunc methods/functions for mpf's * changed a couple exceptions from Value to ZeroDivision * added 'qual' and 'floa' options to gmpy.rand * * 0.7: (good feedback from Keith Briggs, some advice from Tim Peters * and Fred Lundh -- thanks all!): * fixed bug of '"%d" where "%ld" was meant' in many places * and other sundry minor warnings given by gcc * fixed hash (delegating to Python) so mp[nqz](x) will * produce the same value as hash(x) for any Python number x * workaround for GMP 3.1.1 bug, mpz_root wrongly returning * 'exact' for non-exact root if dest==source, which stopped * needed value-error for inexact mpq**mpq operations * determined correct 'actual precision' of floats * explicitly stored precision with binary-form mpf's * extended explicit-bits request to all ->mpf operations * (good in itself, plus, preparing for future MPFR) * removed the limitation of no binary-form for <0 mpz * introduced macros to parse args, for conciseness * * 0.8: (again, requests & suggestions by great Pearu!) * raise test coverage 72.5% -> 90.0% * introduced callbacks (not documented/tested for now; * Pearu will test/support/document in PySymbolic) * some errors went undiagnosed, caused crash: now fixed * workaround for GMP bug(?s?) in mpz_fits_... (?) * added exposure of mpf_ sqrt and pow_ui * * 0.9: (ditto) * change ValueError to OverflowError for 'too-large' errors * fix bug in mpq_pow (negative base, exp. with odd denominator) * (fix now corrected -- _even_ denominator is the error!) * fixed gcc warnings reported by K. Briggs * * 0.9b: * support GMP 4 (but added no GMP4-only functionality yet) * * 0.9c: * updated tests to 0.9, better coverage * * 1.0: * minor cleanups, ensure support for Python 2.3 * fixed misdiagnosis of some argument counts in macro * SELF_ONE_ARG_CONVERTED (tx to Paul Rubin!) * * 1.01: * cleanups, ensure support for Python 2.4.1 on MacOSX 10.4/XCode 2.1 * as well as Python 2.2 and 2.3 (on MacOSX and Linux) * fixed memory leak on divm (thanks to mensanator@aol.com) * fixed bug on mpq('123') [[str2mpq on string w/o a slash]] * added floordiv and truediv operators, and tests for them * NOT tested on GMP 3 (have none left around...), ONLY on GMP 4.* * * 1.02: * fix warning in comparison of mpq's * added support of mpq('12.34') [[string w/o a slash, but with a dot]] * fixes for 64-bit build (thanks to a patch by dmcooke) * added experimental support for decimal.Decimal (and user-coded types) * via wider use of special conversion methods (if present) and their * sly insertion on-the-fly into the decimal.Decimal class (!) * two bugfixes, thanks to Simon Burton * Brought back into C89 compliance (thanks to Chip Turner), had * drifted to C99 (declarations in the middle of the code). * Python 2.5 support (Py_ssize_t, __index__) thanks to Chip Turner * Pushed coverage to 93.3% (missing only "sanity check" level error * tests [mostly for out-of-memory conditions], output to stderr * conditioned by global.debug, & a couple of very obscure cases) * * 1.03: * Fixed the bug that caused crashes on gmpy.mpf(float('inf')) and * other such conversions, implicit and explicit * Fixed a bug in get_zconst's prototype affecting 64-bit machines, * thanks to Gary Bunting * Fixed a bug in hashing on 64-bit systems. hash(long) now equals * hash(mpz) for large values. (casevh) * Changed int() to return a long value instead of OverFlowError. * Complies with PEP 237. (casevh) * Added support in setup.py for darwinports/macports build of GMP * on MacOSX. (aleaxit) * * 1.04: * Avoid GMP/mingw32 bug when converting very small floats to mpz. * (casevh) * Significant performance improvement for long->mpz and mpz->long. * (casevh) * Added "rich comparisons" to mpz, mpq and mpf types (aleaxit) * Added additional tests (casevh, aleaxit) * Fixed bug when converting very large mpz to str (casevh) * Faster conversion from mpz->binary and binary->mpz (casevh) * Added support for pickling (casevh) * Added divexact (casevh) * Fixed mpf comparisons by rounding mpf results when GMP returns * a longer result. Added fround() (casevh) * Added bit_length (Thanks Mario Pernici) * Added helper functions for mpmath (casevh) * Faster conversion from mpq->binary and binary->mpq (casevh) * Recognize MPIR, mpir_version() (casevh) * * 1.10: * Remove dependancy on pymemcompat.h (casevh) * Remove callback (casevh) * Added support for -DMPIR to include MPIR instead of GMP (casevh) * Major code revisions to add support for Python 3.x (casevh) * Fixed bug in binary() and qbinary() (casevh) * Fixed bug in rich comparisons (casevh) * Added % and divmod support to mpq and mpf (casevh) * Changed memory allocation functions to use PyMem (casevh) * Removed small number interning (casevh) * Added tdivmod, cdivmod, and fdivmod (casevh) * Added more helper functions for mpmath (casevh) * Faster mpz<>PyLong conversion (casevh) * Faster hash(mpz) (casevh) * * 1.11: * Recognize True/False (bug in 1.10) (casevh) * Optimize argument handling (casevh) * Added caching for mpz (casevh) * ************************************************************************ * * 2.0.0 alpha and b1: * Added caching for mpq (casevh) * Added rootrem, fib2, lucas, lucas2 (casevh) * Removed mpf.setprec(), use mpf.round() (casevh) * Fix test compatibility with Python 3.1.2 and 3.2 (casevh) * Support changed hash function in Python 3.2 (casevh) * Added is_even, is_odd (casevh) * Rename to gmpy2 to allow backwards incompatible changes (casevh) * Remove old random number functions, to be replaced later (casevh) * Add caching of the calculated hash value (casevh) * Add xmpz (mutable mpz) type (casevh) * Fix mpq formatting issue (casevh) * Add read/write bit access using slices to xmpz (casevh) * Add read-only bit access using slices to mpz (casevh) * Add pack()/unpack() methods (casevh) * Remove tagoff option (casevh) * Add support for MPFR (casevh) * Debug messages only available if compiled with -DDEBUG (casevh) * Removed fcoform float conversion modifier (casevh) * Add support for MPC (casevh) * Renamed 'mpf' to 'mpfr' to reflect use of MPFR (casevh) * Added context manager (casevh) * Allow building with just GMP/MPIR if MPFR not available (casevh) * Allow building with GMP/MPIR and MPFR if MPC not available (casevh) * Removed most instance methods in favor of gmpy2.method (casevh) * Added __ceil__, __floor__, and __trunc__ methods (casevh) * Removed gmpy2.pow to avoid conflicts (casevh) * Removed gmpy2._copy and added xmpz.copy (casevh) * Added support for __format__ (casevh) * Completed support for MPC (casevh) * Added as_integer_ratio, as_mantissa_exp, as_simple_fraction (casevh) * Update rich_compare (casevh) * Require MPFR 3.1.0+ to get divby0 support (casevh) * Added fsum(), degrees(), radians() (casevh) * Renamed context() -> local_context(), new_context() -> context() (casevh) * Added get_context() (casevh) * Added random number generation support (casevh) * Changed license to LGPL 3+ (casevh) * Added lucasu, lucasu_mod, lucasv, and lucasv_mod (casevh) * (Based on code contributed by David Cleaver.) * Added probable-prime tests (casevh) * (Based on code contributed by David Cleaver.) * Added to_binary()/from_binary (casevh) * Renamed numdigits() to num_digits() (casevh) * Added keyword precision to constants (casevh) * Added addmul() and submul() (casevh) * Added __round__(), round2(), round_away() for mpfr (casevh) * round() is no longer a module level function (casevh) * pow() is no longer a module level function (casevh) * Renamed module functions min()/max() to min2()/max2() (casevh) * No longer conflicts with builtin min() and max() * Removed set_debug() and related functionality (casevh) * Released as 2.0.0b1 * * 2.0.0b2 * Allow xmpz slice assignment to increase length of xmpz instance by * specifying a value for stop (casevh) * Fixed ref-count bug in several is_xxx_prp tests (casevh) * Added iter_bits, iter_clear, iter_set methods to xmpz (casevh) * Added powmod() for easy access to three argument pow() (casevh) * Removed addmul() and submul() since they are slower than (casevh) * just using Python code * Bug fix in gcd_ext when both arguments are not mpz (casevh) * Added ieee() to create contexts for 32, 64, or 128 bit floats (casevh) * Bug fix in context() not setting emax/emin correctly if they (casevh) * had been changed earlier * Contexts can be directly used in with statement without (casevh) * requiring set_context()/local_context() sequence * local_context() now accepts an optional context (casevh) * * 2.0.0b3 * mp_version(), mpc_version(), and mpfr_version() shouldn't (casevh) * return Unicode on Python 2.x * Fix warnings when shifting 32-bit integer by 32 bits (casevh) * Faster conversion of Fraction to gmpy2 types (casevh) * Fix conversion with Decimal, especially on Python 3.3 (casevh) * Consistently return OverflowError when converting "inf" (casevh) * Fix mpz.__format__() with # code (casevh) * Add is_infinite(), deprecate is_inf() (casevh) * Add is_finite(), deprecate is_number() (casevh) * Fixed issues with mpc() and various is_XXX() functions (casevh) * Fixed error handling with mpc(); mpc(1,"nan") is properly (casevh) * handled * Added caching for mpc objects; faster when real and (casevh) * imaginary precisions are equal * Add optimal path for mpfr/mpc + - * / when both operands (casevh) * have the same type * Fix mpfr + float segmentation fault (casevh) * * 2.0.0b4 * Add __ceil__, __floor__, __trunc__, __round__ to mpz & mpq (casevh) * Add __complex__ to mpc (casevh) * round(mpfr) now correctly returns an mpz (casevh) * Add mpz.denominator and mpz.numerator (casevh) * mpz() returns mpz(0); also xmpz, mpq, mpfr, and mpc (casevh) * Fix bug when comparing mpz to mpq (with mpz on left) (casevh) * Add __sizeof__ (casevh) * * 2.0.0 * Fix segfault in _mpmath_normalize if rnd not specified (casevh) * Improved setup.py (casevh) * Fix issues encountered when compiled without MPFR support (casevh) * Conversion of too large an mpz to float now raises OverflowError (casevh) * Renamed module functions min2()/max2() to minnum()/maxnum() (casevh) * Added copy() method to contexts (casevh) * get_context() no longer supports keyword arguments (casevh) * ************************************************************************ * * 2.1.0 * Improvements to setup.py. * Add thread-safe contexts. * MPFR and MPC are now required. * Invalid Operation exception now raised for addition, etc. * inverse() now raises exception if inverse does not exist. * Add context methods. * Major code refactoring required to properly support thread-safe * contexts. * __str__ and __repr__ no longer append "L" on Python 2. * mpq(mpfr) now returns the exact result. * Fix repr(mpc) for precision >325 bits. * Intermediate conversions of Integer to mpfr are now done with the * full precision of the Integer. * Remove support for interaction with Decimal type. * No longer attempt to override the memory allocation functions. * Register gmpy2 types into the numeric tower. * mpz(x) call int(x) if mpz() does not know how to convert x * directly. * Convert `mpz` to a type using __new__ instead of a factory * function. * * 2.1.0a1 * Initial release. * * 2.1.0a2 * Revised build process. * Removal of unused code/macros. * Cleanup of Cython interface. * * 2.1.0a3 * Updates to setup.py. * Initial support for MPFR4 * - Add nrandom() * - grandom() now calls nrandom twice; may return different values versus * MPFR3 * - Add rootn(); same as root() except different sign when taking even root * of -0.0 * * 2.1.0a4 * Fix issue 204; missing file for Cython. * Additional support for MPFR 4 * - Add fmma() and fmms() * * 2.1.0a5 * Fix qdiv() not returning mpz() when it should. * Added root_of_unity() * * 2.1.0b1 * Added cmp() and cmp_abs(). * Improved compatibility with _numbers_ protocol. * Many bug fixes. * * 2.1.0b2 * Many bug fixes. * * 2.1.0b3 * Version bump only. * ************************************************************************ * * Discussion on sizes of C integer types. * * GMP, MPIR, MPFR, and MPC use typedef to create integer objects with * different sizes. It can become confusing to map the different types * onto the standard C types used by Python's C API. Below are external * types and how they map to C types. The assumptions are verified when * the module is initialized. * * mp_limb_t: This is usually an 'unsigned long' but is an 'unsigned * long long' on MPIR/64-bit Windows. * * mp_bitcnt_t: This is usually an 'unsigned long' but is an 'unsigned * long long' on MPIR/64-bit Windows. 'size_t' is the best match. * * mp_size_t: This is a 'long'. * * mpfr_rnd_t: This is an 'int'. * * mpfr_prec_t: This is a 'long'. * * mpfr_sign_t: This is an 'int'. * * mpfr_exp_t: This is currently the same as mp_exp_t but will change * to a signed 64-bit integer in the future. * * mpc_rnd_t: This is an 'int'. * * mpc_prec_t: See mpfr_exp_t. * ************************************************************************ */ #define PY_SSIZE_T_CLEAN #include "Python.h" #include #include #include #include #include #include /* * we do have a dependence on Python's internals, specifically: * how Python "long int"s are internally represented. */ #include "longintrepr.h" #define GMPY2_MODULE #include "gmpy2.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Global data declarations begin here. * * NOTE: Because of these global declarations, GMPY2 is not thread-safe! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* The following global strings are used by gmpy_misc.c. */ char gmpy_version[] = "2.1.0b3"; char gmpy_license[] = "\ The GMPY2 source code is licensed under LGPL 3 or later. The supported \ versions of the GMP/MPIR, MPFR, and MPC libraries are also licensed under \ LGPL 3 or later."; /* The following global structures are used by gmpy_cache.c. */ struct gmpy_global { int cache_size; /* size of cache, for all caches */ int cache_obsize; /* maximum size of the objects that are cached */ mpz_t tempz; /* Temporary variable used for integer conversions */ MPZ_Object **gmpympzcache; int in_gmpympzcache; XMPZ_Object **gmpyxmpzcache; int in_gmpyxmpzcache; MPQ_Object **gmpympqcache; int in_gmpympqcache; MPFR_Object **gmpympfrcache; int in_gmpympfrcache; MPC_Object **gmpympccache; int in_gmpympccache; }; static struct gmpy_global global; /* Support for context manager. */ #ifdef WITHOUT_THREADS /* Use a module-level context. */ static CTXT_Object *module_context = NULL; #else /* Key for thread state dictionary */ static PyObject *tls_context_key = NULL; /* Invariant: NULL or the most recently accessed thread local context */ static CTXT_Object *cached_context = NULL; #endif /* Define gmpy2 specific errors for mpfr and mpc data types. No change will * be made the exceptions raised by mpz, xmpz, and mpq. */ static PyObject *GMPyExc_GmpyError = NULL; static PyObject *GMPyExc_DivZero = NULL; static PyObject *GMPyExc_Inexact = NULL; static PyObject *GMPyExc_Invalid = NULL; static PyObject *GMPyExc_Overflow = NULL; static PyObject *GMPyExc_Underflow = NULL; static PyObject *GMPyExc_Erange = NULL; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * End of global data declarations. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* The code for object creation, deletion, and caching is in gmpy_cache.c. */ #include "gmpy2_cache.c" /* Miscellaneous helper functions and simple methods are in gmpy_misc.c. */ #include "gmpy2_misc.c" /* Support for conversion to/from binary representation. */ #include "gmpy2_binary.c" /* Support for conversions to/from numeric types. */ #include "gmpy2_convert.c" #include "gmpy2_convert_utils.c" #include "gmpy2_convert_gmp.c" #include "gmpy2_convert_mpfr.c" #include "gmpy2_convert_mpc.c" /* Support for random numbers. */ #include "gmpy2_random.c" /* Support for Lucas sequences. */ #include "gmpy_mpz_lucas.c" /* Support for probable-prime tests. */ #include "gmpy_mpz_prp.c" /* Include helper functions for mpmath. */ #include "gmpy2_mpmath.c" #include "gmpy2_mpz_divmod.c" #include "gmpy2_mpz_divmod2exp.c" #include "gmpy2_mpz_pack.c" #include "gmpy2_mpz_bitops.c" #include "gmpy2_mpz_inplace.c" #include "gmpy2_xmpz_inplace.c" /* Begin includes of refactored code. */ #include "gmpy2_abs.c" #include "gmpy2_add.c" #include "gmpy2_divmod.c" #include "gmpy2_floordiv.c" #include "gmpy2_minus.c" #include "gmpy2_mod.c" #include "gmpy2_mul.c" #include "gmpy2_plus.c" #include "gmpy2_pow.c" #include "gmpy2_sub.c" #include "gmpy2_truediv.c" #include "gmpy2_math.c" #include "gmpy2_const.c" #include "gmpy2_square.c" #include "gmpy2_format.c" #include "gmpy2_hash.c" #include "gmpy2_fused.c" #include "gmpy2_muldiv_2exp.c" #include "gmpy2_predicate.c" #include "gmpy2_sign.c" #include "gmpy2_richcompare.c" #include "gmpy2_cmp.c" #include "gmpy2_mpc_misc.c" #include "gmpy2_mpfr_misc.c" #include "gmpy2_mpq_misc.c" #include "gmpy2_mpz_misc.c" #include "gmpy2_xmpz_misc.c" #ifdef VECTOR #include "gmpy2_vector.c" #endif /* Include gmpy_context last to avoid adding doc names to .h files. */ #include "gmpy2_mpz.c" #include "gmpy2_xmpz.c" #include "gmpy2_mpq.c" #include "gmpy2_mpfr.c" #include "gmpy2_mpc.c" #include "gmpy2_context.c" static PyMethodDef Pygmpy_methods [] = { { "_printf", GMPy_printf, METH_VARARGS, GMPy_doc_function_printf }, { "add", GMPy_Context_Add, METH_VARARGS, GMPy_doc_function_add }, { "bit_clear", GMPy_MPZ_bit_clear_function, METH_VARARGS, doc_bit_clear_function }, { "bit_flip", GMPy_MPZ_bit_flip_function, METH_VARARGS, doc_bit_flip_function }, { "bit_length", GMPy_MPZ_bit_length_function, METH_O, doc_bit_length_function }, { "bit_mask", GMPy_MPZ_bit_mask, METH_O, doc_bit_mask }, { "bit_scan0", GMPy_MPZ_bit_scan0_function, METH_VARARGS, doc_bit_scan0_function }, { "bit_scan1", GMPy_MPZ_bit_scan1_function, METH_VARARGS, doc_bit_scan1_function }, { "bit_set", GMPy_MPZ_bit_set_function, METH_VARARGS, doc_bit_set_function }, { "bit_test", GMPy_MPZ_bit_test_function, METH_VARARGS, doc_bit_test_function }, { "bincoef", GMPy_MPZ_Function_Bincoef, METH_VARARGS, GMPy_doc_mpz_function_bincoef }, { "cmp", GMPy_MPANY_cmp, METH_VARARGS, GMPy_doc_mpany_cmp }, { "cmp_abs", GMPy_MPANY_cmp_abs, METH_VARARGS, GMPy_doc_mpany_cmp_abs }, { "comb", GMPy_MPZ_Function_Bincoef, METH_VARARGS, GMPy_doc_mpz_function_comb }, { "c_div", GMPy_MPZ_c_div, METH_VARARGS, doc_c_div }, { "c_div_2exp", GMPy_MPZ_c_div_2exp, METH_VARARGS, doc_c_div_2exp }, { "c_divmod", GMPy_MPZ_c_divmod, METH_VARARGS, doc_c_divmod }, { "c_divmod_2exp", GMPy_MPZ_c_divmod_2exp, METH_VARARGS, doc_c_divmod_2exp }, { "c_mod", GMPy_MPZ_c_mod, METH_VARARGS, doc_c_mod }, { "c_mod_2exp", GMPy_MPZ_c_mod_2exp, METH_VARARGS, doc_c_mod_2exp }, { "denom", GMPy_MPQ_Function_Denom, METH_O, GMPy_doc_mpq_function_denom }, { "digits", GMPy_Context_Digits, METH_VARARGS, GMPy_doc_context_digits }, { "div", GMPy_Context_TrueDiv, METH_VARARGS, GMPy_doc_truediv }, { "divexact", GMPy_MPZ_Function_Divexact, METH_VARARGS, GMPy_doc_mpz_function_divexact }, { "divm", GMPy_MPZ_Function_Divm, METH_VARARGS, GMPy_doc_mpz_function_divm }, { "double_fac", GMPy_MPZ_Function_DoubleFac, METH_O, GMPy_doc_mpz_function_double_fac }, { "fac", GMPy_MPZ_Function_Fac, METH_O, GMPy_doc_mpz_function_fac }, { "fib", GMPy_MPZ_Function_Fib, METH_O, GMPy_doc_mpz_function_fib }, { "fib2", GMPy_MPZ_Function_Fib2, METH_O, GMPy_doc_mpz_function_fib2 }, { "floor_div", GMPy_Context_FloorDiv, METH_VARARGS, GMPy_doc_floordiv }, { "from_binary", GMPy_MPANY_From_Binary, METH_O, doc_from_binary }, { "f_div", GMPy_MPZ_f_div, METH_VARARGS, doc_f_div }, { "f_div_2exp", GMPy_MPZ_f_div_2exp, METH_VARARGS, doc_f_div_2exp }, { "f_divmod", GMPy_MPZ_f_divmod, METH_VARARGS, doc_f_divmod }, { "f_divmod_2exp", GMPy_MPZ_f_divmod_2exp, METH_VARARGS, doc_f_divmod_2exp }, { "f_mod", GMPy_MPZ_f_mod, METH_VARARGS, doc_f_mod }, { "f_mod_2exp", GMPy_MPZ_f_mod_2exp, METH_VARARGS, doc_f_mod_2exp }, { "gcd", GMPy_MPZ_Function_GCD, METH_VARARGS, GMPy_doc_mpz_function_gcd }, { "gcdext", GMPy_MPZ_Function_GCDext, METH_VARARGS, GMPy_doc_mpz_function_gcdext }, { "get_cache", GMPy_get_cache, METH_NOARGS, GMPy_doc_get_cache }, { "hamdist", GMPy_MPZ_hamdist, METH_VARARGS, doc_hamdist }, { "invert", GMPy_MPZ_Function_Invert, METH_VARARGS, GMPy_doc_mpz_function_invert }, { "iroot", GMPy_MPZ_Function_Iroot, METH_VARARGS, GMPy_doc_mpz_function_iroot }, { "iroot_rem", GMPy_MPZ_Function_IrootRem, METH_VARARGS, GMPy_doc_mpz_function_iroot_rem }, { "isqrt", GMPy_MPZ_Function_Isqrt, METH_O, GMPy_doc_mpz_function_isqrt }, { "isqrt_rem", GMPy_MPZ_Function_IsqrtRem, METH_O, GMPy_doc_mpz_function_isqrt_rem }, { "is_bpsw_prp", GMPY_mpz_is_bpsw_prp, METH_VARARGS, doc_mpz_is_bpsw_prp }, { "is_congruent", GMPy_MPZ_Function_IsCongruent, METH_VARARGS, GMPy_doc_mpz_function_is_congruent }, { "is_divisible", GMPy_MPZ_Function_IsDivisible, METH_VARARGS, GMPy_doc_mpz_function_is_divisible }, { "is_even", GMPy_MPZ_Function_IsEven, METH_O, GMPy_doc_mpz_function_is_even }, { "is_euler_prp", GMPY_mpz_is_euler_prp, METH_VARARGS, doc_mpz_is_euler_prp }, { "is_extra_strong_lucas_prp", GMPY_mpz_is_extrastronglucas_prp, METH_VARARGS, doc_mpz_is_extrastronglucas_prp }, { "is_fermat_prp", GMPY_mpz_is_fermat_prp, METH_VARARGS, doc_mpz_is_fermat_prp }, { "is_fibonacci_prp", GMPY_mpz_is_fibonacci_prp, METH_VARARGS, doc_mpz_is_fibonacci_prp }, { "is_lucas_prp", GMPY_mpz_is_lucas_prp, METH_VARARGS, doc_mpz_is_lucas_prp }, { "is_odd", GMPy_MPZ_Function_IsOdd, METH_O, GMPy_doc_mpz_function_is_odd }, { "is_power", GMPy_MPZ_Function_IsPower, METH_O, GMPy_doc_mpz_function_is_power }, { "is_prime", GMPy_MPZ_Function_IsPrime, METH_VARARGS, GMPy_doc_mpz_function_is_prime }, { "is_selfridge_prp", GMPY_mpz_is_selfridge_prp, METH_VARARGS, doc_mpz_is_selfridge_prp }, { "is_square", GMPy_MPZ_Function_IsSquare, METH_O, GMPy_doc_mpz_function_is_square }, { "is_strong_prp", GMPY_mpz_is_strong_prp, METH_VARARGS, doc_mpz_is_strong_prp }, { "is_strong_bpsw_prp", GMPY_mpz_is_strongbpsw_prp, METH_VARARGS, doc_mpz_is_strongbpsw_prp }, { "is_strong_lucas_prp", GMPY_mpz_is_stronglucas_prp, METH_VARARGS, doc_mpz_is_stronglucas_prp }, { "is_strong_selfridge_prp", GMPY_mpz_is_strongselfridge_prp, METH_VARARGS, doc_mpz_is_strongselfridge_prp }, { "jacobi", GMPy_MPZ_Function_Jacobi, METH_VARARGS, GMPy_doc_mpz_function_jacobi }, { "kronecker", GMPy_MPZ_Function_Kronecker, METH_VARARGS, GMPy_doc_mpz_function_kronecker }, { "lcm", GMPy_MPZ_Function_LCM, METH_VARARGS, GMPy_doc_mpz_function_lcm }, { "legendre", GMPy_MPZ_Function_Legendre, METH_VARARGS, GMPy_doc_mpz_function_legendre }, { "license", GMPy_get_license, METH_NOARGS, GMPy_doc_license }, { "lucas", GMPy_MPZ_Function_Lucas, METH_O, GMPy_doc_mpz_function_lucas }, { "lucasu", GMPY_mpz_lucasu, METH_VARARGS, doc_mpz_lucasu }, { "lucasu_mod", GMPY_mpz_lucasu_mod, METH_VARARGS, doc_mpz_lucasu_mod }, { "lucasv", GMPY_mpz_lucasv, METH_VARARGS, doc_mpz_lucasv }, { "lucasv_mod", GMPY_mpz_lucasv_mod, METH_VARARGS, doc_mpz_lucasv_mod }, { "lucas2", GMPy_MPZ_Function_Lucas2, METH_O, GMPy_doc_mpz_function_lucas2 }, { "mod", GMPy_Context_Mod, METH_VARARGS, GMPy_doc_mod }, { "mp_version", GMPy_get_mp_version, METH_NOARGS, GMPy_doc_mp_version }, { "mp_limbsize", GMPy_get_mp_limbsize, METH_NOARGS, GMPy_doc_mp_limbsize }, { "mpc_version", GMPy_get_mpc_version, METH_NOARGS, GMPy_doc_mpc_version }, { "mpfr_version", GMPy_get_mpfr_version, METH_NOARGS, GMPy_doc_mpfr_version }, { "mpq_from_old_binary", GMPy_MPQ_From_Old_Binary, METH_O, doc_mpq_from_old_binary }, { "mpz_from_old_binary", GMPy_MPZ_From_Old_Binary, METH_O, doc_mpz_from_old_binary }, { "mpz_random", GMPy_MPZ_random_Function, METH_VARARGS, GMPy_doc_mpz_random_function }, { "mpz_rrandomb", GMPy_MPZ_rrandomb_Function, METH_VARARGS, GMPy_doc_mpz_rrandomb_function }, { "mpz_urandomb", GMPy_MPZ_urandomb_Function, METH_VARARGS, GMPy_doc_mpz_urandomb_function }, { "mul", GMPy_Context_Mul, METH_VARARGS, GMPy_doc_function_mul }, { "multi_fac", GMPy_MPZ_Function_MultiFac, METH_VARARGS, GMPy_doc_mpz_function_multi_fac }, { "next_prime", GMPy_MPZ_Function_NextPrime, METH_O, GMPy_doc_mpz_function_next_prime }, { "numer", GMPy_MPQ_Function_Numer, METH_O, GMPy_doc_mpq_function_numer }, { "num_digits", GMPy_MPZ_Function_NumDigits, METH_VARARGS, GMPy_doc_mpz_function_num_digits }, { "pack", GMPy_MPZ_pack, METH_VARARGS, doc_pack }, { "popcount", GMPy_MPZ_popcount, METH_O, doc_popcount }, { "powmod", GMPy_Integer_PowMod, METH_VARARGS, GMPy_doc_integer_powmod }, { "primorial", GMPy_MPZ_Function_Primorial, METH_O, GMPy_doc_mpz_function_primorial }, { "qdiv", GMPy_MPQ_Function_Qdiv, METH_VARARGS, GMPy_doc_function_qdiv }, { "remove", GMPy_MPZ_Function_Remove, METH_VARARGS, GMPy_doc_mpz_function_remove }, { "random_state", GMPy_RandomState_Factory, METH_VARARGS, GMPy_doc_random_state_factory }, { "set_cache", GMPy_set_cache, METH_VARARGS, GMPy_doc_set_cache }, { "sign", GMPy_Context_Sign, METH_O, GMPy_doc_function_sign }, { "square", GMPy_Context_Square, METH_O, GMPy_doc_function_square }, { "sub", GMPy_Context_Sub, METH_VARARGS, GMPy_doc_sub }, { "to_binary", GMPy_MPANY_To_Binary, METH_O, doc_to_binary }, { "t_div", GMPy_MPZ_t_div, METH_VARARGS, doc_t_div }, { "t_div_2exp", GMPy_MPZ_t_div_2exp, METH_VARARGS, doc_t_div_2exp }, { "t_divmod", GMPy_MPZ_t_divmod, METH_VARARGS, doc_t_divmod }, { "t_divmod_2exp", GMPy_MPZ_t_divmod_2exp, METH_VARARGS, doc_t_divmod_2exp }, { "t_mod", GMPy_MPZ_t_mod, METH_VARARGS, doc_t_mod }, { "t_mod_2exp", GMPy_MPZ_t_mod_2exp, METH_VARARGS, doc_t_mod_2exp }, { "unpack", GMPy_MPZ_unpack, METH_VARARGS, doc_unpack }, { "version", GMPy_get_version, METH_NOARGS, GMPy_doc_version }, { "xbit_mask", GMPy_XMPZ_Function_XbitMask, METH_O, GMPy_doc_xmpz_function_xbit_mask }, { "_mpmath_normalize", Pympz_mpmath_normalize, METH_VARARGS, doc_mpmath_normalizeg }, { "_mpmath_create", Pympz_mpmath_create, METH_VARARGS, doc_mpmath_createg }, { "acos", GMPy_Context_Acos, METH_O, GMPy_doc_function_acos }, { "acosh", GMPy_Context_Acosh, METH_O, GMPy_doc_function_acosh }, { "ai", GMPy_Context_Ai, METH_O, GMPy_doc_function_ai }, { "agm", GMPy_Context_AGM, METH_VARARGS, GMPy_doc_function_agm }, { "asin", GMPy_Context_Asin, METH_O, GMPy_doc_function_asin }, { "asinh", GMPy_Context_Asinh, METH_O, GMPy_doc_function_asinh }, { "atan", GMPy_Context_Atan, METH_O, GMPy_doc_function_atan }, { "atanh", GMPy_Context_Atanh, METH_O, GMPy_doc_function_atanh }, { "atan2", GMPy_Context_Atan2, METH_VARARGS, GMPy_doc_function_atan2 }, { "can_round", GMPy_MPFR_Can_Round, METH_VARARGS, GMPy_doc_mpfr_can_round }, { "cbrt", GMPy_Context_Cbrt, METH_O, GMPy_doc_function_cbrt }, { "ceil", GMPy_Context_Ceil, METH_O, GMPy_doc_function_ceil }, { "check_range", GMPy_Context_CheckRange, METH_O, GMPy_doc_function_check_range }, { "const_catalan", (PyCFunction)GMPy_Function_Const_Catalan, METH_VARARGS | METH_KEYWORDS, GMPy_doc_function_const_catalan }, { "const_euler", (PyCFunction)GMPy_Function_Const_Euler, METH_VARARGS | METH_KEYWORDS, GMPy_doc_function_const_euler }, { "const_log2", (PyCFunction)GMPy_Function_Const_Log2, METH_VARARGS | METH_KEYWORDS, GMPy_doc_function_const_log2 }, { "const_pi", (PyCFunction)GMPy_Function_Const_Pi, METH_VARARGS | METH_KEYWORDS, GMPy_doc_function_const_pi }, { "context", (PyCFunction)GMPy_CTXT_Context, METH_VARARGS | METH_KEYWORDS, GMPy_doc_context }, { "copy_sign", GMPy_MPFR_copy_sign, METH_VARARGS, GMPy_doc_mpfr_copy_sign }, { "cos", GMPy_Context_Cos, METH_O, GMPy_doc_function_cos }, { "cosh", GMPy_Context_Cosh, METH_O, GMPy_doc_function_cosh }, { "cot", GMPy_Context_Cot, METH_O, GMPy_doc_function_cot }, { "coth", GMPy_Context_Coth, METH_O, GMPy_doc_function_coth }, { "csc", GMPy_Context_Csc, METH_O, GMPy_doc_function_csc }, { "csch", GMPy_Context_Csch, METH_O, GMPy_doc_function_csch }, { "degrees", GMPy_Context_Degrees, METH_O, GMPy_doc_function_degrees }, { "digamma", GMPy_Context_Digamma, METH_O, GMPy_doc_function_digamma }, { "div_2exp", GMPy_Context_Div_2exp, METH_VARARGS, GMPy_doc_function_div_2exp }, { "eint", GMPy_Context_Eint, METH_O, GMPy_doc_function_eint }, { "erf", GMPy_Context_Erf, METH_O, GMPy_doc_function_erf }, { "erfc", GMPy_Context_Erfc, METH_O, GMPy_doc_function_erfc }, { "exp", GMPy_Context_Exp, METH_O, GMPy_doc_function_exp }, { "expm1", GMPy_Context_Expm1, METH_O, GMPy_doc_function_expm1 }, { "exp10", GMPy_Context_Exp10, METH_O, GMPy_doc_function_exp10 }, { "exp2", GMPy_Context_Exp2, METH_O, GMPy_doc_function_exp2 }, { "f2q", GMPy_Context_F2Q, METH_VARARGS, GMPy_doc_function_f2q }, { "factorial", GMPy_Context_Factorial, METH_O, GMPy_doc_function_factorial }, { "floor", GMPy_Context_Floor, METH_O, GMPy_doc_function_floor }, { "fma", GMPy_Context_FMA, METH_VARARGS, GMPy_doc_function_fma }, { "fms", GMPy_Context_FMS, METH_VARARGS, GMPy_doc_function_fms }, #if MPFR_VERSION_MAJOR > 3 { "fmma", GMPy_Context_FMMA, METH_VARARGS, GMPy_doc_function_fmma }, { "fmms", GMPy_Context_FMMS, METH_VARARGS, GMPy_doc_function_fmms }, #endif { "fmod", GMPy_Context_Fmod, METH_VARARGS, GMPy_doc_function_fmod }, { "frac", GMPy_Context_Frac, METH_O, GMPy_doc_function_frac }, { "free_cache", GMPy_MPFR_Free_Cache, METH_NOARGS, GMPy_doc_mpfr_free_cache }, { "frexp", GMPy_Context_Frexp, METH_O, GMPy_doc_function_frexp }, { "fsum", GMPy_Context_Fsum, METH_O, GMPy_doc_function_fsum }, { "gamma", GMPy_Context_Gamma, METH_O, GMPy_doc_function_gamma }, { "get_context", GMPy_CTXT_Get, METH_NOARGS, GMPy_doc_get_context }, { "get_emax_max", GMPy_MPFR_get_emax_max, METH_NOARGS, GMPy_doc_mpfr_get_emax_max }, { "get_emin_min", GMPy_MPFR_get_emin_min, METH_NOARGS, GMPy_doc_mpfr_get_emin_min }, { "get_exp", GMPy_MPFR_get_exp, METH_O, GMPy_doc_mpfr_get_exp }, { "get_max_precision", GMPy_MPFR_get_max_precision, METH_NOARGS, GMPy_doc_mpfr_get_max_precision }, { "hypot", GMPy_Context_Hypot, METH_VARARGS, GMPy_doc_function_hypot }, { "ieee", (PyCFunction)GMPy_CTXT_ieee, METH_VARARGS | METH_KEYWORDS, GMPy_doc_context_ieee }, { "inf", GMPy_MPFR_set_inf, METH_VARARGS, GMPy_doc_mpfr_set_inf }, { "is_finite", GMPy_Context_Is_Finite, METH_O, GMPy_doc_function_is_finite }, { "is_infinite", GMPy_Context_Is_Infinite, METH_O, GMPy_doc_function_is_infinite }, { "is_integer", GMPy_Context_Is_Integer, METH_O, GMPy_doc_function_is_integer }, { "is_lessgreater", GMPy_Context_Is_LessGreater, METH_VARARGS, GMPy_doc_function_is_lessgreater }, { "is_nan", GMPy_Context_Is_NAN, METH_O, GMPy_doc_function_is_nan }, { "is_regular", GMPy_Context_Is_Regular, METH_O, GMPy_doc_function_is_regular }, { "is_signed", GMPy_Context_Is_Signed, METH_O, GMPy_doc_function_is_signed }, { "is_unordered", GMPy_Context_Is_Unordered, METH_VARARGS, GMPy_doc_function_is_unordered }, { "is_zero", GMPy_Context_Is_Zero, METH_O, GMPy_doc_function_is_zero }, { "jn", GMPy_Context_Jn, METH_VARARGS, GMPy_doc_function_jn }, { "j0", GMPy_Context_J0, METH_O, GMPy_doc_function_j0 }, { "j1", GMPy_Context_J1, METH_O, GMPy_doc_function_j1 }, { "lgamma", GMPy_Context_Lgamma, METH_O, GMPy_doc_function_lgamma }, { "li2", GMPy_Context_Li2, METH_O, GMPy_doc_function_li2 }, { "lngamma", GMPy_Context_Lngamma, METH_O, GMPy_doc_function_lngamma }, { "local_context", (PyCFunction)GMPy_CTXT_Local, METH_VARARGS | METH_KEYWORDS, GMPy_doc_local_context }, { "log", GMPy_Context_Log, METH_O, GMPy_doc_function_log }, { "log1p", GMPy_Context_Log1p, METH_O, GMPy_doc_function_log1p }, { "log10", GMPy_Context_Log10, METH_O, GMPy_doc_function_log10 }, { "log2", GMPy_Context_Log2, METH_O, GMPy_doc_function_log2 }, { "maxnum", GMPy_Context_Maxnum, METH_VARARGS, GMPy_doc_function_maxnum }, { "minnum", GMPy_Context_Minnum, METH_VARARGS, GMPy_doc_function_minnum }, { "modf", GMPy_Context_Modf, METH_O, GMPy_doc_function_modf }, { "mpfr_from_old_binary", GMPy_MPFR_From_Old_Binary, METH_O, doc_mpfr_from_old_binary }, { "mpfr_random", GMPy_MPFR_random_Function, METH_VARARGS, GMPy_doc_mpfr_random_function }, { "mpfr_grandom", GMPy_MPFR_grandom_Function, METH_VARARGS, GMPy_doc_mpfr_grandom_function }, #if MPFR_VERSION_MAJOR > 3 { "mpfr_nrandom", GMPy_MPFR_nrandom_Function, METH_VARARGS, GMPy_doc_mpfr_nrandom_function }, #endif { "mul_2exp", GMPy_Context_Mul_2exp, METH_VARARGS, GMPy_doc_function_mul_2exp }, { "nan", GMPy_MPFR_set_nan, METH_NOARGS, GMPy_doc_mpfr_set_nan }, { "next_above", GMPy_Context_NextAbove, METH_O, GMPy_doc_function_next_above }, { "next_below", GMPy_Context_NextBelow, METH_O, GMPy_doc_function_next_below }, { "next_toward", GMPy_Context_NextToward, METH_VARARGS, GMPy_doc_function_next_toward }, { "radians", GMPy_Context_Radians, METH_O, GMPy_doc_function_radians }, { "rec_sqrt", GMPy_Context_RecSqrt, METH_O, GMPy_doc_function_rec_sqrt }, { "reldiff", GMPy_Context_RelDiff, METH_VARARGS, GMPy_doc_function_reldiff }, { "remainder", GMPy_Context_Remainder, METH_VARARGS, GMPy_doc_function_remainder }, { "remquo", GMPy_Context_RemQuo, METH_VARARGS, GMPy_doc_function_remquo }, { "rint", GMPy_Context_Rint, METH_O, GMPy_doc_function_rint }, { "rint_ceil", GMPy_Context_RintCeil, METH_O, GMPy_doc_function_rint_ceil }, { "rint_floor", GMPy_Context_RintFloor, METH_O, GMPy_doc_function_rint_floor }, { "rint_round", GMPy_Context_RintRound, METH_O, GMPy_doc_function_rint_round }, { "rint_trunc", GMPy_Context_RintTrunc, METH_O, GMPy_doc_function_rint_trunc }, { "root", GMPy_Context_Root, METH_VARARGS, GMPy_doc_function_root }, { "rootn", GMPy_Context_Rootn, METH_VARARGS, GMPy_doc_function_rootn }, { "round_away", GMPy_Context_RoundAway, METH_O, GMPy_doc_function_round_away }, { "round2", GMPy_Context_Round2, METH_VARARGS, GMPy_doc_function_round2 }, { "sec", GMPy_Context_Sec, METH_O, GMPy_doc_function_sec }, { "sech", GMPy_Context_Sech, METH_O, GMPy_doc_function_sech }, { "set_context", GMPy_CTXT_Set, METH_O, GMPy_doc_set_context }, { "set_exp", GMPy_MPFR_set_exp, METH_VARARGS, GMPy_doc_mpfr_set_exp }, { "set_sign", GMPy_MPFR_set_sign, METH_VARARGS, GMPy_doc_mpfr_set_sign }, { "sin", GMPy_Context_Sin, METH_O, GMPy_doc_function_sin }, { "sin_cos", GMPy_Context_Sin_Cos, METH_O, GMPy_doc_function_sin_cos }, { "sinh", GMPy_Context_Sinh, METH_O, GMPy_doc_function_sinh }, { "sinh_cosh", GMPy_Context_Sinh_Cosh, METH_O, GMPy_doc_function_sinh_cosh }, { "sqrt", GMPy_Context_Sqrt, METH_O, GMPy_doc_function_sqrt }, { "tan", GMPy_Context_Tan, METH_O, GMPy_doc_function_tan }, { "tanh", GMPy_Context_Tanh, METH_O, GMPy_doc_function_tanh }, { "trunc", GMPy_Context_Trunc, METH_O, GMPy_doc_function_trunc}, #ifdef VECTOR { "vector", GMPy_Context_Vector, METH_O, GMPy_doc_function_vector}, { "vector2", GMPy_Context_Vector2, METH_VARARGS, GMPy_doc_function_vector2}, #endif { "yn", GMPy_Context_Yn, METH_VARARGS, GMPy_doc_function_yn }, { "y0", GMPy_Context_Y0, METH_O, GMPy_doc_function_y0 }, { "y1", GMPy_Context_Y1, METH_O, GMPy_doc_function_y1 }, { "zero", GMPy_MPFR_set_zero, METH_VARARGS, GMPy_doc_mpfr_set_zero }, { "zeta", GMPy_Context_Zeta, METH_O, GMPy_doc_function_zeta }, { "mpc_random", GMPy_MPC_random_Function, METH_VARARGS, GMPy_doc_mpc_random_function }, { "norm", GMPy_Context_Norm, METH_O, GMPy_doc_function_norm }, { "polar", GMPy_Context_Polar, METH_O, GMPy_doc_function_polar }, { "phase", GMPy_Context_Phase, METH_O, GMPy_doc_function_phase }, { "proj", GMPy_Context_Proj, METH_O, GMPy_doc_function_proj }, #ifdef MPC_110 { "root_of_unity", GMPy_Context_Root_Of_Unity, METH_VARARGS, GMPy_doc_function_root_of_unity }, #endif { "rect", GMPy_Context_Rect, METH_VARARGS, GMPy_doc_function_rect }, { NULL, NULL, 1} }; static char _gmpy_docs[] = "gmpy2 2.1.0b2 - General Multiple-precision arithmetic for Python\n" "\n" "gmpy2 supports several multiple-precision libraries. Integer and\n" "rational arithmetic is provided by the GMP library. Real floating-\n" "point arithmetic is provided by the MPFR library. Complex floating-\n" "point arithmetic is provided by the MPC library.\n" "\n" "The integer type 'mpz' has comparable functionality to Python's\n" "builtin integers, but is faster for operations on large numbers.\n" "A wide variety of additional functions are provided:\n" " - bit manipulations\n" " - GCD, Extended GCD, LCM\n" " - Fibonacci and Lucas sequences\n" " - primality testing\n" " - powers and integer Nth roots\n" "\n" "The rational type 'mpq' is equivalent to Python's fractions\n" "module, but is faster.\n" "\n" "The real type 'mpfr' and complex type 'mpc' provide multiple-\n" "precision real and complex numbers with user-definable precision,\n" "rounding, and exponent range. All the advanced functions from the\n" "MPFR and MPC libraries are available.\n\ "; /* Notes on Python 3.x support: Full support for PEP-3121 has not been * implemented. No per-module state has been defined. */ #ifdef PY3 #define INITERROR return NULL static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "gmpy2", _gmpy_docs, -1, /*sizeof(struct module_state) */ Pygmpy_methods, NULL, NULL, /* gmpy_traverse */ NULL, /* gmpy_clear */ NULL }; #else #define INITERROR return #endif #ifdef PY3 PyMODINIT_FUNC PyInit_gmpy2(void) #else PyMODINIT_FUNC initgmpy2(void) #endif { PyObject *result = NULL; PyObject *namespace = NULL; PyObject *gmpy_module = NULL; PyObject *copy_reg_module = NULL; PyObject *temp = NULL; PyObject *numbers_module = NULL; #ifndef STATIC static void *GMPy_C_API[GMPy_API_pointers]; PyObject *c_api_object; #endif /* Validate the sizes of the various typedef'ed integer types. */ #if defined _WIN64 && (MPIR || MSYS2) if (sizeof(mp_bitcnt_t) != sizeof(PY_LONG_LONG)) { /* LCOV_EXCL_START */ SYSTEM_ERROR("Size of PY_LONG_LONG and mp_bitcnt_t not compatible (_WIN64 && MPIR)"); INITERROR; /* LCOV_EXCL_STOP */ } #else if (sizeof(mp_bitcnt_t) != sizeof(long)) { /* LCOV_EXCL_START */ SYSTEM_ERROR("Size of long and mp_bitcnt_t not compatible"); INITERROR; /* LCOV_EXCL_STOP */ } #endif if (sizeof(mp_bitcnt_t) > sizeof(size_t)) { /* LCOV_EXCL_START */ SYSTEM_ERROR("Size of size_t and mp_bitcnt_t not compatible"); INITERROR; /* LCOV_EXCL_STOP */ } if (sizeof(mpfr_prec_t) != sizeof(long)) { /* LCOV_EXCL_START */ SYSTEM_ERROR("Size of mpfr_prec_t and long not compatible"); INITERROR; /* LCOV_EXCL_STOP */ } if (sizeof(mpfr_exp_t) != sizeof(long)) { /* LCOV_EXCL_START */ SYSTEM_ERROR("Size of mpfr_exp_t and long not compatible"); INITERROR; /* LCOV_EXCL_STOP */ } /* Configure MPFR to use the maximum possible exponent range. */ mpfr_set_emax(mpfr_get_emax_max()); mpfr_set_emin(mpfr_get_emin_min()); /* Initialize the types. */ if (PyType_Ready(&MPZ_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&MPQ_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&XMPZ_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&GMPy_Iter_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&MPFR_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&CTXT_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&CTXT_Manager_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&MPC_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyType_Ready(&RandomState_Type) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } /* Initialize the global structure. Eventually this should be module local. */ global.cache_size = 100; global.cache_obsize = 128; mpz_init(global.tempz); /* Initialize object caching. */ set_gmpympzcache(); set_gmpympqcache(); set_gmpyxmpzcache(); set_gmpympfrcache(); set_gmpympccache(); /* Initialize exceptions. */ GMPyExc_GmpyError = PyErr_NewException("gmpy2.gmpy2Error", PyExc_ArithmeticError, NULL); if (!GMPyExc_GmpyError) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } GMPyExc_Erange = PyErr_NewException("gmpy2.RangeError", GMPyExc_GmpyError, NULL); if (!GMPyExc_Erange) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } GMPyExc_Inexact = PyErr_NewException("gmpy2.InexactResultError", GMPyExc_GmpyError, NULL); if (!GMPyExc_Inexact) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } GMPyExc_Overflow = PyErr_NewException("gmpy2.OverflowResultError", GMPyExc_Inexact, NULL); if (!GMPyExc_Overflow) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } GMPyExc_Underflow = PyErr_NewException("gmpy2.UnderflowResultError", GMPyExc_Inexact, NULL); if (!GMPyExc_Underflow) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } temp = PyTuple_Pack(2, GMPyExc_GmpyError, PyExc_ValueError); if (!temp) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } GMPyExc_Invalid = PyErr_NewException("gmpy2.InvalidOperationError", temp, NULL); Py_DECREF(temp); if (!GMPyExc_Invalid) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } temp = PyTuple_Pack(2, GMPyExc_GmpyError, PyExc_ZeroDivisionError); if (!temp) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } GMPyExc_DivZero = PyErr_NewException("gmpy2.DivisionByZeroError", temp, NULL); Py_DECREF(temp); if (!GMPyExc_DivZero) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } #ifdef PY3 gmpy_module = PyModule_Create(&moduledef); #else gmpy_module = Py_InitModule3("gmpy2", Pygmpy_methods, _gmpy_docs); #endif if (gmpy_module == NULL) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } /* Add the mpz type to the module namespace. */ Py_INCREF(&MPZ_Type); PyModule_AddObject(gmpy_module, "mpz", (PyObject*)&MPZ_Type); /* Add the xmpz type to the module namespace. */ Py_INCREF(&XMPZ_Type); PyModule_AddObject(gmpy_module, "xmpz", (PyObject*)&XMPZ_Type); /* Add the MPQ type to the module namespace. */ Py_INCREF(&MPQ_Type); PyModule_AddObject(gmpy_module, "mpq", (PyObject*)&MPQ_Type); /* Add the MPFR type to the module namespace. */ Py_INCREF(&MPFR_Type); PyModule_AddObject(gmpy_module, "mpfr", (PyObject*)&MPFR_Type); /* Add the MPC type to the module namespace. */ Py_INCREF(&MPC_Type); PyModule_AddObject(gmpy_module, "mpc", (PyObject*)&MPC_Type); /* Initialize thread local contexts. */ #ifdef WITHOUT_THREADS module_context = (CTXT_Object*)GMPy_CTXT_New(); if (!module_context) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } Py_INCREF(Py_False); if (PyModule_AddObject(gmpy_module, "HAVE_THREADS", Py_False) < 0) { /* LCOV_EXCL_START */ Py_DECREF(Py_False); INITERROR; /* LCOV_EXCL_STOP */ } #else tls_context_key = PyUnicode_FromString("__GMPY2_CTX__"); Py_INCREF(Py_True); if (PyModule_AddObject(gmpy_module, "HAVE_THREADS", Py_True) < 0) { /* LCOV_EXCL_START */ Py_DECREF(Py_True); INITERROR; /* LCOV_EXCL_STOP */ } #endif /* Add the constants for defining rounding modes. */ if (PyModule_AddIntConstant(gmpy_module, "RoundToNearest", MPFR_RNDN) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyModule_AddIntConstant(gmpy_module, "RoundToZero", MPFR_RNDZ) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyModule_AddIntConstant(gmpy_module, "RoundUp", MPFR_RNDU) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyModule_AddIntConstant(gmpy_module, "RoundDown", MPFR_RNDD) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyModule_AddIntConstant(gmpy_module, "RoundAwayZero", MPFR_RNDA) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } if (PyModule_AddIntConstant(gmpy_module, "Default", GMPY_DEFAULT) < 0) { /* LCOV_EXCL_START */ INITERROR; /* LCOV_EXCL_STOP */ } /* Add the exceptions. */ Py_INCREF(GMPyExc_DivZero); if (PyModule_AddObject(gmpy_module, "DivisionByZeroError", GMPyExc_DivZero) < 0) { /* LCOV_EXCL_START */ Py_DECREF(GMPyExc_DivZero); INITERROR; /* LCOV_EXCL_STOP */ } Py_INCREF(GMPyExc_Inexact); if (PyModule_AddObject(gmpy_module, "InexactResultError", GMPyExc_Inexact) < 0) { /* LCOV_EXCL_START */ Py_DECREF(GMPyExc_Inexact); INITERROR; /* LCOV_EXCL_STOP */ } Py_INCREF(GMPyExc_Invalid); if (PyModule_AddObject(gmpy_module, "InvalidOperationError", GMPyExc_Invalid) < 0 ) { /* LCOV_EXCL_START */ Py_DECREF(GMPyExc_Invalid); INITERROR; /* LCOV_EXCL_STOP */ } Py_INCREF(GMPyExc_Overflow); if (PyModule_AddObject(gmpy_module, "OverflowResultError", GMPyExc_Overflow) < 0) { /* LCOV_EXCL_START */ Py_DECREF(GMPyExc_Overflow); INITERROR; /* LCOV_EXCL_STOP */ } Py_INCREF(GMPyExc_Underflow); if (PyModule_AddObject(gmpy_module, "UnderflowResultError", GMPyExc_Underflow) < 0) { /* LCOV_EXCL_START */ Py_DECREF(GMPyExc_Underflow); INITERROR; /* LCOV_EXCL_STOP */ } Py_INCREF(GMPyExc_Erange); if (PyModule_AddObject(gmpy_module, "RangeError", GMPyExc_Erange) < 0) { /* LCOV_EXCL_START */ Py_DECREF(GMPyExc_Erange); INITERROR; /* LCOV_EXCL_STOP */ } #ifdef SHARED /* Create the Capsule for the C-API. */ GMPy_C_API[MPZ_Type_NUM] = (void*)&MPZ_Type; GMPy_C_API[XMPZ_Type_NUM] = (void*)&XMPZ_Type; GMPy_C_API[MPQ_Type_NUM] = (void*)&MPQ_Type; GMPy_C_API[XMPQ_Type_NUM] = (void*)&MPQ_Type; GMPy_C_API[MPFR_Type_NUM] = (void*)&MPFR_Type; GMPy_C_API[XMPFR_Type_NUM] = (void*)&MPFR_Type; GMPy_C_API[MPC_Type_NUM] = (void*)&MPC_Type; GMPy_C_API[XMPC_Type_NUM] = (void*)&MPC_Type; GMPy_C_API[CTXT_Type_NUM] = (void*)&CTXT_Type; GMPy_C_API[CTXT_Manager_Type_NUM] = (void*)&CTXT_Manager_Type; GMPy_C_API[RandomState_Type_NUM] = (void*)&RandomState_Type; GMPy_C_API[GMPy_MPZ_New_NUM] = (void*)GMPy_MPZ_New; GMPy_C_API[GMPy_MPZ_NewInit_NUM] = (void*)GMPy_MPZ_NewInit; GMPy_C_API[GMPy_MPZ_Dealloc_NUM] = (void*)GMPy_MPZ_Dealloc; GMPy_C_API[GMPy_MPZ_ConvertArg_NUM] = (void*)GMPy_MPZ_ConvertArg; GMPy_C_API[GMPy_XMPZ_New_NUM] = (void*)GMPy_XMPZ_New; GMPy_C_API[GMPy_XMPZ_NewInit_NUM] = (void*)GMPy_XMPZ_NewInit; GMPy_C_API[GMPy_XMPZ_Dealloc_NUM] = (void*)GMPy_XMPZ_Dealloc; GMPy_C_API[GMPy_MPQ_New_NUM] = (void*)GMPy_MPQ_New; GMPy_C_API[GMPy_MPQ_NewInit_NUM] = (void*)GMPy_MPQ_NewInit; GMPy_C_API[GMPy_MPQ_Dealloc_NUM] = (void*)GMPy_MPQ_Dealloc; GMPy_C_API[GMPy_MPQ_ConvertArg_NUM] = (void*)GMPy_MPQ_ConvertArg; GMPy_C_API[GMPy_MPFR_New_NUM] = (void*)GMPy_MPFR_New; GMPy_C_API[GMPy_MPFR_NewInit_NUM] = (void*)GMPy_MPFR_NewInit; GMPy_C_API[GMPy_MPFR_Dealloc_NUM] = (void*)GMPy_MPFR_Dealloc; GMPy_C_API[GMPy_MPFR_ConvertArg_NUM] = (void*)GMPy_MPFR_ConvertArg; GMPy_C_API[GMPy_MPC_New_NUM] = (void*)GMPy_MPC_New; GMPy_C_API[GMPy_MPC_NewInit_NUM] = (void*)GMPy_MPC_NewInit; GMPy_C_API[GMPy_MPC_Dealloc_NUM] = (void*)GMPy_MPC_Dealloc; GMPy_C_API[GMPy_MPC_ConvertArg_NUM] = (void*)GMPy_MPC_ConvertArg; c_api_object = PyCapsule_New((void *)GMPy_C_API, "gmpy2._C_API", NULL); if (c_api_object != NULL) { PyModule_AddObject(gmpy_module, "_C_API", c_api_object); } #endif /* Add support for pickling. */ #ifdef PY3 copy_reg_module = PyImport_ImportModule("copyreg"); if (copy_reg_module) { char* enable_pickle = "def gmpy2_reducer(x): return (gmpy2.from_binary, (gmpy2.to_binary(x),))\n" "copyreg.pickle(type(gmpy2.mpz(0)), gmpy2_reducer)\n" "copyreg.pickle(type(gmpy2.xmpz(0)), gmpy2_reducer)\n" "copyreg.pickle(type(gmpy2.mpq(0)), gmpy2_reducer)\n" "copyreg.pickle(type(gmpy2.mpfr(0)), gmpy2_reducer)\n" "copyreg.pickle(type(gmpy2.mpc(0,0)), gmpy2_reducer)\n"; namespace = PyDict_New(); result = NULL; PyDict_SetItemString(namespace, "copyreg", copy_reg_module); PyDict_SetItemString(namespace, "gmpy2", gmpy_module); PyDict_SetItemString(namespace, "type", (PyObject*)&PyType_Type); result = PyRun_String(enable_pickle, Py_file_input, namespace, namespace); if (!result) { /* LCOV_EXCL_START */ PyErr_Clear(); /* LCOV_EXCL_STOP */ } Py_DECREF(namespace); Py_DECREF(copy_reg_module); Py_XDECREF(result); } else { /* LCOV_EXCL_START */ PyErr_Clear(); /* LCOV_EXCL_STOP */ } #else copy_reg_module = PyImport_ImportModule("copy_reg"); if (copy_reg_module) { char* enable_pickle = "def gmpy2_reducer(x): return (gmpy2.from_binary, (gmpy2.to_binary(x),))\n" "copy_reg.pickle(type(gmpy2.mpz(0)), gmpy2_reducer)\n" "copy_reg.pickle(type(gmpy2.xmpz(0)), gmpy2_reducer)\n" "copy_reg.pickle(type(gmpy2.mpq(0)), gmpy2_reducer)\n" "copy_reg.pickle(type(gmpy2.mpfr(0)), gmpy2_reducer)\n" "copy_reg.pickle(type(gmpy2.mpc(0,0)), gmpy2_reducer)\n"; PyObject* namespace = PyDict_New(); PyObject* result = NULL; PyDict_SetItemString(namespace, "copy_reg", copy_reg_module); PyDict_SetItemString(namespace, "gmpy2", gmpy_module); PyDict_SetItemString(namespace, "type", (PyObject*)&PyType_Type); result = PyRun_String(enable_pickle, Py_file_input, namespace, namespace); if (!result) { /* LCOV_EXCL_START */ PyErr_Clear(); /* LCOV_EXCL_STOP */ } Py_DECREF(namespace); Py_DECREF(copy_reg_module); Py_XDECREF(result); } else { /* LCOV_EXCL_START */ PyErr_Clear(); /* LCOV_EXCL_STOP */ } #endif /* Register the gmpy2 types with the numeric tower. */ numbers_module = PyImport_ImportModule("numbers"); if (numbers_module) { char* register_numbers = "numbers.Integral.register(type(gmpy2.mpz()))\n" "numbers.Rational.register(type(gmpy2.mpq()))\n" "numbers.Real.register(type(gmpy2.mpfr()))\n" "numbers.Complex.register(type(gmpy2.mpc()))\n" ; namespace = PyDict_New(); result = NULL; PyDict_SetItemString(namespace, "numbers", numbers_module); PyDict_SetItemString(namespace, "gmpy2", gmpy_module); PyDict_SetItemString(namespace, "type", (PyObject*)&PyType_Type); result = PyRun_String(register_numbers, Py_file_input, namespace, namespace); if (!result) { PyErr_Clear(); } Py_DECREF(namespace); Py_DECREF(numbers_module); Py_XDECREF(result); } else { PyErr_Clear(); } #ifdef PY3 return gmpy_module; #endif } gmpy2-2.1.0b3/src/gmpy2.h0000664000175000017500000005100713525427233014656 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* gmpy C API extension header file. Part of Python's gmpy module since version 0.4 Created by Pearu Peterson , November 2000. Edited by A. Martelli , December 2000. Edited by Case Van Horsen , 2009, 2010, 2011. Version 1.02, February 2007. Version 1.03, June 2008 Version 1.04, June 2008 (no changes) Version 1.05, February 2009 (support MPIR) Version 1.20, January 2010 (remove obsolete MS hacks) casevh Version 2.00, April 2010 (change to gmpy2) casevh October 2010 (added Py_hash_t) casevh December 2010 (added mpfr, mpc) casevh January 2011 (add Pygmpy_context) casevh April 2011 (split into multiple files) casevh Version 2.10 August 2014 (reflect major rewrite during 2013/2014) casevh */ #ifndef Py_GMPYMODULE_H #define Py_GMPYMODULE_H #ifdef __cplusplus extern "C" { #endif /* Structure of gmpy2.h * * Revised 17-APR-2017 casevh * * 1. Checks for specific Python versions. * 2. Include headers for GMP/MPIR, MPFR, and MPC. * 3. Define public C-API. * 1. Define gmpy2 types. * 2. Define the public API. * */ /* Check for minimum Python version requirements. */ #if PY_VERSION_HEX < 0x02060000 # error "GMPY2 requires Python 2.6 or later." #endif /* Include headers for GMP/MPIR, MPFR, and MPC. */ #ifdef MPIR # include #else # include #endif #include #include /* Check MPFR and MPC versions. */ #if (!defined(MPC_VERSION) || (MPC_VERSION < MPC_VERSION_NUM(1,0,3))) # error "GMPY2 requires MPC 1.0.3 or later." #endif #if (defined(MPC_VERSION) && (MPC_VERSION >= MPC_VERSION_NUM(1,1,0))) # define MPC_110 #endif #if PY_VERSION_HEX < 0x030200A4 typedef long Py_hash_t; typedef unsigned long Py_uhash_t; # define _PyHASH_IMAG 1000003 #endif /* The native_si and native_ui types correspond to long long on Windows 64. They * should only be used with the MPIR library (not MPFR/MPC). */ #if defined(MPIR) && defined(_WIN64) typedef long long native_si; typedef unsigned long long native_ui; #define GMPy_Integer_AsNative_siAndError GMPy_Integer_AsLongLongAndError #define GMPy_Integer_AsNative_uiAndError GMPy_Integer_AsUnsignedLongLongAndError #else typedef long native_si; typedef unsigned long native_ui; #define GMPy_Integer_AsNative_siAndError GMPy_Integer_AsLongAndError #define GMPy_Integer_AsNative_uiAndError GMPy_Integer_AsUnsignedLongAndError #endif /* GMPY2 Public API */ /* Types * MPZ_Object * XMPZ_Object (mutable version of MPZ_Object) * MPQ_Object * XMPQ_Object (mutable version of MPQ_Object) * MPFR_Object * XMPFR_Object (mutable version of MPFR_Object) * MPC_Object * XMPC_Object (mutable version of MPC_Object) * CTXT_Object * CTXT_Manager_Object * RandomState_Object */ typedef struct { PyObject_HEAD mpz_t z; Py_hash_t hash_cache; } MPZ_Object; typedef struct { PyObject_HEAD mpz_t z; } XMPZ_Object; typedef struct { PyObject_HEAD mpq_t q; Py_hash_t hash_cache; } MPQ_Object; typedef struct { PyObject_HEAD mpfr_t f; Py_hash_t hash_cache; int rc; } MPFR_Object; typedef struct { PyObject_HEAD mpc_t c; Py_hash_t hash_cache; int rc; } MPC_Object; typedef struct { PyObject_HEAD gmp_randstate_t state; } RandomState_Object; typedef struct { mpfr_prec_t mpfr_prec; /* current precision in bits, for MPFR */ mpfr_rnd_t mpfr_round; /* current rounding mode for float (MPFR) */ mpfr_exp_t emax; /* maximum exponent */ mpfr_exp_t emin; /* minimum exponent */ int subnormalize; /* if 1, subnormalization is performed */ int underflow; /* did an underflow occur? */ int overflow; /* did an overflow occur? */ int inexact; /* was the result inexact? */ int invalid; /* invalid operation (i.e. NaN)? */ int erange; /* did a range error occur? */ int divzero; /* divided by zero? */ int traps; /* if 0, do not trap any exceptions */ /* if not 0, then raise traps per bits above */ mpfr_prec_t real_prec; /* current precision in bits, for Re(MPC) */ mpfr_prec_t imag_prec; /* current precision in bits, for Im(MPC) */ mpfr_rnd_t real_round; /* current rounding mode for Re(MPC) */ mpfr_rnd_t imag_round; /* current rounding mode for Im(MPC) */ int allow_complex; /* if 1, allow mpfr functions to return an mpc */ int rational_division; /* if 1, mpz/mpz returns an mpq result */ } gmpy_context; typedef struct { PyObject_HEAD gmpy_context ctx; #ifndef WITHOUT_THREADS PyThreadState *tstate; #endif } CTXT_Object; typedef struct { PyObject_HEAD CTXT_Object *new_context; /* Context that will be returned when * __enter__ is called. */ CTXT_Object *old_context; /* Context that will restored when * __exit__ is called. */ } CTXT_Manager_Object; #define MPZ(obj) (((MPZ_Object*)(obj))->z) #define MPQ(obj) (((MPQ_Object*)(obj))->q) #define MPFR(obj) (((MPFR_Object*)(obj))->f) #define MPC(obj) (((MPC_Object*)(obj))->c) /* Start of the C-API definitions */ #define MPZ_Type_NUM 0 #define XMPZ_Type_NUM 1 #define MPQ_Type_NUM 2 #define XMPQ_Type_NUM 3 #define MPFR_Type_NUM 4 #define XMPFR_Type_NUM 5 #define MPC_Type_NUM 6 #define XMPC_Type_NUM 7 #define CTXT_Type_NUM 8 #define CTXT_Manager_Type_NUM 9 #define RandomState_Type_NUM 10 /* The following functions are found in gmpy2_cache. */ #define GMPy_MPZ_New_NUM 11 #define GMPy_MPZ_New_RETURN MPZ_Object * #define GMPy_MPZ_New_PROTO (CTXT_Object *context) #define GMPy_MPZ_NewInit_NUM 12 #define GMPy_MPZ_NewInit_RETURN PyObject * #define GMPy_MPZ_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPZ_Dealloc_NUM 13 #define GMPy_MPZ_Dealloc_RETURN void #define GMPy_MPZ_Dealloc_PROTO (MPZ_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPZ_ConvertArg_NUM 14 #define GMPy_MPZ_ConvertArg_RETURN int #define GMPy_MPZ_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* The following functions are found in gmpy2_cache. */ #define GMPy_XMPZ_New_NUM 15 #define GMPy_XMPZ_New_RETURN XMPZ_Object * #define GMPy_XMPZ_New_PROTO (CTXT_Object *context) #define GMPy_XMPZ_NewInit_NUM 16 #define GMPy_XMPZ_NewInit_RETURN PyObject * #define GMPy_XMPZ_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_XMPZ_Dealloc_NUM 17 #define GMPy_XMPZ_Dealloc_RETURN void #define GMPy_XMPZ_Dealloc_PROTO (XMPZ_Object *self) /* The following functions are found in gmpy2_cache. */ #define GMPy_MPQ_New_NUM 18 #define GMPy_MPQ_New_RETURN MPQ_Object * #define GMPy_MPQ_New_PROTO (CTXT_Object *context) #define GMPy_MPQ_NewInit_NUM 19 #define GMPy_MPQ_NewInit_RETURN PyObject * #define GMPy_MPQ_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPQ_Dealloc_NUM 20 #define GMPy_MPQ_Dealloc_RETURN void #define GMPy_MPQ_Dealloc_PROTO (MPQ_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPQ_ConvertArg_NUM 21 #define GMPy_MPQ_ConvertArg_RETURN int #define GMPy_MPQ_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* The following functions are found in gmpy2_cache. */ #define GMPy_MPFR_New_NUM 22 #define GMPy_MPFR_New_RETURN MPFR_Object * #define GMPy_MPFR_New_PROTO (mpfr_prec_t bits, CTXT_Object *context) #define GMPy_MPFR_NewInit_NUM 23 #define GMPy_MPFR_NewInit_RETURN PyObject * #define GMPy_MPFR_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPFR_Dealloc_NUM 24 #define GMPy_MPFR_Dealloc_RETURN void #define GMPy_MPFR_Dealloc_PROTO (MPFR_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPFR_ConvertArg_NUM 25 #define GMPy_MPFR_ConvertArg_RETURN int #define GMPy_MPFR_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* The following functions are found in gmpy2_cache. */ #define GMPy_MPC_New_NUM 26 #define GMPy_MPC_New_RETURN MPC_Object * #define GMPy_MPC_New_PROTO (mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) #define GMPy_MPC_NewInit_NUM 27 #define GMPy_MPC_NewInit_RETURN PyObject * #define GMPy_MPC_NewInit_PROTO (PyTypeObject *type, PyObject *args, PyObject *keywds) #define GMPy_MPC_Dealloc_NUM 28 #define GMPy_MPC_Dealloc_RETURN void #define GMPy_MPC_Dealloc_PROTO (MPC_Object *self) /* The following function is found in gmpy2_convert_gmp. */ #define GMPy_MPC_ConvertArg_NUM 29 #define GMPy_MPC_ConvertArg_RETURN int #define GMPy_MPC_ConvertArg_PROTO (PyObject *arg, PyObject **ptr) /* Total number of C-API pointers. */ #define GMPy_API_pointers 30 /* End of C-API definitions. */ #ifdef GMPY2_MODULE /* Define various macros to deal with differences between Python 2 and 3. */ #if (PY_MAJOR_VERSION == 3) #define PY3 #define Py2or3String_FromString PyUnicode_FromString #define Py2or3String_FromFormat PyUnicode_FromFormat #define Py2or3String_Check PyUnicode_Check #define Py2or3String_Format PyUnicode_Format #define Py2or3String_AsString PyUnicode_AS_DATA #define PyStrOrUnicode_Check(op) (PyBytes_Check(op) || PyUnicode_Check(op)) #define PyIntOrLong_FromLong PyLong_FromLong #define PyIntOrLong_Check(op) PyLong_Check(op) #define PyIntOrLong_FromSize_t PyLong_FromSize_t #define PyIntOrLong_FromSsize_t PyLong_FromSsize_t #define PyIntOrLong_AsSsize_t PyLong_AsSsize_t #define PyIntOrLong_AsLong PyLong_AsLong #else #define PY2 #define Py2or3String_FromString PyString_FromString #define Py2or3String_FromFormat PyString_FromFormat #define Py2or3String_Check PyString_Check #define Py2or3String_Format PyString_Format #define Py2or3String_AsString PyString_AsString #define PyStrOrUnicode_Check(op) (PyString_Check(op) || PyUnicode_Check(op)) #define PyIntOrLong_FromLong PyInt_FromLong #define PyIntOrLong_Check(op) (PyInt_Check(op) || PyLong_Check(op)) #define PyIntOrLong_FromSize_t PyInt_FromSize_t #define PyIntOrLong_FromSsize_t PyInt_FromSsize_t #define PyIntOrLong_AsSsize_t PyInt_AsSsize_t #define PyIntOrLong_AsLong PyInt_AsLong #endif #ifndef ABS # define ABS(a) (((a) < 0) ? -(a) : (a)) #endif #if defined(MS_WIN32) && defined(_MSC_VER) /* so one won't need to link explicitly to gmp.lib...: */ # if defined(MPIR) # pragma comment(lib,"mpir.lib") # else # pragma comment(lib,"gmp.lib") # endif # define USE_ALLOCA 1 # define inline __inline #endif #ifdef __GNUC__ # define USE_ALLOCA 1 #endif #ifndef alloca # ifdef __GNUC__ # define alloca __builtin_alloca # else # ifdef _MSC_VER # include # define alloca _alloca # else # if HAVE_ALLOCA_H # include # else char *alloca (); # endif # endif # endif #endif #define ALLOC_THRESHOLD 8192 #define INDEX_ERROR(msg) PyErr_SetString(PyExc_IndexError, msg) #define TYPE_ERROR(msg) PyErr_SetString(PyExc_TypeError, msg) #define VALUE_ERROR(msg) PyErr_SetString(PyExc_ValueError, msg) #define ZERO_ERROR(msg) PyErr_SetString(PyExc_ZeroDivisionError, msg) #define SYSTEM_ERROR(msg) PyErr_SetString(PyExc_SystemError, msg) #define OVERFLOW_ERROR(msg) PyErr_SetString(PyExc_OverflowError, msg) #define RUNTIME_ERROR(msg) PyErr_SetString(PyExc_RuntimeError, msg) #define GMPY_DEFAULT -1 /* To prevent excessive memory usage, we don't want to save very large * numbers in the cache. The default value specified in the options * structure is 128 words (512 bytes on 32-bit platforms, 1024 bytes on * 64-bit platforms). */ #define MAX_CACHE_LIMBS 16384 /* The maximum number of objects that can be saved in a cache is specified * here. The default value is 100.*/ #define MAX_CACHE 1000 #ifdef USE_ALLOCA # define TEMP_ALLOC(B, S) \ if(S < ALLOC_THRESHOLD) { \ B = alloca(S); \ } else { \ if(!(B = malloc(S))) { \ PyErr_NoMemory(); \ return NULL; \ } \ } # define TEMP_FREE(B, S) if(S >= ALLOC_THRESHOLD) free(B) #else # define TEMP_ALLOC(B, S) \ if(!(B = malloc(S))) { \ PyErr_NoMemory(); \ return NULL; \ } # define TEMP_FREE(B, S) free(B) #endif /* Various defs to mask differences between Python versions. */ #define Py_RETURN_NOTIMPLEMENTED \ return Py_INCREF(Py_NotImplemented), Py_NotImplemented #ifndef Py_SIZE # define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) #endif #ifndef Py_TYPE # define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #endif /* Import a collection of general purpose macros. */ #include "gmpy2_macros.h" /* Import the files that complete the definition of the types defined above. */ #include "gmpy2_mpz.h" #include "gmpy2_xmpz.h" #include "gmpy2_mpq.h" #include "gmpy2_mpfr.h" #include "gmpy2_mpc.h" #include "gmpy2_context.h" #include "gmpy2_random.h" /* Import the header files that provide the various functions. */ /* Support object caching, creation, and deletion. */ #include "gmpy2_cache.h" /* Suport for miscellaneous functions (ie. version, license, etc.). */ #include "gmpy2_misc.h" /* Support conversion to/from binary format. */ #include "gmpy2_binary.h" /* Support for mpz/xmpz specific functions. */ #include "gmpy2_convert.h" #include "gmpy2_convert_utils.h" #include "gmpy2_convert_gmp.h" #include "gmpy2_convert_mpfr.h" #include "gmpy2_convert_mpc.h" #include "gmpy2_mpz_divmod.h" #include "gmpy2_mpz_divmod2exp.h" #include "gmpy2_mpz_pack.h" #include "gmpy2_mpz_bitops.h" #include "gmpy2_mpz_inplace.h" #include "gmpy2_mpz_misc.h" #include "gmpy2_xmpz_inplace.h" #include "gmpy2_xmpz_misc.h" /* Support for mpq specific functions. */ #include "gmpy2_mpq_misc.h" /* Support for mpfr specific functions. */ #include "gmpy2_mpfr_misc.h" /* Support for mpc specific functions. */ #include "gmpy2_mpc_misc.h" /* Support Lucas sequences. */ #include "gmpy_mpz_lucas.h" /* Support probable-prime tests. */ #include "gmpy_mpz_prp.h" /* Support higher-level Python methods and functions; generally not * specific to a single type. */ #include "gmpy2_abs.h" #include "gmpy2_add.h" #include "gmpy2_divmod.h" #include "gmpy2_floordiv.h" #include "gmpy2_minus.h" #include "gmpy2_mod.h" #include "gmpy2_mul.h" #include "gmpy2_plus.h" #include "gmpy2_pow.h" #include "gmpy2_sub.h" #include "gmpy2_truediv.h" #include "gmpy2_math.h" #include "gmpy2_const.h" #include "gmpy2_square.h" #include "gmpy2_format.h" #include "gmpy2_hash.h" #include "gmpy2_fused.h" #include "gmpy2_muldiv_2exp.h" #include "gmpy2_predicate.h" #include "gmpy2_sign.h" #include "gmpy2_richcompare.h" #include "gmpy2_cmp.h" #ifdef VECTOR # include "gmpy2_vector.h" #endif /* defined(VECTOR) */ #else /* defined(GMPY2_MODULE) */ /* This section is used for other C-coded modules that use gmpy2's API. */ static void **GMPy_C_API; #define MPZ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPZ_Type_NUM]) #define XMPZ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPZ_Type_NUM]) #define MPQ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPQ_Type_NUM]) #define XMPQ_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPQ_Type_NUM]) #define MPFR_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPFR_Type_NUM]) #define XMPFR_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPFR_Type_NUM]) #define MPC_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[MPC_Type_NUM]) #define XMPC_Check(op) ((op)->ob_type == (PyTypeObject*)GMPy_C_API[XMPC_Type_NUM]) #define GMPy_MPZ_New (*(GMPy_MPZ_New_RETURN (*)GMPy_MPZ_New_PROTO) GMPy_C_API[GMPy_MPZ_New_NUM]) #define GMPy_MPZ_NewInit (*(GMPy_MPZ_NewInit_RETURN (*)GMPy_MPZ_NewInit_PROTO) GMPy_C_API[GMPy_MPZ_NewInit_NUM]) #define GMPy_MPZ_Dealloc (*(GMPy_MPZ_Dealloc_RETURN (*)GMPy_MPZ_Dealloc_PROTO) GMPy_C_API[GMPy_MPZ_Dealloc_NUM]) #define GMPy_MPZ_ConvertArg (*(GMPy_MPZ_ConvertArg_RETURN (*)GMPy_MPZ_ConvertArg_PROTO) GMPy_C_API[GMPy_MPZ_ConvertArg_NUM]) #define GMPy_XMPZ_New (*(GMPy_XMPZ_New_RETURN (*)GMPy_XMPZ_New_PROTO) GMPy_C_API[GMPy_XMPZ_New_NUM]) #define GMPy_XMPZ_NewInit (*(GMPy_XMPZ_NewInit_RETURN (*)GMPy_XMPZ_NewInit_PROTO) GMPy_C_API[GMPy_XMPZ_NewInit_NUM]) #define GMPy_XMPZ_Dealloc (*(GMPy_XMPZ_Dealloc_RETURN (*)GMPy_XMPZ_Dealloc_PROTO) GMPy_C_API[GMPy_XMPZ_Dealloc_NUM]) #define GMPy_MPQ_New (*(GMPy_MPQ_New_RETURN (*)GMPy_MPQ_New_PROTO) GMPy_C_API[GMPy_MPQ_New_NUM]) #define GMPy_MPQ_NewInit (*(GMPy_MPQ_NewInit_RETURN (*)GMPy_MPQ_NewInit_PROTO) GMPy_C_API[GMPy_MPQ_NewInit_NUM]) #define GMPy_MPQ_Dealloc (*(GMPy_MPQ_Dealloc_RETURN (*)GMPy_MPQ_Dealloc_PROTO) GMPy_C_API[GMPy_MPQ_Dealloc_NUM]) #define GMPy_MPQ_ConvertArg (*(GMPy_MPQ_ConvertArg_RETURN (*)GMPy_MPQ_ConvertArg_PROTO) GMPy_C_API[GMPy_MPQ_ConvertArg_NUM]) #define GMPy_MPFR_New (*(GMPy_MPFR_New_RETURN (*)GMPy_MPFR_New_PROTO) GMPy_C_API[GMPy_MPFR_New_NUM]) #define GMPy_MPFR_NewInit (*(GMPy_MPFR_NewInit_RETURN (*)GMPy_MPFR_NewInit_PROTO) GMPy_C_API[GMPy_MPFR_NewInit_NUM]) #define GMPy_MPFR_Dealloc (*(GMPy_MPFR_Dealloc_RETURN (*)GMPy_MPFR_Dealloc_PROTO) GMPy_C_API[GMPy_MPFR_Dealloc_NUM]) #define GMPy_MPFR_ConvertArg (*(GMPy_MPFR_ConvertArg_RETURN (*)GMPy_MPFR_ConvertArg_PROTO) GMPy_C_API[GMPy_MPFR_ConvertArg_NUM]) #define GMPy_MPC_New (*(GMPy_MPC_New_RETURN (*)GMPy_MPC_New_PROTO) GMPy_C_API[GMPy_MPC_New_NUM]) #define GMPy_MPC_NewInit (*(GMPy_MPC_NewInit_RETURN (*)GMPy_MPC_NewInit_PROTO) GMPy_C_API[GMPy_MPC_NewInit_NUM]) #define GMPy_MPC_Dealloc (*(GMPy_MPC_Dealloc_RETURN (*)GMPy_MPC_Dealloc_PROTO) GMPy_C_API[GMPy_MPC_Dealloc_NUM]) #define GMPy_MPC_ConvertArg (*(GMPy_MPC_ConvertArg_RETURN (*)GMPy_MPC_ConvertArg_PROTO) GMPy_C_API[GMPy_MPC_ConvertArg_NUM]) static int import_gmpy2(void) { GMPy_C_API = (void **)PyCapsule_Import("gmpy2._C_API", 0); return (GMPy_C_API != NULL) ? 0 : -1; } #endif /* defined(GMPY2_MODULE) */ #ifdef __cplusplus } #endif /* defined(__cplusplus */ #endif /* !defined(Py_GMPYMODULE_H */ gmpy2-2.1.0b3/src/gmpy2.pxd0000664000175000017500000001111113356026702015210 0ustar casecase00000000000000cdef extern from "gmp.h": # gmp integers ctypedef long mp_limb_t ctypedef struct __mpz_struct: int _mp_alloc int _mp_size mp_limb_t* _mp_d ctypedef __mpz_struct mpz_t[1] ctypedef __mpz_struct *mpz_ptr ctypedef const __mpz_struct *mpz_srcptr # gmp rationals ctypedef struct __mpq_struct: __mpz_struct _mp_num __mpz_struct _mp_den ctypedef __mpq_struct mpq_t[1] ctypedef __mpq_struct *mpq_ptr ctypedef const __mpq_struct *mpq_srcptr void mpz_set(mpz_t rop, mpz_t op) void mpq_set(mpq_ptr rop, mpq_srcptr op) void mpq_set_num(mpq_t rational, mpz_t numerator) void mpq_set_den(mpq_t rational, mpz_t denominator) cdef extern from "mpfr.h": # mpfr reals ctypedef int mpfr_sign_t ctypedef long mpfr_prec_t ctypedef long mpfr_exp_t ctypedef struct __mpfr_struct: mpfr_prec_t _mpfr_prec mpfr_sign_t _mpfr_sign mpfr_exp_t _mpfr_exp mp_limb_t* _mpfr_d ctypedef __mpfr_struct mpfr_t[1] ctypedef __mpfr_struct *mpfr_ptr ctypedef const __mpfr_struct *mpfr_srcptr ctypedef enum mpfr_rnd_t: MPFR_RNDN MPFR_RNDZ MPFR_RNDU MPFR_RNDD MPFR_RNDA MPFR_RNDF MPFR_RNDNA mpfr_prec_t mpfr_get_prec(mpfr_t x) int mpfr_set(mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd) cdef extern from "mpc.h": # mpc complexes ctypedef struct __mpc_struct: mpfr_t re mpfr_t im ctypedef __mpc_struct mpc_t[1]; ctypedef __mpc_struct *mpc_ptr; ctypedef const __mpc_struct *mpc_srcptr; ctypedef enum mpc_rnd_t: MPC_RNDNN MPC_RNDNZ MPC_RNDNU MPC_RNDND MPC_RNDZN MPC_RNDZZ MPC_RNDZU MPC_RNDZD MPC_RNDUN MPC_RNDUZ MPC_RNDUU MPC_RNDUD MPC_RNDDN MPC_RNDDZ MPC_RNDDU MPC_RNDDD mpfr_prec_t mpc_get_prec(mpc_srcptr x) void mpc_get_prec2(mpfr_prec_t *pr, mpfr_prec_t *pi, mpc_srcptr x) int mpc_set(mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) int mpc_set_fr_fr(mpc_ptr rop, mpfr_srcptr rp, mpfr_srcptr ip, mpc_rnd_t rnd) cdef extern from "gmpy2.h": # Initialize the C-API # This must be called before any other functions, but not to access # the types. cdef int import_gmpy2() except -1 # Object types ctypedef class gmpy2.mpz [object MPZ_Object]: cdef mpz_t z ctypedef class gmpy2.mpq [object MPQ_Object]: cdef mpq_t q ctypedef class gmpy2.mpfr [object MPFR_Object]: cdef mpfr_t f cdef int rc ctypedef class gmpy2.mpc [object MPC_Object]: cdef mpc_t c cdef int rc # Object creation cdef mpz GMPy_MPZ_New(void *) cdef mpq GMPy_MPQ_New(void *) cdef mpfr GMPy_MPFR_New(mpfr_prec_t prec, void *) cdef mpc GMPy_MPC_New(mpfr_prec_t rprec, mpfr_prec_t iprec, void *) # C field access cdef mpz_t MPZ(mpz) cdef mpq_t MPQ(mpq) cdef mpfr_t MPFR(mpfr) cdef mpc_t MPC(mpc) # Type check cdef bint MPZ_Check(object) cdef bint MPQ_Check(object) cdef bint MPFR_Check(object) cdef bint MPC_Check(object) # Build a gmpy2 mpz from a gmp mpz cdef inline mpz GMPy_MPZ_From_mpz(mpz_srcptr z): cdef mpz res = GMPy_MPZ_New(NULL) mpz_set(res.z, z) return res # Build a gmpy2 mpq from a gmp mpq cdef inline mpq GMPy_MPQ_From_mpq(mpq_srcptr q): cdef mpq res = GMPy_MPQ_New(NULL) mpq_set(res.q, q) return res # Build a gmpy2 mpq from gmp mpz numerator and denominator cdef inline mpq GMPy_MPQ_From_mpz(mpz_srcptr num, mpz_srcptr den): cdef mpq res = GMPy_MPQ_New(NULL) mpq_set_num(res.q, num) mpq_set_den(res.q, den) return res # Build a gmpy2 mpfr from a mpfr cdef inline mpfr GMPy_MPFR_From_mpfr(mpfr_srcptr x): cdef mpfr res = GMPy_MPFR_New(mpfr_get_prec(x), NULL) mpfr_set(res.f, x, MPFR_RNDN) return res # Build a gmpy2 mpc from a mpc cdef inline mpc GMPy_MPC_From_mpc(mpc_srcptr c): cdef mpfr_prec_t pr cdef mpfr_prec_t pi mpc_get_prec2(&pr, &pi, c) cdef mpc res = GMPy_MPC_New(pr, pi, NULL) mpc_set(res.c, c, MPC_RNDNN) return res # Build a gmpy2 mpc from a real part mpfr and an imaginary part mpfr cdef inline mpc GMPy_MPC_From_mpfr(mpfr_srcptr re, mpfr_srcptr im): cdef mpc res = GMPy_MPC_New(mpfr_get_prec(re), mpfr_get_prec(im), NULL) # We intentionally use MPFR funtions instead of MPC functions here # in order not to add an unneeded dependency on MPC. It's probably # faster too this way. mpfr_set(res.c.re, re, MPFR_RNDN) mpfr_set(res.c.im, im, MPFR_RNDN) return res gmpy2-2.1.0b3/src/gmpy2_abs.c0000664000175000017500000001550713425751027015503 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_abs.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements __abs__, gmpy2.abs(), and context.abs(). * * Public API * ========== * The following function is available as part of GMPY2's C API. If the value * of context is NULL, then the function should use the currently active * context. * * GMPy_Number_Abs(Number, context) * * Private API * =========== * GMPy_MPZ_Abs_Slot * GMPy_MPQ_Abs_Slot * GMPy_MPFR_Abs_Slot * GMPy_MPC_Abs_Slot * * GMPy_Integer_Abs(Integer, context|NULL) * GMPy_Rational_Abs(Rational, context|NULL) * GMPy_Real_Abs(Real, context|NULL) * GMPy_Complex_Abs(Complex, context|NULL) * * GMPy_Context_Abs(context, obj) */ static PyObject * GMPy_Integer_Abs(PyObject *x, CTXT_Object *context) { MPZ_Object *result = NULL; if (MPZ_Check(x)) { if (mpz_sgn(MPZ(x)) >= 0) { Py_INCREF(x); return x; } else { if ((result = GMPy_MPZ_New(context))) mpz_abs(result->z, MPZ(x)); return (PyObject*)result; } } /* This is safe because result is not an incremented reference to an * existing value. Why? * 1) No values are interned like Python's integers. * 2) MPZ is already handled so GMPy_MPZ_From_Integer() can't return * an incremented reference to an existing value (which it would do * if passed an MPZ). */ if ((result = GMPy_MPZ_From_Integer(x, context))) { mpz_abs(result->z, result->z); } return (PyObject*)result; } static PyObject * GMPy_MPZ_Abs_Slot(MPZ_Object *x) { return GMPy_Integer_Abs((PyObject*)x, NULL); } static PyObject * GMPy_Rational_Abs(PyObject *x, CTXT_Object *context) { MPQ_Object *result = NULL; if (MPQ_Check(x)) { if (mpz_sgn(mpq_numref(MPQ(x))) >= 0) { Py_INCREF(x); return x; } else { if ((result = GMPy_MPQ_New(context))) { mpq_set(result->q, MPQ(x)); mpz_abs(mpq_numref(result->q), mpq_numref(result->q)); } return (PyObject*)result; } } /* This is safe because result is not an incremented reference to an * existing value. MPQ is already handled so GMPy_MPQ_From_Rational() * can't return an incremented reference to an existing value (which it * would do if passed an MPQ). */ if ((result = GMPy_MPQ_From_Rational(x, context))) { mpz_abs(mpq_numref(result->q), mpq_numref(result->q)); } return (PyObject*)result; } static PyObject * GMPy_MPQ_Abs_Slot(MPQ_Object *x) { return GMPy_Rational_Abs((PyObject*)x, NULL); } static PyObject * GMPy_Real_Abs(PyObject *x, CTXT_Object *context) { MPFR_Object *result = NULL, *tempx = NULL; CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_abs(result->f, tempx->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_MPFR_Abs_Slot(MPFR_Object *x) { return GMPy_Real_Abs((PyObject*)x, NULL); } static PyObject * GMPy_Complex_Abs(PyObject *x, CTXT_Object *context) { MPFR_Object *result = NULL; MPC_Object *tempx = NULL; CHECK_CONTEXT(context); if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context)) || !(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpc_abs(result->f, tempx->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_MPC_Abs_Slot(MPC_Object *x) { return GMPy_Complex_Abs((PyObject*)x, NULL); } static PyObject * GMPy_Number_Abs(PyObject *x, CTXT_Object *context) { if (IS_INTEGER(x)) return GMPy_Integer_Abs(x, context); if (IS_RATIONAL_ONLY(x)) return GMPy_Rational_Abs(x, context); if (IS_REAL_ONLY(x)) return GMPy_Real_Abs(x, context); if (IS_COMPLEX_ONLY(x)) return GMPy_Complex_Abs(x, context); TYPE_ERROR("abs() argument type not supported"); return NULL; } /* Implement context.abs(). The following code assumes it used a as method of * a context. */ PyDoc_STRVAR(GMPy_doc_context_abs, "context.abs(x) -> number\n\n" "Return abs(x), the context is applied to the result."); static PyObject * GMPy_Context_Abs(PyObject *self, PyObject *other) { return GMPy_Number_Abs(other, (CTXT_Object*)self); } gmpy2-2.1.0b3/src/gmpy2_abs.h0000664000175000017500000000546413425751631015512 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_abs.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_ABS_H #define GMPY2_ABS_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_Abs(PyObject *x, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_Abs(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Rational_Abs(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Real_Abs(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Abs(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPZ_Abs_Slot(MPZ_Object *x); static PyObject * GMPy_MPQ_Abs_Slot(MPQ_Object *x); static PyObject * GMPy_MPFR_Abs_Slot(MPFR_Object *x); static PyObject * GMPy_MPC_Abs_Slot(MPC_Object *x); static PyObject * GMPy_Context_Abs(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_add.c0000664000175000017500000004244513425751130015462 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_add.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements the + operator, gmpy2.add(), and context.add(). * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL * value for context implies the function should use the currently active * context. * * GMPy_Number_Add(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPZ_Add_Slot * GMPy_MPQ_Add_Slot * GMPy_MPFR_Add_Slot * GMPy_MPC_Add_Slot * * GMPy_Integer_Add(Integer, Integer, context|NULL) * GMPy_Rational_Add(Rational, Rational, context|NULL) * GMPy_Real_Add(Real, Real, context|NULL) * GMPy_Complex_Add(Complex, Complex, context|NULL) * * GMPy_Context_Add(context, args) * */ /* Add two Integer objects (see gmpy2_convert.h). If an error occurs, NULL * is returned and an exception is set. If either x or y can't be converted * into an mpz, Py_NotImplemented is returned. */ static PyObject * GMPy_Integer_Add(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPZ_Check(x)) { if (PyIntOrLong_Check(y)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(y, &error); if (!error) { if (temp >= 0) { mpz_add_ui(result->z, MPZ(x), temp); } else { mpz_sub_ui(result->z, MPZ(x), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, y); mpz_add(result->z, MPZ(x), global.tempz); } return (PyObject*)result; } if (MPZ_Check(y)) { mpz_add(result->z, MPZ(x), MPZ(y)); return (PyObject*)result; } } if (MPZ_Check(y)) { if (PyIntOrLong_Check(x)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(x, &error); if (!error) { if (temp >= 0) { mpz_add_ui(result->z, MPZ(y), temp); } else { mpz_sub_ui(result->z, MPZ(y), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, x); mpz_add(result->z, MPZ(y), global.tempz); } return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { MPZ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPZ_From_Integer(x, context)) || !(tempy = GMPy_MPZ_From_Integer(y, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpz_add(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Integer_Add()."); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } /* Implement __add__ for MPZ_Object. On entry, one of the two arguments must * be an MPZ_Object. If the other object is an Integer, add and return an * MPZ_Object. If the other object isn't an MPZ_Object, call the appropriate * function. If no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPZ_Add_Slot(PyObject *x, PyObject *y) { if (MPZ_Check(x) && MPZ_Check(y)) { MPZ_Object *result = NULL; if ((result = GMPy_MPZ_New(NULL))) { mpz_add(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Add(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Add(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Add(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Add(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* Add two Rational objects (see gmpy2_convert.h). Returns None and * raises TypeError if both objects are not valid rationals. GMPy_Rational_Add * is intended to be called from GMPy_Number_Add(). */ static PyObject * GMPy_Rational_Add(PyObject *x, PyObject *y, CTXT_Object *context) { MPQ_Object *result = NULL; if (!(result = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPQ_Check(x) && MPQ_Check(y)) { mpq_add(result->q, MPQ(x), MPQ(y)); return (PyObject*)result; } if (IS_RATIONAL(x) && IS_RATIONAL(y)) { MPQ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPQ_From_Number(x, context)) || !(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpq_add(result->q, tempx->q, tempy->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Rational_Add()."); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } /* Implement __add__ for Pympq. On entry, one of the two arguments must * be a Pympq. If the other object is a Rational, add and return a Pympq. * If the other object isn't a Pympq, call the appropriate function. If * no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPQ_Add_Slot(PyObject *x, PyObject *y) { if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Add(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Add(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Add(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* Addition can be performed by the equivalent of mpfr.__add__ or by * gmpy2.add(). * * GMPy_Real_Add(x, y, context) returns x+y using the provided context. If * provided context is NULL, then the current context is used. If an error * occurs, NULL is returned and an exception is set. If either x or y can't * be converted to an mpfr, then Py_NotImplemented is returned. * GMPy_Real_Add() will not try to promote the result to a different type * (i.e. mpc). * * GMPy_mpfr_add_fast(x, y) is the entry point for mpfr.__add__. */ /* Attempt to add two numbers and return an mpfr. The code path is optimized by * checking for mpfr objects first. Returns Py_NotImplemented if both objects * are not valid reals. */ static PyObject * GMPy_Real_Add(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPFR_Check(x)) { if (MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_add(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_add_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, y); mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy = NULL; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_add_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_add_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long temp = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_add_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, x); mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(y), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(x)) { mpfr_clear_flags(); result->rc = mpfr_add_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(x)) { MPQ_Object *tempx = NULL; if (!(tempx = GMPy_MPQ_From_Number(x, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_add_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); goto done; } if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_add_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context)); goto done; } } if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_add(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Real_Add()."); return NULL; /* LCOV_EXCL_STOP */ done: _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } /* Implement __add__ for Pympfr. On entry, one of the two arguments must * be a Pympfr. If the other object is a Real, add and return a Pympfr. * If the other object isn't a Pympfr, call the appropriate function. If * no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPFR_Add_Slot(PyObject *x, PyObject *y) { if ((MPFR_Check(x)) && MPFR_Check(y)) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_add(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Add(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Add(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* GMPy_Complex_Add(x, y, context) returns x+y using the provided context. If * context is NULL, then the current context is used. If an error occurs, NULL * is returned and an exception is set. If either x or y can't be converted to * an mpc, then Py_NotImplemented is returned. */ static PyObject * GMPy_Complex_Add(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPC_Check(x) && MPC_Check(y)) { result->rc = mpc_add(result->c, MPC(x), MPC(y), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } if (IS_COMPLEX(x) && IS_COMPLEX(y)) { MPC_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context)) || !(tempy = GMPy_MPC_From_Complex(y, 1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } result->rc = mpc_add(result->c, tempx->c, tempy->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Complex_Add()."); return NULL; /* LCOV_EXCL_STOP */ } /* GMPy_MPC_Add_Slot() is called by mpc.__add__. It just gets a borrowed reference * to the current context and call Pympc_Add_Complex(). Since mpc is the last * step of the numeric ladder, the NotImplemented return value from * Pympc_Add_Complex() is correct and is just passed on. */ static PyObject * GMPy_MPC_Add_Slot(PyObject *x, PyObject *y) { if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Add(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Number_Add(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Add(x, y, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Add(x, y, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Add(x, y, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Add(x, y, context); TYPE_ERROR("add() argument type not supported"); return NULL; } /* Implement context.add() and gmpy2.add(). */ PyDoc_STRVAR(GMPy_doc_function_add, "add(x, y) -> number\n\n" "Return x + y."); PyDoc_STRVAR(GMPy_doc_context_add, "context.add(x, y) -> number\n\n" "Return x + y."); static PyObject * GMPy_Context_Add(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("add() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Add(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_add.h0000664000175000017500000000564013425751160015466 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_add.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_ADD_H #define GMPY2_ADD_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_Add(PyObject *x, PyObject *y, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_Add(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Rational_Add(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Real_Add(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_Add(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPZ_Add_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPQ_Add_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPFR_Add_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPC_Add_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_Context_Add(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_binary.c0000664000175000017500000012234113425751237016220 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_binary.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Conversion routines between GMPY2 objects and a compact, portable * binary representation. The binary format of GMPY2 is not compatible * with GMPY 1.x. Methods to read the old format are provided. */ /* Provide functions to access the old binary formats. */ PyDoc_STRVAR(doc_mpz_from_old_binary, "mpz_from_old_binary(string) -> mpz\n\n" "Return an 'mpz' from a GMPY 1.x binary format."); static PyObject * GMPy_MPZ_From_Old_Binary(PyObject *self, PyObject *other) { unsigned char *cp; Py_ssize_t len; int negative = 0; MPZ_Object *result; if (!(PyBytes_Check(other))) { TYPE_ERROR("mpz_from_old_binary() requires bytes argument"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } len = PyBytes_Size(other); cp = (unsigned char*)PyBytes_AsString(other); if (cp[len-1] == 0xFF) { negative = 1; --len; } mpz_import(result->z, len, -1, sizeof(char), 0, 0, cp); if (negative) mpz_neg(result->z, result->z); return (PyObject*)result; } PyDoc_STRVAR(doc_mpq_from_old_binary, "mpq_from_old_binary(string) -> mpq\n\n" "Return an 'mpq' from a GMPY 1.x binary format."); static PyObject * GMPy_MPQ_From_Old_Binary(PyObject *self, PyObject *other) { unsigned char *cp; Py_ssize_t len; int topper, negative, numlen; mpz_t numerator, denominator; MPQ_Object *result; if (!(PyBytes_Check(other))) { TYPE_ERROR("mpq_from_old_binary() requires bytes argument"); return NULL; } if (!(result = GMPy_MPQ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } len = PyBytes_Size(other); cp = (unsigned char*)PyBytes_AsString(other); if (len < 6) { VALUE_ERROR("invalid mpq binary (too short)"); Py_DECREF((PyObject*)result); return NULL; } topper = cp[3] & 0x7f; negative = cp[3] & 0x80; numlen = cp[0] + 256 * (cp[1] + 256 * (cp[2] + 256 * topper)); if (len < (4 + numlen + 1)) { VALUE_ERROR("invalid mpq binary (num len)"); Py_DECREF((PyObject*)result); return NULL; } mpz_init(numerator); mpz_init(denominator); mpz_import(numerator, numlen, -1, sizeof(char), 0, 0, cp+4); mpz_import(denominator, len-4-numlen, -1, sizeof(char), 0, 0, cp+4+numlen); if (negative) mpz_neg(numerator, numerator); mpq_set_num(result->q, numerator); mpq_set_den(result->q, denominator); mpq_canonicalize(result->q); mpz_clear(numerator); mpz_clear(denominator); return (PyObject*)result; } PyDoc_STRVAR(doc_mpfr_from_old_binary, "mpfr_from_old_binary(string) -> mpfr\n\n" "Return an 'mpfr' from a GMPY 1.x binary mpf format."); static PyObject * GMPy_MPFR_From_Old_Binary(PyObject *self, PyObject *other) { unsigned char *cp; Py_ssize_t len; MPFR_Object *result; mpfr_t digit; mpfr_prec_t prec; int i, codebyte, resusign, exposign, resuzero, precilen; unsigned int expomag = 0; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(PyBytes_Check(other))) { TYPE_ERROR("mpfr_from_old_binary() requires bytes argument"); return NULL; } len = PyBytes_Size(other); cp = (unsigned char*)PyBytes_AsString(other); if (len == 1) { prec = 0; } else { prec = (mpfr_prec_t)(8 * (len - 5)); if ((len>=5) && (cp[0]&8)) { prec = 0; for (i=4; i>0; --i) { prec = (prec << 8) | cp[i]; } } } /* * binary format for MP floats: first, a code-byte, then, a LSB * 4-byte unsigned int (exponent magnitude), then the "mantissa" * (actually, "significand", but "mantissa" is the usual term...) * in MSB form. * * The codebyte encodes both the signs, exponent and result, or * also the zeroness of the result (in which case, nothing more). */ codebyte = cp[0]; resusign = codebyte & 1; exposign = codebyte & 2; resuzero = codebyte & 4; precilen = (codebyte & 8)?4:0; /* mpfr zero has a very compact (1-byte) binary encoding!-) */ if (resuzero) { if (!(result = GMPy_MPFR_New(prec, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } result->rc = mpfr_set_ui(result->f, 0, MPFR_RNDN); return (PyObject*)result; } /* all other numbers are 6+ bytes: codebyte, 4-byte exp, 1+ * bytes for the mantissa; check this string is 6+ bytes */ if (len < 6 + precilen) { VALUE_ERROR("invalid mpf binary encoding (too short)"); return NULL; } if (!(result = GMPy_MPFR_New(prec, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } /* reconstruct exponent */ for (i = 4 + precilen; i > precilen; --i) { expomag = (expomag<<8) | cp[i]; } /* reconstruct 'mantissa' (significand) */ mpfr_set_si(result->f, 0, MPFR_RNDN); mpfr_init2(digit, prec); for (i = 5 + precilen; ictx.mpfr_round); mpfr_add(result->f, result->f, digit, MPFR_RNDN); } mpfr_clear(digit); /* apply exponent, with its appropriate sign */ if (exposign) mpfr_div_2ui(result->f, result->f, 8*expomag, MPFR_RNDN); else mpfr_mul_2ui(result->f, result->f, 8*expomag, MPFR_RNDN); /* apply significand-sign (sign of the overall number) */ if (resusign) mpfr_neg(result->f, result->f, MPFR_RNDN); return (PyObject*)result; } /* Format of the binary representation of an mpz/xmpz. * * byte[0]: 1 => mpz * 2 => xmpz * 3 => mpq (see Pympq_To_Binary) * 4 => mpfr (see Pympfr_To_Binary) * 5 => mpc (see Pympc_To_Binary) * byte[1:0-1]: 0 => value is 0 * 1 => value is > 0 * 2 => value is < 0 * 3 => unassigned * byte[2]+: value */ static PyObject * GMPy_MPZ_To_Binary(MPZ_Object *self) { size_t size = 2; int sgn; char *buffer; PyObject *result; sgn = mpz_sgn(self->z); if (sgn == 0) { TEMP_ALLOC(buffer, size); buffer[0] = 0x01; buffer[1] = 0x00; goto done; } size = ((mpz_sizeinbase(self->z, 2) + 7) / 8) + 2; TEMP_ALLOC(buffer, size); buffer[0] = 0x01; if (sgn > 0) buffer[1] = 0x01; else buffer[1] = 0x02; mpz_export(buffer+2, NULL, -1, sizeof(char), 0, 0, self->z); done: result = PyBytes_FromStringAndSize(buffer, size); TEMP_FREE(buffer, size); return result; } static PyObject * GMPy_XMPZ_To_Binary(XMPZ_Object *self) { size_t size = 2; int sgn; char *buffer; PyObject *result; sgn = mpz_sgn(self->z); if (sgn == 0) { TEMP_ALLOC(buffer, size); buffer[0] = 0x02; buffer[1] = 0x00; goto done; } size = ((mpz_sizeinbase(self->z, 2) + 7) / 8) + 2; TEMP_ALLOC(buffer, size); buffer[0] = 0x02; if (sgn > 0) buffer[1] = 0x01; else buffer[1] = 0x02; mpz_export(buffer+2, NULL, -1, sizeof(char), 0, 0, self->z); done: result = PyBytes_FromStringAndSize(buffer, size); TEMP_FREE(buffer, size); return result; } /* Format of the binary representation of an mpq. * * byte[0]: 1 => mpz (see Pympz_To_Binary) * 2 => xmpz (see Pyxmpz_To_Binary) * 3 => mpq * 4 => mpfr (see Pympfr_To_Binary) * 5 => mpc (see Pympc_To_Binary) * byte[1:0-1]: 0 => value is 0 * 1 => value is > 0 * 2 => value is < 0 * 3 => unassigned * byte[1:2-2]: 0 => 32-bit length (n=4) * 1 => 64-bit length (n=8) * byte[2+]: numerator length, using either 4 or 8 bytes * byte[2+n]+: numerator, followed by denominator */ static PyObject * GMPy_MPQ_To_Binary(MPQ_Object *self) { size_t sizenum, sizeden, sizesize = 4, size = 2, sizetemp, i; size_t count = 0; int sgn; char *buffer, large = 0x00; PyObject *result = 0; sgn = mpq_sgn(self->q); if (sgn == 0) { TEMP_ALLOC(buffer, size); buffer[0] = 0x03; buffer[1] = 0x00; goto done; } sizenum = (mpz_sizeinbase(mpq_numref(self->q), 2) + 7) / 8; sizeden = (mpz_sizeinbase(mpq_denref(self->q), 2) + 7) / 8; size = sizenum + sizeden + 2; /* Check if sizenum larger than 32 bits. */ if ((sizenum >> 16) >> 16) { /* Current versions of GMP do not allow values to be this large. The * test is left to (possibly) support future versions that support * larger values. */ /* LCOV_EXCL_START */ large = 0x04; sizesize = 8; /* LCOV_EXCL_STOP */ } size += sizesize; TEMP_ALLOC(buffer, size); buffer[0] = 0x03; if (sgn > 0) buffer[1] = 0x01 | large; else buffer[1] = 0x02 | large; /* Copy sizenum to the buffer. */ sizetemp = sizenum; for (i=0; i>= 8; } mpz_export(buffer+sizesize+2, &count, -1, sizeof(char), 0, 0, mpq_numref(self->q)); if (count != sizenum) { /* LCOV_EXCL_START */ SYSTEM_ERROR("internal error in Pympq_To_Binary"); TEMP_FREE(buffer, size); return NULL; /* LCOV_EXCL_STOP */ } count = 0; mpz_export(buffer+sizenum+sizesize+2, &count, -1, sizeof(char), 0, 0, mpq_denref(self->q)); if (count != sizeden) { /* LCOV_EXCL_START */ SYSTEM_ERROR("internal error in Pympq_To_Binary"); TEMP_FREE(buffer, size); return NULL; /* LCOV_EXCL_STOP */ } done: result = PyBytes_FromStringAndSize(buffer, size); TEMP_FREE(buffer, size); return result; } /* Format of the binary representation of an mpfr. * * byte[0]: 1 => mpz (see Pympz_To_Binary) * 2 => xmpz (see Pyxmpz_To_Binary) * 3 => mpq (see Pympq_To_Binary) * 4 => mpfr * 5 => mpc (see Pympc_To_Binary) * byte[1:0]: 0 => value is "special" * 1 => value is an actual number * byte[1:1]: 0 => signbit is clear * 1 => signbit is set * byte[1:2-2]: 0 => 32-bit lengths (n=4) * 1 => 64-bit lengths (n=8) * byte[1:3-4]: 0 => 0 (see signbit) * 1 => value is NaN * 2 => value is Inf (see signbit) * 3 => unassigned * byte[1:5]: 0 => exponent is positive * 1 => exponent is negative * byte[1:6]: 0 => 4 byte limbs * 1 => 8 byte limbs * byte[2]: 0 => rc = 0 * 1 => rc > 0 * 2 => rc < 0 * byte[3]: mpfr.round_mode * byte[4]+: precision, saved in 4 or 8 bytes * byte[4+n]+: exponent, saved in 4 or 8 bytes * byte[4+2n]+: mantissa */ static PyObject * GMPy_MPFR_To_Binary(MPFR_Object *self) { size_t sizemant = 0, sizesize = 4, size = 4, sizetemp, i; mp_limb_t templimb; mpfr_prec_t precision; mpfr_exp_t exponent = 0; int sgn; char *buffer, *cp, large = 0x00, expsgn = 0x00; PyObject *result = 0; /* Check if the precision, exponent and mantissa length can fit in * 32 bits. */ sgn = mpfr_signbit(self->f); precision = mpfr_get_prec(self->f); /* Exponent and mantiss are only valid for regular numbers * (not 0, Nan, Inf, -Inf). */ if (mpfr_regular_p(self->f)) { exponent = self->f->_mpfr_exp; if (exponent < 0) { exponent = -exponent; expsgn = 0x20; } /* Calculate the size of mantissa in limbs */ sizemant = (self->f->_mpfr_prec + mp_bits_per_limb - 1)/mp_bits_per_limb; } if (((exponent >> 16) >> 16) || ((precision >> 16) >> 16) || ((sizemant >> 16) >> 16)) { /* This can only be tested on 64-bit platforms. lcov will report the * code as not tested until 64-bit specific tests are created. */ sizesize = 8; large = 0x04; } if (!mpfr_regular_p(self->f)) { /* Only need to save the precision. */ size += sizesize; TEMP_ALLOC(buffer, size); buffer[0] = 0x04; /* Set to all 0 since we are special. */ buffer[1] = 0x00; /* Set the sign bit. */ if (sgn) buffer[1] |= 0x02; /* 4 or 8 byte values. */ buffer[1] |= large; /* Check if NaN. */ if (mpfr_nan_p(self->f)) buffer[1] |= 0x08; /* Check if Infinity. */ if (mpfr_inf_p(self->f)) buffer[1] |= 0x10; /* Save the result code */ if (self->rc == 0) buffer[2] = 0x00; else if (self->rc > 0) buffer[2] = 0x01; else buffer[2] = 0x02; /* Save the precision */ sizetemp = precision; for (i=0; i>= 8; } goto done; } /* Now process all actual numbers. */ size += (2 * sizesize) + (sizemant * (mp_bits_per_limb >> 3)); TEMP_ALLOC(buffer, size); buffer[0] = 0x04; /* Set bit 0 to 1 since we are an actual number. */ buffer[1] = 0x01; /* Save the sign bit. */ if (sgn) buffer[1] |= 0x02; /* Save the size of the values. */ buffer[1] |= large; /* Save the exponent sign. */ buffer[1] |= expsgn; /* Save the limb size. */ if ((mp_bits_per_limb >> 3) == 8) buffer[1] |= 0x40; /* This branch can only be reached on 32-bit platforms. */ else if ((mp_bits_per_limb >> 3) != 4) { /* LCOV_EXCL_START */ SYSTEM_ERROR("cannot support current limb size"); TEMP_FREE(buffer, size); return NULL; /* LCOV_EXCL_STOP */ } /* Save the result code. */ if (self->rc == 0) buffer[2] = 0x00; else if (self->rc > 0) buffer[2] = 0x01; else buffer[2] = 0x02; /* Rounding mode is no longer used, so just store a null byte. */ buffer[3] = 0x00; /* Save the precision */ cp = buffer + 4; sizetemp = precision; for (i=0; i>= 8; } /* Save the exponenet */ cp += sizesize; sizetemp = exponent; for (i=0; i>= 8; } /* Save the actual mantissa */ cp += sizesize; for (i=0; if->_mpfr_d[i]; #if GMP_LIMB_BITS == 64 cp[0] = (char)(templimb & 0xff); templimb >>= 8; cp[1] = (char)(templimb & 0xff); templimb >>= 8; cp[2] = (char)(templimb & 0xff); templimb >>= 8; cp[3] = (char)(templimb & 0xff); templimb >>= 8; cp[4] = (char)(templimb & 0xff); templimb >>= 8; cp[5] = (char)(templimb & 0xff); templimb >>= 8; cp[6] = (char)(templimb & 0xff); templimb >>= 8; cp[7] = (char)(templimb & 0xff); cp += 8; #endif #if GMP_LIMB_BITS == 32 cp[0] = (char)(templimb & 0xff); templimb >>= 8; cp[1] = (char)(templimb & 0xff); templimb >>= 8; cp[2] = (char)(templimb & 0xff); templimb >>= 8; cp[3] = (char)(templimb & 0xff); cp += 4; #endif } done: result = PyBytes_FromStringAndSize(buffer, size); TEMP_FREE(buffer, size); return result; } /* Format of the binary representation of an mpc. * * The format consists of the concatenation of mpfrs (real and imaginary) * converted to binary format. The 0x04 leading byte of each binary string * is replaced by 0x05. */ static PyObject * GMPy_MPC_To_Binary(MPC_Object *obj) { MPFR_Object *real = NULL, *imag = NULL; PyObject *result = NULL, *temp = NULL; mpfr_prec_t rprec = 0, iprec = 0; CTXT_Object *context = NULL; CHECK_CONTEXT(context); mpc_get_prec2(&rprec, &iprec, obj->c); if (!(real = GMPy_MPFR_New(rprec, context)) || !(imag = GMPy_MPFR_New(iprec, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)real); Py_XDECREF((PyObject*)imag); return NULL; /* LCOV_EXCL_STOP */ } mpfr_set(real->f, mpc_realref(obj->c), MPFR_RNDN); mpfr_set(imag->f, mpc_imagref(obj->c), MPFR_RNDN); real->rc = obj->rc; if (!(result = GMPy_MPFR_To_Binary(real)) || !(temp = GMPy_MPFR_To_Binary(imag))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)temp); Py_DECREF((PyObject*)real); Py_DECREF((PyObject*)imag); return NULL; /* LCOV_EXCL_STOP */ } Py_DECREF((PyObject*)real); Py_DECREF((PyObject*)imag); PyBytes_AS_STRING(result)[0] = 0x05; PyBytes_AS_STRING(temp)[0] = 0x05; PyBytes_ConcatAndDel(&result, temp); return result; } PyDoc_STRVAR(doc_from_binary, "from_binary(bytes) -> gmpy2 object\n" "Return a Python object from a byte sequence created by\n" "gmpy2.to_binary()."); static PyObject * GMPy_MPANY_From_Binary(PyObject *self, PyObject *other) { unsigned char *buffer, *cp; Py_ssize_t len; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(PyBytes_Check(other))) { TYPE_ERROR("from_binary() requires bytes argument"); return NULL; } len = PyBytes_Size(other); if (len < 2) { VALUE_ERROR("byte sequence too short for from_binary()"); return NULL; } buffer = (unsigned char*)PyBytes_AsString(other); cp = buffer; switch (cp[0]) { case 0x01: { MPZ_Object *result; if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (cp[1] == 0x00) { mpz_set_ui(result->z, 0); return (PyObject*)result; } mpz_import(result->z, len-2, -1, sizeof(char), 0, 0, cp+2); if (cp[1] == 0x02) mpz_neg(result->z, result->z); return (PyObject*)result; break; } case 0x02: { XMPZ_Object *result; if (!(result = GMPy_XMPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (cp[1] == 0x00) { mpz_set_ui(result->z, 0); return (PyObject*)result; } mpz_import(result->z, len-2, -1, sizeof(char), 0, 0, cp+2); if (cp[1] == 0x02) mpz_neg(result->z, result->z); return (PyObject*)result; break; } case 0x03: { MPQ_Object *result; Py_ssize_t numlen = 0, sizesize = 4, i; mpz_t num, den; if (!(result = GMPy_MPQ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (cp[1] == 0x00) { mpq_set_ui(result->q, 0, 1); return (PyObject*)result; } if (cp[1] & 0x04) sizesize = 8; if (len < 2 + sizesize) { VALUE_ERROR("byte sequence too short for from_binary()"); return NULL; } for (i=sizesize; i>0; --i) { numlen = (numlen << 8) + cp[i+1]; } if (len < 2 + sizesize + numlen + 1) { VALUE_ERROR("byte sequence too short for from_binary()"); return NULL; } mpz_init(num); mpz_init(den); mpz_import(num, numlen, -1, sizeof(char), 0, 0, cp+sizesize+2); mpz_import(den, len-numlen-sizesize-2, -1, sizeof(char), 0, 0, cp+sizesize+numlen+2); mpq_set_num(result->q, num); mpq_set_den(result->q, den); mpq_canonicalize(result->q); mpz_clear(num); mpz_clear(den); if (cp[1] == 0x02) mpq_neg(result->q, result->q); return (PyObject*)result; break; } case 0x04: { MPFR_Object *result; Py_ssize_t sizemant = 0, sizesize = 4, i, newmant; mpfr_prec_t precision = 0; mpfr_exp_t exponent = 0; mp_limb_t templimb; int sgn = 1, expsgn = 1, limbsize = 4; int newlimbsize = (mp_bits_per_limb >> 3); if (len < 4) { VALUE_ERROR("byte sequence too short for from_binary()"); return NULL; } /* Get size of values. */ if (cp[1] & 0x04) sizesize = 8; /* Get the original precision. */ for (i=sizesize; i>0; --i) { precision = (precision << 8) + cp[i+3]; } /* Get the original sign bit. */ if (cp[1] & 0x02) sgn = -1; /* Get the original exponent sign. */ if (cp[1] & 0x20) expsgn = -1; /* Get the limb size of the originating system. */ if (cp[1] & 0x40) limbsize = 8; if (!(result = GMPy_MPFR_New(precision, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } /* Restore the original result code and rounding mode. */ /* Get the original result code. */ if (cp[2] == 0) result->rc = 0; else if (cp[2] == 1) result->rc = 1; else result->rc = -1; if (!(cp[1] & 0x01)) { /* Process special numbers. */ if ((cp[1] & 0x18) == 0x00) mpfr_set_zero(result->f, sgn); else if ((cp[1] & 0x18) == 0x08) mpfr_set_nan(result->f); else mpfr_set_inf(result->f, sgn); return (PyObject*)result; } /* Process actual numbers. */ /* Calculate the number of limbs on the original system. */ if (limbsize == 8) sizemant = ((precision + 63) / 64); else sizemant = ((precision + 31) / 32); /* Calculate the number of limbs on the current system. */ newmant = (precision + mp_bits_per_limb - 1) / mp_bits_per_limb; /* Get the original exponent. */ cp = buffer + 4 + sizesize - 1; for (i=sizesize; i>0; --i) { exponent = (exponent << 8) + cp[i]; } if (len < 2 + sizesize) { VALUE_ERROR("byte sequence too short for from_binary()"); return NULL; } /* Check if the mantissa occupies the same number of bytes * on both the source and target system. */ if (limbsize * sizemant == newmant * newlimbsize) { mpfr_set_ui(result->f, 1, MPFR_RNDN); cp = buffer + 4 + (2 * sizesize); for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } result->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(result->f, result->f, MPFR_RNDN); return (PyObject*)result; } else if (limbsize * sizemant > newmant * newlimbsize) { /* Since the amount of saved data is greater than the amount of * data needed on the new system, we skip the first 32 bits * since they must be 0. */ /* Verify we are on a 32-bit system and the source was 64-bit. */ if ((limbsize == 8) && (newlimbsize == 4)) { VALUE_ERROR("byte sequence invalid for from_binary()"); return NULL; } mpfr_set_ui(result->f, 1, MPFR_RNDN); cp = buffer + 4 + (2 * sizesize) + 4; for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } result->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(result->f, result->f, MPFR_RNDN); return (PyObject*)result; } else { /* Since the amount of saved data is less than the amount of * data needed on the new system, we must "add" 32 0-bits at * the low end. */ /* Verify we are on a 64-bit system and the source was 32-bit. */ if ((limbsize == 4) && (newlimbsize == 8)) { VALUE_ERROR("byte sequence invalid for from_binary()"); return NULL; } mpfr_set_ui(result->f, 1, MPFR_RNDN); cp = buffer + 4 + (2 * sizesize); templimb = cp[3]; templimb = (templimb << 8) + cp[2]; templimb = (templimb << 8) + cp[1]; templimb = (templimb << 8) + cp[0]; result->f->_mpfr_d[i] = ((templimb << 16) << 16); cp += 4; for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } result->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(result->f, result->f, MPFR_RNDN); return (PyObject*)result; } } case 0x05: { MPC_Object *result; MPFR_Object *real = 0, *imag = 0; Py_ssize_t sizemant = 0, sizesize = 4, i, newmant; mpfr_prec_t precision = 0; mpfr_exp_t exponent = 0; mp_limb_t templimb; int sgn = 1, expsgn = 1, limbsize = 4; int newlimbsize = (mp_bits_per_limb >> 3); unsigned char *tempbuf; if (len < 4) { VALUE_ERROR("byte sequence too short for from_binary()"); return NULL; } /* read the real part first */ if (cp[1] & 0x04) sizesize = 8; for (i=sizesize; i>0; --i) { precision = (precision << 8) + cp[i+3]; } if (cp[1] & 0x02) sgn = -1; if (cp[1] & 0x20) expsgn = -1; if (cp[1] & 0x40) limbsize = 8; if (!(real = GMPy_MPFR_New(precision, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (cp[2] == 0) real->rc = 0; else if (cp[2] == 1) real->rc = 1; else real->rc = -1; if (!(cp[1] & 0x01)) { if ((cp[1] & 0x18) == 0x00) mpfr_set_zero(real->f, sgn); else if ((cp[1] & 0x18) == 0x08) mpfr_set_nan(real->f); else mpfr_set_inf(real->f, sgn); cp += 4 + sizesize; goto readimag; } if (limbsize == 8) sizemant = ((precision + 63) / 64); else sizemant = ((precision + 31) / 32); newmant = (precision + mp_bits_per_limb - 1) / mp_bits_per_limb; cp = buffer + 4 + sizesize - 1; for (i=sizesize; i>0; --i) { exponent = (exponent << 8) + cp[i]; } if (limbsize * sizemant == newmant * newlimbsize) { mpfr_set_ui(real->f, 1, MPFR_RNDN); cp = buffer + 4 + (2 * sizesize); for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } real->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(real->f, real->f, MPFR_RNDN); } else if (limbsize * sizemant > newmant * newlimbsize) { if ((limbsize == 8) && (newlimbsize == 4)) { VALUE_ERROR("byte sequence invalid for from_binary()"); Py_DECREF((PyObject*)real); return NULL; } mpfr_set_ui(real->f, 1, MPFR_RNDN); cp = buffer + 4 + (2 * sizesize) + 4; for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } real->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(real->f, real->f, MPFR_RNDN); } else { if ((limbsize == 4) && (newlimbsize == 8)) { VALUE_ERROR("byte sequence invalid for from_binary()"); Py_DECREF((PyObject*)real); return NULL; } mpfr_set_ui(real->f, 1, MPFR_RNDN); cp = buffer + 4 + (2 * sizesize); templimb = cp[3]; templimb = (templimb << 8) + cp[2]; templimb = (templimb << 8) + cp[1]; templimb = (templimb << 8) + cp[0]; real->f->_mpfr_d[i] = ((templimb << 16) << 16); cp += 4; for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } real->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(real->f, real->f, MPFR_RNDN); } readimag: /* Set all the variables back to default. */ tempbuf = cp; sizemant = 0; sizesize = 4; precision = 0; exponent = 0; sgn = 1; expsgn = 1; limbsize = 4; /* Done reading the real part. The next byte should be 0x05. */ if (!(cp[0] == 0x05)) { VALUE_ERROR("byte sequence invalid for from_binary()"); Py_DECREF((PyObject*)real); return NULL; } if (cp[1] & 0x04) sizesize = 8; for (i=sizesize; i>0; --i) { precision = (precision << 8) + cp[i+3]; } if (cp[1] & 0x02) sgn = -1; if (cp[1] & 0x20) expsgn = -1; if (cp[1] & 0x40) limbsize = 8; if (!(imag = GMPy_MPFR_New(precision, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)real); return NULL; /* LCOV_EXCL_STOP */ } if (cp[2] == 0) imag->rc = 0; else if (cp[2] == 1) imag->rc = 1; else imag->rc = -1; if (!(cp[1] & 0x01)) { if ((cp[1] & 0x18) == 0x00) mpfr_set_zero(imag->f, sgn); else if ((cp[1] & 0x18) == 0x08) mpfr_set_nan(imag->f); else mpfr_set_inf(imag->f, sgn); goto alldone; } if (limbsize == 8) sizemant = ((precision + 63) / 64); else sizemant = ((precision + 31) / 32); newmant = (precision + mp_bits_per_limb - 1) / mp_bits_per_limb; cp = tempbuf + 4 + sizesize - 1; for (i=sizesize; i>0; --i) { exponent = (exponent << 8) + cp[i]; } if (limbsize * sizemant == newmant * newlimbsize) { mpfr_set_ui(imag->f, 1, MPFR_RNDN); cp = tempbuf + 4 + (2 * sizesize); for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } imag->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(imag->f, imag->f, MPFR_RNDN); } else if (limbsize * sizemant > newmant * newlimbsize) { if ((limbsize == 8) && (newlimbsize == 4)) { VALUE_ERROR("byte sequence invalid for from_binary()"); Py_DECREF((PyObject*)real); Py_DECREF((PyObject*)imag); return NULL; } mpfr_set_ui(imag->f, 1, MPFR_RNDN); cp = tempbuf + 4 + (2 * sizesize) + 4; for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } imag->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(imag->f, imag->f, MPFR_RNDN); } else { if ((limbsize == 4) && (newlimbsize == 8)) { VALUE_ERROR("byte sequence invalid for from_binary()"); Py_DECREF((PyObject*)real); Py_DECREF((PyObject*)imag); return NULL; } mpfr_set_ui(imag->f, 1, MPFR_RNDN); cp = tempbuf + 4 + (2 * sizesize); templimb = cp[3]; templimb = (templimb << 8) + cp[2]; templimb = (templimb << 8) + cp[1]; templimb = (templimb << 8) + cp[0]; imag->f->_mpfr_d[i] = ((templimb << 16) << 16); cp += 4; for (i=0; if->_mpfr_d[i] = templimb; cp += newlimbsize; } imag->f->_mpfr_exp = expsgn * exponent; if (sgn == -1) mpfr_neg(imag->f, imag->f, MPFR_RNDN); } alldone: if (!(result = (MPC_Object*)GMPy_MPC_New(0, 0, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)real); Py_DECREF((PyObject*)imag); return NULL; /* LCOV_EXCL_STOP */ } mpfr_swap(mpc_realref(result->c), real->f); mpfr_swap(mpc_imagref(result->c), imag->f); Py_DECREF((PyObject*)real); Py_DECREF((PyObject*)imag); return (PyObject*)result; } default: { TYPE_ERROR("from_binary() argument type not supported"); return NULL; } } } PyDoc_STRVAR(doc_to_binary, "to_binary(x) -> bytes\n" "Return a Python byte sequence that is a portable binary\n" "representation of a gmpy2 object x. The byte sequence can\n" "be passed to gmpy2.from_binary() to obtain an exact copy of\n" "x's value. Works with mpz, xmpz, mpq, mpfr, and mpc types. \n" "Raises TypeError if x is not a gmpy2 object."); static PyObject * GMPy_MPANY_To_Binary(PyObject *self, PyObject *other) { if(MPZ_Check(other)) return GMPy_MPZ_To_Binary((MPZ_Object*)other); else if(XMPZ_Check(other)) return GMPy_XMPZ_To_Binary((XMPZ_Object*)other); else if(MPQ_Check(other)) return GMPy_MPQ_To_Binary((MPQ_Object*)other); else if(MPFR_Check(other)) return GMPy_MPFR_To_Binary((MPFR_Object*)other); else if(MPC_Check(other)) return GMPy_MPC_To_Binary((MPC_Object*)other); TYPE_ERROR("to_binary() argument type not supported"); return NULL; } gmpy2-2.1.0b3/src/gmpy2_binary.h0000664000175000017500000000600413425751304016215 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_binary.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_BINARY_H #define GMPY_BINARY_H #ifdef __cplusplus extern "C" { #endif /* Conversion routines between GMPY2 objects and a compact, portable * binary representation. The binary format of GMPY2 is not compatible * with GMPY 1.x. Methods to read the old format are provided. */ static PyObject * GMPy_MPZ_From_Old_Binary(PyObject *self, PyObject *other); static PyObject * GMPy_MPQ_From_Old_Binary(PyObject *self, PyObject *other); static PyObject * GMPy_MPFR_From_Old_Binary(PyObject *self, PyObject *other); static PyObject * GMPy_MPANY_From_Binary(PyObject *self, PyObject *other); static PyObject * GMPy_MPANY_To_Binary(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_To_Binary(MPZ_Object *self); static PyObject * GMPy_XMPZ_To_Binary(XMPZ_Object *self); static PyObject * GMPy_MPQ_To_Binary(MPQ_Object *self); static PyObject * GMPy_MPFR_To_Binary(MPFR_Object *self); static PyObject * GMPy_MPC_To_Binary(MPC_Object *self); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_cache.c0000664000175000017500000007344013461370120015770 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_cache.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* gmpy2 caches objects so they can be reused quickly without involving a new * memory allocation or object construction. * * The "py???cache" is used to cache Py??? objects. The cache is accessed * via Py???_new/Py???_dealloc. The functions set_py???cache and * set_py???cache are used to change the size of the array used to the store * the cached objects. */ /* Caching logic for Pympz. */ static void set_gmpympzcache(void) { if (global.in_gmpympzcache > global.cache_size) { int i; for (i = global.cache_size; i < global.in_gmpympzcache; ++i) { mpz_clear(global.gmpympzcache[i]->z); PyObject_Del(global.gmpympzcache[i]); } global.in_gmpympzcache = global.cache_size; } global.gmpympzcache = realloc(global.gmpympzcache, sizeof(MPZ_Object)*global.cache_size); } /* GMPy_MPZ_New returns a reference to a new MPZ_Object. Its value * is initialized to 0. */ static MPZ_Object * GMPy_MPZ_New(CTXT_Object *context) { MPZ_Object *result = NULL; if (global.in_gmpympzcache) { result = global.gmpympzcache[--(global.in_gmpympzcache)]; /* Py_INCREF does not set the debugging pointers, so need to use * _Py_NewReference instead. */ _Py_NewReference((PyObject*)result); mpz_set_ui(result->z, 0); result->hash_cache = -1; } else { if ((result = PyObject_New(MPZ_Object, &MPZ_Type))) { mpz_init(result->z); result->hash_cache = -1; } } return result; } /* GMPy_MPZ_NewInit returns a reference to an initialized MPZ_Object. It is * used by mpz.__new__ to replace the old mpz() factory function. */ static PyObject * GMPy_MPZ_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds) { MPZ_Object *result = NULL; PyObject *n = NULL; PyObject *temp = NULL; PyObject *out = NULL; int base = 0; Py_ssize_t argc; static char *kwlist[] = {"s", "base", NULL }; CTXT_Object *context = NULL; if (type != &MPZ_Type) { TYPE_ERROR("mpz.__new__() requires mpz type"); return NULL; } /* Optimize the most common use cases first; either 0 or 1 argument */ argc = PyTuple_GET_SIZE(args); if (argc == 0) { return (PyObject*)GMPy_MPZ_New(context); } if (argc == 1 && !keywds) { n = PyTuple_GET_ITEM(args, 0); if (MPZ_Check(n)) { Py_INCREF(n); return n; } if (PyIntOrLong_Check(n)) { return (PyObject*)GMPy_MPZ_From_PyIntOrLong(n, context); } if (MPQ_Check(n)) { return (PyObject*)GMPy_MPZ_From_MPQ((MPQ_Object*)n, context); } if (MPFR_Check(n)) { return (PyObject*)GMPy_MPZ_From_MPFR((MPFR_Object*)n, context); } if (PyFloat_Check(n)) { return (PyObject*)GMPy_MPZ_From_PyFloat(n, context); } if (XMPZ_Check(n)) { return (PyObject*)GMPy_MPZ_From_XMPZ((XMPZ_Object*)n, context); } if (IS_FRACTION(n)) { MPQ_Object *temp = GMPy_MPQ_From_Fraction(n, context); if (temp) { result = GMPy_MPZ_From_MPQ(temp, context); Py_DECREF((PyObject*)temp); } return (PyObject*)result; } if (PyStrOrUnicode_Check(n)) { return (PyObject*)GMPy_MPZ_From_PyStr(n, base, context); } if (HAS_MPZ_CONVERSION(n)) { out = (PyObject *) PyObject_CallMethod(n, "__mpz__", NULL); if (out == NULL) return out; if (!MPZ_Check(out)) { PyErr_Format(PyExc_TypeError, "object of type '%.200s' can not be interpreted as mpz", out->ob_type->tp_name); Py_DECREF(out); return NULL; } return out; } /* Try converting to integer. */ temp = PyNumber_Long(n); if (temp) { result = GMPy_MPZ_From_PyIntOrLong(temp, context); Py_DECREF(temp); return (PyObject*)result; } TYPE_ERROR("mpz() requires numeric or string argument"); return NULL; } if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &n, &base)) { return NULL; } if ((base != 0) && ((base < 2)|| (base > 62))) { VALUE_ERROR("base for mpz() must be 0 or in the interval [2, 62]"); return NULL; } if (PyStrOrUnicode_Check(n)) { return (PyObject*)GMPy_MPZ_From_PyStr(n, base, context); } if (IS_REAL(n)) { TYPE_ERROR("mpz() with number argument only takes 1 argument"); } else { TYPE_ERROR("mpz() requires numeric or string (and optional base) arguments"); } return NULL; } static void GMPy_MPZ_Dealloc(MPZ_Object *self) { if (global.in_gmpympzcache < global.cache_size && self->z->_mp_alloc <= global.cache_obsize) { global.gmpympzcache[(global.in_gmpympzcache)++] = self; } else { mpz_clear(self->z); PyObject_Del(self); } } /* Caching logic for Pyxmpz. */ static void set_gmpyxmpzcache(void) { if (global.in_gmpyxmpzcache > global.cache_size) { int i; for (i = global.cache_size; i < global.in_gmpyxmpzcache; ++i) { mpz_clear(global.gmpyxmpzcache[i]->z); PyObject_Del(global.gmpyxmpzcache[i]); } global.in_gmpyxmpzcache = global.cache_size; } global.gmpyxmpzcache = realloc(global.gmpyxmpzcache, sizeof(XMPZ_Object)*global.cache_size); } static XMPZ_Object * GMPy_XMPZ_New(CTXT_Object *context) { XMPZ_Object *result = NULL; if (global.in_gmpyxmpzcache) { result = global.gmpyxmpzcache[--(global.in_gmpyxmpzcache)]; /* Py_INCREF does not set the debugging pointers, so need to use * _Py_NewReference instead. */ _Py_NewReference((PyObject*)result); mpz_set_ui(result->z, 0); } else { if ((result = PyObject_New(XMPZ_Object, &XMPZ_Type))) { mpz_init(result->z); } } return result; } static PyObject * GMPy_XMPZ_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds) { XMPZ_Object *result = NULL; PyObject *n = NULL; PyObject *temp = NULL; int base = 0; Py_ssize_t argc; static char *kwlist[] = {"s", "base", NULL }; CTXT_Object *context = NULL; if (type != &XMPZ_Type) { TYPE_ERROR("xmpz.__new__() requires xmpz type"); return NULL; } /* Optimize the most common use cases first; either 0 or 1 argument */ argc = PyTuple_GET_SIZE(args); if (argc == 0) { return (PyObject*)GMPy_XMPZ_New(context); } if (argc == 1 && !keywds) { n = PyTuple_GET_ITEM(args, 0); if (XMPZ_Check(n)) { Py_INCREF(n); return n; } if (PyIntOrLong_Check(n)) { return (PyObject*)GMPy_XMPZ_From_PyIntOrLong(n, context); } if (MPQ_Check(n)) { return (PyObject*)GMPy_XMPZ_From_MPQ((MPQ_Object*)n, context); } if (MPFR_Check(n)) { return (PyObject*)GMPy_XMPZ_From_MPFR((MPFR_Object*)n, context); } if (PyFloat_Check(n)) { return (PyObject*)GMPy_XMPZ_From_PyFloat(n, context); } if (MPZ_Check(n)) { return (PyObject*)GMPy_XMPZ_From_MPZ((MPZ_Object*)n, context); } if (IS_FRACTION(n)) { MPQ_Object *temp = GMPy_MPQ_From_Fraction(n, context); if (temp) { result = GMPy_XMPZ_From_MPQ(temp, context); Py_DECREF((PyObject*)temp); } return (PyObject*)result; } if (PyStrOrUnicode_Check(n)) { return (PyObject*)GMPy_XMPZ_From_PyStr(n, base, context); } /* Try converting to integer. */ temp = PyNumber_Long(n); if (temp) { result = GMPy_XMPZ_From_PyIntOrLong(temp, context); Py_DECREF(temp); return (PyObject*)result; } TYPE_ERROR("xmpz() requires numeric or string argument"); return NULL; } if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &n, &base)) { return NULL; } if ((base != 0) && ((base < 2)|| (base > 62))) { VALUE_ERROR("base for xmpz() must be 0 or in the interval [2, 62]"); return NULL; } if (PyStrOrUnicode_Check(n)) { return (PyObject*)GMPy_XMPZ_From_PyStr(n, base, context); } if (IS_REAL(n)) { TYPE_ERROR("xmpz() with number argument only takes 1 argument"); } else { TYPE_ERROR("xmpz() requires numeric or string (and optional base) arguments"); } return NULL; } static void GMPy_XMPZ_Dealloc(XMPZ_Object *obj) { if (global.in_gmpyxmpzcache < global.cache_size && obj->z->_mp_alloc <= global.cache_obsize) { global.gmpyxmpzcache[(global.in_gmpyxmpzcache)++] = obj; } else { mpz_clear(obj->z); PyObject_Del((PyObject*)obj); } } /* Caching logic for Pympq. */ static void set_gmpympqcache(void) { if (global.in_gmpympqcache > global.cache_size) { int i; for (i = global.cache_size; i < global.in_gmpympqcache; ++i) { mpq_clear(global.gmpympqcache[i]->q); PyObject_Del(global.gmpympqcache[i]); } global.in_gmpympqcache = global.cache_size; } global.gmpympqcache = realloc(global.gmpympqcache, sizeof(MPQ_Object)*global.cache_size); } static MPQ_Object * GMPy_MPQ_New(CTXT_Object *context) { MPQ_Object *result = NULL; if (global.in_gmpympqcache) { result = global.gmpympqcache[--(global.in_gmpympqcache)]; /* Py_INCREF does not set the debugging pointers, so need to use _Py_NewReference instead. */ _Py_NewReference((PyObject*)result); } else { if (!(result = PyObject_New(MPQ_Object, &MPQ_Type))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpq_init(result->q); } result->hash_cache = -1; return result; } static PyObject * GMPy_MPQ_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds) { MPQ_Object *result = NULL, *temp = NULL; PyObject *n = NULL, *m = NULL; PyObject *out = NULL; int base = 10; Py_ssize_t argc, keywdc = 0; static char *kwlist[] = {"s", "base", NULL }; CTXT_Object *context = NULL; if (type != &MPQ_Type) { TYPE_ERROR("mpq.__new__() requires mpq type"); return NULL; } argc = PyTuple_Size(args); if (keywds) { keywdc = PyDict_Size(keywds); } if (argc + keywdc > 2) { TYPE_ERROR("mpq() takes at most 2 arguments"); return NULL; } if (argc + keywdc == 0) { if ((result = GMPy_MPQ_New(context))) { mpq_set_ui(result->q, 0, 1); } return (PyObject*)result; } if (argc == 0) { TYPE_ERROR("mpq() requires at least one non-keyword argument"); return NULL; } n = PyTuple_GetItem(args, 0); /* Handle the case where the first argument is a string. */ if (PyStrOrUnicode_Check(n)) { /* keyword base is legal */ if (keywdc || argc > 1) { if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &n, &base))) { return NULL; } } if ((base != 0) && ((base < 2) || (base > 62))) { VALUE_ERROR("base for mpq() must be 0 or in the interval [2, 62]"); return NULL; } return (PyObject*)GMPy_MPQ_From_PyStr(n, base, context); } /* Handle 1 argument. It must be non-complex number or an object with a __mpq__ method. */ if (argc == 1) { if (IS_REAL(n)) { return (PyObject *) GMPy_MPQ_From_Number(n, context); } if (HAS_MPQ_CONVERSION(n)) { out = (PyObject *) PyObject_CallMethod(n, "__mpq__", NULL); if (out == NULL) return out; if (!MPQ_Check(out)) { PyErr_Format(PyExc_TypeError, "object of type '%.200s' can not be interpreted as mpq", out->ob_type->tp_name); Py_DECREF(out); return NULL; } return out; } } /* Handle 2 arguments. Both arguments must be integer or rational. */ if (argc == 2) { m = PyTuple_GetItem(args, 1); if (IS_RATIONAL(n) && IS_RATIONAL(m)) { result = GMPy_MPQ_From_Number(n, context); temp = GMPy_MPQ_From_Number(m, context); if (!result || !temp) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)temp); return NULL; } if (mpq_sgn(temp->q) == 0) { ZERO_ERROR("zero denominator in mpq()"); Py_DECREF((PyObject*)result); Py_DECREF((PyObject*)temp); return NULL; } mpq_div(result->q, result->q, temp->q); Py_DECREF((PyObject*)temp); return (PyObject*)result; } } TYPE_ERROR("mpq() requires numeric or string argument"); return NULL; } static void GMPy_MPQ_Dealloc(MPQ_Object *self) { if (global.in_gmpympqcacheq)->_mp_alloc <= global.cache_obsize && mpq_denref(self->q)->_mp_alloc <= global.cache_obsize) { global.gmpympqcache[(global.in_gmpympqcache)++] = self; } else { mpq_clear(self->q); PyObject_Del(self); } } /* Caching logic for Pympfr. */ static void set_gmpympfrcache(void) { if (global.in_gmpympfrcache > global.cache_size) { int i; for (i = global.cache_size; i < global.in_gmpympfrcache; ++i) { mpfr_clear(global.gmpympfrcache[i]->f); PyObject_Del(global.gmpympfrcache[i]); } global.in_gmpympfrcache = global.cache_size; } global.gmpympfrcache = realloc(global.gmpympfrcache, sizeof(MPFR_Object)*global.cache_size); } static MPFR_Object * GMPy_MPFR_New(mpfr_prec_t bits, CTXT_Object *context) { MPFR_Object *result; if (bits < 2) { CHECK_CONTEXT(context); bits = GET_MPFR_PREC(context); } if (bits < MPFR_PREC_MIN || bits > MPFR_PREC_MAX) { VALUE_ERROR("invalid value for precision"); return NULL; } if (global.in_gmpympfrcache) { result = global.gmpympfrcache[--(global.in_gmpympfrcache)]; /* Py_INCREF does not set the debugging pointers, so need to use _Py_NewReference instead. */ _Py_NewReference((PyObject*)result); mpfr_set_prec(result->f, bits); } else { if (!(result = PyObject_New(MPFR_Object, &MPFR_Type))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpfr_init2(result->f, bits); } result->hash_cache = -1; result->rc = 0; return result; } static PyObject * GMPy_MPFR_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds) { MPFR_Object *result = NULL; CTXT_Object *context = NULL; Py_ssize_t argc, keywdc = 0; PyObject *arg0 = NULL; PyObject *out = NULL; int base = 0; /* Assumes mpfr_prec_t is the same as a long. */ mpfr_prec_t prec = 0; static char *kwlist_s[] = {"s", "precision", "base", "context", NULL}; static char *kwlist_n[] = {"n", "precision", "context", NULL}; if (type != &MPFR_Type) { TYPE_ERROR("mpfr.__new__() requires mpfr type"); return NULL; } CHECK_CONTEXT(context); argc = PyTuple_Size(args); if (keywds) { keywdc = PyDict_Size(keywds); } if (argc + keywdc > 4) { TYPE_ERROR("mpfr() takes at most 4 arguments"); return NULL; } if (argc + keywdc == 0) { if ((result = GMPy_MPFR_New(0, context))) { mpfr_set_ui(result->f, 0, MPFR_RNDN); } return (PyObject*)result; } if (argc == 0) { TYPE_ERROR("mpfr() requires at least one non-keyword argument"); return NULL; } arg0 = PyTuple_GET_ITEM(args, 0); /* A string can have precision, base, and context as additional arguments. */ if (PyStrOrUnicode_Check(arg0)) { if (keywdc || argc > 1) { if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|liO", kwlist_s, &arg0, &prec, &base, &context))) return NULL; } if (!CTXT_Check(context)) { TYPE_ERROR("context argument is not a valid context"); return NULL; } if (prec < 0) { VALUE_ERROR("precision for mpfr() must be >= 0"); return NULL; } if (base != 0 && (base < 2 || base > 62)) { VALUE_ERROR("base for mpfr() must be 0 or in the interval [2, 62]"); return NULL; } return (PyObject*)GMPy_MPFR_From_PyStr(arg0, base, prec, context); } if (HAS_MPFR_CONVERSION(arg0)) { out = (PyObject *) PyObject_CallMethod(arg0, "__mpfr__", NULL); if(out == NULL) return out; if (!MPFR_Check(out)) { PyErr_Format(PyExc_TypeError, "object of type '%.200s' can not be interpreted as mpfr", out->ob_type->tp_name); Py_DECREF(out); return NULL; } return out; } /* A number can only have precision and context as additional arguments. */ if (IS_REAL(arg0)) { if (keywdc || argc > 1) { if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|lO", kwlist_n, &arg0, &prec, &context))) return NULL; } if (!CTXT_Check(context)) { TYPE_ERROR("context argument is not a valid context"); return NULL; } if (prec < 0) { VALUE_ERROR("precision for mpfr() must be >= 0"); return NULL; } return (PyObject*)GMPy_MPFR_From_Real(arg0, prec, context); } TYPE_ERROR("mpfr() requires numeric or string argument"); return NULL; } static void GMPy_MPFR_Dealloc(MPFR_Object *self) { size_t msize; /* Calculate the number of limbs in the mantissa. */ msize = (self->f->_mpfr_prec + mp_bits_per_limb - 1) / mp_bits_per_limb; if (global.in_gmpympfrcache < global.cache_size && msize <= (size_t)global.cache_obsize) { global.gmpympfrcache[(global.in_gmpympfrcache)++] = self; } else { mpfr_clear(self->f); PyObject_Del(self); } } static void set_gmpympccache(void) { if (global.in_gmpympccache > global.cache_size) { int i; for (i = global.cache_size; i < global.in_gmpympccache; ++i) { mpc_clear(global.gmpympccache[i]->c); PyObject_Del(global.gmpympccache[i]); } global.in_gmpympccache = global.cache_size; } global.gmpympccache = realloc(global.gmpympccache, sizeof(MPC_Object)*global.cache_size); } static MPC_Object * GMPy_MPC_New(mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *self; if (rprec < 2) { CHECK_CONTEXT(context); rprec = GET_REAL_PREC(context); } if (iprec < 2) { CHECK_CONTEXT(context); iprec = GET_IMAG_PREC(context); } if (rprec < MPFR_PREC_MIN || rprec > MPFR_PREC_MAX || iprec < MPFR_PREC_MIN || iprec > MPFR_PREC_MAX) { VALUE_ERROR("invalid value for precision"); return NULL; } if (global.in_gmpympccache) { self = global.gmpympccache[--(global.in_gmpympccache)]; /* Py_INCREF does not set the debugging pointers, so need to use _Py_NewReference instead. */ _Py_NewReference((PyObject*)self); if (rprec == iprec) { mpc_set_prec(self->c, rprec); } else { mpc_clear(self->c); mpc_init3(self->c, rprec, iprec); } } else { if (!(self = PyObject_New(MPC_Object, &MPC_Type))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpc_init3(self->c, rprec, iprec); } self->hash_cache = -1; self->rc = 0; return self; } static PyObject * GMPy_MPC_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds) { MPC_Object *result = NULL; MPFR_Object *tempreal = NULL, *tempimag = NULL; PyObject *arg0 = NULL, *arg1 = NULL, *prec = NULL, *out = NULL; int base = 10; Py_ssize_t argc = 0, keywdc = 0; CTXT_Object *context = NULL; /* Assumes mpfr_prec_t is the same as a long. */ mpfr_prec_t rprec = 0, iprec = 0; static char *kwlist_c[] = {"c", "precision", "context", NULL}; static char *kwlist_r[] = {"real", "imag", "precision", "context", NULL}; static char *kwlist_s[] = {"s", "precision", "base", "context", NULL}; if (type != &MPC_Type) { TYPE_ERROR("mpc.__new__() requires mpc type"); return NULL; } CHECK_CONTEXT(context); argc = PyTuple_Size(args); if (keywds) { keywdc = PyDict_Size(keywds); } if (argc + keywdc > 4) { TYPE_ERROR("mpc() takes at most 4 arguments"); return NULL; } if (argc + keywdc == 0) { if ((result = GMPy_MPC_New(0, 0, context))) { mpc_set_ui(result->c, 0, GET_MPC_ROUND(context)); } return (PyObject*)result; } if (argc == 0) { TYPE_ERROR("mpc() requires at least one non-keyword argument"); return NULL; } arg0 = PyTuple_GET_ITEM(args, 0); /* A string can have precision, base, and context as additional arguments. */ if (PyStrOrUnicode_Check(arg0)) { if (keywdc || argc > 1) { if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|OiO", kwlist_s, &arg0, &prec, &base, &context))) return NULL; } if (!CTXT_Check(context)) { TYPE_ERROR("context argument is not a valid context"); return NULL; } if (prec) { if (PyIntOrLong_Check(prec)) { rprec = (mpfr_prec_t)PyIntOrLong_AsLong(prec); iprec = rprec; } else if (PyTuple_Check(prec) && PyTuple_Size(prec) == 2) { rprec = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GET_ITEM(prec, 0)); iprec = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GET_ITEM(prec, 1)); } else { TYPE_ERROR("precision for mpc() must be integer or tuple"); return NULL; } if (rprec < 0 || iprec < 0) { if (PyErr_Occurred()) { VALUE_ERROR("invalid value for precision in mpc()"); } else { VALUE_ERROR("precision for mpc() must be >= 0"); } return NULL; } } if (base < 2 || base > 36) { VALUE_ERROR("base for mpc() must be in the interval [2,36]"); return NULL; } return (PyObject*)GMPy_MPC_From_PyStr(arg0, base, rprec, iprec, context); } if (HAS_MPC_CONVERSION(arg0)) { out = (PyObject*) PyObject_CallMethod(arg0, "__mpc__", NULL); if(out == NULL) return out; if (!MPC_Check(out)) { PyErr_Format(PyExc_TypeError, "object of type '%.200s' can not be interpreted as mpc", out->ob_type->tp_name); Py_DECREF(out); return NULL; } return out; } /* Should special case PyFLoat to avoid double rounding. */ if (IS_REAL(arg0)) { if (keywdc || argc > 1) { if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|OOO", kwlist_r, &arg0, &arg1, &prec, &context))) return NULL; } if (!CTXT_Check(context)) { TYPE_ERROR("context argument is not a valid context"); return NULL; } if (prec) { if (PyIntOrLong_Check(prec)) { rprec = (mpfr_prec_t)PyIntOrLong_AsLong(prec); iprec = rprec; } else if (PyTuple_Check(prec) && PyTuple_Size(prec) == 2) { rprec = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GET_ITEM(prec, 0)); iprec = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GET_ITEM(prec, 1)); } else { TYPE_ERROR("precision for mpc() must be integer or tuple"); return NULL; } if (rprec < 0 || iprec < 0) { if (PyErr_Occurred()) { VALUE_ERROR("invalid value for precision in mpc()"); } else { VALUE_ERROR("precision for mpc() must be >= 0"); } return NULL; } } if (arg1 && !IS_REAL(arg1)) { TYPE_ERROR("invalid type for imaginary component in mpc()"); return NULL; } tempreal = GMPy_MPFR_From_Real(arg0, rprec, context); if (arg1) { tempimag = GMPy_MPFR_From_Real(arg1, iprec, context); } else { if ((tempimag = GMPy_MPFR_New(iprec, context))) { mpfr_set_ui(tempimag->f, 0, MPFR_RNDN); } } result = GMPy_MPC_New(rprec, iprec, context); if (!tempreal || !tempimag || !result) { Py_XDECREF(tempreal); Py_XDECREF(tempimag); Py_XDECREF(result); TYPE_ERROR("mpc() requires string or numeric argument."); return NULL; } mpc_set_fr_fr(result->c, tempreal->f, tempimag->f, GET_MPC_ROUND(context)); Py_DECREF(tempreal); Py_DECREF(tempimag); return (PyObject*)result; } if (IS_COMPLEX_ONLY(arg0)) { if (keywdc || argc > 1) { if (!(PyArg_ParseTupleAndKeywords(args, keywds, "O|O", kwlist_c, &arg0, &prec))) return NULL; } if (prec) { if (PyIntOrLong_Check(prec)) { rprec = (mpfr_prec_t)PyIntOrLong_AsLong(prec); iprec = rprec; } else if (PyTuple_Check(prec) && PyTuple_Size(prec) == 2) { rprec = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GET_ITEM(prec, 0)); iprec = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GET_ITEM(prec, 1)); } else { TYPE_ERROR("precision for mpc() must be integer or tuple"); return NULL; } if (rprec < 0 || iprec < 0) { if (PyErr_Occurred()) { VALUE_ERROR("invalid value for precision in mpc()"); } else { VALUE_ERROR("precision for mpc() must be >= 0"); } return NULL; } } if (PyComplex_Check(arg0)) { result = GMPy_MPC_From_PyComplex(arg0, rprec, iprec, context); } else { result = GMPy_MPC_From_MPC((MPC_Object*)arg0, rprec, iprec, context); } return (PyObject*)result; } TYPE_ERROR("mpc() requires numeric or string argument"); return NULL; } static void GMPy_MPC_Dealloc(MPC_Object *self) { size_t msize; /* Calculate the number of limbs in the mantissa. */ msize = (mpc_realref(self->c)->_mpfr_prec + mp_bits_per_limb - 1) / mp_bits_per_limb; msize += (mpc_imagref(self->c)->_mpfr_prec + mp_bits_per_limb - 1) / mp_bits_per_limb; if (global.in_gmpympccache < global.cache_size && msize <= (size_t)global.cache_obsize) { global.gmpympccache[(global.in_gmpympccache)++] = self; } else { mpc_clear(self->c); PyObject_Del(self); } } gmpy2-2.1.0b3/src/gmpy2_cache.h0000664000175000017500000001067213425751455016011 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_cache.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* gmpy2 caches objects so they can be reused quickly without involving a new * memory allocation or object construction. */ #ifndef GMPY_CACHE_H #define GMPY_CACHE_H #ifdef __cplusplus extern "C" { #endif /* Private functions */ static void set_gmpympzcache(void); static void set_gmpyxmpzcache(void); static void set_gmpympqcache(void); static void set_gmpympfrcache(void); static void set_gmpympccache(void); /* C-API functions */ /* static MPZ_Object * GMPy_MPZ_New(CTXT_Object *context); */ /* static PyObject * GMPy_MPZ_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds); */ /* static void GMPy_MPZ_Dealloc(MPZ_Object *self); */ static GMPy_MPZ_New_RETURN GMPy_MPZ_New GMPy_MPZ_New_PROTO; static GMPy_MPZ_NewInit_RETURN GMPy_MPZ_NewInit GMPy_MPZ_NewInit_PROTO; static GMPy_MPZ_Dealloc_RETURN GMPy_MPZ_Dealloc GMPy_MPZ_Dealloc_PROTO; /* static XMPZ_Object * GMPy_XMPZ_New(CTXT_Object *context); */ /* static PyObject * GMPy_XMPZ_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds); */ /* static void GMPy_XMPZ_Dealloc(XMPZ_Object *self); */ static GMPy_XMPZ_New_RETURN GMPy_XMPZ_New GMPy_XMPZ_New_PROTO; static GMPy_XMPZ_NewInit_RETURN GMPy_XMPZ_NewInit GMPy_XMPZ_NewInit_PROTO; static GMPy_XMPZ_Dealloc_RETURN GMPy_XMPZ_Dealloc GMPy_XMPZ_Dealloc_PROTO; /* static MPQ_Object * GMPy_MPQ_New(CTXT_Object *context); */ /* static PyObject * GMPy_MPQ_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds); */ /* static void GMPy_MPQ_Dealloc(MPQ_Object *self); */ static GMPy_MPQ_New_RETURN GMPy_MPQ_New GMPy_MPQ_New_PROTO; static GMPy_MPQ_NewInit_RETURN GMPy_MPQ_NewInit GMPy_MPQ_NewInit_PROTO; static GMPy_MPQ_Dealloc_RETURN GMPy_MPQ_Dealloc GMPy_MPQ_Dealloc_PROTO; /* static MPFR_Object * GMPy_MPFR_New(CTXT_Object *context); */ /* static PyObject * GMPy_MPFR_NewInit(PyTypeObject *type, PyObject *args, PyObject *keywds); */ /* static void GMPy_MPFR_Dealloc(MPFR_Object *self); */ static GMPy_MPFR_New_RETURN GMPy_MPFR_New GMPy_MPFR_New_PROTO; static GMPy_MPFR_NewInit_RETURN GMPy_MPFR_NewInit GMPy_MPFR_NewInit_PROTO; static GMPy_MPFR_Dealloc_RETURN GMPy_MPFR_Dealloc GMPy_MPFR_Dealloc_PROTO; static MPC_Object * GMPy_MPC_New(mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static void GMPy_MPC_Dealloc(MPC_Object *self); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_cmp.c0000664000175000017500000004157513473132314015514 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_cmp.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_mpany_cmp, "cmp(x, y) -> integer\n\n" "Return -1 if x < y; 0 if x = y; or 1 if x > y. Both x and y must be\n" "integer, rational or real. Note: 0 is returned (and exception flag set)\n" "if either argument is NaN."); static PyObject * _return_cmp(int c) { if (c < 0) return PyIntOrLong_FromLong(-1); if (c > 0) return PyIntOrLong_FromLong(1); return PyIntOrLong_FromLong(0); } static PyObject * _return_negated_cmp(int c) { if (c < 0) return PyIntOrLong_FromLong(1); if (c > 0) return PyIntOrLong_FromLong(-1); return PyIntOrLong_FromLong(0); } static PyObject * GMPy_MPANY_cmp(PyObject *self, PyObject *args) { PyObject *arg0, *arg1, *result = NULL; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("cmp() requires 2 arguments"); return NULL; } arg0 = PyTuple_GET_ITEM(args, 0); arg1 = PyTuple_GET_ITEM(args, 1); if (IS_INTEGER(arg0) && IS_INTEGER(arg1)) { MPZ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPZ_From_Integer(arg0, context)) || !(tempy = GMPy_MPZ_From_Integer(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } result = _return_cmp(mpz_cmp(tempx->z, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } if (IS_RATIONAL(arg0) && IS_INTEGER(arg1)) { MPQ_Object *tempx = NULL; MPZ_Object *tempy = NULL; if (!(tempx = GMPy_MPQ_From_Rational(arg0, context)) || !(tempy = GMPy_MPZ_From_Integer(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } result = _return_cmp(mpq_cmp_z(tempx->q, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } if (IS_INTEGER(arg0) && IS_RATIONAL(arg1)) { MPZ_Object *tempx = NULL; MPQ_Object *tempy = NULL; if (!(tempx = GMPy_MPZ_From_Integer(arg0, context)) || !(tempy = GMPy_MPQ_From_Rational(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } result = _return_negated_cmp(mpq_cmp_z(tempy->q, tempx->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } if (IS_RATIONAL(arg0) && IS_RATIONAL(arg1)) { MPQ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPQ_From_Rational(arg0, context)) || !(tempy = GMPy_MPQ_From_Rational(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } result = _return_cmp(mpq_cmp(tempx->q, tempy->q)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } /* We perform exact comparisons between the mpz, mpq, and mpfr types. */ if (IS_REAL(arg0) && IS_INTEGER(arg1)) { MPFR_Object *tempx = NULL; MPZ_Object *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(arg0, 1, context)) || !(tempy = GMPy_MPZ_From_Integer(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result =_return_cmp(mpfr_cmp_z(tempx->f, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_REAL(arg0) && IS_RATIONAL(arg1)) { MPFR_Object *tempx = NULL; MPQ_Object *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(arg0, 1, context)) || !(tempy = GMPy_MPQ_From_Rational(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result =_return_cmp(mpfr_cmp_q(tempx->f, tempy->q)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_REAL(arg0) && IS_REAL(arg1)) { MPFR_Object *tempx = NULL; MPFR_Object *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(arg0, 1, context)) || !(tempy = GMPy_MPFR_From_Real(arg1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result =_return_cmp(mpfr_cmp(tempx->f, tempy->f)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_INTEGER(arg0) && IS_REAL(arg1)) { MPZ_Object *tempx = NULL; MPFR_Object *tempy = NULL; if (!(tempx = GMPy_MPZ_From_Integer(arg0, context)) || !(tempy = GMPy_MPFR_From_Real(arg1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result =_return_negated_cmp(mpfr_cmp_z(tempy->f, tempx->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_RATIONAL(arg0) && IS_REAL(arg1)) { MPQ_Object *tempx = NULL; MPFR_Object *tempy = NULL; if (!(tempx = GMPy_MPQ_From_Rational(arg0, context)) || !(tempy = GMPy_MPFR_From_Real(arg1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result =_return_negated_cmp(mpfr_cmp_q(tempy->f, tempx->q)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } TYPE_ERROR("cmp() requires integer, rational, or real arguments"); return NULL; } PyDoc_STRVAR(GMPy_doc_mpany_cmp_abs, "cmp_abs(x, y) -> integer\n\n" "Return -1 if |x| < |y|; 0 if |x| = |y|; or 1 if |x| > |y|. Both x and y\n" "can be integer, rational, real, or complex."); static PyObject * GMPy_MPANY_cmp_abs(PyObject *self, PyObject *args) { PyObject *arg0, *arg1, *result = NULL; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("cmp() requires 2 arguments"); return NULL; } arg0 = PyTuple_GET_ITEM(args, 0); arg1 = PyTuple_GET_ITEM(args, 1); if (IS_INTEGER(arg0) && IS_INTEGER(arg1)) { MPZ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPZ_From_Integer(arg0, context)) || !(tempy = GMPy_MPZ_From_Integer(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } result = _return_cmp(mpz_cmpabs(tempx->z, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } if (IS_RATIONAL(arg0) && IS_INTEGER(arg1)) { MPQ_Object *tempx = NULL; MPZ_Object *tempy = NULL; if (!(tempx = GMPy_MPQ_From_RationalAndCopy(arg0, context)) || !(tempy = GMPy_MPZ_From_IntegerAndCopy(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpq_abs(tempx->q, tempx->q); mpz_abs(tempy->z, tempy->z); result = _return_cmp(mpq_cmp_z(tempx->q, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } if (IS_INTEGER(arg0) && IS_RATIONAL(arg1)) { MPZ_Object *tempx = NULL; MPQ_Object *tempy = NULL; if (!(tempx = GMPy_MPZ_From_IntegerAndCopy(arg0, context)) || !(tempy = GMPy_MPQ_From_RationalAndCopy(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpz_abs(tempx->z, tempx->z); mpq_abs(tempy->q, tempy->q); result = _return_negated_cmp(mpq_cmp_z(tempy->q, tempx->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } if (IS_RATIONAL(arg0) && IS_RATIONAL(arg1)) { MPQ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPQ_From_RationalAndCopy(arg0, context)) || !(tempy = GMPy_MPQ_From_RationalAndCopy(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpq_abs(tempx->q, tempx->q); mpq_abs(tempy->q, tempy->q); result = _return_cmp(mpq_cmp(tempx->q, tempy->q)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; } /* We perform exact comparisons between the mpz, mpq, and mpfr types. */ if (IS_REAL(arg0) && IS_INTEGER(arg1)) { MPFR_Object *tempx = NULL; MPZ_Object *tempy = NULL; if (!(tempx = GMPy_MPFR_From_RealAndCopy(arg0, 1, context)) || !(tempy = GMPy_MPZ_From_IntegerAndCopy(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); mpfr_abs(tempx->f, tempx->f, MPFR_RNDN); mpz_abs(tempy->z, tempy->z); result =_return_cmp(mpfr_cmp_z(tempx->f, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_REAL(arg0) && IS_RATIONAL(arg1)) { MPFR_Object *tempx = NULL; MPQ_Object *tempy = NULL; if (!(tempx = GMPy_MPFR_From_RealAndCopy(arg0, 1, context)) || !(tempy = GMPy_MPQ_From_RationalAndCopy(arg1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); mpfr_abs(tempx->f, tempx->f, MPFR_RNDN); mpq_abs(tempy->q, tempy->q); result =_return_cmp(mpfr_cmp_q(tempx->f, tempy->q)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_REAL(arg0) && IS_REAL(arg1)) { MPFR_Object *tempx = NULL; MPFR_Object *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(arg0, 1, context)) || !(tempy = GMPy_MPFR_From_Real(arg1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result =_return_cmp(mpfr_cmpabs(tempx->f, tempy->f)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_INTEGER(arg0) && IS_REAL(arg1)) { MPZ_Object *tempx = NULL; MPFR_Object *tempy = NULL; if (!(tempx = GMPy_MPZ_From_IntegerAndCopy(arg0, context)) || !(tempy = GMPy_MPFR_From_RealAndCopy(arg1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); mpz_abs(tempx->z, tempx->z); mpfr_abs(tempy->f, tempy->f, MPFR_RNDN); result =_return_negated_cmp(mpfr_cmp_z(tempy->f, tempx->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } if (IS_RATIONAL(arg0) && IS_REAL(arg1)) { MPQ_Object *tempx = NULL; MPFR_Object *tempy = NULL; if (!(tempx = GMPy_MPQ_From_RationalAndCopy(arg0, context)) || !(tempy = GMPy_MPFR_From_RealAndCopy(arg1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); mpq_abs(tempx->q, tempx->q); mpfr_abs(tempy->f, tempy->f, MPFR_RNDN); result =_return_negated_cmp(mpfr_cmp_q(tempy->f, tempx->q)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } #ifndef MPC_110 TYPE_ERROR("cmp_abs() requires integer, rational, or real arguments"); return NULL; #else if (IS_COMPLEX(arg0) && IS_COMPLEX(arg1)) { MPC_Object *tempx = NULL; MPC_Object *tempy = NULL; if (!(tempx = GMPy_MPC_From_Complex(arg0, 1, 1, context)) || !(tempy = GMPy_MPC_From_Complex(arg1, 1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result =_return_cmp(mpc_cmp_abs(tempx->c, tempy->c)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); GMPY_CHECK_ERANGE(result, context, "invalid comparison with NaN"); return result; } TYPE_ERROR("cmp_abs() requires integer, rational, real, or complex arguments"); return NULL; #endif } gmpy2-2.1.0b3/src/gmpy2_cmp.h0000664000175000017500000000443413452460010015504 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_cmp.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_CMP_H #define GMPY_CMP_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPANY_cmp(PyObject *self, PyObject *args); static PyObject * GMPy_MPANY_cmp_abs(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_const.c0000664000175000017500000001651413425751653016070 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_const.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_function_const_pi, "const_pi([precision=0]) -> number\n\n" "Return the constant pi using the specified precision. If no\n" "precision is specified, the default precision is used."); static PyObject * GMPy_Function_Const_Pi(PyObject *self, PyObject *args, PyObject *keywds) { MPFR_Object *result = NULL; mpfr_prec_t bits = 0; static char *kwlist[] = {"precision", NULL}; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!PyArg_ParseTupleAndKeywords(args, keywds, "|l", kwlist, &bits)) { return NULL; } if ((result = GMPy_MPFR_New(bits, context))) { mpfr_clear_flags(); result->rc = mpfr_const_pi(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_context_const_pi, "context.const_pi() -> number\n\n" "Return the constant pi using the context's precision."); static PyObject * GMPy_Context_Const_Pi(PyObject *self, PyObject *args) { MPFR_Object *result = NULL; CTXT_Object *context = (CTXT_Object*)self; if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_const_pi(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_const_euler, "const_euler([precision=0]) -> number\n\n" "Return the euler constant using the specified precision. If no\n" "precision is specified, the default precision is used."); static PyObject * GMPy_Function_Const_Euler(PyObject *self, PyObject *args, PyObject *keywds) { MPFR_Object *result = NULL; mpfr_prec_t bits = 0; static char *kwlist[] = {"precision", NULL}; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!PyArg_ParseTupleAndKeywords(args, keywds, "|l", kwlist, &bits)) { return NULL; } if ((result = GMPy_MPFR_New(bits, context))) { mpfr_clear_flags(); result->rc = mpfr_const_euler(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_context_const_euler, "context.const_euler() -> number\n\n" "Return the euler constant using the context's precision."); static PyObject * GMPy_Context_Const_Euler(PyObject *self, PyObject *args) { MPFR_Object *result = NULL; CTXT_Object *context = (CTXT_Object*)self; if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_const_euler(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_const_log2, "const_log2([precision=0]) -> number\n\n" "Return the log2 constant using the specified precision. If no\n" "precision is specified, the default precision is used."); static PyObject * GMPy_Function_Const_Log2(PyObject *self, PyObject *args, PyObject *keywds) { MPFR_Object *result = NULL; mpfr_prec_t bits = 0; static char *kwlist[] = {"precision", NULL}; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!PyArg_ParseTupleAndKeywords(args, keywds, "|l", kwlist, &bits)) { return NULL; } if ((result = GMPy_MPFR_New(bits, context))) { mpfr_clear_flags(); result->rc = mpfr_const_log2(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_context_const_log2, "context.const_log2() -> number\n\n" "Return the log2 constant using the context's precision."); static PyObject * GMPy_Context_Const_Log2(PyObject *self, PyObject *args) { MPFR_Object *result = NULL; CTXT_Object *context = (CTXT_Object*)self; if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_const_log2(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_const_catalan, "const_catalan([precision=0]) -> number\n\n" "Return the catalan constant using the specified precision. If no\n" "precision is specified, the default precision is used."); static PyObject * GMPy_Function_Const_Catalan(PyObject *self, PyObject *args, PyObject *keywds) { MPFR_Object *result = NULL; mpfr_prec_t bits = 0; static char *kwlist[] = {"precision", NULL}; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!PyArg_ParseTupleAndKeywords(args, keywds, "|l", kwlist, &bits)) { return NULL; } if ((result = GMPy_MPFR_New(bits, context))) { mpfr_clear_flags(); result->rc = mpfr_const_catalan(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_context_const_catalan, "context.const_catalan() -> number\n\n" "Return the catalan constant using the context's precision."); static PyObject * GMPy_Context_Const_Catalan(PyObject *self, PyObject *args) { MPFR_Object *result = NULL; CTXT_Object *context = (CTXT_Object*)self; if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_const_catalan(result->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } gmpy2-2.1.0b3/src/gmpy2_const.h0000664000175000017500000000550413425751673016074 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_const.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_CONST_H #define GMPY_CONST_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Function_Const_Pi(PyObject *self, PyObject *args, PyObject *keywds); static PyObject * GMPy_Context_Const_Pi(PyObject *self, PyObject *args); static PyObject * GMPy_Function_Const_Euler(PyObject *self, PyObject *args, PyObject *keywds); static PyObject * GMPy_Context_Const_Euler(PyObject *self, PyObject *args); static PyObject * GMPy_Function_Const_Log2(PyObject *self, PyObject *args, PyObject *keywds); static PyObject * GMPy_Context_Const_Log2(PyObject *self, PyObject *args); static PyObject * GMPy_Function_Const_Catalan(PyObject *self, PyObject *args, PyObject *keywds); static PyObject * GMPy_Context_Const_Catalan(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_context.c0000664000175000017500000014654213525427233016426 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_context.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements contexts and context managers. * * Public API * ========== * TBD * * Private API * =========== * GMPy_CTXT_New * GMPy_CTXT_Dealloc * GMPy_CTXT_Set * GMPy_CTXT_Get * GMPy_CTXT_Copy * GMPy_CTXT_ieee * GMPy_CTXT_Local * GMPy_CTXT_Context * GMPy_CTXT_Repr_Slot * GMPy_CTXT_Enter * GMPy_CTXT_Exit * GMPy_CTXT_Clear_Flags * GMPy_CTXT_Manager_New * GMPy_CTXT_Manager_Dealloc * GMPy_CTXT_Manager_Repr_Slot * GMPy_CTXT_Manager_Enter * GMPy_CTXT_Manager_Exit * plus getters & setters.... * * Internal functions * ================== * GMPy_current_context */ /* Create and delete Context objects. */ static PyObject * GMPy_CTXT_New(void) { CTXT_Object *result; if ((result = PyObject_New(CTXT_Object, &CTXT_Type))) { result->ctx.mpfr_prec = DBL_MANT_DIG; result->ctx.mpfr_round = MPFR_RNDN; result->ctx.emax = MPFR_EMAX_DEFAULT; result->ctx.emin = MPFR_EMIN_DEFAULT; result->ctx.subnormalize = 0; result->ctx.underflow = 0; result->ctx.overflow = 0; result->ctx.inexact = 0; result->ctx.invalid = 0; result->ctx.erange = 0; result->ctx.divzero = 0; result->ctx.traps = TRAP_NONE; result->ctx.real_prec = -1; result->ctx.imag_prec = -1; result->ctx.real_round = -1; result->ctx.imag_round = -1; result->ctx.allow_complex = 0; result->ctx.rational_division = 0; #ifndef WITHOUT_THREADS result->tstate = NULL; #endif } return (PyObject*)result; }; static void GMPy_CTXT_Dealloc(CTXT_Object *self) { PyObject_Del(self); }; /* Support for global and thread local contexts. */ /* Doc-string, alternate definitions below. */ PyDoc_STRVAR(GMPy_doc_set_context, "set_context(context)\n\n" "Activate a context object controlling gmpy2 arithmetic.\n"); #ifdef WITHOUT_THREADS static PyObject * GMPy_CTXT_Set(PyObject *self, PyObject *other) { if (!CTXT_Check(other)) { VALUE_ERROR("set_context() requires a context argument"); return NULL; } Py_DECREF((PyObject*)module_context); Py_INCREF((PyObject*)other); module_context = (CTXT_Object*)other; Py_RETURN_NONE; } #else /* Begin support for thread local contexts. */ /* Get the context from the thread state dictionary. */ static CTXT_Object * current_context_from_dict(void) { PyObject *dict; PyObject *tl_context; PyThreadState *tstate; dict = PyThreadState_GetDict(); if (dict == NULL) { RUNTIME_ERROR("cannot get thread state"); return NULL; } #ifdef PY3 tl_context = PyDict_GetItemWithError(dict, tls_context_key); #else tl_context = PyDict_GetItem(dict, tls_context_key); #endif if (!tl_context) { #ifdef PY3 if (PyErr_Occurred()) { return NULL; } #endif /* Set up a new thread local context. */ tl_context = GMPy_CTXT_New(); if (!tl_context) { return NULL; } if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) { Py_DECREF(tl_context); return NULL; } Py_DECREF(tl_context); } /* Cache the context of the current thread, assuming that it * will be accessed several times before a thread switch. */ tstate = PyThreadState_GET(); if (tstate) { cached_context = (CTXT_Object*)tl_context; cached_context->tstate = tstate; } /* Borrowed reference with refcount==1 */ return (CTXT_Object*)tl_context; } /* Return borrowed reference to thread local context. */ static CTXT_Object * GMPy_current_context(void) { PyThreadState *tstate = PyThreadState_GET(); if (cached_context && cached_context->tstate == tstate) { return (CTXT_Object*)cached_context; } return current_context_from_dict(); } /* Set the thread local context to a new context, decrement old reference */ static PyObject * GMPy_CTXT_Set(PyObject *self, PyObject *other) { PyObject *dict; PyThreadState *tstate; if (!CTXT_Check(other)) { VALUE_ERROR("set_context() requires a context argument"); return NULL; } dict = PyThreadState_GetDict(); if (dict == NULL) { RUNTIME_ERROR("cannot get thread state"); return NULL; } if (PyDict_SetItem(dict, tls_context_key, other) < 0) { return NULL; } /* Cache the context of the current thread, assuming that it * will be accessed several times before a thread switch. */ cached_context = NULL; tstate = PyThreadState_GET(); if (tstate) { cached_context = (CTXT_Object*)other; cached_context->tstate = tstate; } Py_RETURN_NONE; } #endif PyDoc_STRVAR(GMPy_doc_context_ieee, "ieee(size[,subnormalize=True]) -> context\n\n" "Return a new context corresponding to a standard IEEE floating point\n" "format. The supported sizes are 16, 32, 64, 128, and multiples of\n" "32 greater than 128."); static PyObject * GMPy_CTXT_ieee(PyObject *self, PyObject *args, PyObject *kwargs) { long bitwidth; double bitlog2; int sub_mode=1; PyObject *temp; CTXT_Object *result; static char *kwlist[] = {"subnormalize", NULL}; if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("ieee() requires 'int' argument"); return NULL; } bitwidth = PyIntOrLong_AsLong(PyTuple_GET_ITEM(args, 0)); if (bitwidth == -1 && PyErr_Occurred()) { TYPE_ERROR("ieee() requires 'int' argument"); return NULL; } if (bitwidth <= 0) { VALUE_ERROR("ieee() requires positive value for size"); return NULL; } /* Process just the two keyword arguments. */ if (!(temp = PyTuple_New(0))) { return NULL; } if (!(PyArg_ParseTupleAndKeywords(temp, kwargs, "|ii", kwlist, &sub_mode))) { VALUE_ERROR("invalid keyword arguments for ieee()"); Py_DECREF(temp); return NULL; } Py_DECREF(temp); if (sub_mode) sub_mode = 1; if (!(result = (CTXT_Object*)GMPy_CTXT_New())) { return NULL; } if (bitwidth == 16) { result->ctx.mpfr_prec = 11; result->ctx.emax = 16; } else if (bitwidth == 32) { result->ctx.mpfr_prec = 24; result->ctx.emax = 128; } else if (bitwidth == 64) { result->ctx.mpfr_prec = 53; result->ctx.emax = 1024; } else if (bitwidth == 128) { result->ctx.mpfr_prec = 113; result->ctx.emax = 16384; } else { if ((bitwidth < 128) && (bitwidth & 31)) { VALUE_ERROR("bitwidth must be 16, 32, 64, 128; or must be greater than 128 and divisible by 32."); Py_DECREF((PyObject*)result); return NULL; } bitlog2 = floor((4 * log(bitwidth) / log(2.0)) + 0.5); result->ctx.mpfr_prec = bitwidth - (long)(bitlog2) + 13; result->ctx.emax = 1 << (bitwidth - result->ctx.mpfr_prec - 1); } result->ctx.subnormalize = sub_mode; result->ctx.emin = 4 - result->ctx.emax - result->ctx.mpfr_prec; return (PyObject*)result; } /* Create and delete ContextManager objects. */ static PyObject * GMPy_CTXT_Manager_New(void) { PyObject *result; result = (PyObject*)PyObject_New(CTXT_Manager_Object, &CTXT_Manager_Type); ((CTXT_Manager_Object*)(result))->new_context = NULL; ((CTXT_Manager_Object*)(result))->old_context = NULL; return result; } static void GMPy_CTXT_Manager_Dealloc(CTXT_Manager_Object *self) { Py_XDECREF(self->new_context); Py_XDECREF(self->old_context); PyObject_Del(self); } /* Helper function to convert to convert a rounding mode to a string. */ static PyObject * _round_to_name(int val) { if (val == MPFR_RNDN) return Py2or3String_FromString("RoundToNearest"); if (val == MPFR_RNDZ) return Py2or3String_FromString("RoundToZero"); if (val == MPFR_RNDU) return Py2or3String_FromString("RoundUp"); if (val == MPFR_RNDD) return Py2or3String_FromString("RoundDown"); if (val == MPFR_RNDA) return Py2or3String_FromString("RoundAwayZero"); if (val == GMPY_DEFAULT) return Py2or3String_FromString("Default"); return NULL; } static PyObject * GMPy_CTXT_Repr_Slot(CTXT_Object *self) { PyObject *format; PyObject *tuple; PyObject *result = NULL; int i = 0; tuple = PyTuple_New(23); if (!tuple) return NULL; format = Py2or3String_FromString( "context(precision=%s, real_prec=%s, imag_prec=%s,\n" " round=%s, real_round=%s, imag_round=%s,\n" " emax=%s, emin=%s,\n" " subnormalize=%s,\n" " trap_underflow=%s, underflow=%s,\n" " trap_overflow=%s, overflow=%s,\n" " trap_inexact=%s, inexact=%s,\n" " trap_invalid=%s, invalid=%s,\n" " trap_erange=%s, erange=%s,\n" " trap_divzero=%s, divzero=%s,\n" " allow_complex=%s,\n" " rational_division=%s)" ); if (!format) { Py_DECREF(tuple); return NULL; } PyTuple_SET_ITEM(tuple, i++, PyIntOrLong_FromLong(self->ctx.mpfr_prec)); if (self->ctx.real_prec == GMPY_DEFAULT) PyTuple_SET_ITEM(tuple, i++, Py2or3String_FromString("Default")); else PyTuple_SET_ITEM(tuple, i++, PyIntOrLong_FromLong(self->ctx.real_prec)); if (self->ctx.imag_prec == GMPY_DEFAULT) PyTuple_SET_ITEM(tuple, i++, Py2or3String_FromString("Default")); else PyTuple_SET_ITEM(tuple, i++, PyIntOrLong_FromLong(self->ctx.imag_prec)); PyTuple_SET_ITEM(tuple, i++, _round_to_name(self->ctx.mpfr_round)); PyTuple_SET_ITEM(tuple, i++, _round_to_name(self->ctx.real_round)); PyTuple_SET_ITEM(tuple, i++, _round_to_name(self->ctx.imag_round)); PyTuple_SET_ITEM(tuple, i++, PyIntOrLong_FromLong(self->ctx.emax)); PyTuple_SET_ITEM(tuple, i++, PyIntOrLong_FromLong(self->ctx.emin)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.subnormalize)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.traps & TRAP_UNDERFLOW)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.underflow)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.traps & TRAP_OVERFLOW)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.overflow)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.traps & TRAP_INEXACT)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.inexact)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.traps & TRAP_INVALID)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.invalid)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.traps & TRAP_ERANGE)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.erange)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.traps & TRAP_DIVZERO)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.divzero)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.allow_complex)); PyTuple_SET_ITEM(tuple, i++, PyBool_FromLong(self->ctx.rational_division)); if (!PyErr_Occurred()) result = Py2or3String_Format(format, tuple); else SYSTEM_ERROR("internal error in GMPy_CTXT_Repr"); Py_DECREF(format); Py_DECREF(tuple); return result; } static PyObject * GMPy_CTXT_Manager_Repr_Slot(CTXT_Manager_Object *self) { return Py_BuildValue("s", ""); } PyDoc_STRVAR(GMPy_doc_get_context, "get_context() -> gmpy2 context\n\n" "Return a reference to the current context."); static PyObject * GMPy_CTXT_Get(PyObject *self, PyObject *args) { CTXT_Object *context; CURRENT_CONTEXT(context); Py_XINCREF((PyObject*)context); return (PyObject*)context; } PyDoc_STRVAR(GMPy_doc_context_copy, "context.copy() -> gmpy2 context\n\n" "Return a copy of a context."); static PyObject * GMPy_CTXT_Copy(PyObject *self, PyObject *other) { CTXT_Object *result; result = (CTXT_Object*)GMPy_CTXT_New(); result->ctx = ((CTXT_Object*)self)->ctx; return (PyObject*)result; } /* Parse the keyword arguments available to a context. Returns 1 if no * error occurred; returns 0 is an error occurred. */ static int _parse_context_args(CTXT_Object *ctxt, PyObject *kwargs) { PyObject *args; int x_trap_underflow = 0, x_trap_overflow = 0, x_trap_inexact = 0; int x_trap_invalid = 0, x_trap_erange = 0, x_trap_divzero = 0; static char *kwlist[] = { "precision", "real_prec", "imag_prec", "round", "real_round", "imag_round", "emax", "emin", "subnormalize", "trap_underflow", "trap_overflow", "trap_inexact", "trap_invalid", "trap_erange", "trap_divzero", "allow_complex", "rational_division", NULL }; /* Create an empty dummy tuple to use for args. */ if (!(args = PyTuple_New(0))) { return 0; } /* Convert the trap bit positions into ints for the benefit of * PyArg_ParseTupleAndKeywords(). */ x_trap_underflow = ctxt->ctx.traps & TRAP_UNDERFLOW; x_trap_overflow = ctxt->ctx.traps & TRAP_OVERFLOW; x_trap_inexact = ctxt->ctx.traps & TRAP_INEXACT; x_trap_invalid = ctxt->ctx.traps & TRAP_INVALID; x_trap_erange = ctxt->ctx.traps & TRAP_ERANGE; x_trap_divzero = ctxt->ctx.traps & TRAP_DIVZERO; if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "|llliiilliiiiiiiii", kwlist, &ctxt->ctx.mpfr_prec, &ctxt->ctx.real_prec, &ctxt->ctx.imag_prec, &ctxt->ctx.mpfr_round, &ctxt->ctx.real_round, &ctxt->ctx.imag_round, &ctxt->ctx.emax, &ctxt->ctx.emin, &ctxt->ctx.subnormalize, &x_trap_underflow, &x_trap_overflow, &x_trap_inexact, &x_trap_invalid, &x_trap_erange, &x_trap_divzero, &ctxt->ctx.allow_complex, &ctxt->ctx.rational_division))) { VALUE_ERROR("invalid keyword arguments for context"); Py_DECREF(args); return 0; } Py_DECREF(args); ctxt->ctx.traps = TRAP_NONE; if (x_trap_underflow) ctxt->ctx.traps |= TRAP_UNDERFLOW; if (x_trap_overflow) ctxt->ctx.traps |= TRAP_OVERFLOW; if (x_trap_inexact) ctxt->ctx.traps |= TRAP_INEXACT; if (x_trap_invalid) ctxt->ctx.traps |= TRAP_INVALID; if (x_trap_erange) ctxt->ctx.traps |= TRAP_ERANGE; if (x_trap_divzero) ctxt->ctx.traps |= TRAP_DIVZERO; if (ctxt->ctx.subnormalize) ctxt->ctx.subnormalize = 1; /* Sanity check for values. */ if (ctxt->ctx.mpfr_prec < MPFR_PREC_MIN || ctxt->ctx.mpfr_prec > MPFR_PREC_MAX) { VALUE_ERROR("invalid value for precision"); return 0; } if (!(ctxt->ctx.real_prec == GMPY_DEFAULT || (ctxt->ctx.real_prec >= MPFR_PREC_MIN && ctxt->ctx.real_prec <= MPFR_PREC_MAX))) { VALUE_ERROR("invalid value for real_prec"); return 0; } if (!(ctxt->ctx.imag_prec == GMPY_DEFAULT || (ctxt->ctx.imag_prec >= MPFR_PREC_MIN && ctxt->ctx.imag_prec <= MPFR_PREC_MAX))) { VALUE_ERROR("invalid value for imag_prec"); return 0; } if (!(ctxt->ctx.mpfr_round == MPFR_RNDN || ctxt->ctx.mpfr_round == MPFR_RNDZ || ctxt->ctx.mpfr_round == MPFR_RNDU || ctxt->ctx.mpfr_round == MPFR_RNDD || ctxt->ctx.mpfr_round == MPFR_RNDA)) { VALUE_ERROR("invalid value for round"); return 0; } if (ctxt->ctx.mpfr_round == MPFR_RNDA) { /* Since RNDA is not supported for MPC, set the MPC rounding modes * to MPFR_RNDN. */ ctxt->ctx.real_round = MPFR_RNDN; ctxt->ctx.imag_round = MPFR_RNDN; } if (!(ctxt->ctx.real_round == MPFR_RNDN || ctxt->ctx.real_round == MPFR_RNDZ || ctxt->ctx.real_round == MPFR_RNDU || ctxt->ctx.real_round == MPFR_RNDD || ctxt->ctx.real_round == GMPY_DEFAULT)) { VALUE_ERROR("invalid value for real_round"); return 0; } if (!(ctxt->ctx.imag_round == MPFR_RNDN || ctxt->ctx.imag_round == MPFR_RNDZ || ctxt->ctx.imag_round == MPFR_RNDU || ctxt->ctx.imag_round == MPFR_RNDD || ctxt->ctx.imag_round == GMPY_DEFAULT)) { VALUE_ERROR("invalid value for imag_round"); return 0; } if (ctxt->ctx.emin < mpfr_get_emin_min() || ctxt->ctx.emin > mpfr_get_emin_max()) { VALUE_ERROR("invalid value for emin"); return 0; } if (ctxt->ctx.emax < mpfr_get_emax_min() || ctxt->ctx.emax > mpfr_get_emax_max()) { VALUE_ERROR("invalid value for emax"); return 0; } return 1; } PyDoc_STRVAR(GMPy_doc_local_context, "local_context([context[,keywords]]) -> context manager\n\n" "Create a context manager object that will restore the current context\n" "when the 'with ...' block terminates. The temporary context for the\n" "'with ...' block is based on the current context if no context is\n" "specified. Keyword arguments are supported and will modify the\n" "temporary new context."); static PyObject * GMPy_CTXT_Local(PyObject *self, PyObject *args, PyObject *kwargs) { CTXT_Manager_Object *result; int arg_context = 0; CTXT_Object *context, *temp; CURRENT_CONTEXT(context); if (PyTuple_GET_SIZE(args) == 1 && CTXT_Check(PyTuple_GET_ITEM(args, 0))) { arg_context = 1; } else if (PyTuple_GET_SIZE(args)) { VALUE_ERROR("local_context() only supports [context[,keyword]] arguments"); return NULL; } if (!(result = (CTXT_Manager_Object*)GMPy_CTXT_Manager_New())) return NULL; if (arg_context) { temp = (CTXT_Object*)PyTuple_GET_ITEM(args, 0); result->new_context = temp; Py_INCREF((PyObject*)(result->new_context)); } else { result->new_context = context; Py_INCREF((PyObject*)(result->new_context)); } result->old_context = (CTXT_Object*)GMPy_CTXT_Copy((PyObject*)context, NULL); if (!(result->old_context)) { Py_DECREF((PyObject*)result); return NULL; } if (!_parse_context_args(result->new_context, kwargs)) { /* There was an error parsing the keyword arguments. */ Py_DECREF((PyObject*)result); return NULL; } else { /* Parsing was successful. */ return (PyObject*)result; } } PyDoc_STRVAR(GMPy_doc_context, "context() -> context manager\n\n" "Return a new context for controlling MPFR and MPC arithmetic. To load\n" "the new context, use set_context(). Options can only be specified as\n" "keyword arguments. \n" "\nOptions\n" " precision: precision, in bits, of an MPFR result\n" " real_prec: precision, in bits, of Re(MPC)\n" " -1 implies use mpfr_prec\n" " imag_prec: precision, in bits, of Im(MPC)\n" " -1 implies use real_prec\n" " round: rounding mode for MPFR\n" " real_round: rounding mode for Re(MPC)\n" " -1 implies use mpfr_round\n" " imag_round: rounding mode for Im(MPC)\n" " -1 implies use real_round\n" " e_max: maximum allowed exponent\n" " e_min: minimum allowed exponent\n" " subnormalize: if True, subnormalized results can be returned\n" " trap_underflow: if True, raise exception for underflow\n" " if False, set underflow flag\n" " trap_overflow: if True, raise exception for overflow\n" " if False, set overflow flag and return Inf or -Inf\n" " trap_inexact: if True, raise exception for inexact result\n" " if False, set inexact flag\n" " trap_invalid: if True, raise exception for invalid operation\n" " if False, set invalid flag and return NaN\n" " trap_erange: if True, raise exception for range error\n" " if False, set erange flag\n" " trap_divzero: if True, raise exception for division by zero\n" " if False, set divzero flag and return Inf or -Inf\n" " allow_complex: if True, allow mpfr functions to return mpc\n" " if False, mpfr functions cannot return an mpc\n" " rational_division: if True, mpz/mpz returns an mpq\n" " if False, mpz/mpz follows default behavior\n"); #if 0 "\nMethods\n" " abs(x) return absolute value of x\n" " acos(x) return inverse cosine of x\n" " acosh(x) return inverse hyperbolic cosine of x\n" " add(x,y) return x + y\n" " agm(x,y) return arthimetic-geometric mean of x and y\n" " ai(x) return the Airy function of x\n" " asin(x) return inverse sine of x\n" " asinh(x) return inverse hyperbolic sine of x\n" " atan(x) return inverse tangent of x\n" " atan2(y,x) return inverse tangent of (y / x)\n" " atanh(x) return inverse hyperbolic tangent of x\n" " cbrt(x) return cube root of x\n" " ceil(x) return ceiling of x\n" " check_range(x) return value with exponents within current range\n" " clear_flags() clear all exception flags\n" " const_catalan() return Catalan constant (0.91596559...)\n" " const_euler() return Euler contstant (0.57721566...)\n" " const_log() return natural log of 2 (0.69314718...)\n" " const_pi() return Pi (3.14159265...)\n" " copy() return a copy of the context\n" " cos(x) return cosine of x\n" " cosh(x) return hyperbolic cosine of x\n" " cot(x) return cotangent of x\n" " coth(x) return hyperbolic cotangent of x\n" " csc(x) return cosecant of x\n" " csch(x) return hyperbolic cosecant of x\n" " degrees(x) convert value in radians to degrees\n" " digamma(x) return the digamma of x\n" " div(x,y) return x / y\n" " divmod(x,y) return integer quotient and remainder\n" " div_2exp(x,n) return x / 2**n)\n" " eint(x) return exponential integral of x\n" " erf(x) return error function of x\n" " erfc(x) return complementary error function of x\n" " exp(x) return e**x\n" " exp10(x) return 10**x\n" " exp2(x) return 2**x\n" " expm1(x) return e**x - 1\n" " factorial(n) return floating-point approximation to n!\n" " floor(x) return floor of x\n" " fma(x,y,z) return correctly rounded (x * y) + z\n" " fmod(x,y) return x - int(x / y) * y, rounding to 0\n" " fms(x,y,z) return correctly rounded (x * y) - z\n" " fsum(i) return accurate sum of iterable i\n" " gamma(x) return gamma of x\n" " hypot(y,x) return square root of (x**2 + y**2)\n" " is_finite(x) return True if x is finite\n" " is_infinite(x)\n" " is_nan(x)\n" " is_zero(x)\n" " j0(x) return Bessel of first kind of order 0 of x\n" " j1(x) return Bessel of first kind of order 1 of x\n" " jn(x,n) return Bessel of first kind of order n of x\n" " lgamma(x) return tuple (log(abs(gamma(x)), sign(gamma(x)))\n" " li2(x) return real part of dilogarithm of x\n" " lngamma(x) return logarithm of gamma of x\n" " log(x) return natural logarithm of x\n" " log10(x) return base-10 logarithm of x\n" " log2(x) return base-2 logarithm of x\n" " max2(x,y) return maximum of x and y, rounded to context\n" " mpc(...) create a new instance of an mpc\n" " mpfr(...) create a new instance of an mpfr\n" " minus(x) return -x\n" " min2(x,y) return minimum of x and y, rounded to context\n" " mul(x,y) return x * y\n" " mul_2exp(x,n) return x * 2**n\n" " next_above(x) return next mpfr towards +Infinity\n" " next_below(x) return next mpfr towards -Infinity\n" " plus(x) return +x\n" " pow(x,y) return x ** y\n" " radians(x) convert value in degrees to radians\n" " rec_sqrt(x) return 1 / sqrt(x)\n" " rel_diff(x,y) return abs(x - y) / x\n" " remainder(x,y) return x - int(x / y) * y, rounding to even\n" " remquo(x,y) return tuple of remainder(x,y) and low bits of\n" " the quotient\n" " rint(x) return x rounded to integer with current rounding\n" " rint_ceil(x) ...\n" " rint_floor(x) ...\n" " rint_round(x) ...\n" " rint_trunc(x) ...\n" " root(x,n) return the n-th of x\n" #ifdef MPC_110 " root_of_unity() return the k-th power of the n-th root of mpc(1)\n" #endif " round2(x,n) return x rounded to n bits.\n" " round_away(x) return x rounded to integer, ties away from 0\n" " sec(x) return secant of x\n" " sech(x) return hyperbolic secant of x\n" " sin(x) return sine of x\n" " sin_cos(x) return tuple (sin(x), cos(x))\n" " sinh(x) return hyperbolic sine of x\n" " sinh_cosh(x) return tuple (sinh(x), cosh(x))\n" " sqrt(x) return square root of x\n" " square(x) return x * x\n" " sub(x) return x - y\n" " tan(x) return tangent of x\n" " tanh(x) return hyperbolic tangent of x\n" " trunc(x) return x rounded towards 0\n" " y0(x) return Bessel of second kind of order 0 of x\n" " y1(x) return Bessel of second kind of order 1 of x\n" " yn(x,n) return Bessel of second kind of order n of x\n" " zeta(x) return Riemann zeta of x" #endif static PyObject * GMPy_CTXT_Context(PyObject *self, PyObject *args, PyObject *kwargs) { CTXT_Object *result; if (PyTuple_GET_SIZE(args)) { VALUE_ERROR("context() only supports keyword arguments"); return NULL; } if (!(result = (CTXT_Object*)GMPy_CTXT_New())) return NULL; if (!_parse_context_args(result, kwargs)) { /* There was an error parsing the keyword arguments. */ Py_DECREF((PyObject*)result); return NULL; } else { /* Parsing was successful. */ return (PyObject*)result; } } static PyObject * GMPy_CTXT_Manager_Enter(PyObject *self, PyObject *args) { PyObject *temp; temp = GMPy_CTXT_Set(NULL, (PyObject*)((CTXT_Manager_Object*)self)->new_context); if (!temp) return NULL; Py_DECREF(temp); Py_INCREF((PyObject*)(((CTXT_Manager_Object*)self)->new_context)); return (PyObject*)(((CTXT_Manager_Object*)self)->new_context); } static PyObject * GMPy_CTXT_Manager_Exit(PyObject *self, PyObject *args) { PyObject *temp; temp = GMPy_CTXT_Set(NULL, (PyObject*)((CTXT_Manager_Object*)self)->old_context); if (!temp) return NULL; Py_DECREF(temp); Py_RETURN_NONE; } static PyObject * GMPy_CTXT_Enter(PyObject *self, PyObject *args) { PyObject *temp; PyObject *result; result = GMPy_CTXT_Copy(self, NULL); if (!result) return NULL; temp = GMPy_CTXT_Set(NULL, result); if (!temp) return NULL; Py_DECREF(temp); return result; } static PyObject * GMPy_CTXT_Exit(PyObject *self, PyObject *args) { PyObject *temp; temp = GMPy_CTXT_Set(NULL, self); if (!temp) return NULL; Py_DECREF(temp); Py_RETURN_NONE; } PyDoc_STRVAR(GMPy_doc_context_clear_flags, "clear_flags()\n\n" "Clear all MPFR exception flags."); static PyObject * GMPy_CTXT_Clear_Flags(PyObject *self, PyObject *args) { ((CTXT_Object*)self)->ctx.underflow = 0; ((CTXT_Object*)self)->ctx.overflow = 0; ((CTXT_Object*)self)->ctx.inexact = 0; ((CTXT_Object*)self)->ctx.invalid = 0; ((CTXT_Object*)self)->ctx.erange = 0; ((CTXT_Object*)self)->ctx.divzero = 0; Py_RETURN_NONE; } /* Define the get/set functions. */ #define GETSET_BOOLEAN(NAME) \ static PyObject * \ GMPy_CTXT_Get_##NAME(CTXT_Object *self, void *closure) \ { \ return PyBool_FromLong(self->ctx.NAME); \ }; \ static int \ GMPy_CTXT_Set_##NAME(CTXT_Object *self, PyObject *value, void *closure) \ { \ if (!(PyBool_Check(value))) { \ TYPE_ERROR(#NAME " must be True or False"); \ return -1; \ } \ self->ctx.NAME = (value == Py_True) ? 1 : 0; \ return 0; \ } /* Define the get/set functions. This version works with the individual * bits in the traps field. */ #define GETSET_BOOLEAN_BIT(NAME, TRAP) \ static PyObject * \ GMPy_CTXT_Get_##NAME(CTXT_Object *self, void *closure) \ { \ return PyBool_FromLong(self->ctx.traps & TRAP); \ }; \ static int \ GMPy_CTXT_Set_##NAME(CTXT_Object *self, PyObject *value, void *closure) \ { \ if (!(PyBool_Check(value))) { \ TYPE_ERROR(#NAME " must be True or False"); \ return -1; \ } \ if (value == Py_True) \ self->ctx.traps |= TRAP; \ else \ self->ctx.traps &= ~(TRAP); \ return 0; \ } GETSET_BOOLEAN(subnormalize); GETSET_BOOLEAN(underflow); GETSET_BOOLEAN(overflow); GETSET_BOOLEAN(inexact); GETSET_BOOLEAN(invalid); GETSET_BOOLEAN(erange); GETSET_BOOLEAN(divzero); GETSET_BOOLEAN_BIT(trap_underflow, TRAP_UNDERFLOW); GETSET_BOOLEAN_BIT(trap_overflow, TRAP_OVERFLOW); GETSET_BOOLEAN_BIT(trap_inexact, TRAP_INEXACT); GETSET_BOOLEAN_BIT(trap_invalid, TRAP_INVALID); GETSET_BOOLEAN_BIT(trap_erange, TRAP_ERANGE); GETSET_BOOLEAN_BIT(trap_divzero, TRAP_DIVZERO); GETSET_BOOLEAN(allow_complex) GETSET_BOOLEAN(rational_division) static PyObject * GMPy_CTXT_Get_precision(CTXT_Object *self, void *closure) { return PyIntOrLong_FromSsize_t((Py_ssize_t)(self->ctx.mpfr_prec)); } static int GMPy_CTXT_Set_precision(CTXT_Object *self, PyObject *value, void *closure) { Py_ssize_t temp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("precision must be Python integer"); return -1; } temp = PyIntOrLong_AsSsize_t(value); /* A return value of -1 indicates an error has occurred. Since -1 is not * a legal value, we don't specifically check for an error condition. */ if (temp < MPFR_PREC_MIN || temp > MPFR_PREC_MAX) { VALUE_ERROR("invalid value for precision"); return -1; } self->ctx.mpfr_prec = (mpfr_prec_t)temp; return 0; } static PyObject * GMPy_CTXT_Get_real_prec(CTXT_Object *self, void *closure) { return PyIntOrLong_FromSsize_t((Py_ssize_t)(GET_REAL_PREC(self))); } static int GMPy_CTXT_Set_real_prec(CTXT_Object *self, PyObject *value, void *closure) { Py_ssize_t temp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("real_prec must be Python integer"); return -1; } temp = PyIntOrLong_AsSsize_t(value); /* A return value of -1 indicates an error has occurred. Since -1 is not * a legal value, we don't specifically check for an error condition. */ if (temp < MPFR_PREC_MIN || temp > MPFR_PREC_MAX) { VALUE_ERROR("invalid value for real_prec"); return -1; } self->ctx.real_prec = (mpfr_prec_t)temp; return 0; } static PyObject * GMPy_CTXT_Get_imag_prec(CTXT_Object *self, void *closure) { return PyIntOrLong_FromSsize_t((Py_ssize_t)(GET_IMAG_PREC(self))); } static int GMPy_CTXT_Set_imag_prec(CTXT_Object *self, PyObject *value, void *closure) { Py_ssize_t temp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("imag_prec must be Python integer"); return -1; } temp = PyIntOrLong_AsSsize_t(value); /* A return value of -1 indicates an error has occurred. Since -1 is not * a legal value, we don't specifically check for an error condition. */ if (temp < MPFR_PREC_MIN || temp > MPFR_PREC_MAX) { VALUE_ERROR("invalid value for imag_prec"); return -1; } self->ctx.imag_prec = (mpfr_prec_t)temp; return 0; } static PyObject * GMPy_CTXT_Get_round(CTXT_Object *self, void *closure) { return PyIntOrLong_FromLong((long)(self->ctx.mpfr_round)); } static int GMPy_CTXT_Set_round(CTXT_Object *self, PyObject *value, void *closure) { long temp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("round mode must be Python integer"); return -1; } temp = PyIntOrLong_AsLong(value); if (temp == -1 && PyErr_Occurred()) { VALUE_ERROR("invalid value for round mode"); return -1; } if (temp == MPFR_RNDN) self->ctx.mpfr_round = MPFR_RNDN; else if (temp == MPFR_RNDZ) self->ctx.mpfr_round = MPFR_RNDZ; else if (temp == MPFR_RNDU) self->ctx.mpfr_round = MPFR_RNDU; else if (temp == MPFR_RNDD) self->ctx.mpfr_round = MPFR_RNDD; else if (temp == MPFR_RNDA) { self->ctx.mpfr_round = MPFR_RNDA; /* Since RNDA is not supported for MPC, set the MPC rounding modes to MPFR_RNDN. */ self->ctx.real_round = MPFR_RNDN; self->ctx.imag_round = MPFR_RNDN; } else { VALUE_ERROR("invalid value for round mode"); return -1; } return 0; } static PyObject * GMPy_CTXT_Get_real_round(CTXT_Object *self, void *closure) { return PyIntOrLong_FromLong((long)GET_REAL_ROUND(self)); } static int GMPy_CTXT_Set_real_round(CTXT_Object *self, PyObject *value, void *closure) { long temp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("round mode must be Python integer"); return -1; } temp = PyIntOrLong_AsLong(value); if (temp == -1 && PyErr_Occurred()) { VALUE_ERROR("invalid value for round mode"); return -1; } if (temp == GMPY_DEFAULT || temp == MPFR_RNDN || temp == MPFR_RNDZ || temp == MPFR_RNDU || temp == MPFR_RNDD) { self->ctx.real_round = (int)temp; } else { VALUE_ERROR("invalid value for round mode"); return -1; } return 0; } static PyObject * GMPy_CTXT_Get_imag_round(CTXT_Object *self, void *closure) { return PyIntOrLong_FromLong((long)GET_IMAG_ROUND(self)); } static int GMPy_CTXT_Set_imag_round(CTXT_Object *self, PyObject *value, void *closure) { long temp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("round mode must be Python integer"); return -1; } temp = PyIntOrLong_AsLong(value); if (temp == -1 && PyErr_Occurred()) { VALUE_ERROR("invalid value for round mode"); return -1; } if (temp == GMPY_DEFAULT || temp == MPFR_RNDN || temp == MPFR_RNDZ || temp == MPFR_RNDU || temp == MPFR_RNDD) { self->ctx.imag_round = (int)temp; } else { VALUE_ERROR("invalid value for round mode"); return -1; } return 0; } static PyObject * GMPy_CTXT_Get_emin(CTXT_Object *self, void *closure) { return PyIntOrLong_FromLong(self->ctx.emin); } static int GMPy_CTXT_Set_emin(CTXT_Object *self, PyObject *value, void *closure) { long exp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("emin must be Python integer"); return -1; } exp = PyIntOrLong_AsLong(value); if (exp == -1 && PyErr_Occurred()) { VALUE_ERROR("requested minimum exponent is invalid"); return -1; } if (!(exp >= MPFR_EMIN_MIN && exp <= MPFR_EMIN_MAX)) { VALUE_ERROR("requested minimum exponent is invalid"); return -1; } self->ctx.emin = exp; return 0; } static PyObject * GMPy_CTXT_Get_emax(CTXT_Object *self, void *closure) { return PyIntOrLong_FromLong(self->ctx.emax); } static int GMPy_CTXT_Set_emax(CTXT_Object *self, PyObject *value, void *closure) { long exp; if (!(PyIntOrLong_Check(value))) { TYPE_ERROR("emax must be Python integer"); return -1; } exp = PyIntOrLong_AsLong(value); if (exp == -1 && PyErr_Occurred()) { VALUE_ERROR("requested maximum exponent is invalid"); return -1; } if (!(exp >= MPFR_EMAX_MIN && exp <= MPFR_EMAX_MAX)) { VALUE_ERROR("requested maximum exponent is invalid"); return -1; } self->ctx.emax = exp; return 0; } #define ADD_GETSET(NAME) \ {#NAME, \ (getter)GMPy_CTXT_Get_##NAME, \ (setter)GMPy_CTXT_Set_##NAME, NULL, NULL} static PyGetSetDef GMPyContext_getseters[] = { ADD_GETSET(precision), ADD_GETSET(real_prec), ADD_GETSET(imag_prec), ADD_GETSET(round), ADD_GETSET(real_round), ADD_GETSET(imag_round), ADD_GETSET(emax), ADD_GETSET(emin), ADD_GETSET(subnormalize), ADD_GETSET(underflow), ADD_GETSET(overflow), ADD_GETSET(inexact), ADD_GETSET(invalid), ADD_GETSET(erange), ADD_GETSET(divzero), ADD_GETSET(trap_underflow), ADD_GETSET(trap_overflow), ADD_GETSET(trap_inexact), ADD_GETSET(trap_invalid), ADD_GETSET(trap_erange), ADD_GETSET(trap_divzero), ADD_GETSET(allow_complex), ADD_GETSET(rational_division), {NULL} }; static PyMethodDef GMPyContext_methods[] = { { "abs", GMPy_Context_Abs, METH_O, GMPy_doc_context_abs }, { "acos", GMPy_Context_Acos, METH_O, GMPy_doc_context_acos }, { "acosh", GMPy_Context_Acosh, METH_O, GMPy_doc_context_acosh }, { "add", GMPy_Context_Add, METH_VARARGS, GMPy_doc_context_add }, { "agm", GMPy_Context_AGM, METH_VARARGS, GMPy_doc_context_agm }, { "ai", GMPy_Context_Ai, METH_O, GMPy_doc_context_ai }, { "asin", GMPy_Context_Asin, METH_O, GMPy_doc_context_asin }, { "asinh", GMPy_Context_Asinh, METH_O, GMPy_doc_context_asinh }, { "atan", GMPy_Context_Atan, METH_O, GMPy_doc_context_atan }, { "atanh", GMPy_Context_Atanh, METH_O, GMPy_doc_context_atanh }, { "atan2", GMPy_Context_Atan2, METH_VARARGS, GMPy_doc_context_atan2 }, { "clear_flags", GMPy_CTXT_Clear_Flags, METH_NOARGS, GMPy_doc_context_clear_flags }, { "cbrt", GMPy_Context_Cbrt, METH_O, GMPy_doc_context_cbrt }, { "ceil", GMPy_Context_Ceil, METH_O, GMPy_doc_context_ceil }, { "check_range", GMPy_Context_CheckRange, METH_O, GMPy_doc_context_check_range }, { "const_catalan", GMPy_Context_Const_Catalan, METH_NOARGS, GMPy_doc_context_const_catalan }, { "const_euler", GMPy_Context_Const_Euler, METH_NOARGS, GMPy_doc_context_const_euler }, { "const_log2", GMPy_Context_Const_Log2, METH_NOARGS, GMPy_doc_context_const_log2 }, { "const_pi", GMPy_Context_Const_Pi, METH_NOARGS, GMPy_doc_context_const_pi }, { "cos", GMPy_Context_Cos, METH_O, GMPy_doc_context_cos }, { "cosh", GMPy_Context_Cosh, METH_O, GMPy_doc_context_cosh }, { "cot", GMPy_Context_Cot, METH_O, GMPy_doc_context_cot }, { "coth", GMPy_Context_Coth, METH_O, GMPy_doc_context_coth }, { "copy", GMPy_CTXT_Copy, METH_NOARGS, GMPy_doc_context_copy }, { "csc", GMPy_Context_Csc, METH_O, GMPy_doc_context_csc }, { "csch", GMPy_Context_Csch, METH_O, GMPy_doc_context_csch }, { "degrees", GMPy_Context_Degrees, METH_O, GMPy_doc_context_degrees }, { "digamma", GMPy_Context_Digamma, METH_O, GMPy_doc_context_digamma }, { "div", GMPy_Context_TrueDiv, METH_VARARGS, GMPy_doc_context_truediv }, { "divmod", GMPy_Context_DivMod, METH_VARARGS, GMPy_doc_context_divmod }, { "div_2exp", GMPy_Context_Div_2exp, METH_VARARGS, GMPy_doc_context_div_2exp }, { "eint", GMPy_Context_Eint, METH_O, GMPy_doc_context_eint }, { "erf", GMPy_Context_Erf, METH_O, GMPy_doc_context_erf }, { "erfc", GMPy_Context_Erfc, METH_O, GMPy_doc_context_erfc }, { "exp", GMPy_Context_Exp, METH_O, GMPy_doc_context_exp }, { "expm1", GMPy_Context_Expm1, METH_O, GMPy_doc_context_expm1 }, { "exp10", GMPy_Context_Exp10, METH_O, GMPy_doc_context_exp10 }, { "exp2", GMPy_Context_Exp2, METH_O, GMPy_doc_context_exp2 }, { "factorial", GMPy_Context_Factorial, METH_O, GMPy_doc_context_factorial }, { "floor", GMPy_Context_Floor, METH_O, GMPy_doc_context_floor }, { "floor_div", GMPy_Context_FloorDiv, METH_VARARGS, GMPy_doc_context_floordiv }, { "fma", GMPy_Context_FMA, METH_VARARGS, GMPy_doc_context_fma }, { "fms", GMPy_Context_FMS, METH_VARARGS, GMPy_doc_context_fms }, #if MPFR_VERSION_MAJOR > 3 { "fmma", GMPy_Context_FMMA, METH_VARARGS, GMPy_doc_context_fmma }, { "fmms", GMPy_Context_FMMS, METH_VARARGS, GMPy_doc_context_fmms }, #endif { "fmod", GMPy_Context_Fmod, METH_VARARGS, GMPy_doc_context_fmod }, { "frac", GMPy_Context_Frac, METH_O, GMPy_doc_context_frac }, { "frexp", GMPy_Context_Frexp, METH_O, GMPy_doc_context_frexp }, { "fsum", GMPy_Context_Fsum, METH_O, GMPy_doc_context_fsum }, { "gamma", GMPy_Context_Gamma, METH_O, GMPy_doc_context_gamma }, { "hypot", GMPy_Context_Hypot, METH_VARARGS, GMPy_doc_context_hypot }, { "is_finite", GMPy_Context_Is_Finite, METH_O, GMPy_doc_context_is_finite }, { "is_infinite", GMPy_Context_Is_Infinite, METH_O, GMPy_doc_context_is_infinite }, { "is_integer", GMPy_Context_Is_Integer, METH_O, GMPy_doc_context_is_integer }, { "is_nan", GMPy_Context_Is_NAN, METH_O, GMPy_doc_context_is_nan }, { "is_regular", GMPy_Context_Is_Regular, METH_O, GMPy_doc_context_is_regular }, { "is_signed", GMPy_Context_Is_Signed, METH_O, GMPy_doc_context_is_signed }, { "is_zero", GMPy_Context_Is_Zero, METH_O, GMPy_doc_context_is_zero }, { "jn", GMPy_Context_Jn, METH_VARARGS, GMPy_doc_context_jn }, { "j0", GMPy_Context_J0, METH_O, GMPy_doc_context_j0 }, { "j1", GMPy_Context_J1, METH_O, GMPy_doc_context_j1 }, { "li2", GMPy_Context_Li2, METH_O, GMPy_doc_context_li2 }, { "lgamma", GMPy_Context_Lgamma, METH_O, GMPy_doc_context_lgamma }, { "lngamma", GMPy_Context_Lngamma, METH_O, GMPy_doc_context_lngamma }, { "log", GMPy_Context_Log, METH_O, GMPy_doc_context_log }, { "log10", GMPy_Context_Log10, METH_O, GMPy_doc_context_log10 }, { "log1p", GMPy_Context_Log1p, METH_O, GMPy_doc_context_log1p }, { "log2", GMPy_Context_Log2, METH_O, GMPy_doc_context_log2 }, { "maxnum", GMPy_Context_Maxnum, METH_VARARGS, GMPy_doc_context_maxnum }, { "minnum", GMPy_Context_Minnum, METH_VARARGS, GMPy_doc_context_minnum }, { "minus", GMPy_Context_Minus, METH_VARARGS, GMPy_doc_context_minus }, { "mod", GMPy_Context_Mod, METH_VARARGS, GMPy_doc_context_mod }, { "modf", GMPy_Context_Modf, METH_O, GMPy_doc_context_modf }, { "mul", GMPy_Context_Mul, METH_VARARGS, GMPy_doc_context_mul }, { "mul_2exp", GMPy_Context_Mul_2exp, METH_VARARGS, GMPy_doc_context_mul_2exp }, { "next_above", GMPy_Context_NextAbove, METH_O, GMPy_doc_context_next_above }, { "next_below", GMPy_Context_NextBelow, METH_O, GMPy_doc_context_next_below }, { "next_toward", GMPy_Context_NextToward, METH_VARARGS, GMPy_doc_context_next_toward }, { "norm", GMPy_Context_Norm, METH_O, GMPy_doc_context_norm }, { "phase", GMPy_Context_Phase, METH_O, GMPy_doc_context_phase }, { "plus", GMPy_Context_Plus, METH_VARARGS, GMPy_doc_context_plus }, { "polar", GMPy_Context_Polar, METH_O, GMPy_doc_context_polar }, { "proj", GMPy_Context_Proj, METH_O, GMPy_doc_context_proj }, { "pow", GMPy_Context_Pow, METH_VARARGS, GMPy_doc_context_pow }, { "radians", GMPy_Context_Radians, METH_O, GMPy_doc_context_radians }, { "rect", GMPy_Context_Rect, METH_VARARGS, GMPy_doc_context_rect }, { "rec_sqrt", GMPy_Context_RecSqrt, METH_O, GMPy_doc_context_rec_sqrt }, { "reldiff", GMPy_Context_RelDiff, METH_VARARGS, GMPy_doc_context_reldiff }, { "remainder", GMPy_Context_Remainder, METH_VARARGS, GMPy_doc_context_remainder }, { "remquo", GMPy_Context_RemQuo, METH_VARARGS, GMPy_doc_context_remquo }, { "rint", GMPy_Context_Rint, METH_O, GMPy_doc_context_rint }, { "rint_ceil", GMPy_Context_RintCeil, METH_O, GMPy_doc_context_rint_ceil }, { "rint_floor", GMPy_Context_RintFloor, METH_O, GMPy_doc_context_rint_floor }, { "rint_round", GMPy_Context_RintRound, METH_O, GMPy_doc_context_rint_round }, { "rint_trunc", GMPy_Context_RintTrunc, METH_O, GMPy_doc_context_rint_trunc }, { "root", GMPy_Context_Root, METH_VARARGS, GMPy_doc_context_root }, { "rootn", GMPy_Context_Rootn, METH_VARARGS, GMPy_doc_context_rootn }, #ifdef MPC_110 { "root_of_unity", GMPy_Context_Root_Of_Unity, METH_VARARGS, GMPy_doc_context_root_of_unity }, #endif { "round2", GMPy_Context_Round2, METH_VARARGS, GMPy_doc_context_round2 }, { "round_away", GMPy_Context_RoundAway, METH_O, GMPy_doc_context_round_away }, { "sec", GMPy_Context_Sec, METH_O, GMPy_doc_context_sec }, { "sech", GMPy_Context_Sech, METH_O, GMPy_doc_context_sech }, { "sin", GMPy_Context_Sin, METH_O, GMPy_doc_context_sin }, { "sin_cos", GMPy_Context_Sin_Cos, METH_O, GMPy_doc_context_sin_cos }, { "sinh", GMPy_Context_Sinh, METH_O, GMPy_doc_context_sinh }, { "sinh_cosh", GMPy_Context_Sinh_Cosh, METH_O, GMPy_doc_context_sinh_cosh }, { "sqrt", GMPy_Context_Sqrt, METH_O, GMPy_doc_context_sqrt }, { "square", GMPy_Context_Square, METH_O, GMPy_doc_context_square }, { "sub", GMPy_Context_Sub, METH_VARARGS, GMPy_doc_context_sub }, { "tan", GMPy_Context_Tan, METH_O, GMPy_doc_context_tan }, { "tanh", GMPy_Context_Tanh, METH_O, GMPy_doc_context_tanh }, { "trunc", GMPy_Context_Trunc, METH_O, GMPy_doc_context_trunc }, #ifdef VECTOR { "vector", GMPy_Context_Vector, METH_O, GMPy_doc_context_vector }, { "vector2", GMPy_Context_Vector2, METH_VARARGS, GMPy_doc_context_vector2 }, #endif { "yn", GMPy_Context_Yn, METH_VARARGS, GMPy_doc_context_yn }, { "y0", GMPy_Context_Y0, METH_O, GMPy_doc_context_y0 }, { "y1", GMPy_Context_Y1, METH_O, GMPy_doc_context_y1 }, { "zeta", GMPy_Context_Zeta, METH_O, GMPy_doc_context_zeta }, { "__enter__", GMPy_CTXT_Enter, METH_NOARGS, NULL }, { "__exit__", GMPy_CTXT_Exit, METH_VARARGS, NULL }, { NULL, NULL, 1 } }; static PyTypeObject CTXT_Type = { #ifdef PY3 PyVarObject_HEAD_INIT(0, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "gmpy2 context", /* tp_name */ sizeof(CTXT_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) GMPy_CTXT_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_CTXT_Repr_Slot, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "GMPY2 Context Object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ GMPyContext_methods, /* tp_methods */ 0, /* tp_members */ GMPyContext_getseters, /* tp_getset */ }; static PyMethodDef GMPyContextManager_methods[] = { { "__enter__", GMPy_CTXT_Manager_Enter, METH_NOARGS, NULL }, { "__exit__", GMPy_CTXT_Manager_Exit, METH_VARARGS, NULL }, { NULL, NULL, 1 } }; static PyTypeObject CTXT_Manager_Type = { #ifdef PY3 PyVarObject_HEAD_INIT(0, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "gmpy2 context", /* tp_name */ sizeof(CTXT_Manager_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) GMPy_CTXT_Manager_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_CTXT_Manager_Repr_Slot, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "GMPY2 Context manager", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ GMPyContextManager_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ }; gmpy2-2.1.0b3/src/gmpy2_context.h0000664000175000017500000001124213525427233016417 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_context.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_CONTEXT_H #define GMPY_CONTEXT_H #ifdef __cplusplus extern "C" { #endif #define TRAP_NONE 0 #define TRAP_UNDERFLOW 1 #define TRAP_OVERFLOW 2 #define TRAP_INEXACT 4 #define TRAP_INVALID 8 #define TRAP_ERANGE 16 #define TRAP_DIVZERO 32 /* The actual typedefs have been moved to gmpy2_types.h. */ static PyTypeObject CTXT_Type; static PyTypeObject CTXT_Manager_Type; #ifdef WITHOUT_THREADS #define CURRENT_CONTEXT(obj) obj = module_context; #else #define CURRENT_CONTEXT(obj) obj = GMPy_current_context(); #endif #define CHECK_CONTEXT(context) \ if (!context) CURRENT_CONTEXT(context); #define CTXT_Check(v) (((PyObject*)v)->ob_type == &CTXT_Type) #define CTXT_Manager_Check(v) (((PyObject*)v)->ob_type == &CTXT_Manager_Type) #define GET_MPFR_PREC(c) (c->ctx.mpfr_prec) #define GET_REAL_PREC(c) ((c->ctx.real_prec==GMPY_DEFAULT)?GET_MPFR_PREC(c):c->ctx.real_prec) #define GET_IMAG_PREC(c) ((c->ctx.imag_prec==GMPY_DEFAULT)?GET_REAL_PREC(c):c->ctx.imag_prec) #define GET_MPFR_ROUND(c) (c->ctx.mpfr_round) #define GET_REAL_ROUND(c) ((c->ctx.real_round==GMPY_DEFAULT)?GET_MPFR_ROUND(c):c->ctx.real_round) #define GET_IMAG_ROUND(c) ((c->ctx.imag_round==GMPY_DEFAULT)?GET_REAL_ROUND(c):c->ctx.imag_round) #define GET_MPC_ROUND(c) (MPC_RND(GET_REAL_ROUND(c), GET_IMAG_ROUND(c))) #define GET_DIV_MODE(c) (c->ctx.rational_division) static PyObject * GMPy_CTXT_Manager_New(void); static void GMPy_CTXT_Manager_Dealloc(CTXT_Manager_Object *self); static PyObject * GMPy_CTXT_Manager_Repr_Slot(CTXT_Manager_Object *self); static PyObject * GMPy_CTXT_Manager_Enter(PyObject *self, PyObject *args); static PyObject * GMPy_CTXT_Manager_Exit(PyObject *self, PyObject *args); static PyObject * GMPy_CTXT_New(void); static void GMPy_CTXT_Dealloc(CTXT_Object *self); static PyObject * GMPy_CTXT_Repr_Slot(CTXT_Object *self); static PyObject * GMPy_CTXT_Get(PyObject *self, PyObject *args); static PyObject * GMPy_CTXT_Local(PyObject *self, PyObject *args, PyObject *kwargs); static PyObject * GMPy_CTXT_Context(PyObject *self, PyObject *args, PyObject *kwargs); static PyObject * GMPy_CTXT_Set(PyObject *self, PyObject *other); static PyObject * GMPy_CTXT_Clear_Flags(PyObject *self, PyObject *args); static PyObject * GMPy_CTXT_Copy(PyObject *self, PyObject *other); static PyObject * GMPy_CTXT_ieee(PyObject *self, PyObject *args, PyObject *kwargs); static PyObject * GMPy_CTXT_Enter(PyObject *self, PyObject *args); static PyObject * GMPy_CTXT_Exit(PyObject *self, PyObject *args); #ifndef WITHOUT_THREADS static CTXT_Object * GMPy_current_context(void); #endif #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_convert.c0000664000175000017500000002020013452457765016414 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_convert.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains all the conversion functions for gmpy2. * * Overview * -------- * gmpy2 tries to optimize the performance and accuracy of conversions from * other numeric types. gmpy2 uses a LBYL (Look Before You Leap) approach and * identifies the numeric type before conversion before conversion to a gmpy2 * type. The basic operations (+, -, *, /) are optimized to directly work with * some basic types such as C longs or doubles. */ /* ======================================================================== * * Miscellaneous helper functions. * * ======================================================================== */ /* Since macros are used in gmpy2's codebase, these functions are skipped * until they are needed for the C API in the future. */ #if 0 static int GMPy_isInteger(PyObject *obj) { return IS_INTEGER(obj) ? 1 : 0; } static int GMPy_isFraction(PyObject *obj) { return (!strcmp(Py_TYPE(obj)->tp_name, "Fraction")) ? 1 : 0; } static int GMPy_isRational(PyObject *obj) { return IS_RATIONAL(obj) ? 1 : 0; } static int GMPy_isReal(PyObject *obj) { return IS_REAL(obj) ? 1 : 0; } static int GMPy_isComplex(PyObject *obj) { return IS_COMPLEX(obj) ? 1 : 0; } #endif /* mpz_set_PyStr converts a Python "string" into a mpz_t structure. It accepts * a sequence of bytes (i.e. str in Python 2, bytes in Python 3) or a Unicode * string (i.e. unicode in Python 3, str in Python 3). Returns -1 on error, * 1 if successful. */ static int mpz_set_PyStr(mpz_ptr z, PyObject *s, int base) { char *cp; Py_ssize_t len, i; PyObject *ascii_str = NULL; if (PyBytes_Check(s)) { len = PyBytes_Size(s); cp = PyBytes_AsString(s); } else if (PyUnicode_Check(s)) { ascii_str = PyUnicode_AsASCIIString(s); if (!ascii_str) { VALUE_ERROR("string contains non-ASCII characters"); return -1; } len = PyBytes_Size(ascii_str); cp = PyBytes_AsString(ascii_str); } else { TYPE_ERROR("object is not string or Unicode"); return -1; } /* Don't allow NULL characters */ for (i = 0; i < len; i++) { if (cp[i] == '\0') { VALUE_ERROR("string contains NULL characters"); Py_XDECREF(ascii_str); return -1; } } /* Check for leading base indicators. */ if (base == 0) { if (len > 2 && cp[0] == '0') { if (cp[1] == 'b') { base = 2; cp += 2; } else if (cp[1] == 'o') { base = 8; cp += 2; } else if (cp[1] == 'x') { base = 16; cp += 2; } else { base = 10; } } else { base = 10; } } else if (cp[0] == '0') { /* If the specified base matches the leading base indicators, then * we need to skip the base indicators. */ if (cp[1] =='b' && base == 2) { cp += 2; } else if (cp[1] =='o' && base == 8) { cp += 2; } else if (cp[1] =='x' && base == 16) { cp += 2; } } /* delegate rest to GMP's _set_str function */ if (-1 == mpz_set_str(z, cp, base)) { VALUE_ERROR("invalid digits"); Py_XDECREF(ascii_str); return -1; } Py_XDECREF(ascii_str); return 1; } /* Format an mpz into any base (2 to 62). Bits in the option parameter * control various behaviors: * bit 0: if set, output is wrapped with mpz(...) or xmpz(...) * bit 1: if set, a '+' is included for positive numbers * bit 2: if set, a ' ' is included for positive nubmers * bit 3: if set, a '0b', '0o', or '0x' is included for binary, octal, hex * bit 4: if set, no prefix is included for binary, octal, hex * * Note: if neither bit 3 or 4 is set, prefixes that match the platform * default are included. * * If base < 0, capital letters are used. * * If which = 0, then mpz formatting is used (if bit 0 set). Otherwise xmpz * formatting is used (if bit 0 is set). */ static char* _ztag = "mpz("; static char* _xztag = "xmpz("; static PyObject * mpz_ascii(mpz_t z, int base, int option, int which) { PyObject *result; char *buffer, *p; int negative = 0; size_t size; if ( !( ((base >= -36) && (base <= -2)) || ((base >= 2) && (base <= 62)) ) ) { VALUE_ERROR("base must be in the interval 2 ... 62"); return NULL; } /* Allocate extra space for: * * minus sign and trailing NULL byte (2) * 'xmpz()' tag (6) * '0x' prefix (2) * ----- * 10 * * And add one more to be sure... */ size = mpz_sizeinbase(z, (base < 0 ? -base : base)) + 11; TEMP_ALLOC(buffer, size); if (mpz_sgn(z) < 0) { negative = 1; mpz_neg(z, z); } p = buffer; if (option & 1) { if (which) strcpy(p, _xztag); else strcpy(p, _ztag); p += strlen(p); } if (negative) { *(p++) = '-'; } else { if (option & 2) *(p++) = '+'; else if (option & 4) *(p++) = ' '; } if (option & 8) { if (base == 2) { *(p++) = '0'; *(p++) = 'b'; } else if (base == 8) { *(p++) = '0'; *(p++) = 'o'; } else if (base == 16) { *(p++) = '0'; *(p++) = 'x'; } else if (base == -16) { *(p++) = '0'; *(p++) = 'X'; } } else if (!(option & 24)) { #ifdef PY2 if (base == 8) { *(p++) = '0'; } #else if (base == 2) { *(p++) = '0'; *(p++) = 'b'; } else if (base == 8) { *(p++) = '0'; *(p++) = 'o'; } #endif else if (base == 16) { *(p++) = '0'; *(p++) = 'x'; } else if (base == -16) { *(p++) = '0'; *(p++) = 'X'; } } /* Call GMP. */ mpz_get_str(p, base, z); p = buffer + strlen(buffer); if (option & 1) *(p++) = ')'; *(p++) = '\00'; result = Py_BuildValue("s", buffer); if (negative == 1) { mpz_neg(z, z); } TEMP_FREE(buffer, size); return result; } gmpy2-2.1.0b3/src/gmpy2_convert.h0000664000175000017500000001150713512447155016420 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_convert.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_CONVERT_H #define GMPY2_CONVERT_H #ifdef __cplusplus extern "C" { #endif /* The following macros classify the numeric types that are supported by * gmpy2. */ #define HAS_MPZ_CONVERSION(x) PyObject_HasAttrString(x, "__mpz__") #define HAS_MPQ_CONVERSION(x) PyObject_HasAttrString(x, "__mpq__") #define HAS_MPFR_CONVERSION(x) PyObject_HasAttrString(x, "__mpfr__") #define HAS_MPC_CONVERSION(x) PyObject_HasAttrString(x, "__mpc__") #define HAS_STRICT_MPZ_CONVERSION(x) (HAS_MPZ_CONVERSION(x) && \ !HAS_MPQ_CONVERSION(x)) #define HAS_STRICT_MPFR_CONVERSION(x) (HAS_MPFR_CONVERSION(x) && \ !HAS_MPC_CONVERSION(x)) #define IS_FRACTION(x) (!strcmp(Py_TYPE(x)->tp_name, "Fraction")) #define IS_RATIONAL_ONLY(x) (MPQ_Check(x) || IS_FRACTION(x) || HAS_MPQ_CONVERSION(x)) #ifdef PY2 #define IS_INTEGER(x) (MPZ_Check(x) || PyInt_Check(x) || \ PyLong_Check(x) || XMPZ_Check(x) || \ HAS_STRICT_MPZ_CONVERSION(x)) #define IS_RATIONAL(x) (MPQ_Check(x) || IS_FRACTION(x) || \ MPZ_Check(x) || PyInt_Check(x) || PyLong_Check(x) || \ XMPZ_Check(x) || HAS_MPQ_CONVERSION(x) || \ HAS_MPZ_CONVERSION(x)) #else #define IS_INTEGER(x) (MPZ_Check(x) || PyLong_Check(x) || \ XMPZ_Check(x) || HAS_STRICT_MPZ_CONVERSION(x)) #define IS_RATIONAL(x) (MPQ_Check(x) || IS_FRACTION(x) || \ MPZ_Check(x) || PyLong_Check(x) || \ XMPZ_Check(x) || HAS_MPQ_CONVERSION(x) || \ HAS_MPZ_CONVERSION(x)) #endif #define IS_REAL_ONLY(x) (MPFR_Check(x) || PyFloat_Check(x) || HAS_STRICT_MPFR_CONVERSION(x)) #define IS_REAL(x) (IS_RATIONAL(x) || IS_REAL_ONLY(x)) #define IS_COMPLEX_ONLY(x) (MPC_Check(x) || PyComplex_Check(x) || HAS_MPC_CONVERSION(x)) #define IS_COMPLEX(x) (IS_REAL(x) || IS_COMPLEX_ONLY(x)) /* Since the macros are used in gmpy2's codebase, these functions are skipped * until they are needed for the C API in the future. */ #if 0 /* Checks for mpz, xmpz, and the integer types included with Python. */ static int GMPy_isInteger(PyObject *obj); /* Checks for the Fraction type included with Python. */ static int GMPy_isFraction(PyObject *obj); /* Combined mpq, isInteger() and isFraction() check. */ static int GMPy_isRational(PyObject *obj); /* Combined mpfr, PyFloat, and isRational() check. */ static int GMPy_isReal(PyObject *obj); /* Combined mpc, PyComplex, and isReal() check. */ static int GMPy_isComplex(PyObject *obj); #endif /* ======== C helper routines ======== */ static int mpz_set_PyStr(mpz_ptr z, PyObject *s, int base); static PyObject * mpz_ascii(mpz_t z, int base, int option, int which); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_convert_gmp.c0000664000175000017500000007135113473132013017247 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_convert_gmp.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains all the conversion functions for GMP data types. * * Overview * -------- * gmpy2 tries to optimize the performance and accuracy of conversions from * other numeric types. gmpy2 uses a LBYL (Look Before You Leap) approach and * identifies the numeric type before conversion before conversion to a gmpy2 * type. The basic operations (+, -, *, /) are optimized to directly work with * some basic types such as C longs or doubles. */ /* ======================================================================== * * Conversion between native Python objects and MPZ. * * ======================================================================== */ static MPZ_Object * GMPy_MPZ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context) { MPZ_Object *result; int negative; Py_ssize_t len; PyLongObject *templong = (PyLongObject*)obj; assert(PyIntOrLong_Check(obj)); if(!(result = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } #ifdef PY2 if (PyInt_Check(obj)) { mpz_set_si(result->z, PyInt_AS_LONG(obj)); return result; } #endif switch (Py_SIZE(templong)) { case -1: mpz_set_si(result->z, -(sdigit)templong->ob_digit[0]); break; case 0: mpz_set_si(result->z, 0); break; case 1: mpz_set_si(result->z, templong->ob_digit[0]); break; default: mpz_set_si(result->z, 0); if (Py_SIZE(templong) < 0) { len = - Py_SIZE(templong); negative = 1; } else { len = Py_SIZE(templong); negative = 0; } mpz_import(result->z, len, -1, sizeof(templong->ob_digit[0]), 0, sizeof(templong->ob_digit[0])*8 - PyLong_SHIFT, templong->ob_digit); if (negative) { mpz_neg(result->z, result->z); } } return result; } /* To support creation of temporary mpz objects. */ static void mpz_set_PyIntOrLong(mpz_t z, PyObject *obj) { int negative; Py_ssize_t len; PyLongObject *templong = (PyLongObject*)obj; #ifdef PY2 if (PyInt_Check(obj)) { mpz_set_si(z, PyInt_AS_LONG(obj)); return; } #endif switch (Py_SIZE(templong)) { case -1: mpz_set_si(z, -(sdigit)templong->ob_digit[0]); break; case 0: mpz_set_si(z, 0); break; case 1: mpz_set_si(z, templong->ob_digit[0]); break; default: mpz_set_si(z, 0); if (Py_SIZE(templong) < 0) { len = - Py_SIZE(templong); negative = 1; } else { len = Py_SIZE(templong); negative = 0; } mpz_import(z, len, -1, sizeof(templong->ob_digit[0]), 0, sizeof(templong->ob_digit[0])*8 - PyLong_SHIFT, templong->ob_digit); if (negative) { mpz_neg(z, z); } } return; } static MPZ_Object * GMPy_MPZ_From_PyStr(PyObject *s, int base, CTXT_Object *context) { MPZ_Object *result; if (!(result = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (mpz_set_PyStr(result->z, s, base) == -1) { Py_DECREF((PyObject*)result); return NULL; } return result; } static MPZ_Object * GMPy_MPZ_From_PyFloat(PyObject *obj, CTXT_Object *context) { MPZ_Object *result; assert(PyFloat_Check(obj)); if ((result = GMPy_MPZ_New(context))) { double d = PyFloat_AsDouble(obj); if (Py_IS_NAN(d)) { Py_DECREF((PyObject*)result); VALUE_ERROR("'mpz' does not support NaN"); return NULL; } if (Py_IS_INFINITY(d)) { Py_DECREF((PyObject*)result); OVERFLOW_ERROR("'mpz' does not support Infinity"); return NULL; } mpz_set_d(result->z, d); } return result; } static PyObject * GMPy_PyLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context) { int negative; size_t count, size; PyLongObject *result; assert(CHECK_MPZANY(obj)); /* Assume gmp uses limbs as least as large as the builtin longs do */ assert(mp_bits_per_limb >= PyLong_SHIFT); if (mpz_sgn(obj->z) < 0) { negative = 1; } else { negative = 0; } size = (mpz_sizeinbase(obj->z, 2) + PyLong_SHIFT - 1) / PyLong_SHIFT; if (!(result = _PyLong_New(size))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpz_export(result->ob_digit, &count, -1, sizeof(result->ob_digit[0]), 0, sizeof(result->ob_digit[0])*8 - PyLong_SHIFT, obj->z); if (count == 0) { result->ob_digit[0] = 0; } /* long_normalize() is file-static so we must reimplement it */ /* longobjp = long_normalize(longobjp); */ while ((size>0) && (result->ob_digit[size-1] == 0)) { size--; } Py_SIZE(result) = size; if (negative) { Py_SIZE(result) = - Py_SIZE(result); } return (PyObject*)result; } #ifdef PY2 static PyObject * GMPy_MPZ_Long_Slot(MPZ_Object *self) { return GMPy_PyLong_From_MPZ(self, NULL); } #endif /* The PyIntOrLong functions should be used when converting a number back * to a Python value since is automatically returns an "int" or "long" when * using Python 2.x. The PyLong_From functions (above) should only be used * when a PyLong is specifically needed for Python 2.x. */ static PyObject * GMPy_PyIntOrLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context) { assert(CHECK_MPZANY(obj)); #ifdef PY2 if (mpz_fits_slong_p(obj->z)) { /* cast is safe since we know it fits in a signed long */ return PyInt_FromLong((long)mpz_get_si(obj->z)); } #endif return GMPy_PyLong_From_MPZ(obj, context); } static PyObject * GMPy_MPZ_Int_Slot(MPZ_Object *self) { return GMPy_PyIntOrLong_From_MPZ(self, NULL); } static PyObject * GMPy_PyFloat_From_MPZ(MPZ_Object *obj, CTXT_Object *context) { double res; assert(CHECK_MPZANY(obj)); res = mpz_get_d(obj->z); if (Py_IS_INFINITY(res)) { OVERFLOW_ERROR("'mpz' too large to convert to float"); return NULL; } return PyFloat_FromDouble(res); } static PyObject * GMPy_MPZ_Float_Slot(MPZ_Object *self) { return GMPy_PyFloat_From_MPZ(self, NULL); } static PyObject * GMPy_PyStr_From_MPZ(MPZ_Object *obj, int base, int option, CTXT_Object *context) { assert(CHECK_MPZANY(obj)); return mpz_ascii(obj->z, base, option, 0); } static MPZ_Object * GMPy_MPZ_From_Integer(PyObject *obj, CTXT_Object *context) { MPZ_Object *result = NULL; if (MPZ_Check(obj)) { Py_INCREF(obj); return (MPZ_Object*)obj; } if (PyIntOrLong_Check(obj)) return GMPy_MPZ_From_PyIntOrLong(obj, context); if (XMPZ_Check(obj)) return GMPy_MPZ_From_XMPZ((XMPZ_Object*)obj, context); if (HAS_STRICT_MPZ_CONVERSION(obj)) { result = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL); if (result != NULL && MPZ_Check(result)) { return result; } else { Py_XDECREF((PyObject*)result); goto error; } } error: TYPE_ERROR("cannot convert object to mpz"); return NULL; } static MPZ_Object * GMPy_MPZ_From_IntegerAndCopy(PyObject *obj, CTXT_Object *context) { MPZ_Object *result = NULL, *temp = NULL; result = GMPy_MPZ_From_Integer(obj, context); if (result == NULL) return result; if (Py_REFCNT(result) == 1) return result; if (!(temp = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpz_set(temp->z, result->z); Py_DECREF((PyObject*)result); return temp; } /* str and repr implementations for mpz */ static PyObject * GMPy_MPZ_Str_Slot(MPZ_Object *self) { /* base-10, no tag */ return GMPy_PyStr_From_MPZ(self, 10, 0, NULL); } static PyObject * GMPy_MPZ_Repr_Slot(MPZ_Object *self) { /* base-10, with tag */ return GMPy_PyStr_From_MPZ(self, 10, 1, NULL); } #ifdef SHARED /* Helper function for argument parsing. Not used in static build. */ static int GMPy_MPZ_ConvertArg(PyObject *arg, PyObject **ptr) { MPZ_Object *result = GMPy_MPZ_From_Integer(arg, NULL); if (result) { *ptr = (PyObject*)result; return 1; } else { TYPE_ERROR("argument can not be converted to 'mpz'"); return 0; } } #endif /* ======================================================================== * * Conversion between native Python objects/MPZ and XMPZ. * * ======================================================================== */ static XMPZ_Object * GMPy_XMPZ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context) { XMPZ_Object *result; int negative; Py_ssize_t len; PyLongObject *templong = (PyLongObject*)obj; assert(PyIntOrLong_Check(obj)); if(!(result = GMPy_XMPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } #ifdef PY2 if (PyInt_Check(obj)) { mpz_set_si(result->z, PyInt_AS_LONG(obj)); return result; } #endif switch (Py_SIZE(templong)) { case -1: mpz_set_si(result->z, -(sdigit)templong->ob_digit[0]); break; case 0: mpz_set_si(result->z, 0); break; case 1: mpz_set_si(result->z, templong->ob_digit[0]); break; default: mpz_set_si(result->z, 0); if (Py_SIZE(templong) < 0) { len = - Py_SIZE(templong); negative = 1; } else { len = Py_SIZE(templong); negative = 0; } mpz_import(result->z, len, -1, sizeof(templong->ob_digit[0]), 0, sizeof(templong->ob_digit[0])*8 - PyLong_SHIFT, templong->ob_digit); if (negative) { mpz_neg(result->z, result->z); } } return result; } static XMPZ_Object * GMPy_XMPZ_From_PyStr(PyObject *s, int base, CTXT_Object *context) { XMPZ_Object *result; if (!(result = GMPy_XMPZ_New(context))) return NULL; if (mpz_set_PyStr(result->z, s, base) == -1) { Py_DECREF((PyObject*)result); return NULL; } return result; } static XMPZ_Object * GMPy_XMPZ_From_PyFloat(PyObject *obj, CTXT_Object *context) { XMPZ_Object *result; assert(PyFloat_Check(obj)); if ((result = GMPy_XMPZ_New(context))) { double d = PyFloat_AsDouble(obj); if (Py_IS_NAN(d)) { Py_DECREF((PyObject*)result); VALUE_ERROR("'xmpz' does not support NaN"); return NULL; } if (Py_IS_INFINITY(d)) { Py_DECREF((PyObject*)result); OVERFLOW_ERROR("'xmpz' does not support Infinity"); return NULL; } mpz_set_d(result->z, d); } return result; } static XMPZ_Object * GMPy_XMPZ_From_MPZ(MPZ_Object *obj, CTXT_Object *context) { XMPZ_Object *result; assert(CHECK_MPZANY(obj)); if ((result = GMPy_XMPZ_New(context))) mpz_set(result->z, obj->z); return result; } static XMPZ_Object * GMPy_XMPZ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context) { XMPZ_Object *result; assert(XMPZ_Check(obj)); if ((result = GMPy_XMPZ_New(context))) mpz_set(result->z, obj->z); return result; } static PyObject * GMPy_PyStr_From_XMPZ(XMPZ_Object *obj, int base, int option, CTXT_Object *context) { assert(XMPZ_Check(obj)); return mpz_ascii(obj->z, base, option, 1); } static MPZ_Object * GMPy_MPZ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context) { MPZ_Object *result; assert(XMPZ_Check(obj)); if ((result = GMPy_MPZ_New(context))) mpz_set(result->z, obj->z); return result; } /* str and repr implementations for xmpz */ static PyObject * GMPy_XMPZ_Str_Slot(XMPZ_Object *self) { /* base-10, no tag */ return GMPy_PyStr_From_XMPZ(self, 10, 0, NULL); } static PyObject * GMPy_XMPZ_Repr_Slot(XMPZ_Object *self) { /* base-10, with tag */ return GMPy_PyStr_From_XMPZ(self, 10, 1, NULL); } /* ======================================================================== * * Conversion between native Python objects/MPZ/XMPZ and MPQ. * * ======================================================================== */ static MPQ_Object * GMPy_MPQ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context) { MPQ_Object *result; MPZ_Object *temp; assert(PyIntOrLong_Check(obj)); temp = GMPy_MPZ_From_PyIntOrLong(obj, context); if (!temp) return NULL; if ((result = GMPy_MPQ_New(context))) { mpq_set_z(result->q, temp->z); Py_DECREF((PyObject*)temp); } return result; } static MPQ_Object * GMPy_MPQ_From_PyStr(PyObject *s, int base, CTXT_Object *context) { MPQ_Object *result; char *cp; char exp_char = 'E'; Py_ssize_t len, i; PyObject *ascii_str = NULL; long expt = 0; if (!(result = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (PyBytes_Check(s)) { len = PyBytes_Size(s); cp = PyBytes_AsString(s); } else if (PyUnicode_Check(s)) { ascii_str = PyUnicode_AsASCIIString(s); if (!ascii_str) { VALUE_ERROR("string contains non-ASCII characters"); goto error; } len = PyBytes_Size(ascii_str); cp = PyBytes_AsString(ascii_str); } else { TYPE_ERROR("object is not string or Unicode"); goto error; } /* Don't allow NULL characters */ for (i = 0; i < len; i++) { if (cp[i] == '\0') { VALUE_ERROR("string contains NULL characters"); goto error; } } { char *whereslash = strchr((char*)cp, '/'); char *wheredot = strchr((char*)cp, '.'); char *whereexp = strchr((char*)cp, 'E'); if (!whereexp) { whereexp = strchr((char*)cp, 'e'); exp_char = 'e'; } if (whereslash && wheredot) { VALUE_ERROR("illegal string: both . and / found"); goto error; } if (wheredot && (base != 10)) { VALUE_ERROR("illegal string: embedded . requires base=10"); goto error; } /* If base=10, no slash is found, and an exponent symbol is found, then * assume we have decimal number in scientific format. */ if (whereexp && !whereslash && (base == 10)) { /* Temporarily shorten the string and continue processing as * normal. We'll deal with the exponent later. */ *whereexp = '\0'; expt = atol(whereexp+1); } /* Handle the case where an embedded decimal point exists. An optional * exponent is also allowed. We take advantage of the fact that * mpz_set_str() ignores embedded space characters. We count the * number of digits after the decimal point and then replace the '.' * with a ' '. We've already inserted a NUL byte to terminate the * string in the case when an exponent was entered. The value for * the exponent has already been read. */ if (wheredot) { char *counter; long digits = 0; counter = wheredot; digits = 0; *wheredot = ' '; while (*++counter != '\0') { if (isdigit(*counter)) digits++; } if (-1 == mpz_set_str(mpq_numref(result->q), (char*)cp, base)) { if (wheredot) *wheredot = '.'; /* Restore the exponent! */ if (whereexp && !whereslash && (base == 10)) *whereexp = exp_char; VALUE_ERROR("invalid digits"); goto error; } /* Process the exponent. */ digits = expt - digits; if (digits < 0) { mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(-digits)); } else { /* Use the denominator instead of a temporary variable. */ mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(digits)); mpz_mul(mpq_numref(result->q), mpq_numref(result->q), mpq_denref(result->q)); mpz_set_ui(mpq_denref(result->q), 1); } mpq_canonicalize(result->q); /* Restore the decimal point. */ *wheredot = '.'; /* Restore the exponent! */ if (whereexp && (base == 10)) *whereexp = exp_char; goto finish; } if (whereslash) *whereslash = '\0'; /* Read the numerator. */ if (-1 == mpz_set_str(mpq_numref(result->q), (char*)cp, base)) { if (whereslash) *whereslash = '/'; VALUE_ERROR("invalid digits"); goto error; } /* If a slash was present, read the denominator. */ if (whereslash) { *whereslash = '/'; if (-1 == mpz_set_str(mpq_denref(result->q), whereslash+1, base)) { VALUE_ERROR("invalid digits"); goto error; } if (0 == mpz_sgn(mpq_denref(result->q))) { ZERO_ERROR("zero denominator in mpq()"); goto error; } mpq_canonicalize(result->q); } else { /* Since no slash was present, either the denominator is 1 or a * power of 10. */ if (expt <= 0) { mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(-expt)); } else { mpz_ui_pow_ui(mpq_denref(result->q), 10, (unsigned long)(expt)); mpz_mul(mpq_numref(result->q), mpq_numref(result->q), mpq_denref(result->q)); mpz_set_ui(mpq_denref(result->q), 1); } mpq_canonicalize(result->q); if (whereexp && (base == 10)) *whereexp = exp_char; } } finish: Py_XDECREF(ascii_str); return result; error: Py_DECREF((PyObject*)result); Py_XDECREF(ascii_str); return NULL; } static MPQ_Object * GMPy_MPQ_From_PyFloat(PyObject *obj, CTXT_Object *context) { MPQ_Object *result; assert(PyFloat_Check(obj)); if ((result = GMPy_MPQ_New(context))) { double d = PyFloat_AsDouble(obj); if (Py_IS_NAN(d)) { Py_DECREF((PyObject*)result); VALUE_ERROR("'mpq' does not support NaN"); return NULL; } if (Py_IS_INFINITY(d)) { Py_DECREF((PyObject*)result); OVERFLOW_ERROR("'mpq' does not support Infinity"); return NULL; } mpq_set_d(result->q, d); } return result; } static MPQ_Object * GMPy_MPQ_From_MPZ(MPZ_Object *obj, CTXT_Object *context) { MPQ_Object *result; assert(CHECK_MPZANY(obj)); if ((result = GMPy_MPQ_New(context))) mpq_set_z(result->q, obj->z); return result; } static MPQ_Object * GMPy_MPQ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context) { MPQ_Object *result; assert(XMPZ_Check(obj)); if ((result = GMPy_MPQ_New(context))) mpq_set_z(result->q, obj->z); return result; } static MPZ_Object * GMPy_MPZ_From_MPQ(MPQ_Object *obj, CTXT_Object *context) { MPZ_Object *result; assert(MPQ_Check(obj)); if ((result = GMPy_MPZ_New(context))) mpz_set_q(result->z, obj->q); return result; } static XMPZ_Object * GMPy_XMPZ_From_MPQ(MPQ_Object *obj, CTXT_Object *context) { XMPZ_Object *result; assert(MPQ_Check(obj)); if ((result = GMPy_XMPZ_New(context))) mpz_set_q(result->z, obj->q); return result; } #ifdef PY2 static PyObject * GMPy_PyLong_From_MPQ(MPQ_Object *obj, CTXT_Object *context) { PyObject *result; MPZ_Object *temp; assert(MPQ_Check(obj)); temp = GMPy_MPZ_From_MPQ(obj, context); if (!temp) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } result = GMPy_PyLong_From_MPZ(temp, context); Py_DECREF((PyObject*)temp); return result; } static PyObject * GMPy_MPQ_Long_Slot(MPQ_Object *self) { return GMPy_PyLong_From_MPQ(self, NULL); } #endif static PyObject * GMPy_PyIntOrLong_From_MPQ(MPQ_Object *obj, CTXT_Object *context) { PyObject *result; MPZ_Object *temp; assert(MPQ_Check(obj)); temp = GMPy_MPZ_From_MPQ(obj, context); if (!temp) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } result = GMPy_PyIntOrLong_From_MPZ(temp, context); Py_DECREF((PyObject*)temp); return result; } static PyObject * GMPy_MPQ_Int_Slot(MPQ_Object *self) { return GMPy_PyIntOrLong_From_MPQ(self, NULL); } static char* _qtag = "mpq("; static PyObject * GMPy_PyStr_From_MPQ(MPQ_Object *obj, int base, int option, CTXT_Object *context) { PyObject *result = NULL, *numstr = NULL, *denstr = NULL; char buffer[50], *p; numstr = mpz_ascii(mpq_numref(obj->q), base, 0, 0); if (!numstr) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } /* Check if denominator is 1 and no tag is requested. If so, just * return the numerator. */ if (!(option & 1) && (0 == mpz_cmp_ui(mpq_denref(obj->q),1))) return numstr; denstr = mpz_ascii(mpq_denref(obj->q), base, 0, 0); if (!denstr) { /* LCOV_EXCL_START */ Py_DECREF(numstr); return NULL; /* LCOV_EXCL_STOP */ } /* Build the format string. */ p = buffer; if (option & 1) { strcpy(p, _qtag); p += strlen(p); } #ifdef PY2 *(p++) = '%'; *(p++) = 's'; if (option & 1) *(p++) = ','; else *(p++) = '/'; *(p++) = '%'; *(p++) = 's'; if (option & 1) *(p++) = ')'; *(p++) = '\00'; result = PyString_FromFormat(buffer, PyString_AS_STRING(numstr), PyString_AS_STRING(denstr)); #else *(p++) = '%'; *(p++) = 'U'; if (option & 1) *(p++) = ','; else *(p++) = '/'; *(p++) = '%'; *(p++) = 'U'; if (option & 1) *(p++) = ')'; *(p++) = '\00'; result = PyUnicode_FromFormat(buffer, numstr, denstr); #endif Py_DECREF(numstr); Py_DECREF(denstr); return result; } static PyObject * GMPy_PyFloat_From_MPQ(MPQ_Object *obj, CTXT_Object *context) { double res; assert(MPQ_Check(obj)); res = mpq_get_d(obj->q); if (Py_IS_INFINITY(res)) { OVERFLOW_ERROR("'mpq' too large to convert to float"); return NULL; } return PyFloat_FromDouble(res); } static PyObject * GMPy_MPQ_Float_Slot(MPQ_Object *self) { return GMPy_PyFloat_From_MPQ(self, NULL); } static MPQ_Object* GMPy_MPQ_From_Fraction(PyObject* obj, CTXT_Object *context) { MPQ_Object *result; PyObject *num, *den; if (!(result = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpq_set_si(result->q, 0, 1); num = PyObject_GetAttrString(obj, "numerator"); den = PyObject_GetAttrString(obj, "denominator"); if (!num || !PyIntOrLong_Check(num) || !den || !PyIntOrLong_Check(den)) { SYSTEM_ERROR("Object does not appear to be Fraction"); Py_XDECREF(num); Py_XDECREF(den); Py_DECREF((PyObject*)result); return NULL; } mpz_set_PyIntOrLong(mpq_numref(result->q), num); mpz_set_PyIntOrLong(mpq_denref(result->q), den); Py_DECREF(num); Py_DECREF(den); return result; } static MPQ_Object* GMPy_MPQ_From_Number(PyObject *obj, CTXT_Object *context) { if (MPQ_Check(obj)) { Py_INCREF(obj); return (MPQ_Object*)obj; } if (MPZ_Check(obj)) return GMPy_MPQ_From_MPZ((MPZ_Object*)obj, context); if (MPFR_Check(obj)) return GMPy_MPQ_From_MPFR((MPFR_Object*)obj, context); if (PyFloat_Check(obj)) return GMPy_MPQ_From_PyFloat(obj, context); if (PyIntOrLong_Check(obj)) return GMPy_MPQ_From_PyIntOrLong(obj, context); if (XMPZ_Check(obj)) return GMPy_MPQ_From_XMPZ((XMPZ_Object*)obj, context); if (IS_FRACTION(obj)) return GMPy_MPQ_From_Fraction(obj, context); if (HAS_MPQ_CONVERSION(obj)) { MPQ_Object * res = (MPQ_Object *) PyObject_CallMethod(obj, "__mpq__", NULL); if (res != NULL && MPQ_Check(res)) { return res; } else { Py_XDECREF((PyObject*)res); goto error; } } if (HAS_MPZ_CONVERSION(obj)) { MPZ_Object * res = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL); if (res != NULL && MPZ_Check(res)) { MPQ_Object * temp = GMPy_MPQ_From_MPZ(res, context); Py_DECREF(res); return temp; } else { Py_XDECREF((PyObject*)res); goto error; } } error: TYPE_ERROR("cannot convert object to mpq"); return NULL; } static MPQ_Object* GMPy_MPQ_From_RationalAndCopy(PyObject *obj, CTXT_Object *context) { MPQ_Object *result = NULL, *temp = NULL; result = GMPy_MPQ_From_Rational(obj, context); if (result == NULL) return result; if (Py_REFCNT(result) == 1) return result; if (!(temp = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpq_set(temp->q, result->q); Py_DECREF((PyObject*)result); return temp; } static MPQ_Object* GMPy_MPQ_From_Rational(PyObject *obj, CTXT_Object *context) { if (MPQ_Check(obj)) { Py_INCREF(obj); return (MPQ_Object*)obj; } if (MPZ_Check(obj)) return GMPy_MPQ_From_MPZ((MPZ_Object*)obj, context); if (PyIntOrLong_Check(obj)) return GMPy_MPQ_From_PyIntOrLong(obj, context); if (XMPZ_Check(obj)) return GMPy_MPQ_From_XMPZ((XMPZ_Object*)obj, context); if (IS_FRACTION(obj)) return GMPy_MPQ_From_Fraction(obj, context); TYPE_ERROR("cannot convert object to mpq"); return NULL; } /* * coerce any number to a mpq */ #ifdef SHARED /* Helper function for argument parsing. Not used in static build. */ int GMPy_MPQ_ConvertArg(PyObject *arg, PyObject **ptr) { MPQ_Object* result = GMPy_MPQ_From_Number(arg, NULL); if (result) { *ptr = (PyObject*)result; return 1; } else { if (!PyErr_Occurred()) { TYPE_ERROR("argument can not be converted to 'mpq'"); } return 0; } } #endif /* str and repr implementations for mpq */ static PyObject * GMPy_MPQ_Str_Slot(MPQ_Object *self) { /* base-10, no tag */ return GMPy_PyStr_From_MPQ(self, 10, 0, NULL); } static PyObject * GMPy_MPQ_Repr_Slot(MPQ_Object *self) { /* base-10, with tag */ return GMPy_PyStr_From_MPQ(self, 10, 1, NULL); } gmpy2-2.1.0b3/src/gmpy2_convert_gmp.h0000664000175000017500000001500613473132037017255 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_convert_gmp.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_CONVERT_GMP_H #define GMPY2_CONVERT_GMP_H #ifdef __cplusplus extern "C" { #endif /* ======================================================================== * * Conversion between native Python objects and MPZ. * * ======================================================================== */ static MPZ_Object * GMPy_MPZ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context); static MPZ_Object * GMPy_MPZ_From_PyStr(PyObject *s, int base, CTXT_Object *context); static MPZ_Object * GMPy_MPZ_From_PyFloat(PyObject *obj, CTXT_Object *context); static MPZ_Object * GMPy_MPZ_From_Integer(PyObject *obj, CTXT_Object *context); static MPZ_Object * GMPy_MPZ_From_IntegerAndCopy(PyObject *obj, CTXT_Object *context); static PyObject * GMPy_MPZ_Str_Slot(MPZ_Object *self); static PyObject * GMPy_MPZ_Repr_Slot(MPZ_Object *self); #ifdef PY2 static PyObject * GMPy_PyLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context); static PyObject * GMPy_MPZ_Long_Slot(MPZ_Object *self); #endif static PyObject * GMPy_PyIntOrLong_From_MPZ(MPZ_Object *obj, CTXT_Object *context); static PyObject * GMPy_PyFloat_From_MPZ(MPZ_Object *obj, CTXT_Object *context); static PyObject * GMPy_PyStr_From_MPZ(MPZ_Object *obj, int base, int option, CTXT_Object *context); #ifdef SHARED /* static int GMPy_MPZ_ConvertArg(PyObject *arg, PyObject **ptr); */ static GMPy_MPZ_ConvertArg_RETURN GMPy_MPZ_ConvertArg GMPy_MPZ_ConvertArg_PROTO; #endif /* ======================================================================== * * Conversion between native Python objects/MPZ and XMPZ. * * ======================================================================== */ static XMPZ_Object * GMPy_XMPZ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context); static XMPZ_Object * GMPy_XMPZ_From_PyStr(PyObject *s, int base, CTXT_Object *context); static XMPZ_Object * GMPy_XMPZ_From_PyFloat(PyObject *self, CTXT_Object *context); static XMPZ_Object * GMPy_XMPZ_From_MPZ(MPZ_Object *obj, CTXT_Object *context); static XMPZ_Object * GMPy_XMPZ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context); static PyObject * GMPy_XMPZ_Str_Slot(XMPZ_Object *self); static PyObject * GMPy_XMPZ_Repr_Slot(XMPZ_Object *self); static PyObject * GMPy_PyStr_From_XMPZ(XMPZ_Object *self, int base, int option, CTXT_Object *context); static MPZ_Object * GMPy_MPZ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context); /* ======================================================================== * * Conversion between native Python objects/MPZ/XMPZ and MPQ. * * ======================================================================== */ static MPQ_Object * GMPy_MPQ_From_PyIntOrLong(PyObject *obj, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_PyStr(PyObject *s, int base, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_PyFloat(PyObject *obj, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_Fraction(PyObject *obj, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_MPZ(MPZ_Object *obj, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_XMPZ(XMPZ_Object *obj, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_Rational(PyObject* obj, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_Number(PyObject* obj, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_RationalAndCopy(PyObject* obj, CTXT_Object *context); static PyObject * GMPy_PyIntOrLong_From_MPQ(MPQ_Object *obj, CTXT_Object *context); static PyObject * GMPy_PyStr_From_MPQ(MPQ_Object *obj, int base, int option, CTXT_Object *context); static PyObject * GMPy_PyFloat_From_MPQ(MPQ_Object *obj, CTXT_Object *context); static MPZ_Object * GMPy_MPZ_From_MPQ(MPQ_Object *obj, CTXT_Object *context); static XMPZ_Object * GMPy_XMPZ_From_MPQ(MPQ_Object *obj, CTXT_Object *context); /* support str() and repr() */ static PyObject * GMPy_MPQ_Str_Slot(MPQ_Object *obj); static PyObject * GMPy_MPQ_Repr_Slot(MPQ_Object *obj); static PyObject * GMPy_MPQ_Float_Slot(MPQ_Object *obj); static PyObject * GMPy_MPQ_Int_Slot(MPQ_Object *obj); #ifdef PY2 static PyObject * GMPy_PyLong_From_MPQ(MPQ_Object *obj, CTXT_Object *context); static PyObject * GMPy_MPQ_Long_Slot(MPQ_Object *obj); #endif #ifdef SHARED /* int GMPy_MPQ_convert_arg(PyObject *arg, PyObject **ptr); */ static GMPy_MPQ_ConvertArg_RETURN GMPy_MPQ_ConvertArg GMPy_MPQ_ConvertArg_PROTO; #endif #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_convert_mpc.c0000664000175000017500000004573513525427233017263 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_convert_mpc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Please see the documentation for GMPy_MPFR_From_MPFR for detailed * description of this function. */ static MPC_Object * GMPy_MPC_From_MPC(MPC_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result = NULL; assert(MPC_Check(obj)); /* Optimize the critical case when prec==1 or obj is NaN or Inf. */ if ((rprec == 1 && iprec == 1) || (!mpfr_number_p(mpc_realref(obj->c)) && !mpfr_number_p(mpc_imagref(obj->c)))) { Py_INCREF((PyObject*)obj); return obj; } CHECK_CONTEXT(context); if (rprec == 0) rprec = GET_REAL_PREC(context); else if (rprec == 1) rprec = mpfr_get_prec(mpc_realref(obj->c)); if (iprec == 0) iprec = GET_IMAG_PREC(context); else if (iprec == 1) iprec = mpfr_get_prec(mpc_imagref(obj->c)); /* Try to identify when an additional reference to existing instance can * be returned. It is possible when (1) the precision matches, (2) the * exponent is valid and not in the range that might require subnormal- * ization, and (3) subnormalize is not enabled. */ if ((rprec == mpfr_get_prec(mpc_realref(obj->c))) && (iprec == mpfr_get_prec(mpc_imagref(obj->c))) && (!context->ctx.subnormalize) && (mpc_realref(obj->c)->_mpfr_exp >= (context->ctx.emin + mpfr_get_prec(mpc_realref(obj->c)) - 1)) && (mpc_realref(obj->c)->_mpfr_exp <= context->ctx.emax) && (mpc_imagref(obj->c)->_mpfr_exp >= (context->ctx.emin + mpfr_get_prec(mpc_imagref(obj->c)) - 1)) && (mpc_imagref(obj->c)->_mpfr_exp <= context->ctx.emax) ) { Py_INCREF((PyObject*)obj); return obj; } if ((result = GMPy_MPC_New(rprec, iprec, context))) { result->rc = mpc_set(result->c, obj->c, GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); } return result; } static MPC_Object * GMPy_MPC_From_PyComplex(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result; assert(PyComplex_Check(obj)); CHECK_CONTEXT(context); if (rprec == 0) rprec = GET_REAL_PREC(context); else if (rprec == 1) rprec = DBL_MANT_DIG; if (iprec == 0) iprec = GET_IMAG_PREC(context); else if (iprec == 1) rprec = DBL_MANT_DIG; if ((result = GMPy_MPC_New(rprec, iprec, context))) { result->rc = mpc_set_d_d(result->c, PyComplex_RealAsDouble(obj), PyComplex_ImagAsDouble(obj), GET_MPC_ROUND(context)); if (rprec != 1 || iprec != 1) { GMPY_MPC_CHECK_RANGE(result, context); } GMPY_MPC_SUBNORMALIZE(result, context); GMPY_MPC_EXCEPTIONS(result, context); } return result; } static MPC_Object * GMPy_MPC_From_MPFR(MPFR_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result; assert(MPFR_Check(obj)); CHECK_CONTEXT(context); if (rprec == 0) rprec = GET_REAL_PREC(context); else if (rprec == 1) rprec = mpfr_get_prec(obj->f); if (iprec == 0) iprec = GET_IMAG_PREC(context); else if (iprec == 1) rprec = mpfr_get_prec(obj->f); if ((result = GMPy_MPC_New(rprec, iprec, context))) { result->rc = mpc_set_fr(result->c, obj->f, GET_MPC_ROUND(context)); if (rprec != 1) { GMPY_MPC_CHECK_RANGE(result, context); } GMPY_MPC_SUBNORMALIZE(result, context); GMPY_MPC_EXCEPTIONS(result, context); } return result; } static MPC_Object * GMPy_MPC_From_PyFloat(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); assert(PyFloat_Check(obj)); if (rprec == 0) rprec = GET_REAL_PREC(context); else if (rprec == 1) rprec = DBL_MANT_DIG; if (iprec == 0) iprec = GET_IMAG_PREC(context); else if (iprec == 1) rprec = DBL_MANT_DIG; if ((result = GMPy_MPC_New(rprec, iprec, context))) { result->rc = mpc_set_d(result->c, PyFloat_AS_DOUBLE(obj), GET_MPC_ROUND(context)); if (rprec != 1) { GMPY_MPC_CHECK_RANGE(result, context); } GMPY_MPC_SUBNORMALIZE(result, context); GMPY_MPC_EXCEPTIONS(result, context); } return result; } static MPC_Object * GMPy_MPC_From_MPZ(MPZ_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result = NULL; assert(CHECK_MPZANY(obj)); CHECK_CONTEXT(context); if (rprec < 2) { rprec = GET_REAL_PREC(context); } if (iprec < 2) { iprec = GET_IMAG_PREC(context); } if ((result = GMPy_MPC_New(rprec, iprec, context))) { result->rc = mpc_set_z(result->c, obj->z, GET_MPC_ROUND(context)); if (rprec != 1) { GMPY_MPC_CHECK_RANGE(result, context); } GMPY_MPC_SUBNORMALIZE(result, context); GMPY_MPC_EXCEPTIONS(result, context); } return result; } static MPC_Object * GMPy_MPC_From_MPQ(MPQ_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result = NULL; assert(MPQ_Check(obj)); CHECK_CONTEXT(context); if (rprec < 2) { rprec = GET_REAL_PREC(context); } if (iprec < 2) { iprec = GET_IMAG_PREC(context); } if ((result = GMPy_MPC_New(rprec, iprec, context))) { result->rc = mpc_set_q(result->c, obj->q, GET_MPC_ROUND(context)); if (rprec != 1) { GMPY_MPC_CHECK_RANGE(result, context); } GMPY_MPC_SUBNORMALIZE(result, context); GMPY_MPC_EXCEPTIONS(result, context); } return result; } static MPC_Object * GMPy_MPC_From_Fraction(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result = NULL; MPQ_Object *tempq; assert(IS_RATIONAL(obj)); CHECK_CONTEXT(context); if ((tempq = GMPy_MPQ_From_Fraction(obj, context))) { result = GMPy_MPC_From_MPQ(tempq, rprec, iprec, context); Py_DECREF((PyObject*)tempq); } return result; } static MPC_Object * GMPy_MPC_From_PyIntOrLong(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result = NULL; MPZ_Object *tempz; assert(PyIntOrLong_Check(obj)); CHECK_CONTEXT(context); if ((tempz = GMPy_MPZ_From_PyIntOrLong(obj, context))) { result = GMPy_MPC_From_MPZ(tempz, rprec, iprec, context); Py_DECREF((PyObject*)tempz); } return result; } /* Python's string representation of a complex number differs from the format * used by MPC. Both MPC and Python surround the complex number with '(' and * ')' but Python adds a 'j' after the imaginary component and MPC requires a * space between the real and imaginery components. GMPy_MPC_From_PyStr tries * to work around the differences as by reading two MPFR-compatible numbers * from the string and storing into the real and imaginary components * respectively. */ static MPC_Object * GMPy_MPC_From_PyStr(PyObject *s, int base, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context) { MPC_Object *result; PyObject *ascii_str = NULL; Py_ssize_t len; char *cp, *unwind, *tempchar, *lastchar; int firstp = 0, lastp = 0, real_rc = 0, imag_rc = 0; CHECK_CONTEXT(context); if (PyBytes_Check(s)) { len = PyBytes_Size(s); cp = (char*)PyBytes_AsString(s); } else if (PyUnicode_Check(s)) { ascii_str = PyUnicode_AsASCIIString(s); if (!ascii_str) { VALUE_ERROR("string contains non-ASCII characters"); return NULL; } len = PyBytes_Size(ascii_str); cp = (char*)PyBytes_AsString(ascii_str); } else { TYPE_ERROR("string required"); return NULL; } /* Don't allow NULL characters */ if ((Py_ssize_t)strlen(cp) != len) { VALUE_ERROR("string without NULL characters expected"); Py_XDECREF(ascii_str); return NULL; } if (!(result = GMPy_MPC_New(rprec, iprec, context))) { Py_XDECREF(ascii_str); return NULL; } /* Get a pointer to the last valid character (ignoring trailing * whitespace.) */ lastchar = cp + len - 1; while (isspace(*lastchar)) lastchar--; /* Skip trailing ). */ if (*lastchar == ')') { lastp = 1; lastchar--; } /* Skip trailing j. */ if (*lastchar == 'j') lastchar--; /* Skip leading whitespace. */ while (isspace(*cp)) cp++; /* Skip a leading (. */ if (*cp == '(') { firstp = 1; cp++; } if (firstp != lastp) goto invalid_string; /* Read the real component first. */ unwind = cp; real_rc = mpfr_strtofr(mpc_realref(result->c), cp, &tempchar, base, GET_REAL_ROUND(context)); /* Verify that at least one valid character was read. */ if (cp == tempchar) goto invalid_string; /* If the next character is a j, then the real component is 0 and * we just read the imaginary componenet. */ if (*tempchar == 'j') { mpfr_set_zero(mpc_realref(result->c), MPFR_RNDN); cp = unwind; } else { /* Read the imaginary component next. */ cp = tempchar; } imag_rc = mpfr_strtofr(mpc_imagref(result->c), cp, &tempchar, base, GET_IMAG_ROUND(context)); if (cp == tempchar && tempchar > lastchar) goto valid_string; if (*tempchar != 'j' && *cp != ' ') goto invalid_string; if (tempchar <= lastchar) goto invalid_string; valid_string: Py_XDECREF(ascii_str); result->rc = MPC_INEX(real_rc, imag_rc); if (rprec != 1 || iprec != 1) { GMPY_MPC_CHECK_RANGE(result, context); } GMPY_MPC_SUBNORMALIZE(result, context); GMPY_MPC_EXCEPTIONS(result, context); return result; invalid_string: VALUE_ERROR("invalid string in mpc()"); Py_DECREF((PyObject*)result); Py_XDECREF(ascii_str); return NULL; } /* See the comments for GMPy_MPFR_From_Real_Temp. */ static MPC_Object * GMPy_MPC_From_Complex(PyObject* obj, mp_prec_t rprec, mp_prec_t iprec, CTXT_Object *context) { CHECK_CONTEXT(context); if (MPC_Check(obj)) return GMPy_MPC_From_MPC((MPC_Object*)obj, rprec, iprec, context); if (MPFR_Check(obj)) return GMPy_MPC_From_MPFR((MPFR_Object*)obj, rprec, iprec, context); if (PyFloat_Check(obj)) return GMPy_MPC_From_PyFloat(obj, rprec, iprec, context); if (PyComplex_Check(obj)) return GMPy_MPC_From_PyComplex(obj, rprec, iprec, context); if (MPQ_Check(obj)) return GMPy_MPC_From_MPQ((MPQ_Object*)obj, rprec, iprec, context); if (MPZ_Check(obj) || XMPZ_Check(obj)) return GMPy_MPC_From_MPZ((MPZ_Object*)obj, rprec, iprec, context); if (PyIntOrLong_Check(obj)) return GMPy_MPC_From_PyIntOrLong(obj, rprec, iprec, context); if (IS_FRACTION(obj)) return GMPy_MPC_From_Fraction(obj, rprec, iprec, context); if (HAS_MPC_CONVERSION(obj)) { MPC_Object * res = (MPC_Object *) PyObject_CallMethod(obj, "__mpc__", NULL); if (res != NULL && MPC_Check(res)) { return res; } else { Py_XDECREF((PyObject*)res); goto error; } } if (HAS_MPFR_CONVERSION(obj)) { MPFR_Object * res = (MPFR_Object *) PyObject_CallMethod(obj, "__mpfr__", NULL); if (res != NULL && MPFR_Check(res)) { MPC_Object * temp = GMPy_MPC_From_MPFR(res, rprec, iprec, context); Py_DECREF(res); return temp; } else { Py_XDECREF((PyObject*)res); goto error; } } if (HAS_MPQ_CONVERSION(obj)) { MPQ_Object * res = (MPQ_Object *) PyObject_CallMethod(obj, "__mpq__", NULL); if (res != NULL && MPQ_Check(res)) { MPC_Object * temp = GMPy_MPC_From_MPQ(res, rprec, iprec, context); Py_DECREF(res); return temp; } else { Py_XDECREF((PyObject*)res); goto error; } } if (HAS_MPZ_CONVERSION(obj)) { MPZ_Object * res = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL); if (res != NULL && MPZ_Check(res)) { MPC_Object * temp = GMPy_MPC_From_MPZ(res, rprec, iprec, context); Py_DECREF(res); return temp; } else { Py_XDECREF((PyObject*)res); goto error; } } error: TYPE_ERROR("object could not be converted to 'mpc'"); return NULL; } #if 0 static MPC_Object * GMPy_MPC_From_ComplexAndCopy(PyObject* obj, mp_prec_t rprec, mp_prec_t iprec, CTXT_Object *context) { MPC_Object *result = NULL, *temp = NULL; result = GMPy_MPC_From_Complex(obj, rprec, iprec, context); if (result == NULL) return result; if (Py_REFCNT(result) == 1) return result; if (!(temp = GMPy_MPC_New(rprec = mpfr_get_prec(mpc_realref(result->c)), iprec = mpfr_get_prec(mpc_imagref(result->c)), context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } /* Since the precision of temp is the same as the precision of result, * there shouldn't be any rounding. */ mpc_set(temp->c, result->c, MPFR_RNDN); Py_DECREF((PyObject*)result); return temp; } #endif static PyObject * GMPy_PyStr_From_MPC(MPC_Object *self, int base, int digits, CTXT_Object *context) { PyObject *tempreal = 0, *tempimag = 0, *result; CHECK_CONTEXT(context); if (!((base >= 2) && (base <= 62))) { VALUE_ERROR("base must be in the interval [2,62]"); return NULL; } if ((digits < 0) || (digits == 1)) { VALUE_ERROR("digits must be 0 or >= 2"); return NULL; } tempreal = mpfr_ascii(mpc_realref(self->c), base, digits, MPC_RND_RE(GET_MPC_ROUND(context))); tempimag = mpfr_ascii(mpc_imagref(self->c), base, digits, MPC_RND_IM(GET_MPC_ROUND(context))); if (!tempreal || !tempimag) { Py_XDECREF(tempreal); Py_XDECREF(tempimag); return NULL; } result = Py_BuildValue("(NN)", tempreal, tempimag); if (!result) { Py_DECREF(tempreal); Py_DECREF(tempimag); } return result; } static PyObject * GMPy_MPC_Float_Slot(PyObject *self) { TYPE_ERROR("can't covert 'mpc' to 'float'"); return NULL; } PyDoc_STRVAR(GMPy_doc_mpc_complex, "Convert 'mpc' to 'complex'."); static PyObject * GMPy_PyComplex_From_MPC(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; double real, imag; CHECK_CONTEXT(context); real = mpfr_get_d(mpc_realref(MPC(self)), GET_REAL_ROUND(context)); imag = mpfr_get_d(mpc_imagref(MPC(self)), GET_IMAG_ROUND(context)); return PyComplex_FromDoubles(real, imag); } #ifdef PY2 static PyObject * GMPy_MPC_Long_Slot(PyObject *self) { TYPE_ERROR("can't covert mpc to long"); return NULL; } #endif static PyObject * GMPy_MPC_Int_Slot(PyObject *self) { TYPE_ERROR("can't covert mpc to int"); return NULL; } #ifdef SHARED /* * coerce any number to a mpc */ int GMPy_MPC_ConvertArg(PyObject *arg, PyObject **ptr) { MPC_Object *newob = GMPy_MPC_From_Complex(arg, 0, 0, NULL); if (newob) { *ptr = (PyObject*)newob; return 1; } else { TYPE_ERROR("can't convert argument to 'mpc'"); return 0; } } #endif /* str and repr implementations for mpc */ static PyObject * GMPy_MPC_Str_Slot(MPC_Object *self) { PyObject *result, *temp; mpfr_prec_t rbits, ibits; long rprec, iprec; char fmtstr[60]; mpc_get_prec2(&rbits, &ibits, MPC(self)); rprec = (long)(log10(2) * (double)rbits) + 2; iprec = (long)(log10(2) * (double)ibits) + 2; sprintf(fmtstr, "{0:.%ld.%ldg}", rprec, iprec); temp = Py_BuildValue("s", fmtstr); if (!temp) return NULL; result = PyObject_CallMethod(temp, "format", "O", self); Py_DECREF(temp); return result; } static PyObject * GMPy_MPC_Repr_Slot(MPC_Object *self) { PyObject *result, *temp; mpfr_prec_t rbits, ibits; long rprec, iprec; char fmtstr[60]; mpc_get_prec2(&rbits, &ibits, MPC(self)); rprec = (long)(log10(2) * (double)rbits) + 2; iprec = (long)(log10(2) * (double)ibits) + 2; if (rbits != DBL_MANT_DIG || ibits !=DBL_MANT_DIG) sprintf(fmtstr, "mpc('{0:.%ld.%ldg}',(%ld,%ld))", rprec, iprec, rbits, ibits); else sprintf(fmtstr, "mpc('{0:.%ld.%ldg}')", rprec, iprec); temp = Py_BuildValue("s", fmtstr); if (!temp) return NULL; result = PyObject_CallMethod(temp, "format", "O", self); Py_DECREF(temp); return result; } gmpy2-2.1.0b3/src/gmpy2_convert_mpc.h0000664000175000017500000001034413452460010017241 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_convert_mpc.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_CONVERT_MPC_H #define GMPY2_CONVERT_MPC_H #ifdef __cplusplus extern "C" { #endif /* Conversions with Pympc */ static MPC_Object * GMPy_MPC_From_MPC(MPC_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_PyComplex(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_MPFR(MPFR_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_PyFloat(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_MPZ(MPZ_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_MPQ(MPQ_Object *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_Fraction(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_PyIntOrLong(PyObject *obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_PyStr(PyObject *s, int base, mpfr_prec_t rbits, mpfr_prec_t ibits, CTXT_Object *context); static MPC_Object * GMPy_MPC_From_Complex(PyObject* obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); #if 0 static MPC_Object * GMPy_MPC_From_ComplexAndCopy(PyObject* obj, mpfr_prec_t rprec, mpfr_prec_t iprec, CTXT_Object *context); #endif static PyObject * GMPy_MPC_Float_Slot(PyObject *self); #ifdef PY2 static PyObject * GMPy_MPC_Long_Slot(PyObject *self); #endif static PyObject * GMPy_MPC_Int_Slot(PyObject *self); static PyObject * GMPy_PyStr_From_MPC(MPC_Object *self, int base, int digits, CTXT_Object *context); static PyObject * GMPy_PyComplex_From_MPC(PyObject *self, PyObject *other); /* support str() and repr() */ static PyObject * GMPy_MPC_Str_Slot(MPC_Object *self); static PyObject * GMPy_MPC_Repr_Slot(MPC_Object *self); /* Miscellaneous */ #ifdef SHARED /* static int GMPy_MPC_convert_arg(PyObject *arg, PyObject **ptr); */ static GMPy_MPC_ConvertArg_RETURN GMPy_MPC_ConvertArg GMPy_MPC_ConvertArg_PROTO; #endif #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_convert_mpfr.c0000664000175000017500000006637713525427233017455 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_convert_mpfr.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains all the conversion functions for MPFR data types. * * Overview * -------- * gmpy2 tries to optimize the performance and accuracy of conversions from * other numeric types. The basic operations (+, -, *, /) are optimized to * directly work with the basic types such as C longs or doubles. * * gmpy2 supports two different strategies for creating new references to * an mpfr instance. If bits (or prec) is set to 0, the precison of the * result exactly matches the precision of the context. The exponent range * is also limited to the exponents defined in the contest. This is the * default behavior of the mpfr() function. * * If bits (or prec) is set to 1, the precision of the result depends on the * type of the source. * * If the source number is already a radix-2 floating point number, * the precision is not changed. In practical terms, this only applies * to sources operands that are either an mpfr or Python double. * * In addition, the exponent range is taken from the global emin/emax values * set in the MPFR library. * */ /* If prec == 0: * Return an reference to a new mpfr instance. The context argument * specifies the precision, exponent range, and whether or not subnormals * are allowed. * * This is the default behavior of the mpfr() constructor. * * If prec == 1: * Return an additional reference to an existing mpfr. The precision is not * changed. The exponent is not checked and may be outside the bounds * specified in the context argument. * * This is used internally for parsing arguments to functions. * * If prec >= 2: * Return a reference to a new mpfr instance. The precision is taken from * the argument. n instance with the specified precision and the * exponent is valid in the current context. * * This is used by mpfr() with an optional precision keyword. * * Since references to existing objects may be returned, the result should not * modified in-place. */ static MPFR_Object * GMPy_MPFR_From_MPFR(MPFR_Object *obj, mpfr_prec_t prec, CTXT_Object *context) { MPFR_Object *result = NULL; assert(MPFR_Check(obj)); /* Optimize the critical case when prec==1 or obj is NaN or Inf. */ if (prec == 1 || !mpfr_number_p(obj->f)) { Py_INCREF((PyObject*)obj); return obj; } CHECK_CONTEXT(context); if (prec == 0) prec = GET_MPFR_PREC(context); /* Try to identify when an additional reference to existing instance can * be returned. It is possible when (1) the precision matches, (2) the * exponent is valid and not in the range that might require subnormal- * ization, and (3) subnormalize is not enabled. */ if (prec == mpfr_get_prec(obj->f) && !context->ctx.subnormalize && obj->f->_mpfr_exp >= (context->ctx.emin + mpfr_get_prec(obj->f) - 1) && obj->f->_mpfr_exp <= context->ctx.emax ) { Py_INCREF((PyObject*)obj); return obj; } if ((result = GMPy_MPFR_New(prec, context))) { mpfr_clear_flags(); result->rc = mpfr_set(result->f, obj->f, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return result; } static MPFR_Object * GMPy_MPFR_From_PyIntOrLong(PyObject *obj, mpfr_prec_t prec, CTXT_Object *context) { MPFR_Object *result = NULL; MPZ_Object *tempx = NULL; int error, was_one = 0; long temp; assert(PyIntOrLong_Check(obj)); CHECK_CONTEXT(context); if (prec == 0) prec = GET_MPFR_PREC(context); if (prec == 1) { /* This should be made accurate, but is it worth the overhead? */ /* It is only used if the value fits in a C long. */ prec = 64; was_one = 1; } temp = GMPy_Integer_AsLongAndError(obj, &error); if (error) { if (!(tempx = GMPy_MPZ_From_PyIntOrLong(obj, context))) { return NULL; } if (was_one) prec = 1; result = GMPy_MPFR_From_MPZ(tempx, prec, context); Py_DECREF((PyObject*)tempx); return result; } else { if (!(result = GMPy_MPFR_New(prec, context))) return NULL; mpfr_clear_flags(); result->rc = mpfr_set_si(result->f, temp, GET_MPFR_ROUND(context)); if (!was_one) { GMPY_MPFR_CHECK_RANGE(result, context); } GMPY_MPFR_EXCEPTIONS(result, context); } return result; } /* If prec==0, then the precision of the current context is used. * * If prec==1, then the precision of Python float type is used (typically 53). * * If prec>=2, then the specified precision is used. */ static MPFR_Object * GMPy_MPFR_From_PyFloat(PyObject *obj, mpfr_prec_t prec, CTXT_Object *context) { MPFR_Object *result; assert(PyFloat_Check(obj)); CHECK_CONTEXT(context); if (prec == 0) prec = GET_MPFR_PREC(context); else if (prec == 1) prec = DBL_MANT_DIG; if ((result = GMPy_MPFR_New(prec, context))) { mpfr_clear_flags(); result->rc = mpfr_set_d(result->f, PyFloat_AS_DOUBLE(obj), GET_MPFR_ROUND(context)); if (prec != 1) { GMPY_MPFR_CHECK_RANGE(result, context); } GMPY_MPFR_SUBNORMALIZE(result, context); GMPY_MPFR_EXCEPTIONS(result, context); } return result; } /* If prec==0, then the precision of the current context is used. * * If prec==1, then an exact conversion is done by using the bit length of the * argument as the precision. * * If prec>=2, then the specified precision is used. */ static MPFR_Object * GMPy_MPFR_From_MPZ(MPZ_Object *obj, mpfr_prec_t prec, CTXT_Object *context) { MPFR_Object *result; int was_one = 0; size_t bitlen; assert(CHECK_MPZANY(obj)); CHECK_CONTEXT(context); if (prec == 0) prec = GET_MPFR_PREC(context); if (prec == 1) { bitlen = mpz_sizeinbase(obj->z, 2); if (bitlen < MPFR_PREC_MIN) { bitlen = MPFR_PREC_MIN; } if (bitlen > MPFR_PREC_MAX) { OVERFLOW_ERROR("'mpz' to large to convert to 'mpfr'\n"); return NULL; } prec = (mpfr_prec_t)bitlen; was_one = 1; } if ((result = GMPy_MPFR_New(prec, context))) { mpfr_clear_flags(); result->rc = mpfr_set_z(result->f, obj->z, GET_MPFR_ROUND(context)); if (!was_one) { GMPY_MPFR_CHECK_RANGE(result, context); } GMPY_MPFR_EXCEPTIONS(result, context); } return result; } /* If prec<2, then the precision of the current context is used. * * If prec>=2, then the specified precision is used. */ static MPFR_Object * GMPy_MPFR_From_MPQ(MPQ_Object *obj, mpfr_prec_t prec, CTXT_Object *context) { MPFR_Object *result; assert(MPQ_Check(obj)); CHECK_CONTEXT(context); if (prec < 2) prec = GET_MPFR_PREC(context); if ((result = GMPy_MPFR_New(prec, context))) { mpfr_clear_flags(); result->rc = mpfr_set_q(result->f, obj->q, GET_MPFR_ROUND(context)); GMPY_MPFR_CHECK_RANGE(result, context); GMPY_MPFR_SUBNORMALIZE(result, context); GMPY_MPFR_EXCEPTIONS(result, context); } return result; } /* If prec<2, then the precision of the current context is used. * * If prec>=2, then the specified precision is used. */ static MPFR_Object * GMPy_MPFR_From_Fraction(PyObject *obj, mpfr_prec_t prec, CTXT_Object *context) { MPFR_Object *result = NULL; MPQ_Object *tempq; assert(IS_RATIONAL(obj)); CHECK_CONTEXT(context); if ((tempq = GMPy_MPQ_From_Fraction(obj, context))) { result = GMPy_MPFR_From_MPQ(tempq, prec, context); Py_DECREF((PyObject*)tempq); } return result; } static MPFR_Object * GMPy_MPFR_From_PyStr(PyObject *s, int base, mpfr_prec_t prec, CTXT_Object *context) { MPFR_Object *result; MPQ_Object *tempq; char *cp, *endptr; Py_ssize_t len; PyObject *ascii_str = NULL; CHECK_CONTEXT(context); if (prec < 2) prec = GET_MPFR_PREC(context); if (PyBytes_Check(s)) { len = PyBytes_Size(s); cp = PyBytes_AsString(s); } else if (PyUnicode_Check(s)) { ascii_str = PyUnicode_AsASCIIString(s); if (!ascii_str) { VALUE_ERROR("string contains non-ASCII characters"); return NULL; } len = PyBytes_Size(ascii_str); cp = PyBytes_AsString(ascii_str); } else { TYPE_ERROR("object is not string or Unicode"); return NULL; } /* Check for leading base indicators. */ if (base == 0) { if (len > 2 && cp[0] == '0') { if (cp[1] == 'b') { base = 2; cp += 2; len -= 2; } else if (cp[1] == 'x') { base = 16; cp += 2; len -= 2; } else { base = 10; } } else { base = 10; } } else if (cp[0] == '0') { /* If the specified base matches the leading base indicators, then * we need to skip the base indicators. */ if (cp[1] =='b' && base == 2) { cp += 2; len -= 2; } else if (cp[1] =='x' && base == 16) { cp += 2; len -= 2; } } if (!(result = GMPy_MPFR_New(prec, context))) { Py_XDECREF(ascii_str); return NULL; } /* delegate the rest to MPFR */ mpfr_clear_flags(); result->rc = mpfr_strtofr(result->f, cp, &endptr, base, GET_MPFR_ROUND(context)); Py_XDECREF(ascii_str); if (len != (Py_ssize_t)(endptr - cp)) { VALUE_ERROR("invalid digits"); Py_DECREF((PyObject*)result); return NULL; } /* If the context requests subnormals and the result is in the range for subnormals, * we use exact conversion via conversion to an mpq. * * The sticky bit returned by MPFR's string conversion appears to only reflect the * portion of the string needed to compute the correctly rounded result. It does not * accurately reflect whether or not the result is larger or smaller than the entire * input string. A correct sticky bit is needed by mfpr_subnormalize. Converting the * string to an mpq and then converting the mpq to an mpfr does properly set the * sticky bit. */ if (base == 10 && context->ctx.subnormalize && result->f->_mpfr_exp <= context->ctx.emin + mpfr_get_prec(result->f) - 1) { if (!(tempq = GMPy_MPQ_From_PyStr(s, base, context))) { Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_set_q(result->f, tempq->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempq); } GMPY_MPFR_CHECK_RANGE(result, context); GMPY_MPFR_SUBNORMALIZE(result, context); GMPY_MPFR_EXCEPTIONS(result, context); return result; } /* GMPy_MPFR_From_Real() converts a real number (see IS_REAL()) to an mpfr. * * If prec==0, then the result has the precision of the current context. * * If prec==1 and the value can be converted exactly (i.e. the input value is * a floating-point number using radix-2 representation or an integer), then * the conversion is done with the maximum possible precision. If the input * value can't be converted exactly, then the context precision is used. * * If prec >=2, then the specified precision is used. * * The return value is guaranteed to have a valid exponent. */ static MPFR_Object * GMPy_MPFR_From_Real(PyObject *obj, mp_prec_t prec, CTXT_Object *context) { CHECK_CONTEXT(context); if (MPFR_Check(obj)) return GMPy_MPFR_From_MPFR((MPFR_Object*)obj, prec, context); if (PyFloat_Check(obj)) return GMPy_MPFR_From_PyFloat(obj, prec, context); if (MPQ_Check(obj)) return GMPy_MPFR_From_MPQ((MPQ_Object*)obj, prec, context); if (MPZ_Check(obj) || XMPZ_Check(obj)) return GMPy_MPFR_From_MPZ((MPZ_Object*)obj, prec, context); if (PyIntOrLong_Check(obj)) return GMPy_MPFR_From_PyIntOrLong(obj, prec, context); if (IS_FRACTION(obj)) return GMPy_MPFR_From_Fraction(obj, prec, context); if (HAS_MPFR_CONVERSION(obj)) { MPFR_Object *res = (MPFR_Object *) PyObject_CallMethod(obj, "__mpfr__", NULL); if (res != NULL && MPFR_Check(res)) { return res; } else { Py_XDECREF((PyObject*)res); goto error; } } if (HAS_MPQ_CONVERSION(obj)) { MPQ_Object *res = (MPQ_Object *) PyObject_CallMethod(obj, "__mpq__", NULL); if (res != NULL && MPQ_Check(res)) { MPFR_Object * temp = GMPy_MPFR_From_MPQ(res, prec, context); Py_DECREF(res); return temp; } else { Py_XDECREF((PyObject*)res); goto error; } } if (HAS_MPZ_CONVERSION(obj)) { MPZ_Object *res = (MPZ_Object *) PyObject_CallMethod(obj, "__mpz__", NULL); if (res != NULL && MPZ_Check(res)) { MPFR_Object * temp = GMPy_MPFR_From_MPZ(res, prec, context); Py_DECREF(res); return temp; } else { Py_XDECREF((PyObject*)res); goto error; } } error: TYPE_ERROR("object could not be converted to 'mpfr'"); return NULL; } static MPFR_Object * GMPy_MPFR_From_RealAndCopy(PyObject *obj, mp_prec_t prec, CTXT_Object *context) { MPFR_Object *result = NULL, *temp = NULL; result = GMPy_MPFR_From_Real(obj, prec, context); if (result == NULL) return result; if (Py_REFCNT(result) == 1) return result; if (!(temp = GMPy_MPFR_New(mpfr_get_prec(result->f), context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } /* Since the precision of temp is the same as the precision of result, * there shouldn't be any rounding. */ mpfr_set(temp->f, result->f, MPFR_RNDN); Py_DECREF((PyObject*)result); return temp; } static MPZ_Object * GMPy_MPZ_From_MPFR(MPFR_Object *obj, CTXT_Object *context) { MPZ_Object *result; assert(MPFR_Check(obj)); CHECK_CONTEXT(context); if ((result = GMPy_MPZ_New(context))) { if (mpfr_nan_p(MPFR(obj))) { Py_DECREF((PyObject*)result); VALUE_ERROR("'mpz' does not support NaN"); return NULL; } if (mpfr_inf_p(MPFR(obj))) { Py_DECREF((PyObject*)result); OVERFLOW_ERROR("'mpz' does not support Infinity"); return NULL; } /* return code is ignored */ mpfr_get_z(result->z, MPFR(obj), GET_MPFR_ROUND(context)); } return result; } static XMPZ_Object * GMPy_XMPZ_From_MPFR(MPFR_Object *self, CTXT_Object *context) { XMPZ_Object *result; CHECK_CONTEXT(context); if ((result = GMPy_XMPZ_New(context))) { if (mpfr_nan_p(MPFR(self))) { Py_DECREF((PyObject*)result); VALUE_ERROR("'xmpz' does not support NaN"); return NULL; } if (mpfr_inf_p(MPFR(self))) { Py_DECREF((PyObject*)result); OVERFLOW_ERROR("'xmpz' does not support Infinity"); return NULL; } /* return code is ignored */ mpfr_get_z(result->z, MPFR(self), GET_MPFR_ROUND(context)); } return result; } /* Return the simpliest rational number that approximates 'self' to the * requested precision 'err'. If 'err' is negative, then the requested * precision is -2**abs(int(err)). If 'err' is NULL, then the requested * precision is -2**prec. If 'prec' is 0, then the requested precision is * the precision of 'self'. */ static PyObject * stern_brocot(MPFR_Object* self, MPFR_Object *err, mpfr_prec_t prec, int mayz, CTXT_Object *context) { PyObject *result = NULL; int i, negative, errsign; mpfr_t f, al, a, r1[3], r2[3], minerr, curerr, newerr, temp; CHECK_CONTEXT(context); #define F2Q_PREC 20 if (mpfr_nan_p(self->f)) { VALUE_ERROR("Cannot convert NaN to a number."); return NULL; } if (mpfr_inf_p(self->f)) { OVERFLOW_ERROR("Cannot convert Infinity to a number."); return NULL; } if (prec == 0) prec = mpfr_get_prec(self->f); errsign = err ? mpfr_sgn(err->f) : 0; if (errsign < 0) prec = (mpfr_prec_t)(-mpfr_get_si(err->f, MPFR_RNDN)); if (errsign <= 0 && (prec < 2 || prec > mpfr_get_prec(self->f))) { VALUE_ERROR("Requested precision out-of-bounds."); return NULL; } if (!(result = (PyObject*)GMPy_MPQ_New(context))) { return NULL; } mpfr_init2(minerr, F2Q_PREC); if (errsign <= 0) { mpfr_set_ui(minerr, 1, MPFR_RNDN); mpfr_div_2si(minerr, minerr, prec, MPFR_RNDN); } else { mpfr_set(minerr, err->f, MPFR_RNDN); } mpfr_init2(f, prec); if (mpfr_sgn(self->f) < 0) { negative = 1; mpfr_abs(f, self->f, MPFR_RNDN); } else { negative = 0; mpfr_set(f, self->f, MPFR_RNDN); } mpfr_init2(al, prec); mpfr_set(al, f, MPFR_RNDN); mpfr_init2(a, prec); mpfr_floor(a, al); mpfr_init2(temp, prec); for (i=0; i<3; ++i) { mpfr_init2(r1[i], prec); mpfr_init2(r2[i], prec); } mpfr_set_si(r1[0], 0, MPFR_RNDN); mpfr_set_si(r1[1], 0, MPFR_RNDN); mpfr_set_si(r1[2], 1, MPFR_RNDN); mpfr_set_si(r2[0], 0, MPFR_RNDN); mpfr_set_si(r2[1], 1, MPFR_RNDN); mpfr_set(r2[2], a, MPFR_RNDN); mpfr_init2(curerr, F2Q_PREC); mpfr_init2(newerr, F2Q_PREC); mpfr_reldiff(curerr, f, a, MPFR_RNDN); while (mpfr_cmp(curerr, minerr) > 0) { mpfr_sub(temp, al, a, MPFR_RNDN); mpfr_ui_div(al, 1, temp, MPFR_RNDN); mpfr_floor(a, al); mpfr_swap(r1[0], r1[1]); mpfr_swap(r1[1], r1[2]); mpfr_mul(r1[2], r1[1], a, MPFR_RNDN); mpfr_add(r1[2], r1[2], r1[0], MPFR_RNDN); mpfr_swap(r2[0], r2[1]); mpfr_swap(r2[1], r2[2]); mpfr_mul(r2[2], r2[1], a, MPFR_RNDN); mpfr_add(r2[2], r2[2], r2[0], MPFR_RNDN); mpfr_div(temp, r2[2], r1[2], MPFR_RNDN); mpfr_reldiff(newerr, f, temp, MPFR_RNDN); if (mpfr_cmp(curerr, newerr) <= 0) { mpfr_swap(r1[1],r1[2]); mpfr_swap(r2[1],r2[2]); break; } mpfr_swap(curerr, newerr); } if (mayz && (mpfr_cmp_ui(r1[2],1) == 0)) { Py_DECREF(result); result = (PyObject*)GMPy_MPZ_New(context); mpfr_get_z(MPZ(result), r2[2], MPFR_RNDN); if (negative) mpz_neg(MPZ(result), MPZ(result)); } else { mpfr_get_z(mpq_numref(MPQ(result)), r2[2], MPFR_RNDN); mpfr_get_z(mpq_denref(MPQ(result)), r1[2], MPFR_RNDN); if (negative) mpz_neg(mpq_numref(MPQ(result)), mpq_numref(MPQ(result))); } mpfr_clear(minerr); mpfr_clear(al); mpfr_clear(a); mpfr_clear(f); for (i=0; i<3; ++i) { mpfr_clear(r1[i]); mpfr_clear(r2[i]); } mpfr_clear(curerr); mpfr_clear(newerr); mpfr_clear(temp); return result; } static MPQ_Object * GMPy_MPQ_From_MPFR(MPFR_Object *self, CTXT_Object *context) { mpfr_exp_t temp, twocount; MPQ_Object *result; CHECK_CONTEXT(context); if (mpfr_nan_p(self->f)) { VALUE_ERROR("can not convert NaN to MPQ"); return NULL; } if (mpfr_inf_p(self->f)) { OVERFLOW_ERROR("can not convert Infinity to MPQ"); return NULL; } if (!(result = GMPy_MPQ_New(context))) { return NULL; } if (mpfr_zero_p(self->f)) { mpz_set_ui(mpq_numref(result->q), 0); mpz_set_ui(mpq_denref(result->q), 1); } else { temp = mpfr_get_z_2exp(mpq_numref(result->q), self->f); twocount = (mpfr_exp_t)mpz_scan1(mpq_numref(result->q), 0); if (twocount) { temp += twocount; mpz_div_2exp(mpq_numref(result->q), mpq_numref(result->q), twocount); } mpz_set_ui(mpq_denref(result->q), 1); if (temp > 0) mpz_mul_2exp(mpq_numref(result->q), mpq_numref(result->q), temp); else if (temp < 0) mpz_mul_2exp(mpq_denref(result->q), mpq_denref(result->q), -temp); } return result; } static PyObject * GMPy_PyIntOrLong_From_MPFR(MPFR_Object *obj, CTXT_Object *context) { PyObject *result; MPZ_Object *tempz; CHECK_CONTEXT(context); if (!(tempz = GMPy_MPZ_From_MPFR(obj, context))) return NULL; result = GMPy_PyIntOrLong_From_MPZ(tempz, context); Py_DECREF((PyObject*)tempz); return result; } static PyObject * GMPy_MPFR_Int_Slot(MPFR_Object *self) { return GMPy_PyIntOrLong_From_MPFR(self, NULL); } #ifdef PY2 static PyObject * GMPy_PyLong_From_MPFR(MPFR_Object *obj, CTXT_Object *context) { PyObject *result; MPZ_Object *tempz; CHECK_CONTEXT(context); if (!(tempz = GMPy_MPZ_From_MPFR(obj, context))) return NULL; result = GMPy_PyLong_From_MPZ(tempz, context); Py_DECREF((PyObject*)tempz); return result; } static PyObject * GMPy_MPFR_Long_Slot(MPFR_Object *self) { return GMPy_PyLong_From_MPFR(self, NULL); } #endif static PyObject * GMPy_PyFloat_From_MPFR(MPFR_Object *self, CTXT_Object *context) { double res; CHECK_CONTEXT(context); res = mpfr_get_d(self->f, GET_MPFR_ROUND(context)); return PyFloat_FromDouble(res); } static PyObject * GMPy_MPFR_Float_Slot(MPFR_Object *self) { return GMPy_PyFloat_From_MPFR(self, NULL); } static PyObject* GMPy_PyStr_From_MPFR(MPFR_Object *self, int base, int digits, CTXT_Object *context) { PyObject *result; char *buffer; mpfr_exp_t the_exp; CHECK_CONTEXT(context); /* check arguments are valid */ assert(MPFR_Check((PyObject*)self)); if (!((base >= 2) && (base <= 62))) { VALUE_ERROR("base must be in the interval [2,62]"); return NULL; } if ((digits < 0) || (digits == 1)) { VALUE_ERROR("digits must be 0 or >= 2"); return NULL; } /* Process special cases first */ if (!(mpfr_regular_p(self->f))) { if (mpfr_nan_p(self->f)) { return Py_BuildValue("(sii)", "nan", 0, 0); } else if (mpfr_inf_p(self->f) && !mpfr_signbit(self->f)) { return Py_BuildValue("(sii)", "inf", 0, 0); } else if (mpfr_inf_p(self->f) && mpfr_signbit(self->f)) { return Py_BuildValue("(sii)", "-inf", 0, 0); } /* 0 is not considered a 'regular" number */ else if (mpfr_signbit(self->f)) { return Py_BuildValue("(sii)", "-0", 0, mpfr_get_prec(self->f)); } else { return Py_BuildValue("(sii)", "0", 0, mpfr_get_prec(self->f)); } } /* obtain digits-string and exponent */ buffer = mpfr_get_str(0, &the_exp, base, digits, self->f, GET_MPFR_ROUND(context)); if (!*buffer) { SYSTEM_ERROR("Internal error in Pympfr_To_PyStr"); return NULL; } result = Py_BuildValue("(sii)", buffer, the_exp, mpfr_get_prec(self->f)); mpfr_free_str(buffer); return result; } #ifdef SHARED /* * coerce any number to a mpf */ int GMPy_MPFR_ConvertArg(PyObject *arg, PyObject **ptr) { MPFR_Object* newob = GMPy_MPFR_From_Real(arg, 1, NULL); if (newob) { *ptr = (PyObject*)newob; return 1; } else { TYPE_ERROR("argument can not be converted to 'mpfr'"); return 0; } } #endif /* str and repr implementations for mpfr */ static PyObject * GMPy_MPFR_Str_Slot(MPFR_Object *self) { PyObject *result, *temp; long precision; char fmtstr[60]; precision = (long)(log10(2) * (double)mpfr_get_prec(MPFR(self))) + 2; sprintf(fmtstr, "{0:.%ldg}", precision); temp = Py_BuildValue("s", fmtstr); if (!temp) return NULL; result = PyObject_CallMethod(temp, "format", "O", self); Py_DECREF(temp); return result; } static PyObject * GMPy_MPFR_Repr_Slot(MPFR_Object *self) { PyObject *result, *temp; long precision, bits; char fmtstr[60]; bits = mpfr_get_prec(MPFR(self)); precision = (long)(log10(2) * (double)bits) + 2; if (mpfr_number_p(MPFR(self)) && bits != DBL_MANT_DIG) sprintf(fmtstr, "mpfr('{0:.%ldg}',%ld)", precision, bits); else sprintf(fmtstr, "mpfr('{0:.%ldg}')", precision); temp = Py_BuildValue("s", fmtstr); if (!temp) return NULL; result = PyObject_CallMethod(temp, "format", "O", self); Py_DECREF(temp); return result; } static PyObject * mpfr_ascii(mpfr_t self, int base, int digits, int round) { PyObject *result; char *buffer; mpfr_exp_t the_exp; /* Process special cases first */ if (!(mpfr_regular_p(self))) { if (mpfr_nan_p(self)) { return Py_BuildValue("(sii)", "nan", 0, 0); } else if (mpfr_inf_p(self) && !mpfr_signbit(self)) { return Py_BuildValue("(sii)", "inf", 0, 0); } else if (mpfr_inf_p(self) && mpfr_signbit(self)) { return Py_BuildValue("(sii)", "-inf", 0, 0); } /* 0 is not considered a 'regular" number */ else if (mpfr_signbit(self)) { return Py_BuildValue("(sii)", "-0", 0, mpfr_get_prec(self)); } else { return Py_BuildValue("(sii)", "0", 0, mpfr_get_prec(self)); } } /* obtain digits-string and exponent */ buffer = mpfr_get_str(0, &the_exp, base, digits, self, round); if (!*buffer) { SYSTEM_ERROR("Internal error in mpfr_ascii"); return NULL; } result = Py_BuildValue("(sii)", buffer, the_exp, mpfr_get_prec(self)); mpfr_free_str(buffer); return result; } gmpy2-2.1.0b3/src/gmpy2_convert_mpfr.h0000664000175000017500000001100213452460010017416 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_convert_mpfr.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_CONVERT_MPFR_H #define GMPY2_CONVERT_MPFR_H #ifdef __cplusplus extern "C" { #endif /********* Pympfr Conversions *********/ /* Conversions with Pympfr */ static MPFR_Object * GMPy_MPFR_From_MPFR(MPFR_Object *obj, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_PyIntOrLong(PyObject *obj, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_PyFloat(PyObject *obj, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_MPZ(MPZ_Object *obj, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_MPQ(MPQ_Object *obj, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_Fraction(PyObject *obj, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_PyStr(PyObject *s, int base, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_Real(PyObject* obj, mpfr_prec_t prec, CTXT_Object *context); static MPFR_Object * GMPy_MPFR_From_RealAndCopy(PyObject* obj, mpfr_prec_t prec, CTXT_Object *context); static PyObject * GMPy_PyIntOrLong_From_MPFR(MPFR_Object *obj, CTXT_Object *context); static MPZ_Object * GMPy_MPZ_From_MPFR(MPFR_Object *obj, CTXT_Object *context); static XMPZ_Object * GMPy_XMPZ_From_MPFR(MPFR_Object *self, CTXT_Object *context); static MPQ_Object * GMPy_MPQ_From_MPFR(MPFR_Object *self, CTXT_Object *context); static PyObject * GMPy_PyFloat_From_MPFR(MPFR_Object *self, CTXT_Object *context); static PyObject * GMPy_PyStr_From_MPFR(MPFR_Object *self, int base, int digits, CTXT_Object *context); #ifdef PY2 static PyObject * GMPy_PyLong_From_MPFR(MPFR_Object *obj, CTXT_Object *context); static PyObject * GMPy_MPFR_Long_Slot(MPFR_Object *self); #endif static PyObject * GMPy_MPFR_Str_Slot(MPFR_Object *self); static PyObject * GMPy_MPFR_Repr_Slot(MPFR_Object *self); static PyObject * GMPy_MPFR_Int_Slot(MPFR_Object *self); static PyObject * GMPy_MPFR_Float_Slot(MPFR_Object *self); /* Miscellaneous */ #ifdef SHARED /* static int GMPy_MPFR_ConvertArg(PyObject *arg, PyObject **ptr); */ static GMPy_MPFR_ConvertArg_RETURN GMPy_MPFR_ConvertArg GMPy_MPFR_ConvertArg_PROTO; #endif static PyObject * stern_brocot(MPFR_Object* self, MPFR_Object *err, mpfr_prec_t prec, int mayz, CTXT_Object *context); static PyObject * mpfr_ascii(mpfr_t self, int base, int digits, int round); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_convert_utils.c0000664000175000017500000003027713425752152017637 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_convert_utils.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ======================================================================== * * Conversion between Integer objects and C types. * * ======================================================================== * * * Optimized routines for converting an Integer object (Python's integer * type(s) plus mpz) to various C types. * * Note: These functions will not set any exceptions! * * Note: These functions assume the input is either a PyInt, PyLong, or an * mpz. No attempt is made to convert any other type! */ #include "longintrepr.h" #define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN) /* The various ...AndError functions indicate exceptions as follows: * 1) If error is -1, then the argument is negative and the result could * not fit into the desired return type. * 2) If error is 1, then the argument is positive and the result could * not fit into the desired return type. * 3) If error is 2, then the argument is not a recognized type. * 4) If error is 0, then a valid result has been returned. * * Note: The original Python functions will accept any object and attempt to * convert the object to a PyLong. We do not do this. It is assumed that * the argument is a Python integer or a GMPY2 mpz. * * These functions will not set any exceptions. A return value of -1 does * NOT indicate a possible exception. */ /* The following functions are based on PyLong_AsLongAndOverflow(). */ static long GMPy_Integer_AsLongAndError(PyObject *vv, int *error) { register PyLongObject *v; unsigned long x, prev; long res; Py_ssize_t i; int sign; *error = 0; #ifdef PY2 if (PyInt_Check(vv)) { return PyInt_AS_LONG(vv); } #endif if (PyLong_Check(vv)) { res = 0; v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { case -1: res = -(sdigit)v->ob_digit[0]; break; case 0: break; case 1: res = v->ob_digit[0]; break; default: sign = 1; x = 0; if (i < 0) { sign = -1; i = -(i); } while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *error = sign; return res; } } /* Haven't lost any bits, but casting to long requires extra care. */ if (x <= (unsigned long)LONG_MAX) { res = (long)x * sign; } else if (sign < 0 && x == PY_ABS_LONG_MIN) { res = LONG_MIN; } else { *error = sign; } } return res; } if (CHECK_MPZANY(vv)) { if (mpz_fits_slong_p(MPZ(vv))) { res = (long) mpz_get_si(MPZ(vv)); } else { *error = mpz_sgn(MPZ(vv)); res = 0; } return res; } *error = 2; return 0; } static unsigned long GMPy_Integer_AsUnsignedLongAndError(PyObject *vv, int *error) { register PyLongObject *v; unsigned long x, prev, res; Py_ssize_t i; *error = 0; #ifdef PY2 if (PyInt_Check(vv)) { long temp = PyInt_AS_LONG(vv); if (temp < 0) { *error = -1; return 0; } else { return (unsigned long)temp; } } #endif if (PyLong_Check(vv)) { res = 0; v = (PyLongObject *)vv; i = Py_SIZE(v); if (i < 0) { *error = -1; return res; } switch (i) { case 0: break; case 1: res = v->ob_digit[0]; break; default: x = 0; while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *error = 1; return res; } } res = x; } return res; } if (CHECK_MPZANY(vv)) { if (mpz_fits_ulong_p(MPZ(vv))) { res = (unsigned long) mpz_get_ui(MPZ(vv)); } else { *error = mpz_sgn(MPZ(vv)); res = 0; } return res; } *error = 2; return 0; } static long c_long_From_Integer(PyObject *obj) { long result; int error; result = GMPy_Integer_AsLongAndError(obj, &error); if (!error) { return result; } else { if (error == 2) { TYPE_ERROR("could not convert object to integer"); } else { OVERFLOW_ERROR("value too large to convert to C long"); } return -1; } } static unsigned long c_ulong_From_Integer(PyObject *obj) { unsigned long result; int error; result = GMPy_Integer_AsUnsignedLongAndError(obj, &error); if (!error) { return result; } else { if (error == 2) { TYPE_ERROR("could not convert object to integer"); } else if (error == 1) { OVERFLOW_ERROR("value too large to convert to C unsigned long"); } else if (error < 0) { VALUE_ERROR("a non-negative value is required"); } return (unsigned long)(-1); } } /* The follow code is only used on Windows x64 platform. We check for _WIN64 * but we then assume the PY_LONG_LONG is defined. */ #ifdef _WIN64 #define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) static PY_LONG_LONG GMPy_Integer_AsLongLongAndError(PyObject *vv, int *error) { register PyLongObject *v; unsigned PY_LONG_LONG x, prev; PY_LONG_LONG res; Py_ssize_t i; int sign; *error = 0; #ifdef PY2 if (PyInt_Check(vv)) { return (PY_LONG_LONG)PyInt_AS_LONG(vv); } #endif if (PyLong_Check(vv)) { res = 0; v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { case -1: res = -(sdigit)v->ob_digit[0]; break; case 0: break; case 1: res = v->ob_digit[0]; break; default: sign = 1; x = 0; if (i < 0) { sign = -1; i = -(i); } while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *error = sign; return res; } } /* Haven't lost any bits, but casting to long requires extra care. */ if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) { res = (PY_LONG_LONG)x * sign; } else if (sign < 0 && x == PY_ABS_LLONG_MIN) { res = PY_LLONG_MIN; } else { *error = sign; } } return res; } if (CHECK_MPZANY(vv)) { res = 0; sign = mpz_sgn(MPZ(vv)); if (sign) { if (mpz_sizeinbase(MPZ(vv), 256) <= sizeof(x)) { x = 0; mpz_export(&x, NULL, 1, sizeof(x), 0, 0, MPZ(vv)); } if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) { res = (PY_LONG_LONG)x * sign; } else if (sign < 0 && x == PY_ABS_LLONG_MIN) { res = PY_LLONG_MIN; } else { *error = sign; } return res; } } *error = 2; return 0; } static unsigned PY_LONG_LONG GMPy_Integer_AsUnsignedLongLongAndError(PyObject *vv, int *error) { register PyLongObject *v; unsigned PY_LONG_LONG x, prev, res = 0; Py_ssize_t i; int sign; *error = 0; #ifdef PY2 if (PyInt_Check(vv)) { long temp = PyInt_AS_LONG(vv); if (temp < 0) { *error = -1; return res; } else { return (unsigned PY_LONG_LONG)temp; } } #endif if (PyLong_Check(vv)) { v = (PyLongObject *)vv; i = Py_SIZE(v); if (i < 0) { *error = -1; return res; } switch (i) { case 0: break; case 1: res = v->ob_digit[0]; break; default: x = 0; while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *error = 1; return res; } } res = x; } return res; } if (CHECK_MPZANY(vv)) { sign = mpz_sgn(MPZ(vv)); if (sign < 0) { *error = -1; return res; } else if (sign) { if (mpz_sizeinbase(MPZ(vv), 256) <= sizeof(res)) { mpz_export(&res, NULL, 1, sizeof(x), 0, 0, MPZ(vv)); } return res; } } *error = 2; return 0; } static PY_LONG_LONG c_longlong_From_Integer(PyObject *obj) { PY_LONG_LONG result; int error; result = GMPy_Integer_AsLongLongAndError(obj, &error); if (!error) { return result; } else { if (error == 2) { TYPE_ERROR("could not convert object to integer"); } else { OVERFLOW_ERROR("value too large to convert to C long long"); } return -1; } } static unsigned PY_LONG_LONG c_ulonglong_From_Integer(PyObject *obj) { unsigned PY_LONG_LONG result; int error; result = GMPy_Integer_AsUnsignedLongLongAndError(obj, &error); if (!error) { return result; } else { if (error == 2) { TYPE_ERROR("could not convert object to integer"); } else if (error == 1) { OVERFLOW_ERROR("value too large to convert to C unsigned long long"); } else if (error < 0) { VALUE_ERROR("a non-negative value is required"); } return (unsigned PY_LONG_LONG)(-1); } } #endif gmpy2-2.1.0b3/src/gmpy2_convert_utils.h0000664000175000017500000000734713425752164017651 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_convert_utils.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_CONVERT_UTILS_H #define GMPY2_CONVERT_UTILS_H #ifdef __cplusplus extern "C" { #endif /* ======================================================================== * * Conversion between Integer objects and C types. * * ======================================================================== */ static long GMPy_Integer_AsLongAndError(PyObject *vv, int *error); static unsigned long GMPy_Integer_AsUnsignedLongAndError(PyObject *vv, int *error); static long c_long_From_Integer(PyObject *obj); static unsigned long c_ulong_From_Integer(PyObject *obj); #ifdef _WIN64 static PY_LONG_LONG GMPy_Integer_AsLongLongAndError(PyObject *vv, int *error); static unsigned PY_LONG_LONG GMPy_Integer_AsUnsignedLongLongAndError(PyObject *vv, int *error); #endif /* Support conversion to/from mp_bitcnt_t and Py_ssize_t. */ /* The following code assumes that the typedef in gmp.h for mingw64 based * builds has been changed to unsigned long long int. */ #if defined _WIN64 && (MPIR || MSYS2) # define mp_bitcnt_t_From_Integer c_ulonglong_From_Integer # define GMPy_Integer_AsMpBitCntAndError GMPy_Integer_AsUnsignedLongLongAndError #else # define mp_bitcnt_t_From_Integer c_ulong_From_Integer # define GMPy_Integer_AsMpBitCntAndError GMPy_Integer_AsUnsignedLongAndError #endif /* This just requires that sizeof(mp_bitcnt_t) <= sizeof(size_t) */ #ifdef _WIN64 # define ssize_t_From_Integer c_longlong_From_Integer #else # define ssize_t_From_Integer c_long_From_Integer #endif #ifdef PY2 # define PyIntOrLong_FromMpBitCnt PyInt_FromSize_t #else # define PyIntOrLong_FromMpBitCnt PyLong_FromSize_t #endif #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_divmod.c0000664000175000017500000003321413425752202016207 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_divmod.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements __divmod__ and context.divmod(). * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_DivMod(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPZ_DivMod_Slot * GMPy_MPQ_DivMod_Slot * GMPy_MPFR_DivMod_Slot * GMPy_MPC_DivMod_Slot * * GMPy_Integer_DivMod(Integer, Integer, context|NULL) * GMPy_Rational_DivMod(Rational, Rational, context|NULL) * GMPy_Real_DivMod(Real, Real, context|NULL) * GMPy_Complex_DivMod(Complex, Complex, context|NULL) * * GMPy_Context_DivMod(context, args) * */ static PyObject * GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { PyObject *result = NULL; MPZ_Object *tempx = NULL, *tempy = NULL, *rem = NULL, *quo = NULL; if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPZ_New(context)) || !(quo = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(y, &error); if (error) { mpz_set_PyIntOrLong(global.tempz, y); mpz_fdiv_qr(quo->z, rem->z, MPZ(x), global.tempz); } else if (temp > 0) { mpz_fdiv_qr_ui(quo->z, rem->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } else { mpz_cdiv_qr_ui(quo->z, rem->z, MPZ(x), -temp); mpz_neg(quo->z, quo->z); } PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpz_fdiv_qr(quo->z, rem->z, MPZ(x), MPZ(y)); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } if (CHECK_MPZANY(y) && PyIntOrLong_Check(x)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } else { mpz_set_PyIntOrLong(global.tempz, x); mpz_fdiv_qr(quo->z, rem->z, global.tempz, MPZ(y)); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { if (!(tempx = GMPy_MPZ_From_Integer(x, context)) || !(tempy = GMPy_MPZ_From_Integer(y, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpz_fdiv_qr(quo->z, rem->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Integer_DivMod()."); /* LCOV_EXCL_STOP */ error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; } static PyObject * GMPy_MPZ_DivMod_Slot(PyObject *x, PyObject *y) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_DivMod(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_DivMod(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_DivMod(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_DivMod(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Rational_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { MPQ_Object *tempx = NULL, *tempy = NULL, *rem = NULL; MPZ_Object *quo = NULL; PyObject *result = NULL; if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPQ_New(context)) || !(quo = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (IS_RATIONAL(x) && IS_RATIONAL(y)) { if (!(tempx = GMPy_MPQ_From_Number(x, context)) || !(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (mpq_sgn(tempy->q) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpq_div(rem->q, tempx->q, tempy->q); mpz_fdiv_q(quo->z, mpq_numref(rem->q), mpq_denref(rem->q)); /* Need to calculate x - quo * y. */ mpq_set_z(rem->q, quo->z); mpq_mul(rem->q, rem->q, tempy->q); mpq_sub(rem->q, tempx->q, rem->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Rational_DivMod()."); error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; /* LCOV_EXCL_STOP */ } static PyObject * GMPy_MPQ_DivMod_Slot(PyObject *x, PyObject *y) { if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_DivMod(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_DivMod(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_DivMod(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Real_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *quo = NULL, *rem = NULL, *temp; PyObject *result = NULL; CHECK_CONTEXT(context); if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPFR_New(0, context)) || !(quo = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (IS_REAL(x) && IS_REAL(y)) { if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("divmod() division by zero"); goto error; } mpfr_set_nan(quo->f); mpfr_set_nan(rem->f); goto okay; } if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } mpfr_set_nan(quo->f); mpfr_set_nan(rem->f); goto okay; } if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("divmod() invalid operation"); goto error; } if (mpfr_zero_p(tempx->f)) { mpfr_set_zero(quo->f, mpfr_sgn(tempy->f)); mpfr_set_zero(rem->f, mpfr_sgn(tempy->f)); } else if ((mpfr_signbit(tempx->f)) != (mpfr_signbit(tempy->f))) { mpfr_set_si(quo->f, -1, MPFR_RNDN); mpfr_set_inf(rem->f, mpfr_sgn(tempy->f)); } else { mpfr_set_si(quo->f, 0, MPFR_RNDN); rem->rc = mpfr_set(rem->f, tempx->f, MPFR_RNDN); } goto okay; } if (!(temp = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } mpfr_fmod(rem->f, tempx->f, tempy->f, MPFR_RNDN); mpfr_sub(temp->f, tempx->f, rem->f, MPFR_RNDN); mpfr_div(quo->f, temp->f, tempy->f, MPFR_RNDN); if (!mpfr_zero_p(rem->f)) { if ((mpfr_sgn(tempy->f) < 0) != (mpfr_sgn(rem->f) < 0)) { mpfr_add(rem->f, rem->f, tempy->f, MPFR_RNDN); mpfr_sub_ui(quo->f, quo->f, 1, MPFR_RNDN); } } else { mpfr_copysign(rem->f, rem->f, tempy->f, MPFR_RNDN); } if (!mpfr_zero_p(quo->f)) { mpfr_round(quo->f, quo->f); } else { mpfr_setsign(quo->f, quo->f, mpfr_sgn(tempx->f) * mpfr_sgn(tempy->f) - 1, MPFR_RNDN); } Py_DECREF((PyObject*)temp); GMPY_MPFR_CHECK_RANGE(quo, context); GMPY_MPFR_CHECK_RANGE(rem, context); GMPY_MPFR_SUBNORMALIZE(quo, context); GMPY_MPFR_SUBNORMALIZE(rem, context); okay: Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Real_DivMod_1()."); error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; /* LCOV_EXCL_STOP */ } static PyObject * GMPy_MPFR_DivMod_Slot(PyObject *x, PyObject *y) { if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_DivMod(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_DivMod(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Complex_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { TYPE_ERROR("can't take floor or mod of complex number."); return NULL; } static PyObject * GMPy_MPC_DivMod_Slot(PyObject *x, PyObject *y) { return GMPy_Complex_DivMod(x, y, NULL); } static PyObject * GMPy_Number_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_DivMod(x, y, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_DivMod(x, y, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_DivMod(x, y, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_DivMod(x, y, context); TYPE_ERROR("divmod() argument type not supported"); return NULL; } PyDoc_STRVAR(GMPy_doc_context_divmod, "context.div_mod(x, y) -> (quotient, remainder)\n\n" "Return div_mod(x, y); uses alternate spelling to avoid naming conflicts.\n" "Note: overflow, underflow, and inexact exceptions are not supported for\n" "mpfr arguments to context.div_mod()."); static PyObject * GMPy_Context_DivMod(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("div_mod() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_DivMod(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_divmod.h0000664000175000017500000000570413425752217016225 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_divmod.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_DIVMOD_H #define GMPY2_DIVMOD_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_DivMod(PyObject *x, PyObject *y, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Rational_DivMod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Real_DivMod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_DivMod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPZ_DivMod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPQ_DivMod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPFR_DivMod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPC_DivMod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_Context_DivMod(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_floordiv.c0000664000175000017500000003446313425752235016566 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_floordiv.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements the // operator, gmpy2.floor_div() and * context.floor_div(). * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_FloorDiv(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPZ_FloorDiv_Slot * GMPy_MPQ_FloorDiv_Slot * GMPy_MPFR_FloorDiv_Slot * GMPy_MPC_FloorDiv_Slot * * GMPy_Integer_FloorDiv(Integer, Integer, context|NULL) * GMPy_Rational_FloorDiv(Rational, Rational, context|NULL) * GMPy_Real_FloorDiv(Real, Real, context|NULL) * GMPy_Complex_FloorDiv(Complex, Complex, context|NULL) * * GMPy_Context_FloorDiv(context, args) * */ static PyObject * GMPy_Integer_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *result; if (!(result = GMPy_MPZ_New(context))) return NULL; if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(y, &error); if (!error) { if (temp > 0) { mpz_fdiv_q_ui(result->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } else { mpz_cdiv_q_ui(result->z, MPZ(x), -temp); mpz_neg(result->z, result->z); } } else { mpz_set_PyIntOrLong(global.tempz, y); mpz_fdiv_q(result->z, MPZ(x), global.tempz); } return (PyObject*)result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } mpz_fdiv_q(result->z, MPZ(x), MPZ(y)); return (PyObject*)result; } } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } if (PyIntOrLong_Check(x)) { mpz_set_PyIntOrLong(global.tempz, x); mpz_fdiv_q(result->z, global.tempz, MPZ(y)); return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { MPZ_Object *tempx, *tempy; tempx = GMPy_MPZ_From_Integer(x, context); tempy = GMPy_MPZ_From_Integer(y, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpz_fdiv_q(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; } /* Implement floor division for MPZ_Object. On entry, one of the two arguments * must be an MPZ_Object. If the other object is an Integer, return an * MPZ_Object. If the other object isn't an MPZ_Object, call the appropriate * function. If no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPZ_FloorDiv_Slot(PyObject *x, PyObject *y) { if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { MPZ_Object *result; if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_fdiv_q(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_FloorDiv(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_FloorDiv(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_FloorDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_FloorDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Rational_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *result; MPQ_Object *tempq; CHECK_CONTEXT(context); result = GMPy_MPZ_New(context); tempq = GMPy_MPQ_New(context); if (!result || !tempq) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempq); return NULL; } if (MPQ_Check(x) && MPQ_Check(y)) { if (mpq_sgn(MPQ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpq_div(tempq->q, MPQ(x), MPQ(y)); mpz_fdiv_q(result->z, mpq_numref(tempq->q), mpq_denref(tempq->q)); Py_DECREF((PyObject*)tempq); return (PyObject*)result; } if (IS_RATIONAL(x) && IS_RATIONAL(y)) { MPQ_Object *tempx, *tempy; tempx = GMPy_MPQ_From_Number(x, context); tempy = GMPy_MPQ_From_Number(y, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); goto error; } if (mpq_sgn(tempy->q) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto error; } mpq_div(tempq->q, tempx->q, tempy->q); mpz_fdiv_q(result->z, mpq_numref(tempq->q), mpq_denref(tempq->q)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)tempq); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; error: Py_DECREF((PyObject*)result); Py_DECREF((PyObject*)tempq); return NULL; } static PyObject * GMPy_MPQ_FloorDiv_Slot(PyObject *x, PyObject *y) { if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_FloorDiv(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_FloorDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_FloorDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* Attempt floor division of two numbers and return an mpfr. The code path is * optimized by checking for mpfr objects first. Returns Py_NotImplemented if * both objects are not valid reals. */ static PyObject * GMPy_Real_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPFR_Check(x)) { if (MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_div(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } if (PyIntOrLong_Check(y)) { int error; long tempi = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_div_si(result->f, MPFR(x), tempi, GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } else { mpz_set_PyIntOrLong(global.tempz, y); mpfr_clear_flags(); result->rc = mpfr_div_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_div_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_div_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_div_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long tempi = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_si_div(result->f, tempi, MPFR(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } /* Since mpfr_z_div does not exist, this combination is handled at the * end by converting x to an mpfr. Ditto for rational.*/ if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_d_div(result->f, PyFloat_AS_DOUBLE(x), MPFR(y), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); goto done; } } /* Handle the remaining cases. * Note: verify that MPZ if converted at full precision! */ if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx, *tempy; tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_div(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); result->rc = mpfr_floor(result->f, result->f); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; done: _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_MPFR_FloorDiv_Slot(PyObject *x, PyObject *y) { if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_FloorDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_FloorDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Complex_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context) { TYPE_ERROR("can't take floor of complex number"); return NULL; } static PyObject * GMPy_MPC_FloorDiv_Slot(PyObject *x, PyObject *y) { return GMPy_Complex_FloorDiv(x, y, NULL); } PyDoc_STRVAR(GMPy_doc_floordiv, "floor_div(x, y) -> number\n\n" "Return x // y; uses floor division."); static PyObject * GMPy_Number_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_FloorDiv(x, y, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_FloorDiv(x, y, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_FloorDiv(x, y, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_FloorDiv(x, y, context); TYPE_ERROR("floor_div() argument type not supported"); return NULL; } PyDoc_STRVAR(GMPy_doc_context_floordiv, "context.floor_div(x, y) -> number\n\n" "Return x // y; uses floor division."); static PyObject * GMPy_Context_FloorDiv(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("floor_div() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_FloorDiv(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_floordiv.h0000664000175000017500000000573413425752251016570 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_floordiv.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_FLOORDIV_H #define GMPY2_FLOORDIV_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Rational_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Real_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPZ_FloorDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPQ_FloorDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPFR_FloorDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPC_FloorDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_Context_FloorDiv(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_format.c0000664000175000017500000005767513452504734016243 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_format.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_mpz_format, "x.__format__(fmt) -> string\n\n" "Return a Python string by formatting mpz 'x' using the format string\n" "'fmt'. A valid format string consists of:\n" " optional alignment code:\n" " '<' -> left shifted in field\n" " '>' -> right shifted in field\n" " '^' -> centered in field\n" " optional leading sign code:\n" " '+' -> always display leading sign\n" " '-' -> only display minus sign\n" " ' ' -> minus for negative values, space for positive values\n" " optional base indicator\n" " '#' -> precede binary, octal, or hex with 0b, 0o or 0x\n" " optional width\n" " optional conversion code:\n" " 'd' -> decimal format\n" " 'b' -> binary format\n" " 'o' -> octal format\n" " 'x' -> hex format\n" " 'X' -> upper-case hex format\n" "The default format is 'd'."); /* Formatting occurs in two phases. Pympz_ascii() is used to create a string * with the appropriate binary/octal/decimal/hex formatting, including the * leading sign character (+ , -, or space) and base encoding (0b, 0o, or 0x). * Left/right/centering using the specified width is done by creating a * format string and calling the __format__() method of the string object * returned by Pympz_ascii(). */ static PyObject * GMPy_MPZ_Format(PyObject *self, PyObject *args) { PyObject *result = NULL, *mpzstr = NULL; char *fmtcode = 0, *p1, *p2; char fmt[30]; int base = 10, option = 16; int seensign = 0, seenindicator = 0, seenalign = 0, seendigits = 0; if (!CHECK_MPZANY(self)) { TYPE_ERROR("requires mpz type"); return NULL; } if (!PyArg_ParseTuple(args, "s", &fmtcode)) return NULL; p2 = fmt; for (p1 = fmtcode; *p1 != '\00'; p1++) { if (*p1 == '<' || *p1 == '>' || *p1 == '^') { if (seenalign || seensign || seenindicator || seendigits) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(p2++) = *p1; seenalign = 1; continue; } } if (*p1 == '+') { if (seensign || seenindicator || seendigits) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { option |= 2; seensign = 1; continue; } } if (*p1 == '-') { if (seensign || seenindicator || seendigits) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { seensign = 1; continue; } } if (*p1 == ' ') { if (seensign || seenindicator || seendigits) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { option |= 4; seensign = 1; continue; } } if (*p1 == '#') { if (seenindicator || seendigits) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { option |= 8; seenindicator = 1; continue; } } if (isdigit(*p1)) { if (!seenalign) { *(p2++) = '>'; seenalign = 1; } *(p2++) = *p1; seendigits = 1; continue; } if (*p1 == 'b') { base = 2; break; } if (*p1 == 'o') { base = 8; break; } if (*p1 == 'x') { base = 16; break; } if (*p1 == 'd') { base = 10; break; } if (*p1 == 'X') { base = -16; break; } VALUE_ERROR("Invalid conversion specification"); return NULL; } *(p2++) = '\00'; if (!(mpzstr = mpz_ascii(MPZ(self), base, option, 0))) return NULL; result = PyObject_CallMethod(mpzstr, "__format__", "(s)", fmt); Py_DECREF(mpzstr); return result; } PyDoc_STRVAR(GMPy_doc_mpfr_format, "x.__format__(fmt) -> string\n\n" "Return a Python string by formatting 'x' using the format string\n" "'fmt'. A valid format string consists of:\n" " optional alignment code:\n" " '<' -> left shifted in field\n" " '>' -> right shifted in field\n" " '^' -> centered in field\n" " optional leading sign code\n" " '+' -> always display leading sign\n" " '-' -> only display minus for negative values\n" " ' ' -> minus for negative values, space for positive values\n" " optional width.precision\n" " optional rounding mode:\n" " 'U' -> round toward plus Infinity\n" " 'D' -> round toward minus Infinity\n" " 'Y' -> round away from zero\n" " 'Z' -> round toward zero\n" " 'N' -> round to nearest\n" " optional conversion code:\n" " 'a','A' -> hex format\n" " 'b' -> binary format\n" " 'e','E' -> scientific format\n" " 'f','F' -> fixed point format\n" " 'g','G' -> fixed or float format\n\n" "The default format is '.6f'."); static PyObject * GMPy_MPFR_Format(PyObject *self, PyObject *args) { PyObject *result = NULL, *mpfrstr = NULL; char *buffer = 0, *newbuf = 0, *fmtcode = 0, *p1, *p2, *p3; char mpfrfmt[100], fmt[30]; int buflen; int seensign = 0, seenalign = 0, seendecimal = 0, seendigits = 0; int seenround = 0, seenconv = 0; if (!MPFR_Check(self)) { TYPE_ERROR("requires mpfr type"); return NULL; } if (!PyArg_ParseTuple(args, "s", &fmtcode)) return NULL; p2 = mpfrfmt; p3 = fmt; *(p2++) = '%'; for (p1 = fmtcode; *p1 != '\00'; p1++) { if (*p1 == '<' || *p1 == '>' || *p1 == '^') { if (seenalign || seensign || seendecimal || seendigits || seenround) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(p3++) = *p1; seenalign = 1; continue; } } if (*p1 == '+' || *p1 == ' ') { if (seensign || seendecimal || seendigits || seenround) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(p2++) = *p1; seensign = 1; continue; } } if (*p1 == '-') { if (seensign || seendecimal || seendigits || seenround) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { seensign = 1; continue; } } if (*p1 == '.') { if (seendecimal || seendigits || seenround) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(p2++) = *p1; seendecimal = 1; continue; } } if (isdigit(*p1)) { if (seendigits || seenround) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else if (seendecimal) { *(p2++) = *p1; continue; } else { if (p3 == fmt) { *(p3++) = '>'; seenalign = 1; } *(p3++) = *p1; continue; } } if (!seendigits) { seendigits = 1; *(p2++) = 'R'; } if (*p1 == 'U' || *p1 == 'D' || *p1 == 'Y' || *p1 == 'Z' || *p1 == 'N' ) { if (seenround) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(p2++) = *p1; seenround = 1; continue; } } if (*p1 == 'a' || *p1 == 'A' || *p1 == 'b' || *p1 == 'e' || *p1 == 'E' || *p1 == 'f' || *p1 == 'F' || *p1 == 'g' || *p1 == 'G' ) { *(p2++) = *p1; seenconv = 1; break; } VALUE_ERROR("Invalid conversion specification"); return NULL; } if (!seendigits) *(p2++) = 'R'; if (!seenconv) *(p2++) = 'f'; *(p2) = '\00'; *(p3) = '\00'; buflen = mpfr_asprintf(&buffer, mpfrfmt, MPFR(self)); /* If there isn't a decimal point in the output and the output * only consists of digits, then append .0 */ if (strlen(buffer) == strspn(buffer, "+- 0123456789")) { newbuf = malloc(buflen + 3); if (!newbuf) { mpfr_free_str(buffer); return PyErr_NoMemory(); } *newbuf = '\0'; strcat(newbuf, buffer); strcat(newbuf, ".0"); mpfr_free_str(buffer); mpfrstr = Py_BuildValue("s", newbuf); free(newbuf); } else { mpfrstr = Py_BuildValue("s", buffer); mpfr_free_str(buffer); } if (!mpfrstr) { return NULL; } result = PyObject_CallMethod(mpfrstr, "__format__", "(s)", fmt); Py_DECREF(mpfrstr); return result; } PyDoc_STRVAR(GMPy_doc_mpc_format, "x.__format__(fmt) -> string\n\n" "Return a Python string by formatting 'x' using the format string\n" "'fmt'. A valid format string consists of:\n" " optional alignment code:\n" " '<' -> left shifted in field\n" " '>' -> right shifted in field\n" " '^' -> centered in field\n" " optional leading sign code\n" " '+' -> always display leading sign\n" " '-' -> only display minus for negative values\n" " ' ' -> minus for negative values, space for positive values\n" " optional width.real_precision.imag_precision\n" " optional rounding mode:\n" " 'U' -> round toward plus infinity\n" " 'D' -> round toward minus infinity\n" " 'Z' -> round toward zero\n" " 'N' -> round to nearest\n" " optional output style:\n" " 'P' -> Python style, 1+2j, (default)\n" " 'M' -> MPC style, (1 2)\n" " optional conversion code:\n" " 'a','A' -> hex format\n" " 'b' -> binary format\n" " 'e','E' -> scientific format\n" " 'f','F' -> fixed point format\n" " 'g','G' -> fixed or scientific format\n\n" "The default format is 'f'."); static PyObject * GMPy_MPC_Format(PyObject *self, PyObject *args) { PyObject *result = NULL, *tempstr = NULL; char *realbuf = 0, *imagbuf = 0, *tempbuf = 0, *fmtcode = 0; char *p, *rfmtptr, *ifmtptr, *fmtptr; char rfmt[100], ifmt[100], fmt[30]; int rbuflen, ibuflen; int seensign = 0, seenalign = 0, seendecimal = 0, seendigits = 0; int seenround = 0, seenconv = 0, seenstyle = 0, mpcstyle = 0; if (!MPC_Check(self)) { TYPE_ERROR("requires 'mpc' object"); return NULL; } if (!PyArg_ParseTuple(args, "s", &fmtcode)) { return NULL; } rfmtptr = rfmt; ifmtptr = ifmt; fmtptr = fmt; *(rfmtptr++) = '%'; *(ifmtptr++) = '%'; for (p = fmtcode; *p != '\00'; p++) { if (*p == '<' || *p == '>' || *p == '^') { if (seenalign || seensign || seendecimal || seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(fmtptr++) = *p; seenalign = 1; continue; } } if (*p == '+' || *p == ' ' || *p == '-') { if (seensign || seendecimal || seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(rfmtptr++) = *p; *(ifmtptr++) = *p; seensign = 1; continue; } } if (!seensign) { *(rfmtptr++) = '-'; *(ifmtptr++) = '-'; seensign = 1; } if (*p == '.') { if (seendecimal == 2 || seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { if (!seendecimal) { *(rfmtptr++) = *p; *(ifmtptr++) = *p; } seendecimal++; if (seendecimal == 2) { while (isdigit(*(ifmtptr-1))) ifmtptr--; } continue; } } if (isdigit(*p)) { if (seendigits || seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else if (seendecimal == 1) { *(rfmtptr++) = *p; *(ifmtptr++) = *p; continue; } else if (seendecimal == 2) { *(ifmtptr++) = *p; continue; } else { if (fmtptr == fmt) { *(fmtptr++) = '>'; seenalign = 1; } *(fmtptr++) = *p; continue; } } if (!seendigits) { seendigits = 1; *(rfmtptr++) = 'R'; *(ifmtptr++) = 'R'; } if (*p == 'U' || *p == 'D' || *p == 'Y' || *p == 'Z' || *p == 'N' ) { if (seenround || seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { *(rfmtptr++) = *p; *(ifmtptr++) = *p; seenround = 1; continue; } } if (*p == 'P' || *p == 'M') { if (seenstyle) { VALUE_ERROR("Invalid conversion specification"); return NULL; } else { if (*p == 'M') mpcstyle = 1; seenstyle = 1; continue; } } if (*p == 'a' || *p == 'A' || *p == 'b' || *p == 'e' || *p == 'E' || *p == 'f' || *p == 'F' || *p == 'g' || *p == 'G' ) { *(rfmtptr++) = *p; *(ifmtptr++) = *p; seenconv = 1; break; } VALUE_ERROR("Invalid conversion specification"); return NULL; } if (!seensign) { *(rfmtptr++) = '-'; *(ifmtptr++) = '-'; } if (!seendigits) { *(rfmtptr++) = 'R'; *(ifmtptr++) = 'R'; } if (!seenconv) { *(rfmtptr++) = 'f'; *(ifmtptr++) = 'f'; } *(rfmtptr) = '\00'; *(ifmtptr) = '\00'; *(fmtptr) = '\00'; /* Format the real part.... */ rbuflen = mpfr_asprintf(&realbuf, rfmt, mpc_realref(MPC(self))); if (rbuflen < 0) { mpfr_free_str(realbuf); SYSTEM_ERROR("Internal error in mpfr_asprintf"); return NULL; } /* Format the imaginary part. If Python style is wanted, convert the '-' * or ' ' sign indicator to '+'. */ if (!mpcstyle) { if (ifmt[1] == ' ' || ifmt[1] == '-' || ifmt[1] == '+') { ifmt[1] = '+'; } else { mpfr_free_str(realbuf); VALUE_ERROR("Invalid conversion specification for imag"); return NULL; } } ibuflen = mpfr_asprintf(&imagbuf, ifmt, mpc_imagref(MPC(self))); if (ibuflen < 0) { mpfr_free_str(realbuf); mpfr_free_str(imagbuf); SYSTEM_ERROR("Internal error in mpfr_asprintf"); return NULL; } /* Combine the real and imaginary components into a single buffer. * Include space for '(', ' ', and 'j)' and possibly appending '.0' twice. */ tempbuf = malloc(rbuflen + ibuflen + 10); if (!tempbuf) { mpfr_free_str(realbuf); mpfr_free_str(imagbuf); return PyErr_NoMemory(); } tempbuf[0] = '\00'; if (mpcstyle) strcat(tempbuf, "("); strcat(tempbuf, realbuf); /* If there isn't a decimal point in the output and the output * is short and only consists of digits, then append .0 */ if (strlen(realbuf) < 50 && strlen(realbuf) == strspn(realbuf, "+- 0123456789")) { strcat(tempbuf, ".0"); } if (mpcstyle) strcat(tempbuf, " "); else { /* Need to insert + if imag is nan or +inf. */ if (mpfr_nan_p(mpc_imagref(MPC(self))) || (mpfr_inf_p(mpc_imagref(MPC(self))) && mpfr_sgn(mpc_imagref(MPC(self))) > 0)) { strcat(tempbuf, "+"); } } strcat(tempbuf, imagbuf); if (strlen(imagbuf) < 50 && strlen(imagbuf) == strspn(imagbuf, "+- 0123456789")) { strcat(tempbuf, ".0"); } if (mpcstyle) strcat(tempbuf, ")"); else strcat(tempbuf, "j"); mpfr_free_str(realbuf); mpfr_free_str(imagbuf); tempstr = Py_BuildValue("s", tempbuf); if (!tempstr) { free(tempbuf); return NULL; } result = PyObject_CallMethod(tempstr, "__format__", "(s)", fmt); Py_DECREF(tempstr); return result; } /* produce digits for an mpz in requested base, default 10 */ PyDoc_STRVAR(GMPy_doc_mpz_digits_method, "x.digits([base=10]) -> string\n\n" "Return Python string representing x in the given base. Values for\n" "base can range between 2 to 62. A leading '-' is present if x<0\n" "but no leading '+' is present if x>=0."); static PyObject * GMPy_MPZ_Digits_Method(PyObject *self, PyObject *args) { int base = 10; if (PyTuple_GET_SIZE(args) && !PyArg_ParseTuple(args, "|i", &base)) { return NULL; } return GMPy_PyStr_From_MPZ((MPZ_Object*)self, base, 16, NULL); } static PyObject * GMPy_XMPZ_Digits_Method(PyObject *self, PyObject *args) { int base = 10; if (PyTuple_GET_SIZE(args) && !PyArg_ParseTuple(args, "|i", &base)) { return NULL; } return GMPy_PyStr_From_XMPZ((XMPZ_Object*)self, base, 0, NULL); } PyDoc_STRVAR(GMPy_doc_mpq_digits_method, "x.digits([base=10]) -> string\n\n" "Return a Python string representing x in the given base (2 to 62,\n" "default is 10). A leading '-' is present if x<0, but no leading '+'\n" "is present if x>=0.\n"); static PyObject * GMPy_MPQ_Digits_Method(PyObject *self, PyObject *args) { int base = 10; if (PyTuple_GET_SIZE(args) && !PyArg_ParseTuple(args, "|i", &base)) { return NULL; } return GMPy_PyStr_From_MPQ((MPQ_Object*)self, base, 0, NULL); } PyDoc_STRVAR(GMPy_doc_mpfr_digits_method, "x.digits([base=10[, prec=0]]) -> (mantissa, exponent, bits)\n\n" "Returns up to 'prec' digits in the given base. If 'prec' is 0, as many\n" "digits that are available are returned. No more digits than available\n" "given x's precision are returned. 'base' must be between 2 and 62,\n" "inclusive. The result is a three element tuple containing the mantissa,\n" "the exponent, and the number of bits of precision."); static PyObject * GMPy_MPFR_Digits_Method(PyObject *self, PyObject *args) { int base = 10, prec = 0; if (PyTuple_GET_SIZE(args) && !PyArg_ParseTuple(args, "|ii", &base, &prec)) { return NULL; } return GMPy_PyStr_From_MPFR((MPFR_Object*)self, base, prec, NULL); } PyDoc_STRVAR(GMPy_doc_mpc_digits_method, "c.digits(base=10, prec=0) -> ((mant, exp, prec), (mant, exp, prec))\n\n" "Returns up to 'prec' digits in the given base. If 'prec' is 0, as many\n" "digits that are available given c's precision are returned. 'base' must\n" "be between 2 and 62. The result consists of 2 three-element tuples that\n" "contain the mantissa, exponent, and number of bits of precision of the\n" "real and imaginary components."); static PyObject * GMPy_MPC_Digits_Method(PyObject *self, PyObject *args) { int base = 10, prec = 0; if (PyTuple_GET_SIZE(args) && !PyArg_ParseTuple(args, "|ii", &base, &prec)) { return NULL; } return GMPy_PyStr_From_MPC((MPC_Object*)self, base, prec, NULL); } PyDoc_STRVAR(GMPy_doc_context_digits, "digits(x[, base[, prec]]) -> string\n\n" "Return string representing x. Calls mpz.digits, mpq.digits,\n" "mpfr.digits, or mpc.digits as appropriate."); static PyObject * GMPy_Context_Digits(PyObject *self, PyObject *args) { PyObject *arg0, *tuple, *temp, *result; Py_ssize_t argc; argc = PyTuple_GET_SIZE(args); if (argc == 0) { TYPE_ERROR("digits() requires at least one argument"); return NULL; } if (argc > 3) { TYPE_ERROR("digits() accepts at most three arguments"); return NULL; } arg0 = PyTuple_GET_ITEM(args, 0); if (!(tuple = PyTuple_GetSlice(args, 1, argc))) { return NULL; } if (IS_INTEGER(arg0)) { temp = (PyObject*)GMPy_MPZ_From_Integer(arg0, NULL); result = GMPy_MPZ_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } if (IS_RATIONAL(arg0)) { temp = (PyObject*)GMPy_MPQ_From_Rational(arg0, NULL); result = GMPy_MPQ_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } if (IS_REAL(arg0)) { temp = (PyObject*)GMPy_MPFR_From_Real(arg0, 1, NULL); result = GMPy_MPFR_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } if (IS_COMPLEX(arg0)) { temp = (PyObject*)GMPy_MPC_From_Complex(arg0, 1, 1, NULL); result = GMPy_MPC_Digits_Method(temp, tuple); Py_DECREF(temp); Py_DECREF(tuple); return result; } Py_DECREF(tuple); TYPE_ERROR("digits() argument type not supported"); return NULL; } gmpy2-2.1.0b3/src/gmpy2_format.h0000664000175000017500000000543613425752314016233 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_format.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_FORMAT_H #define GMPY_FORMAT_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPZ_Digits_Method(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Format(PyObject *self, PyObject *args); static PyObject * GMPy_MPQ_Digits_Method(PyObject *self, PyObject *args); /* static PyObject * GMPy_MPQ_Format(PyObject *self, PyObject *args); */ static PyObject * GMPy_MPFR_Digits_Method(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_Format(PyObject *self, PyObject *args); static PyObject * GMPy_MPC_Digits_Method(PyObject *self, PyObject *args); static PyObject * GMPy_MPC_Format(PyObject *self, PyObject *args); static PyObject * GMPy_Context_Digits(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_fused.c0000664000175000017500000005065013425752326016045 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_fused.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static PyObject * _GMPy_MPZ_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPZ_Object *result; if (!(result = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpz_mul(result->z, MPZ(x), MPZ(y)); mpz_add(result->z, result->z, MPZ(z)); return (PyObject*)result; } static PyObject * GMPy_Integer_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context)) || !(tempy = (PyObject*)GMPy_MPZ_From_Integer(y, context)) || !(tempz = (PyObject*)GMPy_MPZ_From_Integer(z, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPZ_FMA(tempx, tempy, tempz, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); return result; } static PyObject * _GMPy_MPQ_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPQ_Object *result; if (!(result = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpq_mul(result->q, MPQ(x), MPQ(y)); mpq_add(result->q, result->q, MPQ(z)); return (PyObject*)result; } static PyObject * GMPy_Rational_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context)) || !(tempy = (PyObject*)GMPy_MPQ_From_Rational(y, context)) || !(tempz = (PyObject*)GMPy_MPQ_From_Rational(z, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPQ_FMA(tempx, tempy, tempz, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)tempz); return (result); } static PyObject * _GMPy_MPFR_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_fma(result->f, MPFR(x), MPFR(y), MPFR(z), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = (PyObject*)GMPy_MPFR_From_Real(y, 1, context)) || !(tempz = (PyObject*)GMPy_MPFR_From_Real(z, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPFR_FMA(tempx, tempy, tempz, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); return result; } static PyObject * _GMPy_MPC_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } result->rc = mpc_fma(result->c, MPC(x), MPC(y), MPC(z), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context)) || !(tempy = (PyObject*)GMPy_MPC_From_Complex(y, 1, 1, context)) || !(tempz = (PyObject*)GMPy_MPC_From_Complex(z, 1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPC_FMA(tempx, tempy, tempz, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); return result; } PyDoc_STRVAR(GMPy_doc_context_fma, "context.fma(x, y, z) -> number\n\n" "Return correctly rounded result of (x * y) + z."); PyDoc_STRVAR(GMPy_doc_function_fma, "fma(x, y, z) -> number\n\n" "Return correctly rounded result of (x * y) + z."); GMPY_MPFR_MPC_TRIOP_TEMPLATE(FMA, fma); static PyObject * _GMPy_MPZ_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPZ_Object *result; if (!(result = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpz_mul(result->z, MPZ(x), MPZ(y)); mpz_sub(result->z, result->z, MPZ(z)); return (PyObject*)result; } static PyObject * GMPy_Integer_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context)) || !(tempy = (PyObject*)GMPy_MPZ_From_Integer(y, context)) || !(tempz = (PyObject*)GMPy_MPZ_From_Integer(z, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPZ_FMS(tempx, tempy, tempz, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); return result; } static PyObject * _GMPy_MPQ_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPQ_Object *result; if (!(result = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpq_mul(result->q, MPQ(x), MPQ(y)); mpq_sub(result->q, result->q, MPQ(z)); return (PyObject*)result; } static PyObject * GMPy_Rational_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context)) || !(tempy = (PyObject*)GMPy_MPQ_From_Rational(y, context)) || !(tempz = (PyObject*)GMPy_MPQ_From_Rational(z, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPQ_FMS(tempx, tempy, tempz, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); return result; } static PyObject * _GMPy_MPFR_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_fms(result->f, MPFR(x), MPFR(y), MPFR(z), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = (PyObject*)GMPy_MPFR_From_Real(y, 1, context)) || !(tempz = (PyObject*)GMPy_MPFR_From_Real(z, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPFR_FMS(tempx, tempy, tempz, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); return result; } static PyObject * _GMPy_MPC_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } /* TODO: We shouldn't temporarily mutate an mpc object. */ mpc_neg(MPC(z), MPC(z), GET_MPC_ROUND(context)); result->rc = mpc_fma(result->c, MPC(x), MPC(y), MPC(z), GET_MPC_ROUND(context)); mpc_neg(MPC(z), MPC(z), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context)) || !(tempy = (PyObject*)GMPy_MPC_From_Complex(y, 1, 1, context)) || !(tempz = (PyObject*)GMPy_MPC_From_Complex(z, 1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPC_FMS(tempx, tempy, tempz, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); return result; } PyDoc_STRVAR(GMPy_doc_context_fms, "context.fms(x, y, z) -> number\n\n" "Return correctly rounded result of (x * y) - z."); PyDoc_STRVAR(GMPy_doc_function_fms, "fms(x, y, z) -> number\n\n" "Return correctly rounded result of (x * y) - z."); GMPY_MPFR_MPC_TRIOP_TEMPLATE(FMS, fms); /* Add support for new fmma and fmms functions from MPFr 4. */\ #if MPFR_VERSION_MAJOR > 3 static PyObject * _GMPy_MPZ_FMMA(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { MPZ_Object *result = NULL, *temp = NULL; if (!(result = GMPy_MPZ_New(context)) || !(temp = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ Py_XDECREF(result); Py_XDECREF(temp); return NULL; /* LCOV_EXCL_STOP */ } mpz_mul(result->z, MPZ(x), MPZ(y)); mpz_mul(temp->z, MPZ(z), MPZ(t)); mpz_add(result->z, result->z, temp->z); Py_DECREF(temp); return (PyObject*)result; } static PyObject * GMPy_Integer_FMMA(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL, *tempt = NULL; if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context)) || !(tempy = (PyObject*)GMPy_MPZ_From_Integer(y, context)) || !(tempz = (PyObject*)GMPy_MPZ_From_Integer(z, context)) || !(tempt = (PyObject*)GMPy_MPZ_From_Integer(t, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); Py_XDECREF(tempt); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPZ_FMMA(tempx, tempy, tempz, tempt, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); Py_DECREF(tempt); return result; } static PyObject * _GMPy_MPQ_FMMA(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { MPQ_Object *result = NULL, *temp = NULL; if (!(result = GMPy_MPQ_New(context)) || !(temp = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ Py_XDECREF(result); Py_XDECREF(temp); return NULL; /* LCOV_EXCL_STOP */ } mpq_mul(result->q, MPQ(x), MPQ(y)); mpq_mul(temp->q, MPQ(z), MPQ(t)); mpq_add(result->q, result->q, temp->q); Py_DECREF(temp); return (PyObject*)result; } static PyObject * GMPy_Rational_FMMA(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL, *tempt = NULL; if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context)) || !(tempy = (PyObject*)GMPy_MPQ_From_Rational(y, context)) || !(tempz = (PyObject*)GMPy_MPQ_From_Rational(z, context)) || !(tempt = (PyObject*)GMPy_MPQ_From_Rational(t, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); Py_XDECREF(tempt); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPQ_FMMA(tempx, tempy, tempz, tempt, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)tempz); Py_DECREF((PyObject*)tempt); return (result); } static PyObject * _GMPy_MPFR_FMMA(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_fmma(result->f, MPFR(x), MPFR(y), MPFR(z), MPFR(t), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_FMMA(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL, *tempt = NULL; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = (PyObject*)GMPy_MPFR_From_Real(y, 1, context)) || !(tempz = (PyObject*)GMPy_MPFR_From_Real(z, 1, context)) || !(tempt = (PyObject*)GMPy_MPFR_From_Real(t, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); Py_XDECREF(tempt); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPFR_FMMA(tempx, tempy, tempz, tempt, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); Py_DECREF(tempt); return result; } PyDoc_STRVAR(GMPy_doc_context_fmma, "context.fmma(x, y, z, t) -> number\n\n" "Return correctly rounded result of (x * y) + (z * t)."); PyDoc_STRVAR(GMPy_doc_function_fmma, "fmma(x, y, z, t) -> number\n\n" "Return correctly rounded result of (x * y) + (z + t)."); GMPY_MPFR_QUADOP_TEMPLATE(FMMA, fmma); static PyObject * _GMPy_MPZ_FMMS(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { MPZ_Object *result = NULL, *temp = NULL; if (!(result = GMPy_MPZ_New(context)) || !(temp = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ Py_XDECREF(result); Py_XDECREF(temp); return NULL; /* LCOV_EXCL_STOP */ } mpz_mul(result->z, MPZ(x), MPZ(y)); mpz_mul(temp->z, MPZ(z), MPZ(t)); mpz_sub(result->z, result->z, temp->z); Py_DECREF(temp); return (PyObject*)result; } static PyObject * GMPy_Integer_FMMS(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL, *tempt = NULL; if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context)) || !(tempy = (PyObject*)GMPy_MPZ_From_Integer(y, context)) || !(tempz = (PyObject*)GMPy_MPZ_From_Integer(z, context)) || !(tempt = (PyObject*)GMPy_MPZ_From_Integer(t, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); Py_XDECREF(tempt); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPZ_FMMS(tempx, tempy, tempz, tempt, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); Py_DECREF(tempt); return result; } static PyObject * _GMPy_MPQ_FMMS(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { MPQ_Object *result = NULL, *temp = NULL; if (!(result = GMPy_MPQ_New(context)) || !(temp = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ Py_XDECREF(result); Py_XDECREF(temp); return NULL; /* LCOV_EXCL_STOP */ } mpq_mul(result->q, MPQ(x), MPQ(y)); mpq_mul(temp->q, MPQ(z), MPQ(t)); mpq_sub(result->q, result->q, temp->q); Py_DECREF(temp); return (PyObject*)result; } static PyObject * GMPy_Rational_FMMS(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL, *tempt = NULL; if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context)) || !(tempy = (PyObject*)GMPy_MPQ_From_Rational(y, context)) || !(tempz = (PyObject*)GMPy_MPQ_From_Rational(z, context)) || !(tempt = (PyObject*)GMPy_MPQ_From_Rational(t, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); Py_XDECREF(tempt); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPQ_FMMS(tempx, tempy, tempz, tempt, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)tempz); Py_DECREF((PyObject*)tempt); return (result); } static PyObject * _GMPy_MPFR_FMMS(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_fmms(result->f, MPFR(x), MPFR(y), MPFR(z), MPFR(t), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_FMMS(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) { PyObject *result, *tempx = NULL, *tempy = NULL, *tempz = NULL, *tempt = NULL; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = (PyObject*)GMPy_MPFR_From_Real(y, 1, context)) || !(tempz = (PyObject*)GMPy_MPFR_From_Real(z, 1, context)) || !(tempt = (PyObject*)GMPy_MPFR_From_Real(t, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF(tempx); Py_XDECREF(tempy); Py_XDECREF(tempz); Py_XDECREF(tempt); return NULL; /* LCOV_EXCL_STOP */ } result = _GMPy_MPFR_FMMS(tempx, tempy, tempz, tempt, context); Py_DECREF(tempx); Py_DECREF(tempy); Py_DECREF(tempz); Py_DECREF(tempt); return result; } PyDoc_STRVAR(GMPy_doc_context_fmms, "context.fmms(x, y, z, t) -> number\n\n" "Return correctly rounded result of (x * y) - (z * t)."); PyDoc_STRVAR(GMPy_doc_function_fmms, "fmms(x, y, z, t) -> number\n\n" "Return correctly rounded result of (x * y) - (z + t)."); GMPY_MPFR_QUADOP_TEMPLATE(FMMS, fmms); #endif gmpy2-2.1.0b3/src/gmpy2_fused.h0000664000175000017500000000634513425752341016051 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_fused.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_FUSED_H #define GMPY_FUSED_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Integer_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Rational_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Real_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Complex_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Number_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Context_FMA(PyObject *self, PyObject *args); static PyObject * GMPy_Integer_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Rational_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Real_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Complex_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Number_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Context_FMS(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_hash.c0000664000175000017500000001475413425752350015664 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_hash.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static Py_hash_t GMPy_MPZ_Hash_Slot(MPZ_Object *self) { #ifdef _PyHASH_MODULUS Py_hash_t hash; if (self->hash_cache != -1) { return self->hash_cache; } hash = (Py_hash_t)mpn_mod_1(self->z->_mp_d, mpz_size(self->z), _PyHASH_MODULUS); if (mpz_sgn(self->z) < 0) { hash = -hash; } if (hash == -1) { hash = -2; } return (self->hash_cache = hash); #else unsigned long x; if (self->hash_cache != -1) { return self->hash_cache; } x = (unsigned long)mpn_mod_1(self->z->_mp_d, mpz_size(self->z), ULONG_MAX); if (mpz_sgn(self->z) < 0) { x = x * -1; } if (x == (unsigned long)-1) { x = (unsigned long)-2; } return (self->hash_cache = (long)x); #endif } static Py_hash_t GMPy_MPQ_Hash_Slot(MPQ_Object *self) { #ifdef _PyHASH_MODULUS Py_hash_t hash = 0; mpz_t temp, temp1, mask; if (self->hash_cache != -1) { return self->hash_cache; } mpz_init(temp); mpz_init(temp1); mpz_init(mask); mpz_set_si(mask, 1); mpz_mul_2exp(mask, mask, _PyHASH_BITS); mpz_sub_ui(mask, mask, 1); if (!mpz_invert(temp, mpq_denref(self->q), mask)) { mpz_clear(temp); mpz_clear(temp1); mpz_clear(mask); hash = _PyHASH_INF; if (mpz_sgn(mpq_numref(self->q)) < 0) { hash = -hash; } self->hash_cache = hash; return hash; } mpz_set(temp1, mask); mpz_sub_ui(temp1, temp1, 2); mpz_powm(temp, mpq_denref(self->q), temp1, mask); mpz_tdiv_r(temp1, mpq_numref(self->q), mask); mpz_mul(temp, temp, temp1); hash = (Py_hash_t)mpn_mod_1(temp->_mp_d, mpz_size(temp), _PyHASH_MODULUS); if (mpz_sgn(mpq_numref(self->q)) < 0) { hash = -hash; } if (hash == -1) { hash = -2; } mpz_clear(temp); mpz_clear(temp1); mpz_clear(mask); self->hash_cache = hash; return hash; #else PyObject *temp; if (self->hash_cache != -1) { return self->hash_cache; } if (!(temp = GMPy_PyFloat_From_MPQ(self, NULL))) { SYSTEM_ERROR("Could not convert 'mpq' to float."); return -1; } self->hash_cache = PyObject_Hash(temp); Py_DECREF(temp); return self->hash_cache; #endif } static Py_hash_t _mpfr_hash(mpfr_t f) { #ifdef _PyHASH_MODULUS Py_uhash_t hash = 0; Py_ssize_t exp; size_t msize; int sign; /* Handle special cases first */ if (!mpfr_number_p(f)) { if (mpfr_inf_p(f)) { if (mpfr_sgn(f) > 0) { return _PyHASH_INF; } else { return -_PyHASH_INF; } } else { return _PyHASH_NAN; } } /* Calculate the number of limbs in the mantissa. */ msize = (f->_mpfr_prec + mp_bits_per_limb - 1) / mp_bits_per_limb; /* Calculate the hash of the mantissa. */ if (mpfr_sgn(f) > 0) { hash = mpn_mod_1(f->_mpfr_d, msize, _PyHASH_MODULUS); sign = 1; } else if (mpfr_sgn(f) < 0) { hash = mpn_mod_1(f->_mpfr_d, msize, _PyHASH_MODULUS); sign = -1; } else { return 0; } /* Calculate the final hash. */ exp = f->_mpfr_exp - (msize * mp_bits_per_limb); exp = exp >= 0 ? exp % _PyHASH_BITS : _PyHASH_BITS-1-((-1-exp) % _PyHASH_BITS); hash = ((hash << exp) & _PyHASH_MODULUS) | hash >> (_PyHASH_BITS - exp); hash *= sign; if (hash == (Py_uhash_t)(-1)) { hash = (Py_uhash_t)(-2); } return (Py_hash_t)hash; #else double temp; CTXT_Object *context = NULL; CHECK_CONTEXT(context); temp = mpfr_get_d(f, GET_MPFR_ROUND(context)); return _Py_HashDouble(temp); #endif } static Py_hash_t GMPy_MPFR_Hash_Slot(MPFR_Object *self) { if (self->hash_cache == -1) { self->hash_cache = _mpfr_hash(self->f); } return self->hash_cache; } static Py_hash_t GMPy_MPC_Hash_Slot(MPC_Object *self) { Py_uhash_t hashreal, hashimag, combined; if (self->hash_cache != -1) { return self->hash_cache; } hashreal = (Py_uhash_t)_mpfr_hash(mpc_realref(self->c)); if (hashreal == (Py_uhash_t)(-1)) { return -1; } hashimag = (Py_uhash_t)_mpfr_hash(mpc_imagref(self->c)); if (hashimag == (Py_uhash_t)(-1)) { return -1; } combined = hashreal + _PyHASH_IMAG * hashimag; if (combined == (Py_uhash_t)(-1)) { combined = (Py_uhash_t)(-2); } self->hash_cache = combined; return (Py_hash_t)combined; } gmpy2-2.1.0b3/src/gmpy2_hash.h0000664000175000017500000000456513425752363015674 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_hash.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_HASH_H #define GMPY_HASH_H #ifdef __cplusplus extern "C" { #endif static Py_hash_t GMPy_MPZ_Hash_Slot(MPZ_Object *self); static Py_hash_t GMPy_MPQ_Hash_Slot(MPQ_Object *self); static Py_hash_t GMPy_MPFR_Hash_Slot(MPFR_Object *self); static Py_hash_t GMPy_MPC_Hash_Slot(MPC_Object *self); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_macros.h0000664000175000017500000006314613425752400016225 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_macros.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains a collection of macros that can be used to reduce * repetitive code. As new macros are written to support of refactoring, * they should be placed here. */ /* NAME is used as part of the GMPy function name. It usually uses an upper- * case first character. * FUNC is the component of the actual name used by MPFR and MPC. * * GMPY_MPFR_MPC_UNIOP(NAME, FUNC) creates the following functions: * GMPy_Real_NAME(x, context) * GMPy_Complex_NAME(x, context) * GMPy_Number_NAME(x, context) * GMPy_Context_NAME(self, other) * - called with METH_O * * GMPY_MPFR_MPC_UNIOP_EX(NAME, FUNC) creates the following functions: * GMPy_MPFR_NAME(x, context) * GMPy_Real_NAME(x, context) * GMPy_MPC_NAME(x, context) * GMPy_Complex_NAME(x, context) * GMPy_Number_NAME(x, context) * GMPy_Context_NAME(self, other) * - called with METH_O * * GMPY_MPFR_MPC_UNIOP_TEMPLATE(NAME, FUNC) creates the following functions: * GMPy_Number_NAME(x, context) * - assumes GMPy_Real_NAME & GMPy_Complex_NAME exist * GMPy_Context_NAME(self, other) * - called with METH_O * * GMPY_MPFR_MPC_TRIOP_EX(NAME, FUNC) creates the following functions: * GMPy_Real_NAME(x, y, Z, context) * GMPy_Complex_NAME(x, y, Z, context) * GMPy_Number_NAME(x, y, Z, context) * - assumes GMPy_Integer_NAME & GMPy_Rational_NAME also exist * GMPy_Context_NAME(self, args) * - called with METH_VARARGS * * GMPY_MPFR_MPC_UNIOP_TEMPLATE(NAME, FUNC) creates the following functions: * GMPy_Number_NAME(x, context) * - assumes GMPy_Real_NAME & GMPy_Complex_NAME exist * GMPy_Context_NAME(self, other) * - called with METH_O * * GMPY_MPFR_UNIOP(NAME, FUNC) creates the following functions: * GMPy_Real_NAME(x, context) * GMPy_Number_NAME(x, context) * GMPy_Context_NAME(self, other) * - called with METH_O * * GMPY_MPFR_UNIOP_TEMPLATE(NAME, FUNC) creates the following functions: * GMPy_Number_NAME(x, context) * - assumes GMPy_Real_NAME exists * GMPy_Context_NAME(self, other) * - called with METH_O * * GMPY_MPFR_BINOP(NAME, FUNC) creates the following functions: * GMPy_Real_NAME(x, y, context) * GMPy_Number_NAME(x, y, context) * GMPy_Context_NAME(self, args) * - called with METH_VARARGS * */ #define GMPY_MPFR_MPC_UNIOP(NAME, FUNC) \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPFR_Object *result = NULL, *tempx = NULL; \ CHECK_CONTEXT(context); \ result = GMPy_MPFR_New(0, context); \ tempx = GMPy_MPFR_From_Real(x, 1, context); \ if (!result || !tempx) { \ Py_XDECREF((PyObject*)result); \ Py_XDECREF((PyObject*)tempx); \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, tempx->f, GET_MPFR_ROUND(context)); \ Py_DECREF((PyObject*)tempx); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ #define GMPY_MPFR_MPC_UNIOP_EX(NAME, FUNC) \ static PyObject * \ _GMPy_MPFR_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPFR_Object *result; \ CHECK_CONTEXT(context); \ if (!(result = GMPy_MPFR_New(0, context))) { \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, MPFR(x), GET_MPFR_ROUND(context)); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPFR_Object *tempx; \ PyObject *result; \ CHECK_CONTEXT(context); \ if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { \ return NULL; \ } \ result = _GMPy_MPFR_##NAME((PyObject*)tempx, context); \ Py_DECREF((PyObject*)tempx); \ return (PyObject*)result; \ } \ static PyObject * \ _GMPy_MPC_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPC_Object *result; \ CHECK_CONTEXT(context); \ if (!(result = GMPy_MPC_New(0, 0, context))) { \ return NULL; \ } \ result->rc = mpc_##FUNC(result->c, MPC(x), GET_MPC_ROUND(context)); \ _GMPy_MPC_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Complex_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPC_Object *tempx; \ PyObject *result; \ CHECK_CONTEXT(context); \ if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context))) { \ return NULL; \ } \ result = _GMPy_MPC_##NAME((PyObject*)tempx, context); \ Py_DECREF((PyObject*)tempx); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (MPFR_Check(x)) \ return _GMPy_MPFR_##NAME(x, context); \ if (MPC_Check(x)) \ return _GMPy_MPC_##NAME(x, context); \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ if (IS_COMPLEX(x)) \ return GMPy_Complex_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_MPC_UNIOP_TEMPLATE(NAME, FUNC) \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ if (IS_COMPLEX(x)) \ return GMPy_Complex_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_MPC_UNIOP_TEMPLATE_EX(NAME, FUNC) \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (MPFR_Check(x)) \ return _GMPy_MPFR_##NAME(x, context); \ if (MPC_Check(x)) \ return _GMPy_MPC_##NAME(x, context); \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ if (IS_COMPLEX(x)) \ return GMPy_Complex_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_MPC_TRIOP_TEMPLATE(NAME, FUNC) \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) \ { \ if (MPZ_Check(x) && MPZ_Check(y) && MPZ_Check(z)) \ return _GMPy_MPZ_##NAME(x, y, z, context); \ if (MPQ_Check(x) && MPQ_Check(y) && MPQ_Check(z)) \ return _GMPy_MPQ_##NAME(x, y, z, context); \ if (MPFR_Check(x) && MPFR_Check(y) && MPFR_Check(z)) \ return _GMPy_MPFR_##NAME(x, y, z, context); \ if (MPC_Check(x) && MPC_Check(y) && MPC_Check(z)) \ return _GMPy_MPC_##NAME(x, y, z, context); \ if (IS_INTEGER(x) && IS_INTEGER(y) && IS_INTEGER(z)) \ return GMPy_Integer_##NAME(x, y, z, context); \ if (IS_RATIONAL(x) && IS_RATIONAL(y) && IS_RATIONAL(z)) \ return GMPy_Rational_##NAME(x, y, z, context); \ if (IS_REAL(x) && IS_REAL(y) && IS_REAL(z)) \ return GMPy_Real_##NAME(x, y, z, context); \ if (IS_COMPLEX(x) && IS_COMPLEX(y) && IS_COMPLEX(z)) \ return GMPy_Complex_##NAME(x, y, z, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *args) \ { \ CTXT_Object *context = NULL; \ if (PyTuple_GET_SIZE(args) != 3) { \ TYPE_ERROR(#FUNC"() requires 3 arguments"); \ return NULL; \ } \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), \ PyTuple_GET_ITEM(args, 1), \ PyTuple_GET_ITEM(args, 2), context); \ } #define GMPY_MPFR_QUADOP_TEMPLATE(NAME, FUNC) \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, PyObject *y, PyObject *z, PyObject *t, CTXT_Object *context) \ { \ if (MPZ_Check(x) && MPZ_Check(y) && MPZ_Check(z) && MPZ_Check(t)) \ return _GMPy_MPZ_##NAME(x, y, z, t, context); \ if (MPQ_Check(x) && MPQ_Check(y) && MPQ_Check(z) && MPQ_Check(t)) \ return _GMPy_MPQ_##NAME(x, y, z, t, context); \ if (MPFR_Check(x) && MPFR_Check(y) && MPFR_Check(z) && MPFR_Check(t)) \ return _GMPy_MPFR_##NAME(x, y, z, t, context); \ if (IS_INTEGER(x) && IS_INTEGER(y) && IS_INTEGER(z) && IS_INTEGER(t)) \ return GMPy_Integer_##NAME(x, y, z, t, context); \ if (IS_RATIONAL(x) && IS_RATIONAL(y) && IS_RATIONAL(z) && IS_RATIONAL(t)) \ return GMPy_Rational_##NAME(x, y, z, t, context); \ if (IS_REAL(x) && IS_REAL(y) && IS_REAL(z) && IS_REAL(t)) \ return GMPy_Real_##NAME(x, y, z, t, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *args) \ { \ CTXT_Object *context = NULL; \ if (PyTuple_GET_SIZE(args) != 4) { \ TYPE_ERROR(#FUNC"() requires 4 arguments"); \ return NULL; \ } \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), \ PyTuple_GET_ITEM(args, 1), \ PyTuple_GET_ITEM(args, 2), \ PyTuple_GET_ITEM(args, 3), context); \ } #define GMPY_MPFR_UNIOP(NAME, FUNC) \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPFR_Object *result, *tempx; \ CHECK_CONTEXT(context); \ result = GMPy_MPFR_New(0, context); \ tempx = GMPy_MPFR_From_Real(x, 1, context); \ if (!result || !tempx) { \ Py_XDECREF((PyObject*)result); \ Py_XDECREF((PyObject*)tempx); \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, tempx->f, GET_MPFR_ROUND(context)); \ Py_DECREF((PyObject*)tempx); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_UNIOP_NOROUND(NAME, FUNC) \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPFR_Object *result, *tempx; \ CHECK_CONTEXT(context); \ result = GMPy_MPFR_New(0, context); \ tempx = GMPy_MPFR_From_Real(x, 1, context); \ if (!result || !tempx) { \ Py_XDECREF((PyObject*)result); \ Py_XDECREF((PyObject*)tempx); \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, tempx->f); \ Py_DECREF((PyObject*)tempx); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_MPFR_Method_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ CHECK_CONTEXT(context); \ return GMPy_Number_##NAME(self, context); \ }\ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_UNIOP_NOROUND_NOMETHOD(NAME, FUNC) \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPFR_Object *result, *tempx; \ CHECK_CONTEXT(context); \ result = GMPy_MPFR_New(0, context); \ tempx = GMPy_MPFR_From_Real(x, 1, context); \ if (!result || !tempx) { \ Py_XDECREF((PyObject*)result); \ Py_XDECREF((PyObject*)tempx); \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, tempx->f); \ Py_DECREF((PyObject*)tempx); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_UNIOP_EX(NAME, FUNC) \ static PyObject * \ _GMPy_MPFR_##NAME(PyObject *x, CTXT_Object *context) \ { \ MPFR_Object *result; \ CHECK_CONTEXT(context); \ if (!(result = GMPy_MPFR_New(0, context))) { \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, MPFR(x), GET_MPFR_ROUND(context)); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, CTXT_Object *context) \ { \ PyObject *result, *tempx; \ CHECK_CONTEXT(context); \ if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { \ return NULL; \ } \ result = _GMPy_MPFR_##NAME(tempx, context); \ Py_DECREF(tempx); \ return result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (MPFR_Check(x)) \ return _GMPy_MPFR_##NAME(x, context); \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_UNIOP_TEMPLATE(NAME, FUNC) \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_UNIOP_TEMPLATE_EX(NAME, FUNC) \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, CTXT_Object *context) \ { \ if (MPFR_Check(x)) \ return _GMPy_MPFR_##NAME(x, context); \ if (IS_REAL(x)) \ return GMPy_Real_##NAME(x, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *other) \ { \ CTXT_Object *context = NULL; \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(other, context); \ } #define GMPY_MPFR_BINOP(NAME, FUNC) \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ MPFR_Object *result = NULL, *tempx = NULL, *tempy = NULL; \ CHECK_CONTEXT(context); \ tempx = GMPy_MPFR_From_Real(x, 1, context); \ tempy = GMPy_MPFR_From_Real(y, 1, context); \ result = GMPy_MPFR_New(0, context); \ if (!result || !tempx || !tempy) { \ Py_XDECREF((PyObject*)tempx); \ Py_XDECREF((PyObject*)tempy); \ Py_XDECREF((PyObject*)result); \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context)); \ Py_DECREF((PyObject*)tempx); \ Py_DECREF((PyObject*)tempy); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ if (IS_REAL(x) && IS_REAL(y)) \ return GMPy_Real_##NAME(x, y, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *args) \ { \ CTXT_Object *context = NULL; \ if (PyTuple_GET_SIZE(args) != 2) { \ TYPE_ERROR(#FUNC"() requires 2 arguments"); \ return NULL; \ } \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ } \ /* Macro to support functions that require ('mpfr', 'int'). * More precisely, the first argument must pass IS_REAL() and the second * argument must pass IS_INTEGER(). */ #define GMPY_MPFR_BINOP_REAL_ULONG(NAME, FUNC) \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ MPFR_Object *result = NULL, *tempx = NULL; \ unsigned long n; \ CHECK_CONTEXT(context); \ result = GMPy_MPFR_New(0, context); \ tempx = GMPy_MPFR_From_Real(x, 1, context); \ n = c_ulong_From_Integer(y); \ if (!result || !tempx || (n == (unsigned long)(-1) && PyErr_Occurred())) { \ Py_XDECREF((PyObject*)tempx); \ Py_XDECREF((PyObject*)result); \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, tempx->f, n, GET_MPFR_ROUND(context)); \ Py_DECREF((PyObject*)tempx); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ if (IS_REAL(x) && PyIntOrLong_Check(y)) \ return GMPy_Real_##NAME(x, y, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *args) \ { \ CTXT_Object *context = NULL; \ if (PyTuple_GET_SIZE(args) != 2) { \ TYPE_ERROR(#FUNC"() requires 2 arguments"); \ return NULL; \ } \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ } \ /* Macro to support functions that require ('mpfr', 'int'). * More precisely, the first argument must pass IS_REAL() and the second * argument must pass IS_INTEGER(). The calling sequence passes n first * to the MPFR library.*/ #define GMPY_MPFR_BINOP_REAL_LONG(NAME, FUNC) \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ MPFR_Object *result = NULL, *tempx = NULL; \ long n; \ CHECK_CONTEXT(context); \ result = GMPy_MPFR_New(0, context); \ tempx = GMPy_MPFR_From_Real(x, 1, context); \ n = c_long_From_Integer(y); \ if (!result || !tempx || (n == -1 && PyErr_Occurred())) { \ Py_XDECREF((PyObject*)tempx); \ Py_XDECREF((PyObject*)result); \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, n, tempx->f, GET_MPFR_ROUND(context)); \ Py_DECREF((PyObject*)tempx); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ if (IS_REAL(x) && PyIntOrLong_Check(y)) \ return GMPy_Real_##NAME(x, y, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *args) \ { \ CTXT_Object *context = NULL; \ if (PyTuple_GET_SIZE(args) != 2) { \ TYPE_ERROR(#FUNC"() requires 2 arguments"); \ return NULL; \ } \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ } \ #define GMPY_MPFR_BINOP_TEMPLATE(NAME, FUNC) \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ if (IS_REAL(x) && IS_REAL(y)) \ return GMPy_Real_##NAME(x, y, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *args) \ { \ CTXT_Object *context = NULL; \ if (PyTuple_GET_SIZE(args) != 2) { \ TYPE_ERROR(#FUNC"() requires 2 arguments"); \ return NULL; \ } \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ } \ #define GMPY_MPFR_BINOP_EX(NAME, FUNC) \ static PyObject * \ _GMPy_MPFR_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ MPFR_Object *result; \ CHECK_CONTEXT(context); \ if (!(result = GMPy_MPFR_New(0, context))) { \ return NULL; \ } \ mpfr_clear_flags(); \ result->rc = mpfr_##FUNC(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); \ _GMPy_MPFR_Cleanup(&result, context); \ return (PyObject*)result; \ } \ static PyObject * \ GMPy_Real_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ PyObject *result, *tempx, *tempy; \ CHECK_CONTEXT(context); \ tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context); \ tempy = (PyObject*)GMPy_MPFR_From_Real(y, 1, context); \ if (!tempx || !tempy) { \ Py_XDECREF(tempx); \ Py_XDECREF(tempy); \ return NULL; \ } \ result = _GMPy_MPFR_##NAME(tempx, tempy, context); \ Py_DECREF(tempx); \ Py_DECREF(tempy); \ return result; \ } \ static PyObject * \ GMPy_Number_##NAME(PyObject *x, PyObject *y, CTXT_Object *context) \ { \ if (MPFR_Check(x) && MPFR_Check(y)) \ return _GMPy_MPFR_##NAME(x, y, context); \ if (IS_REAL(x) && IS_REAL(y)) \ return GMPy_Real_##NAME(x, y, context); \ TYPE_ERROR(#FUNC"() argument type not supported"); \ return NULL; \ } \ static PyObject * \ GMPy_Context_##NAME(PyObject *self, PyObject *args) \ { \ CTXT_Object *context = NULL; \ if (PyTuple_GET_SIZE(args) != 2) { \ TYPE_ERROR(#FUNC"() requires 2 arguments"); \ return NULL; \ } \ if (self && CTXT_Check(self)) { \ context = (CTXT_Object*)self; \ } \ else { \ CHECK_CONTEXT(context); \ } \ return GMPy_Number_##NAME(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); \ } gmpy2-2.1.0b3/src/gmpy2_math.c0000664000175000017500000015532713444603111015663 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_math.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_context_sin, "context.sin(x) -> number\n\n" "Return sine of x; x in radians."); PyDoc_STRVAR(GMPy_doc_function_sin, "sin(x) -> number\n\n" "Return sine of x; x in radians."); GMPY_MPFR_MPC_UNIOP_EX(Sin, sin) PyDoc_STRVAR(GMPy_doc_context_cos, "context.cos(x) -> number\n\n" "Return cosine of x; x in radians."); PyDoc_STRVAR(GMPy_doc_function_cos, "cos(x) -> number\n\n" "Return cosine of x; x in radians."); GMPY_MPFR_MPC_UNIOP_EX(Cos, cos) PyDoc_STRVAR(GMPy_doc_context_tan, "context.tan(x) -> number\n\n" "Return tangent of x; x in radians."); PyDoc_STRVAR(GMPy_doc_function_tan, "tan(x) -> number\n\n" "Return tangent of x; x in radians."); GMPY_MPFR_MPC_UNIOP_EX(Tan, tan) PyDoc_STRVAR(GMPy_doc_context_atan, "context.atan(x) -> number\n\n" "Return inverse tangent of x; result in radians."); PyDoc_STRVAR(GMPy_doc_function_atan, "atan(x) -> number\n\n" "Return inverse tangent of x; result in radians."); GMPY_MPFR_MPC_UNIOP_EX(Atan, atan) PyDoc_STRVAR(GMPy_doc_context_sinh, "context.sinh(x) -> number\n\n" "Return hyperbolic sine of x."); PyDoc_STRVAR(GMPy_doc_function_sinh, "sinh(x) -> number\n\n" "Return hyperbolic sine of x."); GMPY_MPFR_MPC_UNIOP_EX(Sinh, sinh) PyDoc_STRVAR(GMPy_doc_context_cosh, "context.cosh(x) -> number\n\n" "Return hyperbolic cosine of x."); PyDoc_STRVAR(GMPy_doc_function_cosh, "cosh(x) -> number\n\n" "Return hyperbolic cosine of x."); GMPY_MPFR_MPC_UNIOP_EX(Cosh, cosh) PyDoc_STRVAR(GMPy_doc_context_tanh, "context.tanh(x) -> number\n\n" "Return hyperbolic tangent of x."); PyDoc_STRVAR(GMPy_doc_function_tanh, "tanh(x) -> number\n\n" "Return hyperbolic tangent of x."); GMPY_MPFR_MPC_UNIOP_EX(Tanh, tanh) PyDoc_STRVAR(GMPy_doc_context_asinh, "context.asinh(x) -> number\n\n" "Return inverse hyperbolic sine of x."); PyDoc_STRVAR(GMPy_doc_function_asinh, "asinh(x) -> number\n\n" "Return inverse hyperbolic sine of x."); GMPY_MPFR_MPC_UNIOP_EX(Asinh, asinh) PyDoc_STRVAR(GMPy_doc_context_acosh, "context.acosh(x) -> number\n\n" "Return inverse hyperbolic cosine of x."); PyDoc_STRVAR(GMPy_doc_function_acosh, "acosh(x) -> number\n\n" "Return inverse hyperbolic cosine of x."); GMPY_MPFR_MPC_UNIOP_EX(Acosh, acosh) /* Section 2: * These functions accept a single argument and return an mpfr result. * * GMPY_MPFR_UNIOP(NAME, FUNC) creates the following functions: * GMPy_Real_NAME(x, context) * GMPy_Number_NAME(x, context) * GMPy_Context_NAME(self, other) * - called with METH_O */ PyDoc_STRVAR(GMPy_doc_context_sec, "context.sec(x) -> number\n\n" "Return secant of x; x in radians."); PyDoc_STRVAR(GMPy_doc_function_sec, "sec(x) -> number\n\n" "Return secant of x; x in radians."); GMPY_MPFR_UNIOP_EX(Sec, sec) PyDoc_STRVAR(GMPy_doc_context_csc, "context.csc(x) -> number\n\n" "Return cosecant of x; x in radians."); PyDoc_STRVAR(GMPy_doc_function_csc, "csc(x) -> number\n\n" "Return cosecant of x; x in radians."); GMPY_MPFR_UNIOP_EX(Csc, csc) PyDoc_STRVAR(GMPy_doc_context_cot, "context.cot(x) -> number\n\n" "Return cotangent of x; x in radians."); PyDoc_STRVAR(GMPy_doc_function_cot, "cot(x) -> number\n\n" "Return cotangent of x; x in radians."); GMPY_MPFR_UNIOP_EX(Cot, cot) PyDoc_STRVAR(GMPy_doc_context_sech, "context.sech(x) -> number\n\n" "Return hyperbolic secant of x."); PyDoc_STRVAR(GMPy_doc_function_sech, "sech(x) -> number\n\n" "Return hyperbolic secant of x."); GMPY_MPFR_UNIOP_EX(Sech, sech) PyDoc_STRVAR(GMPy_doc_context_csch, "context.csch(x) -> number\n\n" "Return hyperbolic cosecant of x."); PyDoc_STRVAR(GMPy_doc_function_csch, "csch(x) -> number\n\n" "Return hyperbolic cosecant of x."); GMPY_MPFR_UNIOP_EX(Csch, csch) PyDoc_STRVAR(GMPy_doc_context_coth, "context.coth(x) -> number\n\n" "Return hyperbolic cotangent of x."); PyDoc_STRVAR(GMPy_doc_function_coth, "coth(x) -> number\n\n" "Return hyperbolic cotangent of x."); GMPY_MPFR_UNIOP_EX(Coth, coth) PyDoc_STRVAR(GMPy_doc_context_rec_sqrt, "context.rec_sqrt(x) -> number\n\n" "Return the reciprocal of the square root of x."); PyDoc_STRVAR(GMPy_doc_function_rec_sqrt, "rec_sqrt(x) -> number\n\n" "Return the reciprocal of the square root of x."); GMPY_MPFR_UNIOP_EX(RecSqrt, rec_sqrt) PyDoc_STRVAR(GMPy_doc_context_rint, "context.rint(x) -> number\n\n" "Return x rounded to the nearest integer using the context rounding\n" "mode."); PyDoc_STRVAR(GMPy_doc_function_rint, "rint(x) -> number\n\n" "Return x rounded to the nearest integer using the current rounding\n" "mode."); GMPY_MPFR_UNIOP_EX(Rint, rint) PyDoc_STRVAR(GMPy_doc_context_rint_ceil, "context.rint_ceil(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding to the\n" "next higher or equal integer and then, if needed, using the context\n" "rounding mode."); PyDoc_STRVAR(GMPy_doc_function_rint_ceil, "rint_ceil(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding to the\n" "next higher or equal integer and then, if needed, using the current\n" "rounding mode."); GMPY_MPFR_UNIOP_EX(RintCeil, rint_ceil) PyDoc_STRVAR(GMPy_doc_context_rint_floor, "context.rint_floor(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding to the\n" "next lower or equal integer and then, if needed, using the context\n" "rounding mode."); PyDoc_STRVAR(GMPy_doc_function_rint_floor, "rint_floor(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding to the\n" "next lower or equal integer and then, if needed, using the current\n" "rounding mode."); GMPY_MPFR_UNIOP_EX(RintFloor, rint_floor) PyDoc_STRVAR(GMPy_doc_context_rint_round, "context.rint_round(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding to the\n" "nearest integer (ties away from 0) and then, if needed, using\n" "the context rounding mode."); PyDoc_STRVAR(GMPy_doc_function_rint_round, "rint_round(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding to the\n" "nearest integer (ties away from 0) and then, if needed, using\n" "the current rounding mode."); GMPY_MPFR_UNIOP_EX(RintRound, rint_round) PyDoc_STRVAR(GMPy_doc_context_rint_trunc, "context.rint_trunc(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding towards\n" "zero and then, if needed, using the context rounding mode."); PyDoc_STRVAR(GMPy_doc_function_rint_trunc, "rint_trunc(x) -> number\n\n" "Return x rounded to the nearest integer by first rounding towards\n" "zero and then, if needed, using the current rounding mode."); GMPY_MPFR_UNIOP_EX(RintTrunc, rint_trunc) PyDoc_STRVAR(GMPy_doc_context_frac, "context.frac(x) -> number\n\n" "Return fractional part of x."); PyDoc_STRVAR(GMPy_doc_function_frac, "frac(x) -> number\n\n" "Return fractional part of x."); GMPY_MPFR_UNIOP_EX(Frac, frac) PyDoc_STRVAR(GMPy_doc_context_cbrt, "context.cbrt(x) -> number\n\n" "Return the cube root of x."); PyDoc_STRVAR(GMPy_doc_function_cbrt, "cbrt(x) -> number\n\n" "Return the cube root of x."); GMPY_MPFR_UNIOP_EX(Cbrt, cbrt) PyDoc_STRVAR(GMPy_doc_context_log2, "context.log2(x) -> number\n\n" "Return base-2 logarithm of x."); PyDoc_STRVAR(GMPy_doc_function_log2, "log2(x) -> number\n\n" "Return base-2 logarithm of x."); GMPY_MPFR_UNIOP_EX(Log2, log2) PyDoc_STRVAR(GMPy_doc_context_exp2, "context.exp2(x) -> number\n\n" "Return 2**x."); PyDoc_STRVAR(GMPy_doc_function_exp2, "exp2(x) -> number\n\n" "Return 2**x."); GMPY_MPFR_UNIOP_EX(Exp2, exp2) PyDoc_STRVAR(GMPy_doc_context_exp10, "context.exp10(x) -> number\n\n" "Return 10**x."); PyDoc_STRVAR(GMPy_doc_function_exp10, "exp10(x) -> number\n\n" "Return 10**x."); GMPY_MPFR_UNIOP_EX(Exp10, exp10) PyDoc_STRVAR(GMPy_doc_context_log1p, "context.log1p(x) -> number\n\n" "Return natural logarithm of (1+x)."); PyDoc_STRVAR(GMPy_doc_function_log1p, "log1p(x) -> number\n\n" "Return natural logarithm of (1+x)."); GMPY_MPFR_UNIOP_EX(Log1p, log1p) PyDoc_STRVAR(GMPy_doc_context_expm1, "context.expm1(x) -> number\n\n" "Return exp(x) - 1."); PyDoc_STRVAR(GMPy_doc_function_expm1, "expm1(x) -> number\n\n" "Return exp(x) - 1."); GMPY_MPFR_UNIOP_EX(Expm1, expm1) PyDoc_STRVAR(GMPy_doc_context_eint, "context.eint(x) -> number\n\n" "Return exponential integral of x."); PyDoc_STRVAR(GMPy_doc_function_eint, "eint(x) -> number\n\n" "Return exponential integral of x."); GMPY_MPFR_UNIOP_EX(Eint, eint) PyDoc_STRVAR(GMPy_doc_context_li2, "context.li2(x) -> number\n\n" "Return real part of dilogarithm of x."); PyDoc_STRVAR(GMPy_doc_function_li2, "li2(x) -> number\n\n" "Return real part of dilogarithm of x."); GMPY_MPFR_UNIOP_EX(Li2, li2) PyDoc_STRVAR(GMPy_doc_context_gamma, "context.gamma(x) -> number\n\n" "Return gamma of x."); PyDoc_STRVAR(GMPy_doc_function_gamma, "gamma(x) -> number\n\n" "Return gamma of x."); GMPY_MPFR_UNIOP_EX(Gamma, gamma) PyDoc_STRVAR(GMPy_doc_context_lngamma, "context.lngamma(x) -> number\n\n" "Return natural logarithm of gamma(x)."); PyDoc_STRVAR(GMPy_doc_function_lngamma, "lngamma(x) -> number\n\n" "Return natural logarithm of gamma(x)."); GMPY_MPFR_UNIOP_EX(Lngamma, lngamma) PyDoc_STRVAR(GMPy_doc_context_digamma, "context.digamma(x) -> number\n\n" "Return digamma of x."); PyDoc_STRVAR(GMPy_doc_function_digamma, "digamma(x) -> number\n\n" "Return digamma of x."); GMPY_MPFR_UNIOP_EX(Digamma, digamma) PyDoc_STRVAR(GMPy_doc_context_zeta, "context.zeta(x) -> number\n\n" "Return Riemann zeta of x."); PyDoc_STRVAR(GMPy_doc_function_zeta, "zeta(x) -> number\n\n" "Return Riemann zeta of x."); GMPY_MPFR_UNIOP_EX(Zeta, zeta) PyDoc_STRVAR(GMPy_doc_context_erf, "context.erf(x) -> number\n\n" "Return error function of x."); PyDoc_STRVAR(GMPy_doc_function_erf, "erf(x) -> number\n\n" "Return error function of x."); GMPY_MPFR_UNIOP_EX(Erf, erf) PyDoc_STRVAR(GMPy_doc_context_erfc, "context.erfc(x) -> number\n\n" "Return complementary error function of x."); PyDoc_STRVAR(GMPy_doc_function_erfc, "erfc(x) -> number\n\n" "Return complementary error function of x."); GMPY_MPFR_UNIOP_EX(Erfc, erfc) PyDoc_STRVAR(GMPy_doc_context_j0, "context.j0(x) -> number\n\n" "Return first kind Bessel function of order 0 of x."); PyDoc_STRVAR(GMPy_doc_function_j0, "j0(x) -> number\n\n" "Return first kind Bessel function of order 0 of x."); GMPY_MPFR_UNIOP_EX(J0, j0) PyDoc_STRVAR(GMPy_doc_context_j1, "context.j1(x) -> number\n\n" "Return first kind Bessel function of order 1 of x."); PyDoc_STRVAR(GMPy_doc_function_j1, "j1(x) -> number\n\n" "Return first kind Bessel function of order 1 of x."); GMPY_MPFR_UNIOP_EX(J1, j1) PyDoc_STRVAR(GMPy_doc_context_y0, "context.y0(x) -> number\n\n" "Return second kind Bessel function of order 0 of x."); PyDoc_STRVAR(GMPy_doc_function_y0, "y0(x) -> number\n\n" "Return second kind Bessel function of order 0 of x."); GMPY_MPFR_UNIOP_EX(Y0, y0) PyDoc_STRVAR(GMPy_doc_context_y1, "context.y1(x) -> number\n\n" "Return second kind Bessel function of order 1 of x."); PyDoc_STRVAR(GMPy_doc_function_y1, "y1(x) -> number\n\n" "Return second kind Bessel function of order 1 of x."); GMPY_MPFR_UNIOP_EX(Y1, y1) PyDoc_STRVAR(GMPy_doc_context_ai, "context.ai(x) -> number\n\n" "Return Airy function of x."); PyDoc_STRVAR(GMPy_doc_function_ai, "ai(x) -> number\n\n" "Return Airy function of x."); GMPY_MPFR_UNIOP_EX(Ai, ai) /* Section 3: * The following functions may return an mpc result for certain mpfr arguments. * Since the expectional values vary between functions, the 'Real' and 'Complex' * functions do not use macros. However, they do use a macro to create the * higher-level functions. * * GMPY_MPFR_MPC_UNIOP_TEMPLATE(NAME, FUNC) creates the following functions: * GMPy_Number_NAME(x, context) * - assumes GMPy_Real_NAME & GMPy_Complex_NAME exist * GMPy_Context_NAME(self, other) * - called with METH_O */ PyDoc_STRVAR(GMPy_doc_context_acos, "context.acos(x) -> number\n\n" "Return inverse cosine of x; result in radians."); PyDoc_STRVAR(GMPy_doc_function_acos, "acos(x) -> number\n\n" "Return inverse cosine of x; result in radians."); static PyObject * _GMPy_MPFR_Acos(PyObject *x, CTXT_Object *context) { MPFR_Object *result; if (!mpfr_nan_p(MPFR(x)) && (mpfr_cmp_si(MPFR(x), 1) > 0 || mpfr_cmp_si(MPFR(x), -1) < 0) && context->ctx.allow_complex ) { return GMPy_Complex_Acos(x, context); } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); result->rc = mpfr_acos(result->f, MPFR(x), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Acos(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Acos(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPC_Acos(PyObject *x, CTXT_Object *context) { MPC_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_acos(result->c, MPC(x), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Acos(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } result = _GMPy_MPC_Acos(tempx, context); Py_DECREF(tempx); return result; } GMPY_MPFR_MPC_UNIOP_TEMPLATE_EX(Acos, acos) PyDoc_STRVAR(GMPy_doc_context_asin, "context.asin(x) -> number\n\n" "Return inverse sine of x; result in radians."); PyDoc_STRVAR(GMPy_doc_function_asin, "asin(x) -> number\n\n" "Return inverse sine of x; result in radians."); static PyObject * _GMPy_MPFR_Asin(PyObject *x, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!mpfr_nan_p(MPFR(x)) && (mpfr_cmp_si(MPFR(x), 1) > 0 || mpfr_cmp_si(MPFR(x), -1) < 0) && context->ctx.allow_complex ) { return GMPy_Complex_Asin(x, context); } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); result->rc = mpfr_asin(result->f, MPFR(x), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Asin(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Asin(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPC_Asin(PyObject *x, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_asin(result->c, MPC(x), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Asin(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } result = _GMPy_MPC_Asin(tempx, context); Py_DECREF(tempx); return result; } GMPY_MPFR_MPC_UNIOP_TEMPLATE_EX(Asin, asin) PyDoc_STRVAR(GMPy_doc_context_atanh, "context.atanh(x) -> number\n\n" "Return inverse hyperbolic tanget of x."); PyDoc_STRVAR(GMPy_doc_function_atanh, "atanh(x) -> number\n\n" "Return inverse hyperbolic tangent of x."); static PyObject * _GMPy_MPFR_Atanh(PyObject *x, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!mpfr_nan_p(MPFR(x)) && (mpfr_cmp_si(MPFR(x), 1) > 0 || mpfr_cmp_si(MPFR(x), -1) < 0) && context->ctx.allow_complex ) { return GMPy_Complex_Atanh(x, context); } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); result->rc = mpfr_atanh(result->f, MPFR(x), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Atanh(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Atanh(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPC_Atanh(PyObject *x, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_atanh(result->c, MPC(x), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Atanh(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } result = _GMPy_MPC_Atanh(tempx, context); Py_DECREF(tempx); return result; } GMPY_MPFR_MPC_UNIOP_TEMPLATE_EX(Atanh, atanh) PyDoc_STRVAR(GMPy_doc_function_atan2, "atan2(y, x) -> number\n\n" "Return arc-tangent of (y/x); result in radians."); PyDoc_STRVAR(GMPy_doc_context_atan2, "context.atan2(y, x) -> number\n\n" "Return arc-tangent of (y/x); result in radians."); GMPY_MPFR_BINOP_EX(Atan2, atan2) PyDoc_STRVAR(GMPy_doc_function_hypot, "hypot(x, y) -> number\n\n" "Return square root of (x**2 + y**2)."); PyDoc_STRVAR(GMPy_doc_context_hypot, "context.hypot(x, y) -> number\n\n" "Return square root of (x**2 + y**2)."); GMPY_MPFR_BINOP_EX(Hypot, hypot) static PyObject * _GMPy_MPFR_Sin_Cos(PyObject *x, CTXT_Object *context) { MPFR_Object *s, *c; PyObject *result; int code; CHECK_CONTEXT(context); s = GMPy_MPFR_New(0, context); c = GMPy_MPFR_New(0, context); result = PyTuple_New(2); if (!s || !c || !result) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } mpfr_clear_flags(); code = mpfr_sin_cos(s->f, c->f, MPFR(x), GET_MPFR_ROUND(context)); s->rc = code & 0x03; c->rc = code >> 2; if (s->rc == 2) s->rc = -1; if (c->rc == 2) c->rc = -1; _GMPy_MPFR_Cleanup(&s, context); _GMPy_MPFR_Cleanup(&c, context); if (!s || !c) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_DECREF(result); return NULL; } PyTuple_SET_ITEM(result, 0, (PyObject*)s); PyTuple_SET_ITEM(result, 1, (PyObject*)c); return result; } static PyObject * GMPy_Real_Sin_Cos(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Sin_Cos(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPC_Sin_Cos(PyObject *x, CTXT_Object *context) { MPC_Object *s, *c; PyObject *result; int code; CHECK_CONTEXT(context); s = GMPy_MPC_New(0, 0, context); c = GMPy_MPC_New(0, 0, context); result = PyTuple_New(2); if (!s || !c || !result) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } code = mpc_sin_cos(s->c, c->c, MPC(x), GET_MPC_ROUND(context), GET_MPC_ROUND(context)); s->rc = MPC_INEX1(code); c->rc = MPC_INEX2(code); _GMPy_MPC_Cleanup(&s, context); _GMPy_MPC_Cleanup(&c, context); if (!s || !c) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } PyTuple_SET_ITEM(result, 0, (PyObject*)s); PyTuple_SET_ITEM(result, 1, (PyObject*)c); return result; } static PyObject * GMPy_Complex_Sin_Cos(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } result = _GMPy_MPC_Sin_Cos(tempx, context); Py_DECREF(tempx); return result; } PyDoc_STRVAR(GMPy_doc_context_sin_cos, "context.sin_cos(x) -> (number, number)\n\n" "Return a tuple containing the sine and cosine of x; x in radians."); PyDoc_STRVAR(GMPy_doc_function_sin_cos, "sin_cos(x) -> (number, number)\n\n" "Return a tuple containing the sine and cosine of x; x in radians."); GMPY_MPFR_MPC_UNIOP_TEMPLATE_EX(Sin_Cos, sin_cos) static PyObject * _GMPy_MPFR_Sinh_Cosh(PyObject *x, CTXT_Object *context) { MPFR_Object *s, *c; PyObject *result; int code; CHECK_CONTEXT(context); s = GMPy_MPFR_New(0, context); c = GMPy_MPFR_New(0, context); result = PyTuple_New(2); if (!s || !c || !result) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } mpfr_clear_flags(); code = mpfr_sinh_cosh(s->f, c->f, MPFR(x), GET_MPFR_ROUND(context)); s->rc = code & 0x03; c->rc = code >> 2; if (s->rc == 2) s->rc = -1; if (c->rc == 2) c->rc = -1; _GMPy_MPFR_Cleanup(&s, context); _GMPy_MPFR_Cleanup(&c, context); if (!s || !c) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } PyTuple_SET_ITEM(result, 0, (PyObject*)s); PyTuple_SET_ITEM(result, 1, (PyObject*)c); return result; } static PyObject * GMPy_Real_Sinh_Cosh(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Sinh_Cosh(tempx, context); Py_DECREF(tempx); return result; } PyDoc_STRVAR(GMPy_doc_context_sinh_cosh, "context.sinh_cosh(x) -> (number, number)\n\n" "Return a tuple containing the hyperbolic sine and cosine of x."); PyDoc_STRVAR(GMPy_doc_function_sinh_cosh, "sinh_cosh(x) -> (number, number)\n\n" "Return a tuple containing the hyperbolic sine and cosine of x."); GMPY_MPFR_UNIOP_TEMPLATE_EX(Sinh_Cosh, sinh_cosh) PyDoc_STRVAR(GMPy_doc_function_degrees, "degrees(x) -> mpfr\n\n" "Convert angle x from radians to degrees.\n" "Note: In rare cases the result may not be correctly rounded."); PyDoc_STRVAR(GMPy_doc_context_degrees, "context.degrees(x) -> mpfr\n\n" "Convert angle x from radians to degrees.\n" "Note: In rare cases the result may not be correctly rounded."); static PyObject * GMPy_Context_Degrees(PyObject *self, PyObject *other) { MPFR_Object *result, *tempx, *temp; CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } result = GMPy_MPFR_New(0, context); temp = GMPy_MPFR_New(context->ctx.mpfr_prec + 100, context); tempx = GMPy_MPFR_From_Real(other, 1, context); if (!result || !temp || !tempx) { Py_XDECREF((PyObject*)temp); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; } mpfr_const_pi(temp->f, MPFR_RNDN); mpfr_ui_div(temp->f, 180, temp->f, MPFR_RNDN); mpfr_clear_flags(); mpfr_mul(result->f, temp->f, tempx->f, MPFR_RNDN); Py_DECREF((PyObject*)temp); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_radians, "radians(x) -> mpfr\n\n" "Convert angle x from degrees to radians.\n" "Note: In rare cases the result may not be correctly rounded."); PyDoc_STRVAR(GMPy_doc_context_radians, "context.radians(x) -> mpfr\n\n" "Convert angle x from degrees to radians.\n" "Note: In rare cases the result may not be correctly rounded."); static PyObject * GMPy_Context_Radians(PyObject *self, PyObject *other) { MPFR_Object *result, *tempx, *temp; CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } result = GMPy_MPFR_New(0, context); temp = GMPy_MPFR_New(context->ctx.mpfr_prec + 100, context); tempx = GMPy_MPFR_From_Real(other, 1, context); if (!result || !temp || !tempx) { Py_XDECREF((PyObject*)temp); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; } mpfr_const_pi(temp->f, MPFR_RNDN); mpfr_div_ui(temp->f, temp->f, 180, MPFR_RNDN); mpfr_clear_flags(); mpfr_mul(result->f, tempx->f, temp->f, MPFR_RNDN); Py_DECREF((PyObject*)temp); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_context_log10, "context.log10(x) -> number\n\n" "Return the base-10 logarithm of x."); PyDoc_STRVAR(GMPy_doc_function_log10, "log10(x) -> number\n\n" "Return the base-10 logarithm of x."); GMPY_MPFR_MPC_UNIOP_EX(Log10, log10) PyDoc_STRVAR(GMPy_doc_context_log, "context.log(x) -> number\n\n" "Return the natural logarithm of x."); PyDoc_STRVAR(GMPy_doc_function_log, "log(x) -> number\n\n" "Return the natural logarithm of x."); GMPY_MPFR_MPC_UNIOP_EX(Log, log) PyDoc_STRVAR(GMPy_doc_context_exp, "context.exp(x) -> number\n\n" "Return the exponential of x."); PyDoc_STRVAR(GMPy_doc_function_exp, "exp(x) -> number\n\n" "Return the exponential of x."); GMPY_MPFR_MPC_UNIOP_EX(Exp, exp) PyDoc_STRVAR(GMPy_doc_context_sqrt, "context.sqrt(x) -> number\n\n" "Return the square root of x."); PyDoc_STRVAR(GMPy_doc_function_sqrt, "sqrt(x) -> number\n\n" "Return the square root of x."); static PyObject * _GMPy_MPFR_Sqrt(PyObject *x, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (mpfr_sgn(MPFR(x)) < 0 && context->ctx.allow_complex) { return GMPy_Complex_Sqrt(x, context); } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); result->rc = mpfr_sqrt(result->f, MPFR(x), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Sqrt(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Sqrt(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPC_Sqrt(PyObject *x, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_sqrt(result->c, MPC(x), GET_MPFR_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Sqrt(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } result = _GMPy_MPC_Sqrt(tempx, context); Py_DECREF(tempx); return result; } GMPY_MPFR_MPC_UNIOP_TEMPLATE_EX(Sqrt, sqrt) PyDoc_STRVAR(GMPy_doc_function_root, "root(x, n) -> mpfr\n\n" "Return n-th root of x. The result always an 'mpfr'.\n" "Note: not IEEE 754-2008 compliant; result differs when\n" "x = -0 and n is even. See rootn()."); PyDoc_STRVAR(GMPy_doc_context_root, "context.root(x, n) -> mpfr\n\n" "Return n-th root of x. The result always an 'mpfr'.\n" "Note: not IEEE 754-2008 compliant; result differs when\n" "x = -0 and n is even. See rootn()."); PyDoc_STRVAR(GMPy_doc_function_rootn, "rootn(x, n) -> mpfr\n\n" "Return n-th root of x. The result always an 'mpfr'.\n" "Note: this is IEEE 754-2008 compliant version of root()."); PyDoc_STRVAR(GMPy_doc_context_rootn, "context.rootn(x, n) -> mpfr\n\n" "Return n-th root of x. The result always an 'mpfr'.\n" "Note: this is IEEE 754-2008 compliant version of root()."); #if MPFR_VERSION_MAJOR > 3 /* Since mpfr_root is deprecated in MPFR 4, we use mpfr_rootn_ui to * mimic the behavior of mpfr_root. And the converse will be true when * using MPFR 3. */ static PyObject * GMPy_Real_Rootn(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL, *tempx = NULL; unsigned long n; CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); n = c_ulong_From_Integer(y); if (!result || !tempx || (n == (unsigned long)(-1) && PyErr_Occurred())) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_rootn_ui(result->f, tempx->f, n, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Root(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL, *tempx = NULL; unsigned long n; CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); n = c_ulong_From_Integer(y); if (!result || !tempx || (n == (unsigned long)(-1) && PyErr_Occurred())) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); /* Mimic the non-compliant IEEE 752-2008 behavior. */ if (mpfr_zero_p(tempx->f)) { mpfr_set(result->f, tempx->f, GET_MPFR_ROUND(context)); } else { result->rc = mpfr_rootn_ui(result->f, tempx->f, n, GET_MPFR_ROUND(context)); } Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } #else static PyObject * GMPy_Real_Rootn(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL, *tempx = NULL; unsigned long n; CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); n = c_ulong_From_Integer(y); if (!result || !tempx || (n == (unsigned long)(-1) && PyErr_Occurred())) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); /* Mimic the compliant IEEE 752-2008 behavior. */ if (mpfr_zero_p(tempx->f) && mpfr_signbit(tempx->f)) { if ((n & 1)) { /* Odd, so result is -0. */ mpfr_set_zero(result->f, -1); } else { /* Even, so result is 0. */ mpfr_set_zero(result->f, 1); } } else { result->rc = mpfr_root(result->f, tempx->f, n, GET_MPFR_ROUND(context)); } Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Root(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL, *tempx = NULL; unsigned long n; CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); n = c_ulong_From_Integer(y); if (!result || !tempx || (n == (unsigned long)(-1) && PyErr_Occurred())) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_root(result->f, tempx->f, n, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } #endif static PyObject * GMPy_Number_Rootn(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_REAL(x) && PyIntOrLong_Check(y)) return GMPy_Real_Rootn(x, y, context); TYPE_ERROR("rootn() argument type not supported"); return NULL; } static PyObject * GMPy_Context_Rootn(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("rootn() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Rootn(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } static PyObject * GMPy_Number_Root(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_REAL(x) && PyIntOrLong_Check(y)) return GMPy_Real_Root(x, y, context); TYPE_ERROR("root() argument type not supported"); return NULL; } static PyObject * GMPy_Context_Root(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("root() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Root(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } PyDoc_STRVAR(GMPy_doc_function_jn, "jn(x,n) -> mpfr\n\n" "Return the first kind Bessel function of order n of x."); PyDoc_STRVAR(GMPy_doc_context_jn, "context.jn(x,n) -> mpfr\n\n" "Return the first kind Bessel function of order n of x."); GMPY_MPFR_BINOP_REAL_LONG(Jn, jn) PyDoc_STRVAR(GMPy_doc_function_yn, "yn(x,n) -> mpfr\n\n" "Return the second kind Bessel function of order n of x."); PyDoc_STRVAR(GMPy_doc_context_yn, "context.yn(x,n) -> mpfr\n\n" "Return the second kind Bessel function of order n of x."); GMPY_MPFR_BINOP_REAL_LONG(Yn, yn) PyDoc_STRVAR(GMPy_doc_function_agm, "agm(x, y) -> mpfr\n\n" "Return arithmetic-geometric mean of x and y."); PyDoc_STRVAR(GMPy_doc_context_agm, "context.agm(x, y) -> mpfr\n\n" "Return arithmetic-geometric mean of x and y."); GMPY_MPFR_BINOP(AGM, agm) PyDoc_STRVAR(GMPy_doc_function_maxnum, "maxnum(x, y) -> mpfr\n\n" "Return the maximum number of x and y. If x and y are not 'mpfr', they are\n" "converted to 'mpfr'. The result is rounded to match the current context.\n" "If only one of x or y is a number, then that number is returned."); PyDoc_STRVAR(GMPy_doc_context_maxnum, "context.maxnum(x, y) -> mpfr\n\n" "Return the maximum number of x and y. If x and y are not 'mpfr', they are\n" "converted to 'mpfr'. The result is rounded to match the specified context.\n" "If only one of x or y is a number, then that number is returned."); GMPY_MPFR_BINOP(Maxnum, max) PyDoc_STRVAR(GMPy_doc_function_minnum, "minnum(x, y) -> mpfr\n\n" "Return the minimum number of x and y. If x and y are not 'mpfr', they are\n" "converted to 'mpfr'. The result is rounded to match the current context.\n" "If only one of x or y is a number, then that number is returned."); PyDoc_STRVAR(GMPy_doc_context_minnum, "context.minnum(x, y) -> mpfr\n\n" "Return the minimum number of x and y. If x and y are not 'mpfr', they are\n" "converted to 'mpfr'. The result is rounded to match the specified context.\n" "If only one of x or y is a number, then that number is returned."); GMPY_MPFR_BINOP(Minnum, min) PyDoc_STRVAR(GMPy_doc_function_remainder, "remainder(x, y) -> mpfr\n\n" "Return x - n*y where n is the integer quotient of x/y, rounded to\n" "the nearest integer and ties rounded to even."); PyDoc_STRVAR(GMPy_doc_context_remainder, "context.remainder(x, y) -> mpfr\n\n" "Return x - n*y where n is the integer quotient of x/y, rounded to\n" "the nearest integer and ties rounded to even."); GMPY_MPFR_BINOP(Remainder, remainder) PyDoc_STRVAR(GMPy_doc_function_fmod, "fmod(x, y) -> mpfr\n\n" "Return x - n*y where n is the integer quotient of x/y, rounded to 0."); PyDoc_STRVAR(GMPy_doc_context_fmod, "context.fmod(x, y) -> mpfr\n\n" "Return x - n*y where n is the integer quotient of x/y, rounded to 0."); GMPY_MPFR_BINOP(Fmod, fmod) PyDoc_STRVAR(GMPy_doc_function_round2, "round2(x[, n]) -> mpfr\n\n" "Return x rounded to n bits. Uses default precision if n is not\n" "specified. See round_away() to access the mpfr_round() function."); PyDoc_STRVAR(GMPy_doc_context_round2, "context.round2(x[, n]) -> mpfr\n\n" "Return x rounded to n bits. Uses default precision if n is not\n" "specified. See round_away() to access the mpfr_round() function."); static PyObject * GMPy_Real_Round2(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result, *tempx; long n; CHECK_CONTEXT(context); n = GET_MPFR_PREC(context); if (y) { n = PyIntOrLong_AsLong(y); if ( (n == -1 && PyErr_Occurred()) || n < MPFR_PREC_MIN || n > MPFR_PREC_MAX) { VALUE_ERROR("invalid precision"); return NULL; } } if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } if (!(result = GMPy_MPFR_New(mpfr_get_prec(tempx->f), context))) { Py_DECREF((PyObject*)tempx); return NULL; } mpfr_set(result->f, tempx->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); mpfr_clear_flags(); result->rc = mpfr_prec_round(result->f, n, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Number_Round2(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_REAL(x) && (!y || PyIntOrLong_Check(y))) return GMPy_Real_Round2(x, y, context); TYPE_ERROR("round2() argument type not supported"); return NULL; } static PyObject * GMPy_Context_Round2(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) < 1 || PyTuple_GET_SIZE(args) > 2) { TYPE_ERROR("round2() requires 1 or 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } if (PyTuple_GET_SIZE(args) == 1) { return GMPy_Number_Round2(PyTuple_GET_ITEM(args, 0), NULL, context); } else { return GMPy_Number_Round2(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } } PyDoc_STRVAR(GMPy_doc_function_reldiff, "reldiff(x, y) -> mpfr\n\n" "Return the relative difference between x and y. Result is equal to\n" "abs(x-y)/x."); PyDoc_STRVAR(GMPy_doc_context_reldiff, "context.reldiff(x, y) -> mpfr\n\n" "Return the relative difference between x and y. Result is equal to\n" "abs(x-y)/x."); static PyObject * GMPy_Real_RelDiff(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx, *tempy, *result; CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!result || !tempx || !tempy) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; } mpfr_clear_flags(); mpfr_reldiff(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context)); result->rc = 0; _GMPy_MPFR_Cleanup(&result, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } GMPY_MPFR_BINOP_TEMPLATE(RelDiff, reldiff) PyDoc_STRVAR(GMPy_doc_mpfr_ceil_method, "x.__ceil__() -> mpfr\n\n" "Return an 'mpfr' that is the smallest integer >= x."); PyDoc_STRVAR(GMPy_doc_function_ceil, "ceil(x) ->mpfr\n\n" "Return an 'mpfr' that is the smallest integer >= x."); PyDoc_STRVAR(GMPy_doc_context_ceil, "context.ceil(x) ->mpfr\n\n" "Return an 'mpfr' that is the smallest integer >= x."); GMPY_MPFR_UNIOP_NOROUND(Ceil, ceil) PyDoc_STRVAR(GMPy_doc_mpfr_floor_method, "x.__floor__() -> mpfr\n\n" "Return an 'mpfr' that is the smallest integer <= x."); PyDoc_STRVAR(GMPy_doc_function_floor, "floor(x) -> mpfr\n\n" "Return an 'mpfr' that is the smallest integer <= x."); PyDoc_STRVAR(GMPy_doc_context_floor, "context.floor(x) -> mpfr\n\n" "Return an 'mpfr' that is the smallest integer <= x."); GMPY_MPFR_UNIOP_NOROUND(Floor, floor); PyDoc_STRVAR(GMPy_doc_mpfr_trunc_method, "x.__trunc__() -> mpfr\n\n" "Return an 'mpfr' that is truncated towards 0. Same as\n" "x.floor() if x>=0 or x.ceil() if x<0."); PyDoc_STRVAR(GMPy_doc_function_trunc, "trunc(x) -> mpfr\n\n" "Return an 'mpfr' that is x truncated towards 0. Same as\n" "x.floor() if x>=0 or x.ceil() if x<0."); PyDoc_STRVAR(GMPy_doc_context_trunc, "context.trunc(x) -> mpfr\n\n" "Return an 'mpfr' that is x truncated towards 0. Same as\n" "x.floor() if x>=0 or x.ceil() if x<0."); GMPY_MPFR_UNIOP_NOROUND(Trunc, trunc) PyDoc_STRVAR(GMPy_doc_function_round_away, "round_away(x) -> mpfr\n\n" "Return an 'mpfr' that is x rounded to the nearest integer,\n" "with ties rounded away from 0."); PyDoc_STRVAR(GMPy_doc_context_round_away, "context.round_away(x) -> mpfr\n\n" "Return an 'mpfr' that is x rounded to the nearest integer,\n" "with ties rounded away from 0."); GMPY_MPFR_UNIOP_NOROUND_NOMETHOD(RoundAway, round) PyDoc_STRVAR(GMPy_doc_function_modf, "modf(x) -> (mpfr, mpfr)\n\n" "Return a tuple containing the integer and fractional portions\n" "of x."); PyDoc_STRVAR(GMPy_doc_context_modf, "context.modf(x) -> (mpfr, mpfr)\n\n" "Return a tuple containing the integer and fractional portions\n" "of x."); static PyObject * GMPy_Real_Modf(PyObject *x, CTXT_Object *context) { MPFR_Object *s, *c, *tempx; PyObject *result; int code; CHECK_CONTEXT(context); tempx = GMPy_MPFR_From_Real(x, 1, context); s = GMPy_MPFR_New(0, context); c = GMPy_MPFR_New(0, context); result = PyTuple_New(2); if (! tempx || !s || !c || !result) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_XDECREF(result); return NULL; } mpfr_clear_flags(); code = mpfr_modf(s->f, c->f, tempx->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); s->rc = code & 0x03; c->rc = code >> 2; if (s->rc == 2) s->rc = -1; if (c->rc == 2) c->rc = -1; _GMPy_MPFR_Cleanup(&s, context); _GMPy_MPFR_Cleanup(&c, context); if (!s || !c) { Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)c); Py_DECREF(result); return NULL; } PyTuple_SET_ITEM(result, 0, (PyObject*)s); PyTuple_SET_ITEM(result, 1, (PyObject*)c); return result; } GMPY_MPFR_UNIOP_TEMPLATE(Modf, modf) PyDoc_STRVAR(GMPy_doc_function_lgamma, "lgamma(x) -> (mpfr, int)\n\n" "Return a tuple containing the logarithm of the absolute value of\n" "gamma(x) and the sign of gamma(x)"); PyDoc_STRVAR(GMPy_doc_context_lgamma, "context.lgamma(x) -> (mpfr, int)\n\n" "Return a tuple containing the logarithm of the absolute value of\n" "gamma(x) and the sign of gamma(x)"); static PyObject * GMPy_Real_Lgamma(PyObject *x, CTXT_Object *context) { PyObject *result; MPFR_Object *value, *tempx; int signp = 0; CHECK_CONTEXT(context) tempx = GMPy_MPFR_From_Real(x, 1, context); value = GMPy_MPFR_New(0, context); result = PyTuple_New(2); if (!tempx || !value || !result) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)value); Py_XDECREF(result); return NULL; } mpfr_clear_flags(); value->rc = mpfr_lgamma(value->f, &signp, tempx->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&value, context); if (!value) { Py_DECREF(result); return NULL; } PyTuple_SET_ITEM(result, 0, (PyObject*)value); PyTuple_SET_ITEM(result, 1, PyIntOrLong_FromLong((long)signp)); return result; } GMPY_MPFR_UNIOP_TEMPLATE(Lgamma, lgamma) PyDoc_STRVAR(GMPy_doc_function_remquo, "remquo(x, y) -> (mpfr, int)\n\n" "Return a tuple containing the remainder(x,y) and the low bits of the\n" "quotient."); PyDoc_STRVAR(GMPy_doc_context_remquo, "context.remquo(x, y) -> (mpfr, int)\n\n" "Return a tuple containing the remainder(x,y) and the low bits of the\n" "quotient."); static PyObject * GMPy_Real_RemQuo(PyObject *x, PyObject *y, CTXT_Object *context) { PyObject *result; MPFR_Object *value, *tempx, *tempy; long quobits = 0; CHECK_CONTEXT(context); value = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); result = PyTuple_New(2); if (!value || !tempx || !tempx || !result) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)value); Py_XDECREF(result); return NULL; } mpfr_clear_flags(); value->rc = mpfr_remquo(value->f, &quobits, tempx->f, tempy->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); _GMPy_MPFR_Cleanup(&value, context); PyTuple_SET_ITEM(result, 0, (PyObject*)value); PyTuple_SET_ITEM(result, 1, PyIntOrLong_FromLong(quobits)); return result; } GMPY_MPFR_BINOP_TEMPLATE(RemQuo, remquo); PyDoc_STRVAR(GMPy_doc_function_frexp, "frexp(x) -> (int, mpfr)\n\n" "Return a tuple containing the exponent and mantissa of x."); PyDoc_STRVAR(GMPy_doc_context_frexp, "context.frexp(x) -> (int, mpfr)\n\n" "Return a tuple containing the exponent and mantissa of x."); static PyObject * GMPy_Real_Frexp(PyObject *x, CTXT_Object *context) { PyObject *result; MPFR_Object *value, *tempx; mpfr_exp_t exp = 0; CHECK_CONTEXT(context); value = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); result = PyTuple_New(2); if (!value || !result || !tempx) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)value); Py_XDECREF(result); return NULL; } mpfr_clear_flags(); value->rc = mpfr_frexp(&exp, value->f, tempx->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&value, context); PyTuple_SET_ITEM(result, 0, PyIntOrLong_FromSsize_t((Py_ssize_t)exp)); PyTuple_SET_ITEM(result, 1, (PyObject*)value); return result; } GMPY_MPFR_UNIOP_TEMPLATE(Frexp, frexp) PyDoc_STRVAR(GMPy_doc_function_next_toward, "next_toward(x, y) -> mpfr\n\n" "Return the next 'mpfr' from x in the direction of y. The result has\n" "the same precision as x."); PyDoc_STRVAR(GMPy_doc_context_next_toward, "context.next_toward(x, y) -> mpfr\n\n" "Return the next 'mpfr' from x in the direction of y. The result has\n" "the same precision as x."); static PyObject * GMPy_Context_NextToward(PyObject *self, PyObject *args) { MPFR_Object *result, *tempx, *tempy; CTXT_Object *context = NULL; int direction; mpfr_rnd_t temp_round; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("next_toward() requires 2 arguments"); return NULL; } tempx = GMPy_MPFR_From_Real(PyTuple_GET_ITEM(args, 0), 1, context); tempy = GMPy_MPFR_From_Real(PyTuple_GET_ITEM(args, 1), 1, context); if (!tempx || !tempy) { TYPE_ERROR("next_toward() argument type not supported"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; } if (!(result = GMPy_MPFR_New(mpfr_get_prec(tempx->f), context))) { Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return NULL; } mpfr_clear_flags(); mpfr_set(result->f, tempx->f, GET_MPFR_ROUND(context)); mpfr_nexttoward(result->f, tempy->f); result->rc = 0; direction = mpfr_signbit(tempy->f); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); temp_round = GET_MPFR_ROUND(context); if (direction) context->ctx.mpfr_round = MPFR_RNDD; else context->ctx.mpfr_round = MPFR_RNDU; _GMPy_MPFR_Cleanup(&result, context); context->ctx.mpfr_round = temp_round; return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_next_above, "next_above(x) -> mpfr\n\n" "Return the next 'mpfr' from x toward +Infinity."); PyDoc_STRVAR(GMPy_doc_context_next_above, "context.next_above(x) -> mpfr\n\n" "Return the next 'mpfr' from x toward +Infinity."); static PyObject * GMPy_Context_NextAbove(PyObject *self, PyObject *other) { MPFR_Object *result, *tempx; CTXT_Object *context = NULL; mpfr_rnd_t temp_round; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } if (!(tempx = GMPy_MPFR_From_Real(other, 1, context))) { TYPE_ERROR("next_above() argument type not supported"); return NULL; } if (!(result = GMPy_MPFR_New(mpfr_get_prec(tempx->f), context))) { Py_DECREF((PyObject*)tempx); return NULL; } mpfr_clear_flags(); mpfr_set(result->f, tempx->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); mpfr_nextabove(result->f); result->rc = 0; temp_round = GET_MPFR_ROUND(context); context->ctx.mpfr_round = MPFR_RNDU; _GMPy_MPFR_Cleanup(&result, context); context->ctx.mpfr_round = temp_round; return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_next_below, "next_below(x) -> mpfr\n\n" "Return the next 'mpfr' from x toward -Infinity."); PyDoc_STRVAR(GMPy_doc_context_next_below, "context.next_below(x) -> mpfr\n\n" "Return the next 'mpfr' from x toward -Infinity."); static PyObject * GMPy_Context_NextBelow(PyObject *self, PyObject *other) { MPFR_Object *result, *tempx; CTXT_Object *context = NULL; mpfr_rnd_t temp_round; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } if (!(tempx = GMPy_MPFR_From_Real(other, 1, context))) { TYPE_ERROR("next_below() argument type not supported"); return NULL; } if (!(result = GMPy_MPFR_New(mpfr_get_prec(tempx->f), context))) { Py_DECREF((PyObject*)tempx); return NULL; } mpfr_clear_flags(); mpfr_set(result->f, tempx->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); mpfr_nextbelow(result->f); result->rc = 0; temp_round = GET_MPFR_ROUND(context); context->ctx.mpfr_round = MPFR_RNDD; _GMPy_MPFR_Cleanup(&result, context); context->ctx.mpfr_round = temp_round; return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_factorial, "factorial(n) -> mpfr\n\n" "Return the floating-point approximation to the factorial of n.\n\n" "See fac(n) to get the exact integer result."); PyDoc_STRVAR(GMPy_doc_context_factorial, "context.factorial(n) -> mpfr\n\n" "Return the floating-point approximation to the factorial of n.\n\n" "See fac(n) to get the exact integer result."); static PyObject * GMPy_Context_Factorial(PyObject *self, PyObject *other) { MPFR_Object *result; long n; CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } n = PyLong_AsLong(other); if ((n == -1) && PyErr_Occurred()) { TYPE_ERROR("factorial() requires 'int' argument"); return NULL; } if (n < 0) { VALUE_ERROR("factorial() of negative number"); return NULL; } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); mpfr_fac_ui(result->f, n, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_fsum, "fsum(iterable) -> mpfr\n\n" "Return an accurate sum of the values in the iterable."); PyDoc_STRVAR(GMPy_doc_context_fsum, "fsum(iterable) -> mpfr\n\n" "Return an accurate sum of the values in the iterable."); static PyObject * GMPy_Context_Fsum(PyObject *self, PyObject *other) { MPFR_Object *temp, *result; mpfr_ptr *tab; int errcode; Py_ssize_t i, seq_length = 0; CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } if (!(other = PySequence_List(other))) { Py_DECREF((PyObject*)result); TYPE_ERROR("argument must be an iterable"); return NULL; } /* other contains a new list containing all the values from the * iterable. Now make sure each item in the list is an mpfr. */ seq_length = PyList_GET_SIZE(other); if (seq_length > LONG_MAX) { OVERFLOW_ERROR("temporary array is too large"); Py_DECREF(other); Py_DECREF((PyObject*)result); return NULL; } for (i=0; i < seq_length; i++) { if (!(temp = GMPy_MPFR_From_Real(PyList_GET_ITEM(other, i), 1, context))) { Py_DECREF(other); Py_DECREF((PyObject*)result); TYPE_ERROR("all items in iterable must be real numbers"); return NULL; } errcode = PyList_SetItem(other, i,(PyObject*)temp); if (errcode < 0) { Py_DECREF(other); Py_DECREF((PyObject*)result); TYPE_ERROR("all items in iterable must be real numbers"); return NULL; } } /* create an array of pointers to the mpfr_t field of a Pympfr object */ if (!(tab = (mpfr_ptr *)malloc((sizeof(mpfr_srcptr) * seq_length)))) { Py_DECREF(other); Py_DECREF((PyObject*)result); return PyErr_NoMemory(); } for (i=0; i < seq_length; i++) { temp = (MPFR_Object*)PyList_GET_ITEM(other, i); tab[i] = temp->f; } mpfr_clear_flags(); /* The cast is safe since we have compared seq_length to LONG_MAX. */ result->rc = mpfr_sum(result->f, tab, (unsigned long)seq_length, GET_MPFR_ROUND(context)); Py_DECREF(other); free(tab); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } gmpy2-2.1.0b3/src/gmpy2_math.h0000664000175000017500000004637013425752437015704 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_math.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MATH_H #define GMPY_MATH_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Real_Sin(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Sin(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sin(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sin(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Cos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Cos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Cos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Cos(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Tan(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Tan(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Tan(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Tan(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Atan(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Atan(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Atan(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Atan(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Sinh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Sinh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sinh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sinh(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Cosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Cosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Cosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Cosh(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Tanh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Tanh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Tanh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Tanh(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Asinh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Asinh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Asinh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Asinh(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Acosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Acosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Acosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Acosh(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Sec(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sec(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sec(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Csc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Csc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Csc(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Cot(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Cot(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Cot(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Sech(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sech(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sech(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Csch(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Csch(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Csch(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Coth(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Coth(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Coth(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Acos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Acos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Acos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Acos(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Asin(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Asin(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Asin(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Asin(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Atanh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Atanh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Atanh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Atanh(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Sin_Cos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Sin_Cos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sin_Cos(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sin_Cos(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Sinh_Cosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sinh_Cosh(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sinh_Cosh(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Atan2(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Atan2(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Atan2(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Hypot(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Hypot(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Hypot(PyObject *self, PyObject *args); static PyObject * GMPy_Context_Degrees(PyObject *self, PyObject *other); static PyObject * GMPy_Context_Radians(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Log(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Log(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Log(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Log(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Log10(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Log10(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Log10(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Log10(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Exp(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Exp(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Exp(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Exp(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Sqrt(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Sqrt(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sqrt(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sqrt(PyObject *self, PyObject *other); static PyObject * GMPy_Real_RecSqrt(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_RecSqrt(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_RecSqrt(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Rint(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Rint(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Rint(PyObject *self, PyObject *other); static PyObject * GMPy_Real_RintCeil(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_RintCeil(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_RintCeil(PyObject *self, PyObject *other); static PyObject * GMPy_Real_RintFloor(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_RintFloor(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_RintFloor(PyObject *self, PyObject *other); static PyObject * GMPy_Real_RintRound(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_RintRound(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_RintRound(PyObject *self, PyObject *other); static PyObject * GMPy_Real_RintTrunc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_RintTrunc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_RintTrunc(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Frac(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Frac(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Frac(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Cbrt(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Cbrt(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Cbrt(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Log2(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Log2(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Log2(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Exp2(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Exp2(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Exp2(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Exp10(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Exp10(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Exp10(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Log1p(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Log1p(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Log1p(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Expm1(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Expm1(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Expm1(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Eint(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Eint(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Eint(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Li2(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Li2(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Li2(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Lngamma(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Lngamma(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Lngamma(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Digamma(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Digamma(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Digamma(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Zeta(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Zeta(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Zeta(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Erf(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Erf(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Erf(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Erfc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Erfc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Erfc(PyObject *self, PyObject *other); static PyObject * GMPy_Real_J0(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_J0(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_J0(PyObject *self, PyObject *other); static PyObject * GMPy_Real_J1(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_J1(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_J1(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Y0(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Y0(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Y0(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Y1(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Y1(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Y1(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Ai(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Ai(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Ai(PyObject *self, PyObject *other); static PyObject * GMPy_Real_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Number_FMA(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Context_FMA(PyObject *self, PyObject *args); static PyObject * GMPy_Real_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Number_FMS(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); static PyObject * GMPy_Context_FMS(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Root(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Root(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Root(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Jn(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Jn(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Jn(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Yn(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Yn(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Yn(PyObject *self, PyObject *args); static PyObject * GMPy_Real_AGM(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_AGM(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_AGM(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Maxnum(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Maxnum(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Maxnum(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Minnum(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Minnum(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Minnum(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Remainder(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Remainder(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Remainder(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Fmod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Fmod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Fmod(PyObject *self, PyObject *args); static PyObject * GMPy_Real_RelDiff(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_RelDiff(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_RelDiff(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Ceil(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Ceil(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Method_Ceil(PyObject *self, PyObject *args); static PyObject * GMPy_Context_Ceil(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Floor(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Floor(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Method_Floor(PyObject *self, PyObject *args); static PyObject * GMPy_Context_Floor(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Trunc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Trunc(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Method_Trunc(PyObject *self, PyObject *args); static PyObject * GMPy_Context_Trunc(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Round2(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Round2(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Round2(PyObject *self, PyObject *args); static PyObject * GMPy_Real_RoundAway(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_RoundAway(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_RoundAway(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Modf(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Modf(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Modf(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Lgamma(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Lgamma(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Lgamma(PyObject *self, PyObject *other); static PyObject * GMPy_Real_RemQuo(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_RemQuo(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_RemQuo(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Frexp(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Frexp(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Frexp(PyObject *self, PyObject *other); static PyObject * GMPy_Context_NextToward(PyObject *self, PyObject *args); static PyObject * GMPy_Context_NextAbove(PyObject *self, PyObject *other); static PyObject * GMPy_Context_NextBelow(PyObject *self, PyObject *other); static PyObject * GMPy_Context_Factorial(PyObject *self, PyObject *other); static PyObject * GMPy_Context_Fsum(PyObject *self, PyObject *other); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_minus.c0000664000175000017500000001536313425752452016074 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_minus.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements __neg__ and context.minus(). * * Public API * ========== * The following function is available as part of GMPY2's C API. If the value * of context is NULL, then the function should use the currently active * context. * * GMPy_Number_Minus(Number, context) * * Private API * =========== * GMPy_MPZ_Minus_Slot * GMPy_MPQ_Minus_Slot * GMPy_MPFR_Minus_Slot * GMPy_MPC_Minus_Slot * * GMPy_Integer_Minus(Integer, context|NULL) * GMPy_Rational_Minus(Rational, context|NULL) * GMPy_Real_Minus(Real, context|NULL) * GMPy_Complex_Minus(Complex, context|NULL) * * GMPy_Context_Minus(context, args) */ static PyObject * _GMPy_MPZ_Minus(PyObject *x, CTXT_Object *context) { MPZ_Object *result; if (!(result = GMPy_MPZ_New(context))) { return NULL; } mpz_neg(result->z, MPZ(x)); return (PyObject*)result; } static PyObject * GMPy_Integer_Minus(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context))) { return NULL; } result = _GMPy_MPZ_Minus(tempx, context); Py_DECREF(tempx); return result; } static PyObject * GMPy_MPZ_Minus_Slot(MPZ_Object *x) { return _GMPy_MPZ_Minus((PyObject*)x, NULL); } static PyObject * _GMPy_MPQ_Minus(PyObject *x, CTXT_Object *context) { MPQ_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPQ_New(context))) { return NULL; } mpq_neg(result->q, MPQ(x)); return (PyObject*)result; } static PyObject * GMPy_Rational_Minus(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context))) { return NULL; } result = _GMPy_MPQ_Minus(tempx, context); Py_DECREF(tempx); return result; } static PyObject * GMPy_MPQ_Minus_Slot(MPQ_Object *x) { return _GMPy_MPQ_Minus((PyObject*)x, NULL); } static PyObject * _GMPy_MPFR_Minus(PyObject *x, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); result->rc = mpfr_neg(result->f, MPFR(x), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Minus(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Minus(tempx, context); Py_DECREF(tempx); return result; } static PyObject * GMPy_MPFR_Minus_Slot(MPFR_Object *x) { return _GMPy_MPFR_Minus((PyObject*)x, NULL); } static PyObject * _GMPy_MPC_Minus(PyObject *x, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_neg(result->c, MPC(x), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Minus(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } result = _GMPy_MPC_Minus(tempx, context); Py_DECREF(tempx); return result; } static PyObject * GMPy_MPC_Minus_Slot(MPC_Object *x) { return _GMPy_MPC_Minus((PyObject*)x, NULL); } static PyObject * GMPy_Number_Minus(PyObject *x, CTXT_Object *context) { if (MPZ_Check(x)) return _GMPy_MPZ_Minus(x, context); if (MPQ_Check(x)) return _GMPy_MPQ_Minus(x, context); if (MPFR_Check(x)) return _GMPy_MPFR_Minus(x, context); if (MPC_Check(x)) return _GMPy_MPC_Minus(x, context); if (IS_INTEGER(x)) return GMPy_Integer_Minus(x, context); if (IS_RATIONAL_ONLY(x)) return GMPy_Rational_Minus(x, context); if (IS_REAL_ONLY(x)) return GMPy_Real_Minus(x, context); if (IS_COMPLEX_ONLY(x)) return GMPy_Complex_Minus(x, context); TYPE_ERROR("minus() argument type not supported"); return NULL; } PyDoc_STRVAR(GMPy_doc_context_minus, "context.minus(x) -> number\n\n" "Return -x. The context is applied to the result."); static PyObject * GMPy_Context_Minus(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("minus() requires 1 argument."); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Minus(PyTuple_GET_ITEM(args, 0), context); } gmpy2-2.1.0b3/src/gmpy2_minus.h0000664000175000017500000000551413425752464016101 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_minus.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_MINUS_H #define GMPY2_MINUS_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_Minus(PyObject *x, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_Minus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Rational_Minus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Real_Minus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Minus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPZ_Minus_Slot(MPZ_Object *x); static PyObject * GMPy_MPQ_Minus_Slot(MPQ_Object *x); static PyObject * GMPy_MPFR_Minus_Slot(MPFR_Object *x); static PyObject * GMPy_MPC_Minus_Slot(MPC_Object *x); static PyObject * GMPy_Context_Minus(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_misc.c0000664000175000017500000001502713425752502015665 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_misc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Miscellaneous module-level functions and helper functions. */ PyDoc_STRVAR(GMPy_doc_license, "license() -> string\n\n" "Return string giving license information."); static PyObject * GMPy_get_license(PyObject *self, PyObject *args) { return Py_BuildValue("s", gmpy_license); } PyDoc_STRVAR(GMPy_doc_version, "version() -> string\n\n" "Return string giving current GMPY2 version."); static PyObject * GMPy_get_version(PyObject *self, PyObject *args) { return Py_BuildValue("s", gmpy_version); } PyDoc_STRVAR(GMPy_doc_mp_version, "mp_version() -> string\n\n" "Return string giving the name and version of the multiple precision\n" "library used."); static PyObject * GMPy_get_mp_version(PyObject *self, PyObject *args) { #ifndef __MPIR_VERSION return Py2or3String_FromFormat("%s %s", "GMP", gmp_version); #else return Py2or3String_FromFormat("%s %s", "MPIR", mpir_version); #endif } PyDoc_STRVAR(GMPy_doc_mpfr_version, "mpfr_version() -> string\n\n" "Return string giving current MPFR version."); static PyObject * GMPy_get_mpfr_version(PyObject *self, PyObject *args) { return Py2or3String_FromFormat("%s %s", "MPFR", MPFR_VERSION_STRING); } PyDoc_STRVAR(GMPy_doc_mpc_version, "mpc_version() -> string\n\n" "Return string giving current MPC version."); static PyObject * GMPy_get_mpc_version(PyObject *self, PyObject *args) { return Py2or3String_FromFormat("%s %s", "MPC", MPC_VERSION_STRING); } PyDoc_STRVAR(GMPy_doc_mp_limbsize, "mp_limbsize() -> integer\n\n\ Return the number of bits per limb."); static PyObject * GMPy_get_mp_limbsize(PyObject *self, PyObject *args) { return Py_BuildValue("i", mp_bits_per_limb); } /* * access cache options */ PyDoc_STRVAR(GMPy_doc_get_cache, "get_cache() -> (cache_size, object_size)\n\n\ Return the current cache size (number of objects) and maximum size\n\ per object (number of limbs) for all GMPY2 objects."); static PyObject * GMPy_get_cache(PyObject *self, PyObject *args) { return Py_BuildValue("(ii)", global.cache_size, global.cache_obsize); } PyDoc_STRVAR(GMPy_doc_set_cache, "set_cache(cache_size, object_size)\n\n\ Set the current cache size (number of objects) and the maximum size\n\ per object (number of limbs). Raises ValueError if cache size exceeds\n\ 1000 or object size exceeds 16384."); static PyObject * GMPy_set_cache(PyObject *self, PyObject *args) { int newcache = -1, newsize = -1; if (!PyArg_ParseTuple(args, "ii", &newcache, &newsize)) return NULL; if (newcache<0 || newcache>MAX_CACHE) { VALUE_ERROR("cache size must between 0 and 1000"); return NULL; } if (newsize<0 || newsize>MAX_CACHE_LIMBS) { VALUE_ERROR("object size must between 0 and 16384"); return NULL; } global.cache_size = newcache; global.cache_obsize = newsize; set_gmpympzcache(); set_gmpympqcache(); set_gmpyxmpzcache(); set_gmpympfrcache(); set_gmpympccache(); Py_RETURN_NONE; } PyDoc_STRVAR(GMPy_doc_function_printf, "_printf(fmt, x) -> string\n\n" "Return a Python string by formatting 'x' using the format string\n" "'fmt'.\n\n" "WARNING: Invalid format strings will cause a crash. Please see the\n" " GMP and MPFR manuals for details on the format code. 'mpc'\n" " objects are not supported."); static PyObject * GMPy_printf(PyObject *self, PyObject *args) { PyObject *result = NULL, *x = NULL; char *buffer = NULL, *fmtcode = NULL; void *generic; int buflen; if (!PyArg_ParseTuple(args, "sO", &fmtcode, &x)) return NULL; if (CHECK_MPZANY(x) || MPQ_Check(x)) { if (CHECK_MPZANY(x)) generic = MPZ(x); else generic = MPQ(x); buflen = mpfr_asprintf(&buffer, fmtcode, generic); if (buflen < 0) { VALUE_ERROR("_printf() could not format the 'mpz' or 'mpq' object"); } else { result = Py_BuildValue("s", buffer); mpfr_free_str(buffer); } return result; } else if(MPFR_Check(x)) { generic = MPFR(x); buflen = mpfr_asprintf(&buffer, fmtcode, generic); if (buflen < 0) { VALUE_ERROR("_printf() could not format the 'mpfr' object"); } else { result = Py_BuildValue("s", buffer); mpfr_free_str(buffer); } return result; } else if(MPC_Check(x)) { TYPE_ERROR("_printf() does not support 'mpc'"); return NULL; } else { TYPE_ERROR("_printf() argument type not supported"); return NULL; } } gmpy2-2.1.0b3/src/gmpy2_misc.h0000664000175000017500000000540113425752543015672 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_misc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MISC_H #define GMPY_MISC_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_get_license(PyObject *self, PyObject *args); static PyObject * GMPy_get_version(PyObject *self, PyObject *args); static PyObject * GMPy_get_mp_version(PyObject *self, PyObject *args); static PyObject * GMPy_get_mpfr_version(PyObject *self, PyObject *args); static PyObject * GMPy_get_mpc_version(PyObject *self, PyObject *args); static PyObject * GMPy_get_mp_limbsize(PyObject *self, PyObject *args); static PyObject * GMPy_get_cache(PyObject *self, PyObject *args); static PyObject * GMPy_set_cache(PyObject *self, PyObject *args); static PyObject * GMPy_printf(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mod.c0000664000175000017500000002764613452562272015526 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mod.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements __mod__, gmpy2.mod(), and context.mod(). * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_Mod(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPZ_Mod_Slot * GMPy_MPQ_Mod_Slot * GMPy_MPFR_Mod_Slot * GMPy_MPC_Mod_Slot * * GMPy_Integer_Mod(Integer, Integer, context|NULL) * GMPy_Rational_Mod(Rational, Rational, context|NULL) * GMPy_Real_Mod(Real, Real, context|NULL) * GMPy_Complex_Mod(Complex, Complex, context|NULL) * * GMPy_Context_Mod(context, args) * */ static PyObject * GMPy_Integer_Mod(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPZ_New(context))) return NULL; if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(y, &error); if (!error) { if (temp > 0) { mpz_fdiv_r_ui(result->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } else { mpz_cdiv_r_ui(result->z, MPZ(x), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, y); mpz_fdiv_r(result->z, MPZ(x), global.tempz); } return (PyObject*)result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } mpz_fdiv_r(result->z, MPZ(x), MPZ(y)); return (PyObject*)result; } } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } if (PyIntOrLong_Check(x)) { mpz_set_PyIntOrLong(global.tempz, x); mpz_fdiv_r(result->z, global.tempz, MPZ(y)); return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { MPZ_Object *tempx, *tempy; tempx = GMPy_MPZ_From_Integer(x, context); tempy = GMPy_MPZ_From_Integer(y, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Integer to mpz"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpz_fdiv_r(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPZ_Mod_Slot(PyObject *x, PyObject *y) { if (MPZ_Check(x) && MPZ_Check(y)) { MPZ_Object *result = NULL; if ((result = GMPy_MPZ_New(NULL))) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)result); return NULL; } mpz_fdiv_r(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Mod(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Mod(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mod(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mod(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Rational_Mod(PyObject *x, PyObject *y, CTXT_Object *context) { MPQ_Object *tempx, *tempy, *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPQ_New(context))) return NULL; if (IS_RATIONAL(x) && IS_RATIONAL(y)) { tempx = GMPy_MPQ_From_Number(x, context); tempy = GMPy_MPQ_From_Number(y, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Rational to mpq"); goto error; } if (mpq_sgn(tempy->q) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpq_div(result->q, tempx->q, tempy->q); mpz_fdiv_q(global.tempz, mpq_numref(result->q), mpq_denref(result->q)); /* Need to calculate x - tempz * y. */ mpq_set_z(result->q, global.tempz); mpq_mul(result->q, result->q, tempy->q); mpq_sub(result->q, tempx->q, result->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } static PyObject * GMPy_MPQ_Mod_Slot(PyObject *x, PyObject *y) { if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Mod(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mod(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mod(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Real_Mod(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx = NULL, *tempy = NULL, *result; CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); if (!result) { Py_XDECREF((PyObject*)result); return NULL; } if (IS_REAL(x) && IS_REAL(y)) { tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Real to mpfr"); goto error; } if (mpfr_zero_p(tempy->f)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("mod() modulo by zero"); goto error; } } mpfr_clear_flags(); if (mpfr_nan_p(tempx->f) || mpfr_nan_p(tempy->f) || mpfr_inf_p(tempx->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("mod() invalid operation"); goto error; } mpfr_set_nan(result->f); } else if (mpfr_inf_p(tempy->f)) { context->ctx.invalid = 1; if (context->ctx.traps & TRAP_INVALID) { GMPY_INVALID("mod() invalid operation"); goto error; } if (mpfr_signbit(tempy->f)) { mpfr_set_inf(result->f, -1); } else { result->rc = mpfr_set(result->f, tempx->f, GET_MPFR_ROUND(context)); } } else { mpfr_fmod(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context)); if (!mpfr_zero_p(result->f)) { if ((mpfr_sgn(tempy->f) < 0) != (mpfr_sgn(result->f) < 0)) { mpfr_add(result->f, result->f, tempy->f, GET_MPFR_ROUND(context)); } } else { mpfr_copysign(result->f, result->f, tempy->f, GET_MPFR_ROUND(context)); } } _GMPy_MPFR_Cleanup(&result, context); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } static PyObject * GMPy_MPFR_Mod_Slot(PyObject *x, PyObject *y) { if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mod(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mod(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Complex_Mod(PyObject *x, PyObject *y, CTXT_Object *context) { TYPE_ERROR("can't take mod of complex number"); return NULL; } static PyObject * GMPy_MPC_Mod_Slot(PyObject *x, PyObject *y) { return GMPy_Complex_Mod(x, y, NULL); } PyDoc_STRVAR(GMPy_doc_mod, "mod(x, y) -> number\n\n" "Return mod(x, y).\n" "Note: overflow, underflow, and inexact exceptions are not supported for\n" "mpfr arguments to mod()."); static PyObject * GMPy_Number_Mod(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Mod(x, y, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Mod(x, y, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mod(x, y, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mod(x, y, context); TYPE_ERROR("mod() argument type not supported"); return NULL; } PyDoc_STRVAR(GMPy_doc_context_mod, "context.mod(x, y) -> number\n\n" "Return mod(x, y).\n" "Note: overflow, underflow, and inexact exceptions are not supported for\n" "mpfr arguments to context.mod()."); static PyObject * GMPy_Context_Mod(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("mod() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Mod(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_mod.h0000664000175000017500000000564013425752600015515 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mod.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_MOD_H #define GMPY2_MOD_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_Mod(PyObject *x, PyObject *y, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_Mod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Rational_Mod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Real_Mod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_Mod(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPZ_Mod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPQ_Mod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPFR_Mod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPC_Mod_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_Context_Mod(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpc.c0000664000175000017500000004171113444070732015507 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static void _GMPy_MPC_Cleanup(MPC_Object **v, CTXT_Object *ctext) { /* GMPY_MPC_CHECK_RANGE(V, CTX) */ { int rcr, rci; rcr = MPC_INEX_RE((*v)->rc); rci = MPC_INEX_IM((*v)->rc); if (mpfr_regular_p(mpc_realref((*v)->c)) && (!((mpc_realref((*v)->c)->_mpfr_exp >= ctext->ctx.emin) && (mpc_realref((*v)->c)->_mpfr_exp <= ctext->ctx.emax)))) { mpfr_exp_t _oldemin, _oldemax; _oldemin = mpfr_get_emin(); _oldemax = mpfr_get_emax(); mpfr_set_emin(ctext->ctx.emin); mpfr_set_emax(ctext->ctx.emax); rcr = mpfr_check_range(mpc_realref((*v)->c), rcr, GET_REAL_ROUND(ctext)); mpfr_set_emin(_oldemin); mpfr_set_emax(_oldemax); } if (mpfr_regular_p(mpc_imagref((*v)->c)) && (!((mpc_imagref((*v)->c)->_mpfr_exp >= ctext->ctx.emin) && (mpc_imagref((*v)->c)->_mpfr_exp <= ctext->ctx.emax)))) { mpfr_exp_t _oldemin, _oldemax; _oldemin = mpfr_get_emin(); _oldemax = mpfr_get_emax(); mpfr_set_emin(ctext->ctx.emin); mpfr_set_emax(ctext->ctx.emax); rci = mpfr_check_range(mpc_imagref((*v)->c), rci, GET_IMAG_ROUND(ctext)); mpfr_set_emin(_oldemin); mpfr_set_emax(_oldemax); } (*v)->rc = MPC_INEX(rcr, rci); } /* GMPY_MPC_SUBNORMALIZE(V, CTX) */ { int rcr, rci; rcr = MPC_INEX_RE((*v)->rc); rci = MPC_INEX_IM((*v)->rc); if (ctext->ctx.subnormalize && (!((mpc_realref((*v)->c)->_mpfr_exp >= ctext->ctx.emin) && (mpc_realref((*v)->c)->_mpfr_exp <= ctext->ctx.emin + mpfr_get_prec(mpc_realref((*v)->c)) - 2)))) { mpfr_exp_t _oldemin, _oldemax; _oldemin = mpfr_get_emin(); _oldemax = mpfr_get_emax(); mpfr_set_emin(ctext->ctx.emin); mpfr_set_emax(ctext->ctx.emax); rcr = mpfr_subnormalize(mpc_realref((*v)->c), rcr, GET_REAL_ROUND(ctext)); mpfr_set_emin(_oldemin); mpfr_set_emax(_oldemax); } if (ctext->ctx.subnormalize && (!((mpc_imagref((*v)->c)->_mpfr_exp >= ctext->ctx.emin) && (mpc_imagref((*v)->c)->_mpfr_exp <= ctext->ctx.emin + mpfr_get_prec(mpc_imagref((*v)->c)) - 2)))) { mpfr_exp_t _oldemin, _oldemax; _oldemin = mpfr_get_emin(); _oldemax = mpfr_get_emax(); mpfr_set_emin(ctext->ctx.emin); mpfr_set_emax(ctext->ctx.emax); rci = mpfr_check_range(mpc_imagref((*v)->c), rci, GET_IMAG_ROUND(ctext)); mpfr_set_emin(_oldemin); mpfr_set_emax(_oldemax); } (*v)->rc = MPC_INEX(rcr, rci); } /* GMPY_MPC_EXCEPTIONS(V, CTX) */ { int _invalid = 0, _underflow = 0, _overflow = 0, _inexact = 0; int rcr, rci; rcr = MPC_INEX_RE((*v)->rc); rci = MPC_INEX_IM((*v)->rc); if (MPC_IS_NAN_P(*v)) { ctext->ctx.invalid = 1; _invalid = 1; } if ((*v)->rc) { ctext->ctx.inexact = 1; _inexact = 1; } if ((rcr && mpfr_zero_p(mpc_realref((*v)->c))) || (rci && mpfr_zero_p(mpc_imagref((*v)->c)))) { ctext->ctx.underflow = 1; _underflow = 1; } if ((rcr && mpfr_inf_p(mpc_realref((*v)->c))) || (rci && mpfr_inf_p(mpc_imagref((*v)->c)))) { ctext->ctx.overflow = 1; _overflow = 1; } if (ctext->ctx.traps) { if ((ctext->ctx.traps & TRAP_UNDERFLOW) && _underflow) { \ GMPY_UNDERFLOW("underflow"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } if ((ctext->ctx.traps & TRAP_OVERFLOW) && _overflow) { GMPY_OVERFLOW("overflow"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } if ((ctext->ctx.traps & TRAP_INEXACT) && _inexact) { GMPY_INEXACT("inexact result"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } if ((ctext->ctx.traps & TRAP_INVALID) && _invalid) { GMPY_INVALID("invalid operation"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } } } } PyDoc_STRVAR(GMPy_doc_mpc, "mpc() -> mpc(0.0+0.0j)\n\n" " If no argument is given, return mpc(0.0+0.0j).\n\n" "mpc(c [, precision=0]) -> mpc\n\n" " Return a new 'mpc' object from an existing complex number (either\n" " a Python complex object or another 'mpc' object).\n\n" "mpc(real [,imag=0 [, precision=0]]) -> mpc\n\n" " Return a new 'mpc' object by converting two non-complex numbers\n" " into the real and imaginary components of an 'mpc' object.\n\n" "mpc(s [, precision=0 [, base=10]]) -> mpc\n\n" " Return a new 'mpc' object by converting a string s into a complex\n" " number. If base is omitted, then a base-10 representation is\n" " assumed otherwise the base must be in the interval [2,36].\n\n" "Note: The precision can be specified either a single number that\n" " is used for both the real and imaginary components, or as a\n" " tuple that can specify different precisions for the real\n" " and imaginary components.\n\n" " If a precision greater than or equal to 2 is specified, then it\n" " is used.\n\n" " A precision of 0 (the default) implies the precision of the\n" " current context is used.\n\n" " A precision of 1 minimizes the loss of precision by following\n" " these rules:\n" " 1) If n is a radix-2 floating point number, then the full\n" " precision of n is retained.\n" " 2) If n is an integer, then the precision is the bit length\n" " of the integer.\n" ); static PyMethodDef Pympc_methods[] = { { "__complex__", GMPy_PyComplex_From_MPC, METH_NOARGS, GMPy_doc_mpc_complex }, { "__format__", GMPy_MPC_Format, METH_VARARGS, GMPy_doc_mpc_format }, { "__sizeof__", GMPy_MPC_SizeOf_Method, METH_NOARGS, GMPy_doc_mpc_sizeof_method }, { "conjugate", GMPy_MPC_Conjugate_Method, METH_NOARGS, GMPy_doc_mpc_conjugate_method }, { "digits", GMPy_MPC_Digits_Method, METH_VARARGS, GMPy_doc_mpc_digits_method }, { "is_finite", GMPy_MPC_Is_Finite_Method, METH_NOARGS, GMPy_doc_method_is_finite }, { "is_infinite", GMPy_MPC_Is_Infinite_Method, METH_NOARGS, GMPy_doc_method_is_infinite }, { "is_nan", GMPy_MPC_Is_NAN_Method, METH_NOARGS, GMPy_doc_method_is_nan }, { "is_zero", GMPy_MPC_Is_Zero_Method, METH_NOARGS, GMPy_doc_method_is_zero }, { NULL, NULL, 1 } }; #ifdef PY3 static PyNumberMethods mpc_number_methods = { (binaryfunc) GMPy_MPC_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPC_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPC_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPC_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPC_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPC_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPC_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPC_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPC_NonZero_Slot, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ (unaryfunc) GMPy_MPC_Int_Slot, /* nb_int */ 0, /* nb_reserved */ (unaryfunc) GMPy_MPC_Float_Slot, /* nb_float */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply */ 0, /* nb_inplace_remainder */ 0, /* nb_inplace_power */ 0, /* nb_inplace_lshift */ 0, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPC_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPC_TrueDiv_Slot, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ 0, /* nb_index */ }; #else static PyNumberMethods mpc_number_methods = { (binaryfunc) GMPy_MPC_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPC_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPC_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPC_TrueDiv_Slot, /* nb_divide */ (binaryfunc) GMPy_MPC_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPC_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPC_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPC_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPC_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPC_NonZero_Slot, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ 0, /* nb_coerce */ (unaryfunc) GMPy_MPC_Int_Slot, /* nb_int */ (unaryfunc) GMPy_MPC_Long_Slot, /* nb_long */ (unaryfunc) GMPy_MPC_Float_Slot, /* nb_float */ 0, /* nb_oct */ 0, /* nb_hex */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply */ 0, /* nb_inplace_divide */ 0, /* nb_inplace_remainder */ 0, /* nb_inplace_power */ 0, /* nb_inplace_lshift */ 0, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPC_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPC_TrueDiv_Slot, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ }; #endif static PyGetSetDef Pympc_getseters[] = { {"precision", (getter)GMPy_MPC_GetPrec_Attrib, NULL, "precision in bits", NULL}, {"rc", (getter)GMPy_MPC_GetRc_Attrib, NULL, "return code", NULL}, {"imag", (getter)GMPy_MPC_GetImag_Attrib, NULL, "imaginary component", NULL}, {"real", (getter)GMPy_MPC_GetReal_Attrib, NULL, "real component", NULL}, {NULL} }; static PyTypeObject MPC_Type = { /* PyObject_HEAD_INIT(&PyType_Type) */ #ifdef PY3 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "mpc", /* tp_name */ sizeof(MPC_Object), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor) GMPy_MPC_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_MPC_Repr_Slot, /* tp_repr */ &mpc_number_methods, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc) GMPy_MPC_Hash_Slot, /* tp_hash */ 0, /* tp_call */ (reprfunc) GMPy_MPC_Str_Slot, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ #ifdef PY3 Py_TPFLAGS_DEFAULT, /* tp_flags */ #else Py_TPFLAGS_HAVE_RICHCOMPARE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */ #endif GMPy_doc_mpc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)&GMPy_RichCompare_Slot, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ Pympc_methods, /* tp_methods */ 0, /* tp_members */ Pympc_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ GMPy_MPC_NewInit, /* tp_new */ 0, /* tp_free */ }; gmpy2-2.1.0b3/src/gmpy2_mpc.h0000664000175000017500000001747413425752625015534 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpc.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPC_H #define GMPY_MPC_H #ifdef __cplusplus extern "C" { #endif /* gmpy_mpc C API extension header file. * * Provide interface to the MPC (Multiple Precision Complex) library. * * Version 2.00, April 2011 (created) casevh * * This file is expected to be included from gmpy.h */ #if defined(MS_WIN32) && defined(_MSC_VER) # pragma comment(lib,"mpc.lib") #endif static PyTypeObject MPC_Type; #define MPC_Check(v) (((PyObject*)v)->ob_type == &MPC_Type) /* * Define macros for comparing with zero, checking if either component is * 'nan' or 'inf', etc. Based on the macros found in mpc-impl.h. */ #define MPC_IS_ZERO_P(x) \ (mpfr_zero_p(mpc_realref(MPC(x))) && \ mpfr_zero_p(mpc_imagref(MPC(x)))) #define MPC_IS_NAN_P(x) \ ((mpfr_nan_p(mpc_realref(MPC(x))) && !mpfr_inf_p(mpc_imagref(MPC(x)))) || \ (mpfr_nan_p(mpc_imagref(MPC(x))) && !mpfr_inf_p(mpc_realref(MPC(x))))) #define MPC_IS_INF_P(x) \ (mpfr_inf_p(mpc_realref(MPC(x))) || \ mpfr_inf_p(mpc_imagref(MPC(x)))) #define MPC_IS_FINITE_P(x) \ (mpfr_number_p(mpc_realref(MPC(x))) && \ mpfr_number_p(mpc_imagref(MPC(x)))) /* V is the value that is expected to be returned. * CTX is the context. * NAME is prepended to the error message. */ #define GMPY_MPC_CHECK_RANGE(V, CTX) \ { \ int rcr, rci; \ rcr = MPC_INEX_RE(V->rc); \ rci = MPC_INEX_IM(V->rc); \ if (mpfr_regular_p(mpc_realref(V->c)) && \ (!((mpc_realref(V->c)->_mpfr_exp >= CTX->ctx.emin) && \ (mpc_realref(V->c)->_mpfr_exp <= CTX->ctx.emax)))) { \ mpfr_exp_t _oldemin, _oldemax; \ _oldemin = mpfr_get_emin(); \ _oldemax = mpfr_get_emax(); \ mpfr_set_emin(CTX->ctx.emin); \ mpfr_set_emax(CTX->ctx.emax); \ rcr = mpfr_check_range(mpc_realref(V->c), rcr, GET_REAL_ROUND(CTX)); \ mpfr_set_emin(_oldemin); \ mpfr_set_emax(_oldemax); \ } \ if (mpfr_regular_p(mpc_imagref(V->c)) && \ (!((mpc_imagref(V->c)->_mpfr_exp >= CTX->ctx.emin) && \ (mpc_imagref(V->c)->_mpfr_exp <= CTX->ctx.emax)))) { \ mpfr_exp_t _oldemin, _oldemax; \ _oldemin = mpfr_get_emin(); \ _oldemax = mpfr_get_emax(); \ mpfr_set_emin(CTX->ctx.emin); \ mpfr_set_emax(CTX->ctx.emax); \ rci = mpfr_check_range(mpc_imagref(V->c), rci, GET_IMAG_ROUND(CTX)); \ mpfr_set_emin(_oldemin); \ mpfr_set_emax(_oldemax); \ } \ V->rc = MPC_INEX(rcr, rci); \ } #define GMPY_MPC_SUBNORMALIZE(V, CTX) \ { \ int rcr, rci; \ rcr = MPC_INEX_RE(V->rc); \ rci = MPC_INEX_IM(V->rc); \ if (CTX->ctx.subnormalize && \ (!((mpc_realref(V->c)->_mpfr_exp >= CTX->ctx.emin) && \ (mpc_realref(V->c)->_mpfr_exp <= CTX->ctx.emin + mpfr_get_prec(mpc_realref(V->c)) - 2)))) { \ mpfr_exp_t _oldemin, _oldemax; \ _oldemin = mpfr_get_emin(); \ _oldemax = mpfr_get_emax(); \ mpfr_set_emin(CTX->ctx.emin); \ mpfr_set_emax(CTX->ctx.emax); \ rcr = mpfr_subnormalize(mpc_realref(V->c), rcr, GET_REAL_ROUND(CTX)); \ mpfr_set_emin(_oldemin); \ mpfr_set_emax(_oldemax); \ } \ if (CTX->ctx.subnormalize && \ (!((mpc_imagref(V->c)->_mpfr_exp >= CTX->ctx.emin) && \ (mpc_imagref(V->c)->_mpfr_exp <= CTX->ctx.emin + mpfr_get_prec(mpc_imagref(V->c)) - 2)))) { \ mpfr_exp_t _oldemin, _oldemax; \ _oldemin = mpfr_get_emin(); \ _oldemax = mpfr_get_emax(); \ mpfr_set_emin(CTX->ctx.emin); \ mpfr_set_emax(CTX->ctx.emax); \ rci = mpfr_check_range(mpc_imagref(V->c), rci, GET_IMAG_ROUND(CTX)); \ mpfr_set_emin(_oldemin); \ mpfr_set_emax(_oldemax); \ } \ V->rc = MPC_INEX(rcr, rci); \ } #define GMPY_MPC_EXCEPTIONS(V, CTX) \ do { \ int _invalid = 0, _underflow = 0, _overflow = 0, _inexact = 0; \ int rcr, rci; \ rcr = MPC_INEX_RE(V->rc); \ rci = MPC_INEX_IM(V->rc); \ if (MPC_IS_NAN_P(V)) { \ CTX->ctx.invalid = 1; \ _invalid = 1; \ } \ if (V->rc) { \ CTX->ctx.inexact = 1; \ _inexact = 1; \ } \ if ((rcr && mpfr_zero_p(mpc_realref(V->c))) || (rci && mpfr_zero_p(mpc_imagref(V->c)))) { \ CTX->ctx.underflow = 1; \ _underflow = 1; \ } \ if ((rcr && mpfr_inf_p(mpc_realref(V->c))) || (rci && mpfr_inf_p(mpc_imagref(V->c)))) { \ CTX->ctx.overflow = 1; \ _overflow = 1; \ } \ if (CTX->ctx.traps) { \ if ((CTX->ctx.traps & TRAP_UNDERFLOW) && _underflow) { \ GMPY_UNDERFLOW("underflow"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ if ((CTX->ctx.traps & TRAP_OVERFLOW) && _overflow) { \ GMPY_OVERFLOW("overflow"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ if ((CTX->ctx.traps & TRAP_INEXACT) && _inexact) { \ GMPY_INEXACT("inexact result"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ if ((CTX->ctx.traps & TRAP_INVALID) && _invalid) { \ GMPY_INVALID("invalid operation"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ } \ } while(0); \ #define GMPY_MPC_CLEANUP(V, CTX) \ GMPY_MPC_CHECK_RANGE(V, CTX); \ GMPY_MPC_SUBNORMALIZE(V, CTX); \ GMPY_MPC_EXCEPTIONS(V, CTX); \ static void _GMPy_MPC_Cleanup(MPC_Object **v, CTXT_Object *ctext); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpc_misc.c0000664000175000017500000003252313444615157016531 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpc_misc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_context_phase, "context.phase(x) -> mpfr\n\n" "Return the phase angle, also known as argument, of a complex x."); PyDoc_STRVAR(GMPy_doc_function_phase, "phase(x) -> mpfr\n\n" "Return the phase angle, also known as argument, of a complex x."); static PyObject * GMPy_Complex_Phase(PyObject *x, CTXT_Object *context) { MPFR_Object *result = NULL; MPC_Object *tempx = NULL; CHECK_CONTEXT(context) if (!(IS_COMPLEX_ONLY(x))) { TYPE_ERROR("phase() argument type not supported"); return NULL; } result = GMPy_MPFR_New(0, context); tempx = GMPy_MPC_From_Complex(x, 1, 1, context); if (!result || !tempx) { Py_XDECREF(result); Py_XDECREF(tempx); return NULL; } mpfr_clear_flags(); result->rc = mpc_arg(result->f, tempx->c, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Context_Phase(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Complex_Phase(other, context); } #ifdef MPC_110 PyDoc_STRVAR(GMPy_doc_context_root_of_unity, "context.root_of_unity(n, k) -> mpc\n\n" "Return the n-th root of mpc(1) raised to the k-th power.."); PyDoc_STRVAR(GMPy_doc_function_root_of_unity, "root_of_unity(n, k) -> mpc\n\n" "Return the n-th root of mpc(1) raised to the k-th power.."); static PyObject * GMPy_Complex_Root_Of_Unity(PyObject *n, PyObject *k, CTXT_Object *context) { MPC_Object *result; unsigned long n_val, k_val; CHECK_CONTEXT(context) result = GMPy_MPC_New(0, 0, context); if (!result) { return NULL; } n_val = c_ulong_From_Integer(n); k_val = c_ulong_From_Integer(k); if ((n_val == (unsigned long)(-1) && PyErr_Occurred()) || (k_val == (unsigned long)(-1) && PyErr_Occurred())) { Py_DECREF((PyObject*)result); VALUE_ERROR("root_of_unity() requires positive integer arguments."); return NULL; } result->rc = mpc_rootofunity(result->c, n_val, k_val, GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Context_Root_Of_Unity(PyObject *self, PyObject *args) { PyObject *n, *k; CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("root_of_unity() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } n = PyTuple_GET_ITEM(args, 0); k = PyTuple_GET_ITEM(args, 1); if (IS_INTEGER(n) && IS_INTEGER(k)) { return GMPy_Complex_Root_Of_Unity(n, k, context); } else { TYPE_ERROR("root_of_unity() requires integer arguments"); return NULL; } } #endif PyDoc_STRVAR(GMPy_doc_context_norm, "context.norm(x) -> mpfr\n\n" "Return the norm of a complex x. The norm(x) is defined as\n" "x.real**2 + x.imag**2. abs(x) is the square root of norm(x).\n"); PyDoc_STRVAR(GMPy_doc_function_norm, "norm(x) -> mpfr\n\n" "Return the norm of a complex x. The norm(x) is defined as\n" "x.real**2 + x.imag**2. abs(x) is the square root of norm(x).\n"); static PyObject * GMPy_Complex_Norm(PyObject *x, CTXT_Object *context) { MPFR_Object *result = NULL; MPC_Object *tempx = NULL; CHECK_CONTEXT(context); if (!(IS_COMPLEX_ONLY(x))) { TYPE_ERROR("norm() argument type not supported"); return NULL; } result = GMPy_MPFR_New(0, context); tempx = GMPy_MPC_From_Complex(x, 1, 1, context); if (!result || !tempx) { Py_XDECREF(result); Py_XDECREF(tempx); return NULL; } mpfr_clear_flags(); result->rc = mpc_norm(result->f, tempx->c, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Context_Norm(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Complex_Norm(other, context); } PyDoc_STRVAR(GMPy_doc_context_polar, "context.polar(x) -> (abs(x), phase(x))\n\n" "Return the polar coordinate form of a complex x that is in\n" "rectangular form."); PyDoc_STRVAR(GMPy_doc_function_polar, "polar(x) -> (abs(x), phase(x))\n\n" "Return the polar coordinate form of a complex x that is in\n" "rectangular form."); static PyObject * GMPy_Complex_Polar(PyObject *x, CTXT_Object *context) { PyObject *tempx, *abs, *phase, *result; CHECK_CONTEXT(context); if (!(IS_COMPLEX_ONLY(x))) { TYPE_ERROR("polar() argument type not supported"); return NULL; } if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } abs = GMPy_Complex_Abs(tempx, context); phase = GMPy_Complex_Phase(tempx, context); Py_DECREF(tempx); result = PyTuple_New(2); if (!abs || !phase || !result) { Py_XDECREF(abs); Py_XDECREF(phase); Py_XDECREF(result); return NULL; } PyTuple_SET_ITEM(result, 0, abs); PyTuple_SET_ITEM(result, 1, phase); return result; } static PyObject * GMPy_Context_Polar(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Complex_Polar(other, context); } PyDoc_STRVAR(GMPy_doc_context_rect, "context.rect(r, phi) -> mpc\n\n" "Return the rectangular coordinate form of a complex number that is\n" "given in polar form."); PyDoc_STRVAR(GMPy_doc_function_rect, "rect(r, phi) -> mpc\n\n" "Return the rectangular coordinate form of a complex number that is\n" "given in polar form."); static PyObject * GMPy_Complex_Rect(PyObject *r, PyObject *phi, CTXT_Object *context) { MPFR_Object *tempx, *tempy; MPC_Object *result; CHECK_CONTEXT(context); tempx = GMPy_MPFR_From_Real(r, 1, context); tempy = GMPy_MPFR_From_Real(phi, 1, context); result = GMPy_MPC_New(0, 0, context); if (!tempx || !tempy || !result) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)result); return NULL; } mpfr_cos(mpc_realref(result->c), tempy->f, GET_REAL_ROUND(context)); mpfr_mul(mpc_realref(result->c), mpc_realref(result->c), tempx->f, GET_REAL_ROUND(context)); mpfr_sin(mpc_imagref(result->c), tempy->f, GET_IMAG_ROUND(context)); mpfr_mul(mpc_imagref(result->c), mpc_imagref(result->c), tempx->f, GET_IMAG_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Context_Rect(PyObject *self, PyObject *args) { PyObject *r, *phi; CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("rect() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } r = PyTuple_GET_ITEM(args, 0); phi = PyTuple_GET_ITEM(args, 1); if (IS_REAL(r) && IS_REAL(phi)) { return GMPy_Complex_Rect(r, phi, context); } else { TYPE_ERROR("rect() argument type not supported"); return NULL; } } PyDoc_STRVAR(GMPy_doc_context_proj, "context.proj(x) -> mpc\n\n" "Returns the projection of a complex x on to the Riemann sphere."); PyDoc_STRVAR(GMPy_doc_function_proj, "proj(x) -> mpc\n\n" "Returns the projection of a complex x on to the Riemann sphere."); static PyObject * GMPy_Complex_Proj(PyObject *x, CTXT_Object *context) { MPC_Object *result = NULL, *tempx = NULL; CHECK_CONTEXT(context); if (!(IS_COMPLEX_ONLY(x))) { TYPE_ERROR("proj() argument type not supported"); return NULL; } result = GMPy_MPC_New(0, 0, context); tempx = GMPy_MPC_From_Complex(x, 1, 1, context); if (!result || !tempx) { Py_XDECREF(result); Py_XDECREF(tempx); return NULL; } mpfr_clear_flags(); result->rc = mpc_proj(result->c, tempx->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Context_Proj(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Complex_Proj(other, context); } /* Implement the conjugate() method. */ PyDoc_STRVAR(GMPy_doc_mpc_conjugate_method, "x.conjugate() -> mpc\n\n" "Returns the conjugate of x."); static PyObject * GMPy_MPC_Conjugate_Method(PyObject *self, PyObject *args) { MPC_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } result->rc = mpc_conj(result->c, MPC(self), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } /* Implement the .precision attribute of an mpc. */ static PyObject * GMPy_MPC_GetPrec_Attrib(MPC_Object *self, void *closure) { mpfr_prec_t rprec = 0, iprec = 0; mpc_get_prec2(&rprec, &iprec, self->c); return Py_BuildValue("(nn)", rprec, iprec); } /* Implement the .rc attribute of an mpc. */ static PyObject * GMPy_MPC_GetRc_Attrib(MPC_Object *self, void *closure) { return Py_BuildValue("(ii)", MPC_INEX_RE(self->rc), MPC_INEX_IM(self->rc)); } /* Implement the .imag attribute of an mpc. */ static PyObject * GMPy_MPC_GetImag_Attrib(MPC_Object *self, void *closure) { MPFR_Object *result = NULL; CTXT_Object *context = NULL; CHECK_CONTEXT(context); mpfr_prec_t rprec = 0, iprec = 0; mpc_get_prec2(&rprec, &iprec, self->c); if ((result = GMPy_MPFR_New(iprec, context))) { result->rc = mpc_imag(result->f, self->c, GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } /* Implement the .real attribute of an mpc. */ static PyObject * GMPy_MPC_GetReal_Attrib(MPC_Object *self, void *closure) { MPFR_Object *result = NULL; CTXT_Object *context = NULL; CHECK_CONTEXT(context); mpfr_prec_t rprec = 0, iprec = 0; mpc_get_prec2(&rprec, &iprec, self->c); if ((result = GMPy_MPFR_New(rprec, context))) { result->rc = mpc_real(result->f, self->c, context->ctx.mpfr_round); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } /* Implement the nb_bool slot. */ static int GMPy_MPC_NonZero_Slot(MPC_Object *self) { return !MPC_IS_ZERO_P(self->c); } PyDoc_STRVAR(GMPy_doc_mpc_sizeof_method, "x.__sizeof__()\n\n" "Returns the amount of memory consumed by x."); static PyObject * GMPy_MPC_SizeOf_Method(PyObject *self, PyObject *other) { return PyIntOrLong_FromSize_t(sizeof(MPC_Object) + \ (((mpc_realref(MPC(self))->_mpfr_prec + mp_bits_per_limb - 1) / \ mp_bits_per_limb) * sizeof(mp_limb_t)) + \ (((mpc_imagref(MPC(self))->_mpfr_prec + mp_bits_per_limb - 1) / \ mp_bits_per_limb) * sizeof(mp_limb_t))); } gmpy2-2.1.0b3/src/gmpy2_mpc_misc.h0000664000175000017500000000776613446330331016537 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpc_misc.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPC_MISC_H #define GMPY_MPC_MISC_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Complex_Phase(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Phase(PyObject *self, PyObject *other); #ifdef MPC_110 static PyObject * GMPy_Complex_Root_Of_Unity(PyObject *n, PyObject *k, CTXT_Object *context); static PyObject * GMPy_Context_Root_Of_Unity(PyObject *self, PyObject *args); #endif static PyObject * GMPy_Complex_Norm(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Norm(PyObject *self, PyObject *other); static PyObject * GMPy_Complex_Polar(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Polar(PyObject *self, PyObject *other); static PyObject * GMPy_Complex_Rect(PyObject *r, PyObject *phi, CTXT_Object *context); static PyObject * GMPy_Context_Rect(PyObject *self, PyObject *args); static PyObject * GMPy_Complex_Proj(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Proj(PyObject *self, PyObject *other); static PyObject * GMPy_MPC_Conjugate_Method(PyObject *self, PyObject *args); static PyObject * GMPy_MPC_GetPrec_Attrib(MPC_Object *self, void *closure); static PyObject * GMPy_MPC_GetRc_Attrib(MPC_Object *self, void *closure); static PyObject * GMPy_MPC_GetImag_Attrib(MPC_Object *self, void *closure); static PyObject * GMPy_MPC_GetReal_Attrib(MPC_Object *self, void *closure); static int GMPy_MPC_NonZero_Slot(MPC_Object *self); static PyObject * GMPy_MPC_SizeOf_Method(PyObject *self, PyObject *other); static PyObject * GMPy_MPC_Conjugate_Method(PyObject *self, PyObject *args); static PyObject * GMPy_MPC_GetPrec_Attrib(MPC_Object *self, void *closure); static PyObject * GMPy_MPC_GetRc_Attrib(MPC_Object *self, void *closure); static PyObject * GMPy_MPC_GetImag_Attrib(MPC_Object *self, void *closure); static PyObject * GMPy_MPC_GetReal_Attrib(MPC_Object *self, void *closure); static int GMPy_MPC_NonZero_Slot(MPC_Object *self); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpfr.c0000664000175000017500000004036413525427233015701 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpfr.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* General purpose functions are defined here. They are used as an alternative * to code bloat via macro overuse. */ static void _GMPy_MPFR_Cleanup(MPFR_Object **v, CTXT_Object *ctext) { /* GMPY_MPFR_CHECK_RANGE(V, CTX) */ if (mpfr_regular_p((*v)->f) && (!(((*v)->f->_mpfr_exp >= ctext->ctx.emin) && ((*v)->f->_mpfr_exp <= ctext->ctx.emax)))) { mpfr_exp_t _oldemin, _oldemax; _oldemin = mpfr_get_emin(); _oldemax = mpfr_get_emax(); mpfr_set_emin(ctext->ctx.emin); mpfr_set_emax(ctext->ctx.emax); \ (*v)->rc = mpfr_check_range((*v)->f, (*v)->rc, GET_MPFR_ROUND(ctext)); mpfr_set_emin(_oldemin); mpfr_set_emax(_oldemax); } /* GMPY_MPFR_SUBNORMALIZE(V, CTX) */ if (ctext->ctx.subnormalize && (*v)->f->_mpfr_exp >= ctext->ctx.emin && (*v)->f->_mpfr_exp <= ctext->ctx.emin + mpfr_get_prec((*v)->f) - 2) { mpfr_exp_t _oldemin, _oldemax; _oldemin = mpfr_get_emin(); _oldemax = mpfr_get_emax(); mpfr_set_emin(ctext->ctx.emin); mpfr_set_emax(ctext->ctx.emax); (*v)->rc = mpfr_subnormalize((*v)->f, (*v)->rc, GET_MPFR_ROUND(ctext)); mpfr_set_emin(_oldemin); mpfr_set_emax(_oldemax); } /* GMPY_MPFR_EXCEPTIONS(V, CTX) */ ctext->ctx.underflow |= mpfr_underflow_p(); ctext->ctx.overflow |= mpfr_overflow_p(); ctext->ctx.invalid |= mpfr_nanflag_p(); ctext->ctx.inexact |= mpfr_inexflag_p(); ctext->ctx.divzero |= mpfr_divby0_p(); if (ctext->ctx.traps) { if ((ctext->ctx.traps & TRAP_UNDERFLOW) && mpfr_underflow_p()) { PyErr_SetString(GMPyExc_Underflow, "underflow"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } if ((ctext->ctx.traps & TRAP_OVERFLOW) && mpfr_overflow_p()) { PyErr_SetString(GMPyExc_Overflow, "overflow"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } if ((ctext->ctx.traps & TRAP_INEXACT) && mpfr_inexflag_p()) { PyErr_SetString(GMPyExc_Inexact, "inexact result"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } if ((ctext->ctx.traps & TRAP_INVALID) && mpfr_nanflag_p()) { PyErr_SetString(GMPyExc_Invalid, "invalid operation"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } if ((ctext->ctx.traps & TRAP_DIVZERO) && mpfr_divby0_p()) { PyErr_SetString(GMPyExc_DivZero, "division by zero"); Py_XDECREF((PyObject*)(*v)); (*v) = NULL; } } } PyDoc_STRVAR(GMPy_doc_mpfr, "mpfr() -> mpfr(0.0)\n\n" " If no argument is given, return mpfr(0.0).\n\n" "mpfr(n [, precision=0 [, context]]) -> mpfr\n\n" " Return an 'mpfr' object after converting a numeric value. See\n" " below for the interpretation of precision.\n\n" "mpfr(s [, precision=0 [, base=0 [, context]]]) -> mpfr\n\n" " Return a new 'mpfr' object by converting a string s made of\n" " digits in the given base, possibly with fraction-part (with a\n" " period as a separator) and/or exponent-part (with an exponent\n" " marker 'e' for base<=10, else '@'). The base of the string\n" " representation must be 0 or in the interval [2,62]. If the base\n" " is 0, the leading digits of the string are used to identify the\n" " base: 0b implies base=2, 0x implies base=16, otherwise base=10\n" " is assumed.\n\n" "Note: If a precision greater than or equal to 2 is specified, then it\n" " is used.\n\n" " A precision of 0 (the default) implies the precision of either\n" " the specified context or the current context is used.\n\n" " A precision of 1 minimizes the loss of precision by following\n" " these rules:\n" " 1) If n is a radix-2 floating point number, then the full\n" " precision of n is retained.\n" " 2) If n is an integer, then the precision is the bit length\n" " of the integer.\n" ); #ifdef PY3 static PyNumberMethods mpfr_number_methods = { (binaryfunc) GMPy_MPFR_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPFR_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPFR_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPFR_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPFR_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPFR_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPFR_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPFR_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPFR_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPFR_NonZero_Slot, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ (unaryfunc) GMPy_MPFR_Int_Slot, /* nb_int */ 0, /* nb_reserved */ (unaryfunc) GMPy_MPFR_Float_Slot, /* nb_float */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply */ 0, /* nb_inplace_remainder */ 0, /* nb_inplace_power */ 0, /* nb_inplace_lshift */ 0, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPFR_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPFR_TrueDiv_Slot, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ 0, /* nb_index */ }; #else static PyNumberMethods mpfr_number_methods = { (binaryfunc) GMPy_MPFR_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPFR_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPFR_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPFR_TrueDiv_Slot, /* nb_divide */ (binaryfunc) GMPy_MPFR_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPFR_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPFR_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPFR_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPFR_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPFR_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPFR_NonZero_Slot, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ 0, /* nb_coerce */ (unaryfunc) GMPy_MPFR_Int_Slot, /* nb_int */ (unaryfunc) GMPy_MPFR_Long_Slot, /* nb_long */ (unaryfunc) GMPy_MPFR_Float_Slot, /* nb_float */ 0, /* nb_oct */ 0, /* nb_hex */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply */ 0, /* nb_inplace_divide */ 0, /* nb_inplace_remainder */ 0, /* nb_inplace_power */ 0, /* nb_inplace_lshift */ 0, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPFR_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPFR_TrueDiv_Slot, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ }; #endif static PyGetSetDef Pympfr_getseters[] = { {"precision", (getter)GMPy_MPFR_GetPrec_Attrib, NULL, "precision in bits", NULL}, {"rc", (getter)GMPy_MPFR_GetRc_Attrib, NULL, "return code", NULL}, {"imag", (getter)GMPy_MPFR_GetImag_Attrib, NULL, "imaginary component", NULL}, {"real", (getter)GMPy_MPFR_GetReal_Attrib, NULL, "real component", NULL}, {NULL} }; static PyMethodDef Pympfr_methods [] = { { "__ceil__", GMPy_MPFR_Method_Ceil, METH_NOARGS, GMPy_doc_mpfr_ceil_method }, { "__floor__", GMPy_MPFR_Method_Floor, METH_NOARGS, GMPy_doc_mpfr_floor_method }, { "__format__", GMPy_MPFR_Format, METH_VARARGS, GMPy_doc_mpfr_format }, { "__round__", GMPy_MPFR_Method_Round10, METH_VARARGS, GMPy_doc_method_round10 }, { "__sizeof__", GMPy_MPFR_SizeOf_Method, METH_NOARGS, GMPy_doc_mpfr_sizeof_method }, { "__trunc__", GMPy_MPFR_Method_Trunc, METH_NOARGS, GMPy_doc_mpfr_trunc_method }, { "as_integer_ratio", GMPy_MPFR_Integer_Ratio_Method, METH_NOARGS, GMPy_doc_method_integer_ratio }, { "as_mantissa_exp", GMPy_MPFR_Mantissa_Exp_Method, METH_NOARGS, GMPy_doc_method_mantissa_exp }, { "as_simple_fraction", (PyCFunction)GMPy_MPFR_Simple_Fraction_Method, METH_VARARGS | METH_KEYWORDS, GMPy_doc_method_simple_fraction }, { "conjugate", GMPy_MP_Method_Conjugate, METH_NOARGS, GMPy_doc_mp_method_conjugate }, { "digits", GMPy_MPFR_Digits_Method, METH_VARARGS, GMPy_doc_mpfr_digits_method }, { "is_finite", GMPy_MPFR_Is_Finite_Method, METH_NOARGS, GMPy_doc_method_is_finite }, { "is_infinite", GMPy_MPFR_Is_Infinite_Method, METH_NOARGS, GMPy_doc_method_is_infinite }, { "is_integer", GMPy_MPFR_Is_Integer_Method, METH_NOARGS, GMPy_doc_method_is_integer }, { "is_nan", GMPy_MPFR_Is_NAN_Method, METH_NOARGS, GMPy_doc_method_is_nan }, { "is_signed", GMPy_MPFR_Is_Regular_Method, METH_NOARGS, GMPy_doc_method_is_regular }, { "is_signed", GMPy_MPFR_Is_Signed_Method, METH_NOARGS, GMPy_doc_method_is_signed }, { "is_zero", GMPy_MPFR_Is_Zero_Method, METH_NOARGS, GMPy_doc_method_is_zero }, { NULL, NULL, 1 } }; static PyTypeObject MPFR_Type = { /* PyObject_HEAD_INIT(&PyType_Type) */ #ifdef PY3 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "mpfr", /* tp_name */ sizeof(MPFR_Object), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor) GMPy_MPFR_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_MPFR_Repr_Slot, /* tp_repr */ &mpfr_number_methods, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc) GMPy_MPFR_Hash_Slot, /* tp_hash */ 0, /* tp_call */ (reprfunc) GMPy_MPFR_Str_Slot, /* tp_str */ (getattrofunc) 0, /* tp_getattro */ (setattrofunc) 0, /* tp_setattro */ 0, /* tp_as_buffer */ #ifdef PY3 Py_TPFLAGS_DEFAULT, /* tp_flags */ #else Py_TPFLAGS_HAVE_RICHCOMPARE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */ #endif GMPy_doc_mpfr, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)&GMPy_RichCompare_Slot, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ Pympfr_methods, /* tp_methods */ 0, /* tp_members */ Pympfr_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ GMPy_MPFR_NewInit, /* tp_new */ 0, /* tp_free */ }; gmpy2-2.1.0b3/src/gmpy2_mpfr.h0000664000175000017500000001775013425752720015712 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpfr.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* gmpy_mpfr C API extension header file. * * Provide interface to the MPFR (Multiple Precision Floating-point with * Rounding) library. * * Version 2.00, April 2011 (created) casevh */ #ifndef GMPY_MPFR_H #define GMPY_MPFR_H #ifdef __cplusplus extern "C" { #endif #if !defined(FLT_RADIX) || (FLT_RADIX!=2) # error "FLT_RADIX undefined or != 2, GMPY2 is confused. :(" #endif #if defined(MS_WIN32) && defined(_MSC_VER) # pragma comment(lib,"mpfr.lib") #endif #ifdef FAST /* Very bad code ahead. I've copied portions of mpfr-impl.h and * hacked them so they work. This code will only be enabled if you * specify the --fast option. */ #define MPFR_THREAD_ATTR __thread __MPFR_DECLSPEC extern MPFR_THREAD_ATTR unsigned int __gmpfr_flags; __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emin; __MPFR_DECLSPEC extern MPFR_THREAD_ATTR mpfr_exp_t __gmpfr_emax; /* Flags of __gmpfr_flags */ #define MPFR_FLAGS_UNDERFLOW 1 #define MPFR_FLAGS_OVERFLOW 2 #define MPFR_FLAGS_NAN 4 #define MPFR_FLAGS_INEXACT 8 #define MPFR_FLAGS_ERANGE 16 #define MPFR_FLAGS_DIVBY0 32 #define MPFR_FLAGS_ALL 63 /* Replace some common functions for direct access to the global vars */ #define mpfr_get_emin() (__gmpfr_emin + 0) #define mpfr_get_emax() (__gmpfr_emax + 0) #define mpfr_clear_flags() ((void) (__gmpfr_flags = 0)) #define mpfr_clear_underflow() ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_UNDERFLOW)) #define mpfr_clear_overflow() ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_OVERFLOW)) #define mpfr_clear_nanflag() ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_NAN)) #define mpfr_clear_inexflag() ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_INEXACT)) #define mpfr_clear_erangeflag() ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE)) #define mpfr_clear_divby0() ((void) (__gmpfr_flags &= MPFR_FLAGS_ALL ^ MPFR_FLAGS_DIVBY0)) #define mpfr_underflow_p() ((int) (__gmpfr_flags & MPFR_FLAGS_UNDERFLOW)) #define mpfr_overflow_p() ((int) (__gmpfr_flags & MPFR_FLAGS_OVERFLOW)) #define mpfr_nanflag_p() ((int) (__gmpfr_flags & MPFR_FLAGS_NAN)) #define mpfr_inexflag_p() ((int) (__gmpfr_flags & MPFR_FLAGS_INEXACT)) #define mpfr_erangeflag_p() ((int) (__gmpfr_flags & MPFR_FLAGS_ERANGE)) #define mpfr_divby0_p() ((int) (__gmpfr_flags & MPFR_FLAGS_DIVBY0)) #define mpfr_check_range(x,t,r) \ ((((x)->_mpfr_exp) >= __gmpfr_emin && ((x)->_mpfr_exp) <= __gmpfr_emax) \ ? ((t) ? (__gmpfr_flags |= MPFR_FLAGS_INEXACT, (t)) : 0) \ : mpfr_check_range(x,t,r)) /* End of the really bad code. Hopefully. */ #endif static PyTypeObject MPFR_Type; #define MPFR_Check(v) (((PyObject*)v)->ob_type == &MPFR_Type) #define GMPY_DIVZERO(msg) PyErr_SetString(GMPyExc_DivZero, msg) #define GMPY_INEXACT(msg) PyErr_SetString(GMPyExc_Inexact, msg) #define GMPY_INVALID(msg) PyErr_SetString(GMPyExc_Invalid, msg) #define GMPY_OVERFLOW(msg) PyErr_SetString(GMPyExc_Overflow, msg) #define GMPY_UNDERFLOW(msg) PyErr_SetString(GMPyExc_Underflow, msg) #define GMPY_ERANGE(msg) PyErr_SetString(GMPyExc_Erange, msg) #define GMPY_MPFR_CHECK_RANGE(V, CTX) \ if (mpfr_regular_p(V->f) && \ (!((V->f->_mpfr_exp >= CTX->ctx.emin) && \ (V->f->_mpfr_exp <= CTX->ctx.emax)))) { \ mpfr_exp_t _oldemin, _oldemax; \ _oldemin = mpfr_get_emin(); \ _oldemax = mpfr_get_emax(); \ mpfr_set_emin(CTX->ctx.emin); \ mpfr_set_emax(CTX->ctx.emax); \ V->rc = mpfr_check_range(V->f, V->rc, GET_MPFR_ROUND(CTX)); \ mpfr_set_emin(_oldemin); \ mpfr_set_emax(_oldemax); \ } #define GMPY_MPFR_SUBNORMALIZE(V, CTX) \ if (CTX->ctx.subnormalize && \ V->f->_mpfr_exp >= CTX->ctx.emin && \ V->f->_mpfr_exp <= CTX->ctx.emin + mpfr_get_prec(V->f) - 2) { \ mpfr_exp_t _oldemin, _oldemax; \ _oldemin = mpfr_get_emin(); \ _oldemax = mpfr_get_emax(); \ mpfr_set_emin(CTX->ctx.emin); \ mpfr_set_emax(CTX->ctx.emax); \ V->rc = mpfr_subnormalize(V->f, V->rc, GET_MPFR_ROUND(CTX)); \ mpfr_set_emin(_oldemin); \ mpfr_set_emax(_oldemax); \ } /* Exceptions should be checked in order of least important to most important. */ #define GMPY_MPFR_EXCEPTIONS(V, CTX) \ CTX->ctx.underflow |= mpfr_underflow_p(); \ CTX->ctx.overflow |= mpfr_overflow_p(); \ CTX->ctx.invalid |= mpfr_nanflag_p(); \ CTX->ctx.inexact |= mpfr_inexflag_p(); \ CTX->ctx.divzero |= mpfr_divby0_p(); \ if (CTX->ctx.traps) { \ if ((CTX->ctx.traps & TRAP_UNDERFLOW) && mpfr_underflow_p()) { \ GMPY_UNDERFLOW("underflow"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ if ((CTX->ctx.traps & TRAP_OVERFLOW) && mpfr_overflow_p()) { \ GMPY_OVERFLOW("overflow"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ if ((CTX->ctx.traps & TRAP_INEXACT) && mpfr_inexflag_p()) { \ GMPY_INEXACT("inexact result"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ if ((CTX->ctx.traps & TRAP_INVALID) && mpfr_nanflag_p()) { \ GMPY_INVALID("invalid operation"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ if ((CTX->ctx.traps & TRAP_DIVZERO) && mpfr_divby0_p()) { \ GMPY_DIVZERO("division by zero"); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ } #define GMPY_MPFR_CLEANUP(V, CTX) \ GMPY_MPFR_CHECK_RANGE(V, CTX); \ GMPY_MPFR_SUBNORMALIZE(V, CTX); \ GMPY_MPFR_EXCEPTIONS(V, CTX); #define GMPY_CHECK_ERANGE(V, CTX, MSG) \ CTX->ctx.erange |= mpfr_erangeflag_p(); \ if (CTX->ctx.traps) { \ if ((CTX->ctx.traps & TRAP_ERANGE) && mpfr_erangeflag_p()) { \ GMPY_ERANGE(MSG); \ Py_XDECREF((PyObject*)V); \ V = NULL; \ } \ } \ static void _GMPy_MPFR_Cleanup(MPFR_Object **v, CTXT_Object *ctext); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpfr_misc.c0000664000175000017500000005216213444071152016706 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpfr_misc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_function_f2q, "f2q(x,[err]) -> mpq\n\n" "Return the 'best' mpq approximating x to within relative error 'err'.\n" "Default is the precision of x. Uses Stern-Brocot tree to find the\n" "'best' approximation. An 'mpz' is returned if the the denominator\n" "is 1. If 'err'<0, relative error is 2.0 ** err."); static PyObject * GMPy_Real_F2Q(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx, *tempy = NULL; PyObject *result; CHECK_CONTEXT(context); if (y) { if (!(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } } if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempy); return NULL; /* LCOV_EXCL_STOP */ } /* See gmpy2_convert_mpfr for stern_brocot(). */ result = stern_brocot(tempx, tempy, 0, 1, context); Py_DECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return result; } static PyObject * GMPy_Number_F2Q(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_REAL(x) && (!y || IS_REAL(y))) return GMPy_Real_F2Q(x, y, context); TYPE_ERROR("f2q() argument types not supported"); return NULL; } static PyObject * GMPy_Context_F2Q(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) < 1 || PyTuple_GET_SIZE(args) > 2) { TYPE_ERROR("f2q() requires 1 or 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { /* LCOV_EXCL_START */ context = (CTXT_Object*)self; /* LCOV_EXCL_STOP */ } else { CHECK_CONTEXT(context); } if (PyTuple_GET_SIZE(args) == 1) { return GMPy_Number_F2Q(PyTuple_GET_ITEM(args, 0), NULL, context); } else { return GMPy_Number_F2Q(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } } PyDoc_STRVAR(GMPy_doc_mpfr_free_cache, "free_cache()\n\n" "Free the internal cache of constants maintained by MPFR."); static PyObject * GMPy_MPFR_Free_Cache(PyObject *self, PyObject *args) { mpfr_free_cache(); Py_RETURN_NONE; } PyDoc_STRVAR(GMPy_doc_mpfr_can_round, "can_round(b, err, rnd1, rnd2, prec)\n\n" "Let b be an approximation to an unknown number x that is rounded\n" "according to rnd1. Assume the b has an error at most two to the power\n" "of E(b)-err where E(b) is the exponent of b. Then return true if x\n" "can be rounded correctly to prec bits with rounding mode rnd2."); static PyObject * GMPy_MPFR_Can_Round(PyObject *self, PyObject *args) { int rnd1, rnd2; long err, prec; PyObject *b; if (!PyArg_ParseTuple(args, "O!liil", &MPFR_Type, &b, &err, &rnd1, &rnd2, &prec)) { return NULL; } if (!(rnd1 == MPFR_RNDN || rnd1 == MPFR_RNDZ || rnd1 == MPFR_RNDU || rnd1 == MPFR_RNDD || rnd1 == MPFR_RNDA)) { VALUE_ERROR("invalid value for rounding mode"); return NULL; } if (!(rnd2 == MPFR_RNDN || rnd2 == MPFR_RNDZ || rnd2 == MPFR_RNDU || rnd2 == MPFR_RNDD || rnd2 == MPFR_RNDA)) { VALUE_ERROR("invalid value for rounding mode"); return NULL; } if (prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) { VALUE_ERROR("invalid value for precision"); return NULL; } if (mpfr_can_round(MPFR(b), err, rnd1, rnd2, prec)) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpfr_get_emin_min, "get_emin_min() -> integer\n\n" "Return the minimum possible exponent that can be set for 'mpfr'."); static PyObject * GMPy_MPFR_get_emin_min(PyObject *self, PyObject *args) { return PyIntOrLong_FromSsize_t((Py_ssize_t)mpfr_get_emin_min()); } PyDoc_STRVAR(GMPy_doc_mpfr_get_emax_max, "get_emax_max() -> integer\n\n" "Return the maximum possible exponent that can be set for 'mpfr'."); static PyObject * GMPy_MPFR_get_emax_max(PyObject *self, PyObject *args) { return PyIntOrLong_FromSsize_t((Py_ssize_t)mpfr_get_emax_max()); } PyDoc_STRVAR(GMPy_doc_mpfr_get_max_precision, "get_max_precision() -> integer\n\n" "Return the maximum bits of precision that can be used for calculations.\n" "Note: to allow extra precision for intermediate calculations, avoid\n" "setting precision close the maximum precision."); static PyObject * GMPy_MPFR_get_max_precision(PyObject *self, PyObject *args) { return PyIntOrLong_FromSsize_t((Py_ssize_t)MPFR_PREC_MAX); } PyDoc_STRVAR(GMPy_doc_mpfr_get_exp, "get_exp(mpfr) -> integer\n\n" "Return the exponent of an mpfr. Returns 0 for NaN or Infinity and\n" "sets the erange flag and will raise an exception if trap_erange\n" "is set."); static PyObject * GMPy_MPFR_get_exp(PyObject *self, PyObject *other) { PyObject *result = NULL; Py_ssize_t exp; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(MPFR_Check(other))) { TYPE_ERROR("get_exp() requires 'mpfr' argument"); return NULL; } if (mpfr_regular_p(MPFR(other))) { exp = (Py_ssize_t)mpfr_get_exp(MPFR(other)); result = PyIntOrLong_FromSsize_t(exp); } else if (mpfr_zero_p(MPFR(other))) { result = PyIntOrLong_FromSsize_t(0); } else { context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("Can not get exponent from NaN or Infinity."); } else { result = PyIntOrLong_FromSsize_t(0); } } return result; } PyDoc_STRVAR(GMPy_doc_mpfr_set_exp, "set_exp(mpfr, n) -> mpfr\n\n" "Set the exponent of an mpfr to n. If n is outside the range of\n" "valid exponents, set_exp() will set the erange flag and either\n" "return the original value or raise an exception if trap_erange\n" "is set."); static PyObject * GMPy_MPFR_set_exp(PyObject *self, PyObject *args) { MPFR_Object *result; PyObject *temp; mpfr_exp_t _oldemin, _oldemax, exp; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 2 || !MPFR_Check(PyTuple_GET_ITEM(args, 0)) || !PyIntOrLong_Check(PyTuple_GET_ITEM(args, 1))) { TYPE_ERROR("set_exp() requires 'mpfr', 'integer' arguments"); return NULL; } temp = PyTuple_GET_ITEM(args, 0); exp = (mpfr_exp_t)PyIntOrLong_AsLong(PyTuple_GET_ITEM(args, 1)); if (exp == -1 && PyErr_Occurred()) { VALUE_ERROR("exponent too large"); return NULL; } if (!(result = GMPy_MPFR_New(mpfr_get_prec(MPFR(temp)), context))) { return NULL; } _oldemin = mpfr_get_emin(); _oldemax = mpfr_get_emax(); mpfr_set_emin(context->ctx.emin); mpfr_set_emax(context->ctx.emax); mpfr_set(MPFR(result), MPFR(temp), GET_MPFR_ROUND(context)); result->rc = mpfr_set_exp(MPFR(result), exp); mpfr_set_emin(_oldemin); mpfr_set_emax(_oldemax); if (result->rc) { context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("new exponent is out-of-bounds"); Py_DECREF((PyObject*)result); return NULL; } } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpfr_set_sign, "set_sign(mpfr, bool) -> mpfr\n\n" "If 'bool' is True, then return an 'mpfr' with the sign bit set."); static PyObject * GMPy_MPFR_set_sign(PyObject *self, PyObject *args) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 2 || !MPFR_Check(PyTuple_GET_ITEM(args, 0)) || !PyIntOrLong_Check(PyTuple_GET_ITEM(args, 1))) { TYPE_ERROR("set_sign() requires 'mpfr', 'boolean' arguments"); return NULL; } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } result->rc = mpfr_setsign(MPFR(result), MPFR(PyTuple_GET_ITEM(args, 0)), PyObject_IsTrue(PyTuple_GET_ITEM(args, 1)), GET_MPFR_ROUND(context)); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpfr_copy_sign, "copy_sign(mpfr, mpfr) -> mpfr\n\n" "Return an 'mpfr' composed of the first argument with the sign of the\n" "second argument."); static PyObject * GMPy_MPFR_copy_sign(PyObject *self, PyObject *args) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 2 || !MPFR_Check(PyTuple_GET_ITEM(args, 0)) || !MPFR_Check(PyTuple_GET_ITEM(args, 1))) { TYPE_ERROR("copy_sign() requires 'mpfr', 'mpfr' arguments"); return NULL; } if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } result->rc = mpfr_copysign(MPFR(result), MPFR(PyTuple_GET_ITEM(args, 0)), MPFR(PyTuple_GET_ITEM(args, 1)), GET_MPFR_ROUND(context)); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpfr_set_nan, "nan() -> mpfr\n\n" "Return an 'mpfr' initialized to NaN (Not-A-Number)."); static PyObject * GMPy_MPFR_set_nan(PyObject *self, PyObject *other) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(0, context))) { mpfr_set_nan(result->f); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpfr_set_inf, "inf(n) -> mpfr\n\n" "Return an 'mpfr' initialized to Infinity with the same sign as n.\n" "If n is not given, +Infinity is returned."); static PyObject * GMPy_MPFR_set_inf(PyObject *self, PyObject *args) { MPFR_Object *result; long s = 1; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_Size(args) == 1) { s = c_long_From_Integer(PyTuple_GET_ITEM(args, 0)); if (s == -1 && PyErr_Occurred()) { return NULL; } } if ((result = GMPy_MPFR_New(0, context))) { mpfr_set_inf(result->f, s < 0 ? -1 : 1); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpfr_set_zero, "zero(n) -> mpfr\n\n" "Return an 'mpfr' inialized to 0.0 with the same sign as n.\n" "If n is not given, +0.0 is returned."); static PyObject * GMPy_MPFR_set_zero(PyObject *self, PyObject *args) { MPFR_Object *result; long s = 1; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_Size(args) == 1) { s = c_long_From_Integer(PyTuple_GET_ITEM(args, 0)); if (s == -1 && PyErr_Occurred()) { return NULL; } } if ((result = GMPy_MPFR_New(0, context))) { mpfr_set_zero(result->f, s < 0 ? -1 : 1); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_method_integer_ratio, "x.as_integer_ratio() -> (num, den)\n\n" "Return the exact rational equivalent of an mpfr. Value is a tuple\n" "for compatibility with Python's float.as_integer_ratio()."); /* Note: almost identical code exists in gmpy2_convert_mpfr.c as the * function GMPy_MPQ_From_MPFR. They should be refactored. */ static PyObject * GMPy_MPFR_Integer_Ratio_Method(PyObject *self, PyObject *args) { MPZ_Object *num, *den; mpfr_exp_t temp, twocount; PyObject *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (mpfr_nan_p(MPFR(self))) { VALUE_ERROR("Cannot pass NaN to mpfr.as_integer_ratio."); return NULL; } if (mpfr_inf_p(MPFR(self))) { OVERFLOW_ERROR("Cannot pass Infinity to mpfr.as_integer_ratio."); return NULL; } num = GMPy_MPZ_New(context); den = GMPy_MPZ_New(context); if (!num || !den) { Py_XDECREF((PyObject*)num); Py_XDECREF((PyObject*)den); return NULL; } if (mpfr_zero_p(MPFR(self))) { mpz_set_ui(num->z, 0); mpz_set_ui(den->z, 1); } else { temp = mpfr_get_z_2exp(num->z, MPFR(self)); twocount = (mpfr_exp_t)mpz_scan1(num->z, 0); if (twocount) { temp += twocount; mpz_div_2exp(num->z, num->z, twocount); } mpz_set_ui(den->z, 1); if (temp > 0) mpz_mul_2exp(num->z, num->z, temp); else if (temp < 0) mpz_mul_2exp(den->z, den->z, -temp); } result = Py_BuildValue("(NN)", (PyObject*)num, (PyObject*)den); if (!result) { Py_DECREF((PyObject*)num); Py_DECREF((PyObject*)den); } return result; } PyDoc_STRVAR(GMPy_doc_method_mantissa_exp, "x.as_mantissa_exp() -> (mantissa,exponent)\n\n" "Return the mantissa and exponent of an mpfr."); static PyObject * GMPy_MPFR_Mantissa_Exp_Method(PyObject *self, PyObject *args) { MPZ_Object *mantissa , *exponent; mpfr_exp_t temp; PyObject *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (mpfr_nan_p(MPFR(self))) { VALUE_ERROR("Cannot pass NaN to mpfr.as_mantissa_exp."); return NULL; } if (mpfr_inf_p(MPFR(self))) { OVERFLOW_ERROR("Cannot pass Infinity to mpfr.as_mantissa_exp."); return NULL; } mantissa = GMPy_MPZ_New(context); exponent = GMPy_MPZ_New(context); if (!mantissa || !exponent) { Py_XDECREF((PyObject*)mantissa); Py_XDECREF((PyObject*)exponent); return NULL; } if (mpfr_zero_p(MPFR(self))) { mpz_set_ui(mantissa->z, 0); mpz_set_ui(exponent->z, 1); } else { temp = mpfr_get_z_2exp(mantissa->z, MPFR(self)); mpz_set_si(exponent->z, temp); } result = Py_BuildValue("(NN)", (PyObject*)mantissa, (PyObject*)exponent); if (!result) { Py_DECREF((PyObject*)mantissa); Py_DECREF((PyObject*)exponent); } return result; } PyDoc_STRVAR(GMPy_doc_method_simple_fraction, "x.as_simple_fraction([precision=0]) -> mpq\n\n" "Return a simple rational approximation to x. The result will be\n" "accurate to 'precision' bits. If 'precision' is 0, the precision\n" "of 'x' will be used."); static PyObject * GMPy_MPFR_Simple_Fraction_Method(PyObject *self, PyObject *args, PyObject *keywds) { mpfr_prec_t prec = 0; static char *kwlist[] = {"precision", NULL}; CTXT_Object *context = NULL; if (!PyArg_ParseTupleAndKeywords(args, keywds, "|l", kwlist, &prec)) { return NULL; } return (PyObject*)stern_brocot((MPFR_Object*)self, 0, prec, 0, context); } /* Implement the .precision attribute of an mpfr. */ static PyObject * GMPy_MPFR_GetPrec_Attrib(MPFR_Object *self, void *closure) { return PyIntOrLong_FromSsize_t((Py_ssize_t)mpfr_get_prec(self->f)); } /* Implement the .rc attribute of an mpfr. */ static PyObject * GMPy_MPFR_GetRc_Attrib(MPFR_Object *self, void *closure) { return PyIntOrLong_FromLong((long)self->rc); } /* Implement the .imag attribute of an mpfr. */ static PyObject * GMPy_MPFR_GetImag_Attrib(MPFR_Object *self, void *closure) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(0, context))) mpfr_set_zero(result->f, 1); return (PyObject*)result; } /* Implement the .real attribute of an mpfr. */ static PyObject * GMPy_MPFR_GetReal_Attrib(MPFR_Object *self, void *closure) { Py_INCREF((PyObject*)self); return (PyObject*)self; } /* Implement the nb_bool slot. */ static int GMPy_MPFR_NonZero_Slot(MPFR_Object *self) { return !mpfr_zero_p(self->f); } PyDoc_STRVAR(GMPy_doc_function_check_range, "check_range(x) -> mpfr\n\n" "Return a new 'mpfr' with exponent that lies within the current range\n" "of emin and emax."); PyDoc_STRVAR(GMPy_doc_context_check_range, "context.check_range(x) -> mpfr\n\n" "Return a new 'mpfr' with exponent that lies within the range of emin\n" "and emax specified by context."); static PyObject * GMPy_MPFR_CheckRange(PyObject *x, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(mpfr_get_prec(MPFR(x)), context))) { mpfr_set(result->f, MPFR(x), GET_MPFR_ROUND(context)); mpfr_clear_flags(); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } static PyObject * GMPy_Number_CheckRange(PyObject *x, CTXT_Object *context) { if (MPFR_Check(x)) return GMPy_MPFR_CheckRange(x, context); TYPE_ERROR("check_range() argument types not supported"); return NULL; } static PyObject * GMPy_Context_CheckRange(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_CheckRange(other, context); } PyDoc_STRVAR(GMPy_doc_mpfr_sizeof_method, "x.__sizeof__()\n\n" "Returns the amount of memory consumed by x."); static PyObject * GMPy_MPFR_SizeOf_Method(PyObject *self, PyObject *other) { return PyIntOrLong_FromSize_t(sizeof(MPFR_Object) + \ (((MPFR(self))->_mpfr_prec + mp_bits_per_limb - 1) / \ mp_bits_per_limb) * sizeof(mp_limb_t)); } PyDoc_STRVAR(GMPy_doc_method_round10, "__round__(x[, n = 0]) -> mpfr\n\n" "Return x rounded to n decimal digits before (n < 0) or after (n > 0)\n" "the decimal point. Rounds to an integer if n is not specified."); static PyObject * GMPy_MPFR_Method_Round10(PyObject *self, PyObject *args) { long digits = 0; mpz_t temp; MPFR_Object *resultf = 0; MPZ_Object *resultz; CTXT_Object *context = NULL; CHECK_CONTEXT(context); /* If the size of args is 0, we just return an mpz. */ if (PyTuple_GET_SIZE(args) == 0) { if ((resultz = GMPy_MPZ_New(context))) { if (mpfr_nan_p(MPFR(self))) { Py_DECREF((PyObject*)resultz); VALUE_ERROR("'mpz' does not support NaN"); return NULL; } if (mpfr_inf_p(MPFR(self))) { Py_DECREF((PyObject*)resultz); OVERFLOW_ERROR("'mpz' does not support Infinity"); return NULL; } /* return code is ignored */ mpfr_get_z(resultz->z, MPFR(self), MPFR_RNDN); } return (PyObject*)resultz; } /* Now we need to return an mpfr, so handle the simple cases. */ if (!mpfr_regular_p(MPFR(self))) { Py_INCREF(self); return self; } if (PyTuple_GET_SIZE(args) > 1) { TYPE_ERROR("__round__() requires 0 or 1 argument"); return NULL; } if (PyTuple_GET_SIZE(args) == 1) { digits = PyIntOrLong_AsLong(PyTuple_GET_ITEM(args, 0)); if (digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } } /* TODO: better error analysis, or else convert the mpfr to an exact * fraction, round the fraction, and then convert back to an mpfr. */ if (!(resultf = GMPy_MPFR_New(mpfr_get_prec(MPFR(self))+100, context))) { return NULL; } mpz_init(temp); mpz_ui_pow_ui(temp, 10, digits > 0 ? digits : -digits); if (digits >= 0) { mpfr_mul_z(resultf->f, MPFR(self), temp, MPFR_RNDN); } else { mpfr_div_z(resultf->f, MPFR(self), temp, MPFR_RNDN); } mpfr_rint(resultf->f, resultf->f, MPFR_RNDN); if (digits >= 0) { mpfr_div_z(resultf->f, resultf->f, temp, MPFR_RNDN); } else { mpfr_mul_z(resultf->f, resultf->f, temp, MPFR_RNDN); } mpfr_prec_round(resultf->f, mpfr_get_prec(MPFR(self)), MPFR_RNDN); mpz_clear(temp); return((PyObject*)resultf); } gmpy2-2.1.0b3/src/gmpy2_mpfr_misc.h0000664000175000017500000000777613444071152016726 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpfr_misc.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPFR_MISC_H #define GMPY_MPFR_MISC_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Real_F2Q(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPFR_Free_Cache(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_Can_Round(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_get_emax_max(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_get_max_precision(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_get_exp(PyObject *self, PyObject *other); static PyObject * GMPy_MPFR_set_exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_set_sign(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_copy_sign(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_Integer_Ratio_Method(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_Mantissa_Exp_Method(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_Simple_Fraction_Method(PyObject *self, PyObject *args, PyObject *keywds); static PyObject * GMPy_MPFR_set_nan(PyObject *self, PyObject *other); static PyObject * GMPy_MPFR_set_inf(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_set_zero(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_GetPrec_Attrib(MPFR_Object *self, void *closure); static PyObject * GMPy_MPFR_GetRc_Attrib(MPFR_Object *self, void *closure); static PyObject * GMPy_MPFR_GetImag_Attrib(MPFR_Object *self, void *closure); static PyObject * GMPy_MPFR_GetReal_Attrib(MPFR_Object *self, void *closure); static int GMPy_MPFR_NonZero_Slot(MPFR_Object *self); static PyObject * GMPy_MPFR_SizeOf_Method(PyObject *self, PyObject *other); static PyObject * GMPy_MPFR_CheckRange(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_CheckRange(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_CheckRange(PyObject *self, PyObject *other); static PyObject * GMPy_MPFR_Method_Round10(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpmath.c0000664000175000017500000003114413425752764016230 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpmath.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Internal helper function for mpmath. */ static PyObject * mpmath_build_mpf(long sign, MPZ_Object *man, PyObject *exp, mp_bitcnt_t bc) { PyObject *tup, *tsign, *tbc; if (!(tup = PyTuple_New(4))) { Py_DECREF((PyObject*)man); Py_DECREF(exp); return NULL; } if (!(tsign = PyIntOrLong_FromLong(sign))) { Py_DECREF((PyObject*)man); Py_DECREF(exp); Py_DECREF(tup); return NULL; } if (!(tbc = PyIntOrLong_FromMpBitCnt(bc))) { Py_DECREF((PyObject*)man); Py_DECREF(exp); Py_DECREF(tup); Py_DECREF(tsign); return NULL; } PyTuple_SET_ITEM(tup, 0, tsign); PyTuple_SET_ITEM(tup, 1, (PyObject*)man); PyTuple_SET_ITEM(tup, 2, (exp)?exp:PyIntOrLong_FromLong(0)); PyTuple_SET_ITEM(tup, 3, tbc); return tup; } PyDoc_STRVAR(doc_mpmath_normalizeg, "_mpmath_normalize(...): helper function for mpmath."); static PyObject * Pympz_mpmath_normalize(PyObject *self, PyObject *args) { long sign = 0; mp_bitcnt_t zbits, bc = 0, prec = 0, shift; long carry = 0; PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0, *rndstr = 0; MPZ_Object *man = 0, *upper = 0, *lower = 0; char rnd = 0; int err1, err2, err3; if (PyTuple_GET_SIZE(args) == 6) { /* Need better error-checking here. Under Python 3.0, overflow into C-long is possible. */ sign = GMPy_Integer_AsLongAndError(PyTuple_GET_ITEM(args, 0), &err1); man = (MPZ_Object*)PyTuple_GET_ITEM(args, 1); exp = PyTuple_GET_ITEM(args, 2); bc = GMPy_Integer_AsMpBitCntAndError(PyTuple_GET_ITEM(args, 3), &err2); prec = GMPy_Integer_AsMpBitCntAndError(PyTuple_GET_ITEM(args, 4), &err3); rndstr = PyTuple_GET_ITEM(args, 5); if (err1 || err2 || err3) { TYPE_ERROR("arguments long, MPZ_Object*, PyObject*, long, long, char needed"); return NULL; } } else { TYPE_ERROR("6 arguments required"); return NULL; } if (!MPZ_Check(man)) { /* Try to convert to an mpz... */ if (!(man = GMPy_MPZ_From_Integer((PyObject*)man, NULL))) { TYPE_ERROR("argument is not an mpz"); return NULL; } } /* If rndstr really is a string, extract the first character. */ if (Py2or3String_Check(rndstr)) { rnd = Py2or3String_AsString(rndstr)[0]; } else { VALUE_ERROR("invalid rounding mode specified"); return NULL; } /* If the mantissa is 0, return the normalized representation. */ if (!mpz_sgn(man->z)) { Py_INCREF((PyObject*)man); return mpmath_build_mpf(0, man, 0, 0); } /* if bc <= prec and the number is odd return it */ if ((bc <= prec) && mpz_odd_p(man->z)) { Py_INCREF((PyObject*)man); Py_INCREF((PyObject*)exp); return mpmath_build_mpf(sign, man, exp, bc); } if (!(upper = GMPy_MPZ_New(NULL)) || !(lower = GMPy_MPZ_New(NULL))) { Py_XDECREF((PyObject*)upper); Py_XDECREF((PyObject*)lower); } if (bc > prec) { shift = bc - prec; switch (rnd) { case 'f': if(sign) { mpz_cdiv_q_2exp(upper->z, man->z, shift); } else { mpz_fdiv_q_2exp(upper->z, man->z, shift); } break; case 'c': if(sign) { mpz_fdiv_q_2exp(upper->z, man->z, shift); } else { mpz_cdiv_q_2exp(upper->z, man->z, shift); } break; case 'd': mpz_fdiv_q_2exp(upper->z, man->z, shift); break; case 'u': mpz_cdiv_q_2exp(upper->z, man->z, shift); break; case 'n': default: mpz_tdiv_r_2exp(lower->z, man->z, shift); mpz_tdiv_q_2exp(upper->z, man->z, shift); if (mpz_sgn(lower->z)) { /* lower is not 0 so it must have at least 1 bit set */ if (mpz_sizeinbase(lower->z, 2) == shift) { /* lower is >= 1/2 */ if (mpz_scan1(lower->z, 0) == shift-1) { /* lower is exactly 1/2 */ if (mpz_odd_p(upper->z)) carry = 1; } else { carry = 1; } } } if (carry) mpz_add_ui(upper->z, upper->z, 1); } if (!(tmp = PyIntOrLong_FromMpBitCnt(shift))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); return NULL; } if (!(newexp = PyNumber_Add(exp, tmp))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); return NULL; } Py_DECREF(tmp); bc = prec; } else { mpz_set(upper->z, man->z); newexp = exp; Py_INCREF(newexp); } /* Strip trailing 0 bits. */ if ((zbits = mpz_scan1(upper->z, 0))) mpz_tdiv_q_2exp(upper->z, upper->z, zbits); if (!(tmp = PyIntOrLong_FromMpBitCnt(zbits))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(newexp); return NULL; } if (!(newexp2 = PyNumber_Add(newexp, tmp))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); Py_DECREF(newexp); return NULL; } Py_DECREF(newexp); Py_DECREF(tmp); bc -= zbits; /* Check if one less than a power of 2 was rounded up. */ if (!mpz_cmp_ui(upper->z, 1)) bc = 1; Py_DECREF((PyObject*)lower); return mpmath_build_mpf(sign, upper, newexp2, bc); } PyDoc_STRVAR(doc_mpmath_createg, "_mpmath_create(...): helper function for mpmath."); static PyObject * Pympz_mpmath_create(PyObject *self, PyObject *args) { long sign; mp_bitcnt_t zbits, bc = 0, prec = 0, shift; long carry = 0; PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0; MPZ_Object *man = 0, *upper = 0, *lower = 0; int error; const char *rnd = "f"; if (PyTuple_GET_SIZE(args) < 2) { TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments"); return NULL; } switch (PyTuple_GET_SIZE(args)) { case 4: rnd = Py2or3String_AsString(PyTuple_GET_ITEM(args, 3)); case 3: prec = GMPy_Integer_AsMpBitCntAndError(PyTuple_GET_ITEM(args, 2), &error); if (error) return NULL; case 2: exp = PyTuple_GET_ITEM(args, 1); case 1: man = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); if (!man) { TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments"); return NULL; } } /* If the mantissa is 0, return the normalized representation. */ if (!mpz_sgn(man->z)) { return mpmath_build_mpf(0, man, 0, 0); } upper = GMPy_MPZ_New(NULL); lower = GMPy_MPZ_New(NULL); if (!upper || !lower) { Py_DECREF((PyObject*)man); Py_XDECREF((PyObject*)upper); Py_XDECREF((PyObject*)lower); return NULL; } /* Extract sign, make man positive, and set bit count */ sign = (mpz_sgn(man->z) == -1); mpz_abs(upper->z, man->z); bc = mpz_sizeinbase(upper->z, 2); if (!prec) { prec = bc; } if (bc > prec) { shift = bc - prec; switch (rnd[0]) { case 'f': if (sign) { mpz_cdiv_q_2exp(upper->z, upper->z, shift); } else { mpz_fdiv_q_2exp(upper->z, upper->z, shift); } break; case 'c': if (sign) { mpz_fdiv_q_2exp(upper->z, upper->z, shift); } else { mpz_cdiv_q_2exp(upper->z, upper->z, shift); } break; case 'd': mpz_fdiv_q_2exp(upper->z, upper->z, shift); break; case 'u': mpz_cdiv_q_2exp(upper->z, upper->z, shift); break; case 'n': default: mpz_tdiv_r_2exp(lower->z, upper->z, shift); mpz_tdiv_q_2exp(upper->z, upper->z, shift); if (mpz_sgn(lower->z)) { /* lower is not 0 so it must have at least 1 bit set */ if (mpz_sizeinbase(lower->z, 2)==shift) { /* lower is >= 1/2 */ if (mpz_scan1(lower->z, 0)==shift-1) { /* lower is exactly 1/2 */ if (mpz_odd_p(upper->z)) carry = 1; } else { carry = 1; } } } if (carry) { mpz_add_ui(upper->z, upper->z, 1); } } if (!(tmp = PyIntOrLong_FromMpBitCnt(shift))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); return NULL; } if (!(newexp = PyNumber_Add(exp, tmp))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); return NULL; } Py_DECREF(tmp); bc = prec; } else { newexp = exp; Py_INCREF(newexp); } /* Strip trailing 0 bits. */ if ((zbits = mpz_scan1(upper->z, 0))) mpz_tdiv_q_2exp(upper->z, upper->z, zbits); if (!(tmp = PyIntOrLong_FromMpBitCnt(zbits))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(newexp); return NULL; } if (!(newexp2 = PyNumber_Add(newexp, tmp))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); Py_DECREF(newexp); return NULL; } Py_DECREF(newexp); Py_DECREF(tmp); bc -= zbits; /* Check if one less than a power of 2 was rounded up. */ if (!mpz_cmp_ui(upper->z, 1)) bc = 1; Py_DECREF((PyObject*)lower); Py_DECREF((PyObject*)man); return mpmath_build_mpf(sign, upper, newexp2, bc); } gmpy2-2.1.0b3/src/gmpy2_mpq.c0000664000175000017500000003004013444071152015513 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpq.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_mpq, "mpq() -> mpq(0,1)\n\n" " If no argument is given, return mpq(0,1).\n\n" "mpq(n) -> mpq\n\n" " Return an 'mpq' object with a numeric value n. Fraction values\n" " are converted exactly.\n\n" "mpq(n,m) -> mpq\n\n" " Return an 'mpq' object with a numeric value n/m.\n\n" "mpq(s[, base=10]) -> mpq\n\n" " Return an 'mpq' object from a string s made up of digits in\n" " the given base. s may be made up of two numbers in the same\n" " base separated by a '/' character.\n"); /* Since `gmpy2.mpq` is now a type and no longer a factory function, see * gmpy2_cache.c/GMPy_MPQ_NewInit for details on creation. */ #ifdef PY3 static PyNumberMethods mpq_number_methods = { (binaryfunc) GMPy_MPQ_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPQ_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPQ_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPQ_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPQ_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPQ_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPQ_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPQ_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPQ_NonZero_Slot, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ (unaryfunc) GMPy_MPQ_Int_Slot, /* nb_int */ 0, /* nb_reserved */ (unaryfunc) GMPy_MPQ_Float_Slot, /* nb_float */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply */ 0, /* nb_inplace_remainder */ 0, /* nb_inplace_power */ 0, /* nb_inplace_lshift */ 0, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPQ_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPQ_TrueDiv_Slot, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ 0, /* nb_index */ }; #else static PyNumberMethods mpq_number_methods = { (binaryfunc) GMPy_MPQ_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPQ_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPQ_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPQ_TrueDiv_Slot, /* nb_divide */ (binaryfunc) GMPy_MPQ_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPQ_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPQ_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPQ_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPQ_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPQ_NonZero_Slot, /* nb_bool */ 0, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ 0, /* nb_coerce */ (unaryfunc) GMPy_MPQ_Int_Slot, /* nb_int */ (unaryfunc) GMPy_MPQ_Long_Slot, /* nb_long */ (unaryfunc) GMPy_MPQ_Float_Slot, /* nb_float */ 0, /* nb_oct */ 0, /* nb_hex */ 0, /* nb_inplace_add; */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply */ 0, /* nb_inplace_divide */ 0, /* nb_inplace_remainder */ 0, /* nb_inplace_power */ 0, /* nb_inplace_lshift */ 0, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPQ_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPQ_TrueDiv_Slot, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ }; #endif static PyGetSetDef GMPy_MPQ_getseters[] = { { "numerator", (getter)GMPy_MPQ_Attrib_GetNumer, NULL, "the numerator of a rational number in lowest terms", NULL }, { "denominator", (getter)GMPy_MPQ_Attrib_GetDenom, NULL, "the denominator of a rational number in lowest terms", NULL }, { "real", (getter)GMPy_MPQ_Attrib_GetReal, NULL, "the real part of a complex number", NULL }, { "imag", (getter)GMPy_MPQ_Attrib_GetImag, NULL, "the imaginary part of a complex number", NULL }, {NULL} }; static PyMethodDef GMPy_MPQ_methods [] = { { "__ceil__", GMPy_MPQ_Method_Ceil, METH_NOARGS, GMPy_doc_mpq_method_ceil }, { "__floor__", GMPy_MPQ_Method_Floor, METH_NOARGS, GMPy_doc_mpq_method_floor }, { "__round__", GMPy_MPQ_Method_Round, METH_VARARGS, GMPy_doc_mpq_method_round }, { "__sizeof__", GMPy_MPQ_Method_Sizeof, METH_NOARGS, GMPy_doc_mpq_method_sizeof }, { "__trunc__", GMPy_MPQ_Method_Trunc, METH_NOARGS, GMPy_doc_mpq_method_trunc }, { "conjugate", GMPy_MP_Method_Conjugate, METH_NOARGS, GMPy_doc_mp_method_conjugate }, { "digits", GMPy_MPQ_Digits_Method, METH_VARARGS, GMPy_doc_mpq_digits_method }, { NULL, NULL, 1 } }; static PyTypeObject MPQ_Type = { /* PyObject_HEAD_INIT(&PyType_Type) */ #ifdef PY3 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "mpq", /* tp_name */ sizeof(MPQ_Object), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor) GMPy_MPQ_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_MPQ_Repr_Slot, /* tp_repr */ &mpq_number_methods, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc) GMPy_MPQ_Hash_Slot, /* tp_hash */ 0, /* tp_call */ (reprfunc) GMPy_MPQ_Str_Slot, /* tp_str */ (getattrofunc) 0, /* tp_getattro */ (setattrofunc) 0, /* tp_setattro */ 0, /* tp_as_buffer */ #ifdef PY3 Py_TPFLAGS_DEFAULT, /* tp_flags */ #else Py_TPFLAGS_HAVE_RICHCOMPARE | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ #endif GMPy_doc_mpq, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)&GMPy_RichCompare_Slot, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ GMPy_MPQ_methods, /* tp_methods */ 0, /* tp_members */ GMPy_MPQ_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ GMPy_MPQ_NewInit, /* tp_new */ 0, /* tp_free */ }; gmpy2-2.1.0b3/src/gmpy2_mpq.h0000664000175000017500000000435613425753021015534 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpq.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPQ_H #define GMPY_MPQ_H #ifdef __cplusplus extern "C" { #endif static PyTypeObject MPQ_Type; #define MPQ_Check(v) (((PyObject*)v)->ob_type == &MPQ_Type) #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpq_misc.c0000664000175000017500000002643213473131605016542 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpq_misc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static PyObject * GMPy_MPQ_Attrib_GetNumer(MPQ_Object *self, void *closure) { MPZ_Object *result; CTXT_Object *context = NULL; if ((result = GMPy_MPZ_New(context))) mpz_set(result->z, mpq_numref(self->q)); return (PyObject*)result; } static PyObject * GMPy_MPQ_Attrib_GetReal(MPQ_Object *self, void *closure) { Py_INCREF((PyObject*)self); return (PyObject*)self; } static PyObject * GMPy_MPQ_Attrib_GetDenom(MPQ_Object *self, void *closure) { MPZ_Object *result; CTXT_Object *context = NULL; if ((result = GMPy_MPZ_New(context))) mpz_set(result->z, mpq_denref(self->q)); return (PyObject*)result; } static PyObject * GMPy_MPQ_Attrib_GetImag(MPQ_Object *self, void *closure) { MPZ_Object *result; CTXT_Object *context = NULL; if ((result = GMPy_MPZ_New(context))) mpz_set_ui(result->z, 0); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpq_function_numer, "numer(x) -> mpz\n\n" "Return the numerator of x."); static PyObject * GMPy_MPQ_Function_Numer(PyObject *self, PyObject *other) { MPZ_Object *result; MPQ_Object *tempq; CTXT_Object *context = NULL; if (!(result = (MPZ_Object*)GMPy_MPZ_New(context))) return NULL; if (!(tempq = GMPy_MPQ_From_Rational(other, context))) { Py_DECREF((PyObject*)result); return NULL; } mpz_set(result->z, mpq_numref(tempq->q)); Py_DECREF((PyObject*)tempq); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpq_function_denom, "denom(x) -> mpz\n\n" "Return the denominator of x."); static PyObject * GMPy_MPQ_Function_Denom(PyObject *self, PyObject *other) { MPZ_Object *result; MPQ_Object *tempq; CTXT_Object *context = NULL; if (!(result = (MPZ_Object*)GMPy_MPZ_New(context))) return NULL; if (!(tempq = GMPy_MPQ_From_Rational(other, context))) { Py_DECREF((PyObject*)result); return NULL; } mpz_set(result->z, mpq_denref(tempq->q)); Py_DECREF((PyObject*)tempq); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_qdiv, "qdiv(x[, y=1]) -> number\n\n" "Return x/y as 'mpz' if possible, or as 'mpq' if x is not exactly\n" "divisible by y."); static PyObject * GMPy_MPQ_Function_Qdiv(PyObject *self, PyObject *args) { Py_ssize_t argc; PyObject *result = NULL, *x, *y; MPQ_Object *tempx = NULL, *tempy = NULL, *tempr = NULL; CTXT_Object *context = NULL; CHECK_CONTEXT(context); /* Validate the argument(s). */ /* If there is only one argument, it should be either an integer or * rational type. If it is an integer, then immediately return an mpz(). * If it is a rational type, convert it to an mpq and check the denominator. */ argc = PyTuple_GET_SIZE(args); if (argc == 1) { x = PyTuple_GET_ITEM(args, 0); if (!IS_RATIONAL(x)) { goto arg_error; } if (IS_INTEGER(x)) { return (PyObject*)GMPy_MPZ_From_Integer(x, context); } if (!(tempx = GMPy_MPQ_From_Rational(x, context))) { return NULL; } if (mpz_cmp_ui(mpq_denref(tempx->q), 1) == 0) { if ((result = (PyObject*)GMPy_MPZ_New(context))) { mpz_set(MPZ(result), mpq_numref(tempx->q)); } Py_DECREF((PyObject*)tempx); return result; } else { return (PyObject*)tempx; } } /* If there are two rational arguments, just convert them both to mpq, * divide, and then check the denominator. */ if (argc == 2) { x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (!IS_RATIONAL(x) || !IS_RATIONAL(y)) { goto arg_error; } if (!(tempx = GMPy_MPQ_From_Rational(x, context)) || !(tempy = GMPy_MPQ_From_Rational(y, context))) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; } if (mpq_sgn(tempy->q) == 0) { Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); ZERO_ERROR("qdiv() division by zero"); return NULL; } /* tempr contains the result of the division. */ if (!(tempr = GMPy_MPQ_New(context))) { Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return NULL; } mpq_div(tempr->q, tempx->q, tempy->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); if (mpz_cmp_ui(mpq_denref(tempr->q), 1) == 0) { if ((result = (PyObject*)GMPy_MPZ_New(context))) { mpz_set(MPZ(result), mpq_numref(tempr->q)); } Py_DECREF((PyObject*)tempr); return result; } else { return (PyObject*)tempr; }; } arg_error: TYPE_ERROR("qdiv() requires 1 or 2 integer or rational arguments"); return NULL; } PyDoc_STRVAR(GMPy_doc_mpq_method_floor, "Return greatest integer less than or equal to an mpq."); static PyObject * GMPy_MPQ_Method_Floor(PyObject *self, PyObject *other) { MPZ_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPZ_New(context))) { mpz_fdiv_q(result->z, mpq_numref(MPQ(self)), mpq_denref(MPQ(self))); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpq_method_ceil, "Return least integer greater than or equal to an mpq."); static PyObject * GMPy_MPQ_Method_Ceil(PyObject *self, PyObject *other) { MPZ_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPZ_New(context))) { mpz_cdiv_q(result->z, mpq_numref(MPQ(self)), mpq_denref(MPQ(self))); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpq_method_trunc, "Return integer portion of an mpq."); static PyObject * GMPy_MPQ_Method_Trunc(PyObject *self, PyObject *other) { MPZ_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPZ_New(context))) { mpz_tdiv_q(result->z, mpq_numref(MPQ(self)), mpq_denref(MPQ(self))); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpq_method_round, "Round an mpq to power of 10."); static PyObject * GMPy_MPQ_Method_Round(PyObject *self, PyObject *args) { Py_ssize_t round_digits = 0; MPQ_Object *resultq; MPZ_Object *resultz; mpz_t temp, rem; CTXT_Object *context = NULL; CHECK_CONTEXT(context); /* If args is NULL or the size of args is 0, we just return an mpz. */ if (!args || PyTuple_GET_SIZE(args) == 0) { if (!(resultz = GMPy_MPZ_New(context))) { return NULL; } mpz_init(rem); mpz_fdiv_qr(resultz->z, rem, mpq_numref(MPQ(self)), mpq_denref(MPQ(self))); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, mpq_denref(MPQ(self))) > 0) { mpz_add_ui(resultz->z, resultz->z, 1); } else if (mpz_cmp(rem, mpq_denref(MPQ(self))) == 0) { if (mpz_odd_p(resultz->z)) { mpz_add_ui(resultz->z, resultz->z, 1); } } mpz_clear(rem); return (PyObject*)resultz; } if (PyTuple_GET_SIZE(args) > 1) { TYPE_ERROR("Too many arguments for __round__()"); return NULL; } if (PyTuple_GET_SIZE(args) == 1) { round_digits = PyIntOrLong_AsSsize_t(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } } if (!(resultq = GMPy_MPQ_New(context))) { return NULL; } mpz_init(temp); mpz_ui_pow_ui(temp, 10, round_digits > 0 ? round_digits : -round_digits); mpq_set(resultq->q, MPQ(self)); if (round_digits > 0) { mpz_mul(mpq_numref(resultq->q), mpq_numref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (MPZ_Object*)GMPy_MPQ_Method_Round((PyObject*)resultq, NULL))) { mpz_clear(temp); return NULL; } mpz_set(mpq_numref(resultq->q), resultz->z); Py_DECREF((PyObject*)resultz); mpz_set(mpq_denref(resultq->q), temp); mpz_clear(temp); mpq_canonicalize(resultq->q); } else { mpz_mul(mpq_denref(resultq->q), mpq_denref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (MPZ_Object*)GMPy_MPQ_Method_Round((PyObject*)resultq, NULL))) { mpz_clear(temp); return NULL; } mpq_set_ui(resultq->q, 0, 1); mpz_mul(mpq_numref(resultq->q), resultz->z, temp); Py_DECREF((PyObject*)resultz); mpz_clear(temp); mpq_canonicalize(resultq->q); } return (PyObject*)resultq; } static int GMPy_MPQ_NonZero_Slot(MPQ_Object *self) { return mpq_sgn(self->q) != 0; } PyDoc_STRVAR(GMPy_doc_mpq_method_sizeof, "x.__sizeof__()\n\n" "Returns the amount of memory consumed by x. Note: deleted mpq objects\n" "are reused and may or may not be resized when a new value is assigned."); static PyObject * GMPy_MPQ_Method_Sizeof(PyObject *self, PyObject *other) { return PyIntOrLong_FromSize_t(sizeof(MPQ_Object) + \ (mpq_numref(MPQ(self))->_mp_alloc * sizeof(mp_limb_t)) + \ (mpq_denref(MPQ(self))->_mp_alloc * sizeof(mp_limb_t))); } gmpy2-2.1.0b3/src/gmpy2_mpq_misc.h0000664000175000017500000000602213444071152016536 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpq_misc.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPQ_MISC_H #define GMPY_MPQ_MISC_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPQ_Attrib_GetNumer(MPQ_Object *self, void *closure); static PyObject * GMPy_MPQ_Attrib_GetDenom(MPQ_Object *self, void *closure); static PyObject * GMPy_MPQ_Attrib_GetReal(MPQ_Object *self, void *closure); static PyObject * GMPy_MPQ_Attrib_GetImag(MPQ_Object *self, void *closure); static PyObject * GMPy_MPQ_Function_Numer(PyObject *self, PyObject *other); static PyObject * GMPy_MPQ_Function_Denom(PyObject *self, PyObject *other); static PyObject * GMPy_MPQ_Function_Qdiv(PyObject *self, PyObject *args); static PyObject * GMPy_MPQ_Method_Ceil(PyObject *self, PyObject *other); static PyObject * GMPy_MPQ_Method_Floor(PyObject *self, PyObject *other); static PyObject * GMPy_MPQ_Method_Trunc(PyObject *self, PyObject *other); static PyObject * GMPy_MPQ_Method_Round(PyObject *self, PyObject *other); static int GMPy_MPQ_NonZero_Slot(MPQ_Object *x); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpz.c0000664000175000017500000003317313444071152015536 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_mpz, "mpz() -> mpz(0)\n\n" " If no argument is given, return mpz(0).\n\n" "mpz(n) -> mpz\n\n" " Return an 'mpz' object with a numeric value 'n' (truncating n\n" " to its integer part if it's a Fraction, 'mpq', float or 'mpfr').\n\n" "mpz(s[, base=0]):\n\n" " Return an 'mpz' object from a string 's' made of digits in the\n" " given base. If base=0, binary, octal, or hex Python strings\n" " are recognized by leading 0b, 0o, or 0x characters, otherwise\n" " the string is assumed to be decimal. Values for base can range\n" " between 2 and 62."); /* Since `gmpy2.mpz` is now a type and no longer a factory function, see * gmpy2_cache.c/GMPy_MPZ_NewInit for details on creation. */ #ifdef PY3 static PyNumberMethods GMPy_MPZ_number_methods = { (binaryfunc) GMPy_MPZ_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPZ_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPZ_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPZ_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPZ_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPZ_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPZ_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPZ_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPZ_NonZero_Slot, /* nb_bool */ (unaryfunc) GMPy_MPZ_Invert_Slot, /* nb_invert */ (binaryfunc) GMPy_MPZ_Lshift_Slot, /* nb_lshift */ (binaryfunc) GMPy_MPZ_Rshift_Slot, /* nb_rshift */ (binaryfunc) GMPy_MPZ_And_Slot, /* nb_and */ (binaryfunc) GMPy_MPZ_Xor_Slot, /* nb_xor */ (binaryfunc) GMPy_MPZ_Ior_Slot, /* nb_or */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_int */ 0, /* nb_reserved */ (unaryfunc) GMPy_MPZ_Float_Slot, /* nb_float */ (binaryfunc) GMPy_MPZ_IAdd_Slot, /* nb_inplace_add */ (binaryfunc) GMPy_MPZ_ISub_Slot, /* nb_inplace_subtract */ (binaryfunc) GMPy_MPZ_IMul_Slot, /* nb_inplace_multiply */ (binaryfunc) GMPy_MPZ_IRem_Slot, /* nb_inplace_remainder */ (ternaryfunc) GMPy_MPZ_IPow_Slot, /* nb_inplace_power */ (binaryfunc) GMPy_MPZ_ILshift_Slot, /* nb_inplace_lshift */ (binaryfunc) GMPy_MPZ_IRshift_Slot, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPZ_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPZ_TrueDiv_Slot, /* nb_true_divide */ (binaryfunc) GMPy_MPZ_IFloorDiv_Slot, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_index */ }; #else static PyNumberMethods GMPy_MPZ_number_methods = { (binaryfunc) GMPy_MPZ_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPZ_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPZ_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPZ_Div2_Slot, /* nb_divide */ (binaryfunc) GMPy_MPZ_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPZ_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_MPZ_Minus_Slot, /* nb_negative */ (unaryfunc) GMPy_MPZ_Plus_Slot, /* nb_positive */ (unaryfunc) GMPy_MPZ_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_MPZ_NonZero_Slot, /* nb_bool */ (unaryfunc) GMPy_MPZ_Invert_Slot, /* nb_invert */ (binaryfunc) GMPy_MPZ_Lshift_Slot, /* nb_lshift */ (binaryfunc) GMPy_MPZ_Rshift_Slot, /* nb_rshift */ (binaryfunc) GMPy_MPZ_And_Slot, /* nb_and */ (binaryfunc) GMPy_MPZ_Xor_Slot, /* nb_xor */ (binaryfunc) GMPy_MPZ_Ior_Slot, /* nb_or */ 0, /* nb_coerce */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_int */ (unaryfunc) GMPy_MPZ_Long_Slot, /* nb_long */ (unaryfunc) GMPy_MPZ_Float_Slot, /* nb_float */ (unaryfunc) GMPy_MPZ_Oct_Slot, /* nb_oct */ (unaryfunc) GMPy_MPZ_Hex_Slot, /* nb_hex */ (binaryfunc) GMPy_MPZ_IAdd_Slot, /* nb_inplace_add */ (binaryfunc) GMPy_MPZ_ISub_Slot, /* nb_inplace_subtract */ (binaryfunc) GMPy_MPZ_IMul_Slot, /* nb_inplace_multiply */ 0, /* nb_inplace_divide */ (binaryfunc) GMPy_MPZ_IRem_Slot, /* nb_inplace_remainder */ (ternaryfunc) GMPy_MPZ_IPow_Slot, /* nb_inplace_power */ (binaryfunc) GMPy_MPZ_ILshift_Slot, /* nb_inplace_lshift */ (binaryfunc) GMPy_MPZ_IRshift_Slot, /* nb_inplace_rshift */ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ (binaryfunc) GMPy_MPZ_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPZ_TrueDiv_Slot, /* nb_true_divide */ (binaryfunc) GMPy_MPZ_IFloorDiv_Slot, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_index */ }; #endif static PyMappingMethods GMPy_MPZ_mapping_methods = { (lenfunc)GMPy_MPZ_Method_Length, (binaryfunc)GMPy_MPZ_Method_SubScript, NULL }; static PyGetSetDef GMPy_MPZ_getseters[] = { { "numerator", (getter)GMPy_MPZ_Attrib_GetNumer, NULL, "the numerator of a rational number in lowest terms", NULL }, { "denominator", (getter)GMPy_MPZ_Attrib_GetDenom, NULL, "the denominator of a rational number in lowest terms", NULL }, { "real", (getter)GMPy_MPZ_Attrib_GetReal, NULL, "the real part of a complex number", NULL }, { "imag", (getter)GMPy_MPZ_Attrib_GetImag, NULL, "the imaginary part of a complex number", NULL }, {NULL} }; static PyMethodDef GMPy_MPZ_methods [] = { { "__format__", GMPy_MPZ_Format, METH_VARARGS, GMPy_doc_mpz_format }, { "__ceil__", GMPy_MPZ_Method_Ceil, METH_NOARGS, GMPy_doc_mpz_method_ceil }, { "__floor__", GMPy_MPZ_Method_Floor, METH_NOARGS, GMPy_doc_mpz_method_floor }, { "__round__", GMPy_MPZ_Method_Round, METH_VARARGS, GMPy_doc_mpz_method_round }, { "__sizeof__", GMPy_MPZ_Method_SizeOf, METH_NOARGS, GMPy_doc_mpz_method_sizeof }, { "__trunc__", GMPy_MPZ_Method_Trunc, METH_NOARGS, GMPy_doc_mpz_method_trunc }, { "bit_clear", GMPy_MPZ_bit_clear_method, METH_O, doc_bit_clear_method }, { "bit_flip", GMPy_MPZ_bit_flip_method, METH_O, doc_bit_flip_method }, { "bit_length", GMPy_MPZ_bit_length_method, METH_NOARGS, doc_bit_length_method }, { "bit_scan0", GMPy_MPZ_bit_scan0_method, METH_VARARGS, doc_bit_scan0_method }, { "bit_scan1", GMPy_MPZ_bit_scan1_method, METH_VARARGS, doc_bit_scan1_method }, { "bit_set", GMPy_MPZ_bit_set_method, METH_O, doc_bit_set_method }, { "bit_test", GMPy_MPZ_bit_test_method, METH_O, doc_bit_test_method }, { "conjugate", GMPy_MP_Method_Conjugate, METH_NOARGS, GMPy_doc_mp_method_conjugate }, { "digits", GMPy_MPZ_Digits_Method, METH_VARARGS, GMPy_doc_mpz_digits_method }, { "is_congruent", GMPy_MPZ_Method_IsCongruent, METH_VARARGS, GMPy_doc_mpz_method_is_congruent }, { "is_divisible", GMPy_MPZ_Method_IsDivisible, METH_O, GMPy_doc_mpz_method_is_divisible }, { "is_even", GMPy_MPZ_Method_IsEven, METH_NOARGS, GMPy_doc_mpz_method_is_even }, { "is_odd", GMPy_MPZ_Method_IsOdd, METH_NOARGS, GMPy_doc_mpz_method_is_odd }, { "is_power", GMPy_MPZ_Method_IsPower, METH_NOARGS, GMPy_doc_mpz_method_is_power }, { "is_prime", GMPy_MPZ_Method_IsPrime, METH_VARARGS, GMPy_doc_mpz_method_is_prime }, { "is_square", GMPy_MPZ_Method_IsSquare, METH_NOARGS, GMPy_doc_mpz_method_is_square }, { "num_digits", GMPy_MPZ_Method_NumDigits, METH_VARARGS, GMPy_doc_mpz_method_num_digits }, { NULL, NULL, 1 } }; static PyTypeObject MPZ_Type = { /* PyObject_HEAD_INIT(&PyType_Type) */ #ifdef PY3 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "mpz", /* tp_name */ sizeof(MPZ_Object), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor) GMPy_MPZ_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_MPZ_Repr_Slot, /* tp_repr */ &GMPy_MPZ_number_methods, /* tp_as_number */ 0, /* tp_as_sequence */ &GMPy_MPZ_mapping_methods, /* tp_as_mapping */ (hashfunc) GMPy_MPZ_Hash_Slot, /* tp_hash */ 0, /* tp_call */ (reprfunc) GMPy_MPZ_Str_Slot, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ #ifdef PY3 Py_TPFLAGS_DEFAULT, /* tp_flags */ #else Py_TPFLAGS_HAVE_INDEX|Py_TPFLAGS_HAVE_RICHCOMPARE| \ Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_CLASS| \ Py_TPFLAGS_HAVE_INPLACEOPS, #endif GMPy_doc_mpz, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)&GMPy_RichCompare_Slot, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ GMPy_MPZ_methods, /* tp_methods */ 0, /* tp_members */ GMPy_MPZ_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ GMPy_MPZ_NewInit, /* tp_new */ 0, /* tp_free */ }; gmpy2-2.1.0b3/src/gmpy2_mpz.h0000664000175000017500000000443113425753122015541 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPZ_H #define GMPY_MPZ_H #ifdef __cplusplus extern "C" { #endif static PyTypeObject MPZ_Type; #define MPZ(obj) (((MPZ_Object*)(obj))->z) #define MPZ_Check(v) (((PyObject*)v)->ob_type == &MPZ_Type) #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpz_bitops.c0000664000175000017500000004546113452637224017130 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_bitops.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(doc_bit_length_method, "x.bit_length() -> int\n\n" "Return the number of significant bits in the radix-2\n" "representation of x. Note: mpz(0).bit_length() returns 0."); static PyObject * GMPy_MPZ_bit_length_method(PyObject *self, PyObject *other) { mp_bitcnt_t n = 0; if (mpz_size(MPZ(self))) n = mpz_sizeinbase(MPZ(self), 2); return PyIntOrLong_FromMpBitCnt(n); } PyDoc_STRVAR(doc_bit_length_function, "bit_length(x) -> int\n\n" "Return the number of significant bits in the radix-2\n" "representation of x. Note: bit_length(0) returns 0."); static PyObject * GMPy_MPZ_bit_length_function(PyObject *self, PyObject *other) { mp_bitcnt_t n = 0; MPZ_Object* tempx; if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("bit_length() requires 'mpz' argument"); return NULL; } if (mpz_size(MPZ(tempx))) n = mpz_sizeinbase(tempx->z, 2); Py_DECREF((PyObject*)tempx); return PyIntOrLong_FromMpBitCnt(n); } PyDoc_STRVAR(doc_bit_mask, "bit_mask(n) -> mpz\n\n" "Return an 'mpz' exactly n bits in length with all bits set.\n"); static PyObject * GMPy_MPZ_bit_mask(PyObject *self, PyObject *other) { mp_bitcnt_t n = 0; MPZ_Object* result; n = mp_bitcnt_t_From_Integer(other); if (n == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } if (!(result = GMPy_MPZ_New(NULL))) return NULL; mpz_set_ui(result->z, 1); mpz_mul_2exp(result->z, result->z, n); mpz_sub_ui(result->z, result->z, 1); return (PyObject*)result; } /* return scan0/scan1 for an mpz */ PyDoc_STRVAR(doc_bit_scan0_method, "x.bit_scan0(n=0) -> int\n\n" "Return the index of the first 0-bit of x with index >= n. n >= 0.\n" "If there are no more 0-bits in x at or above index n (which can\n" "only happen for x<0, assuming an infinitely long 2's complement\n" "format), then None is returned."); static PyObject * GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *args) { mp_bitcnt_t index, starting_bit = 0; if (PyTuple_GET_SIZE(args) == 1) { starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } } index = mpz_scan0(MPZ(self), starting_bit); if (index == (mp_bitcnt_t)(-1)) { Py_RETURN_NONE; } else { return PyIntOrLong_FromMpBitCnt(index); } } PyDoc_STRVAR(doc_bit_scan0_function, "bit_scan0(x, n=0) -> int\n\n" "Return the index of the first 0-bit of x with index >= n. n >= 0.\n" "If there are no more 0-bits in x at or above index n (which can\n" "only happen for x<0, assuming an infinitely long 2's complement\n" "format), then None is returned."); static PyObject * GMPy_MPZ_bit_scan0_function(PyObject *self, PyObject *args) { mp_bitcnt_t index, starting_bit = 0; MPZ_Object *tempx = NULL; if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_SIZE(args) > 2) { goto err; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { goto err; } if (PyTuple_GET_SIZE(args) == 2) { starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { goto err_index; } } index = mpz_scan0(tempx->z, starting_bit); Py_DECREF((PyObject*)tempx); if (index == (mp_bitcnt_t)(-1)) { Py_RETURN_NONE; } else { return PyIntOrLong_FromMpBitCnt(index); } err: TYPE_ERROR("bit_scan0() requires 'mpz',['int'] arguments"); err_index: Py_XDECREF((PyObject*)tempx); return NULL; } PyDoc_STRVAR(doc_bit_scan1_method, "x.bit_scan1(n=0) -> int\n\n" "Return the index of the first 1-bit of x with index >= n. n >= 0.\n" "If there are no more 1-bits in x at or above index n (which can\n" "only happen for x>=0, assuming an infinitely long 2's complement\n" "format), then None is returned."); static PyObject * GMPy_MPZ_bit_scan1_method(PyObject *self, PyObject *args) { mp_bitcnt_t index, starting_bit = 0; if (PyTuple_GET_SIZE(args) == 1) { starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } } index = mpz_scan1(MPZ(self), starting_bit); if (index == (mp_bitcnt_t)(-1)) { Py_RETURN_NONE; } else { return PyIntOrLong_FromMpBitCnt(index); } } PyDoc_STRVAR(doc_bit_scan1_function, "bit_scan1(x, n=0) -> int\n\n" "Return the index of the first 1-bit of x with index >= n. n >= 0.\n" "If there are no more 1-bits in x at or above index n (which can\n" "only happen for x>=0, assuming an infinitely long 2's complement\n" "format), then None is returned."); static PyObject * GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *args) { mp_bitcnt_t index, starting_bit = 0; MPZ_Object *tempx = NULL; if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_SIZE(args) > 2) { goto err; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { goto err; } if (PyTuple_GET_SIZE(args) == 2) { starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { goto err_index; } } index = mpz_scan1(tempx->z, starting_bit); Py_DECREF((PyObject*)tempx); if (index == (mp_bitcnt_t)(-1)) { Py_RETURN_NONE; } else { return PyIntOrLong_FromMpBitCnt(index); } err: TYPE_ERROR("bit_scan1() requires 'mpz',['int'] arguments"); err_index: Py_XDECREF((PyObject*)tempx); return NULL; } /* get & return one bit from an mpz */ PyDoc_STRVAR(doc_bit_test_function, "bit_test(x, n) -> bool\n\n" "Return the value of the n-th bit of x."); static PyObject * GMPy_MPZ_bit_test_function(PyObject *self, PyObject *args) { mp_bitcnt_t bit_index; int temp; MPZ_Object *tempx = NULL; if (PyTuple_GET_SIZE(args) != 2) { goto err; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { goto err; } bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { goto err_index; } temp = mpz_tstbit(tempx->z, bit_index); Py_DECREF((PyObject*)tempx); if (temp) Py_RETURN_TRUE; else Py_RETURN_FALSE; err: TYPE_ERROR("bit_test() requires 'mpz','int' arguments"); err_index: Py_XDECREF((PyObject*)tempx); return NULL; } PyDoc_STRVAR(doc_bit_test_method, "x.bit_test(n) -> bool\n\n" "Return the value of the n-th bit of x."); static PyObject * GMPy_MPZ_bit_test_method(PyObject *self, PyObject *other) { mp_bitcnt_t bit_index; bit_index = mp_bitcnt_t_From_Integer(other); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } if (mpz_tstbit(MPZ(self), bit_index)) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(doc_bit_clear_function, "bit_clear(x, n) -> mpz\n\n" "Return a copy of x with the n-th bit cleared."); static PyObject * GMPy_MPZ_bit_clear_function(PyObject *self, PyObject *args) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL, *tempx = NULL; if (PyTuple_GET_SIZE(args) != 2) goto err; if (!(result = GMPy_MPZ_New(NULL))) return NULL; if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) goto err; bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) goto err_index; mpz_set(result->z, tempx->z); mpz_clrbit(result->z, bit_index); Py_DECREF((PyObject*)tempx); return (PyObject*)result; err: TYPE_ERROR("bit_clear() requires 'mpz','int' arguments"); err_index: Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } PyDoc_STRVAR(doc_bit_clear_method, "x.bit_clear(n) -> mpz\n\n" "Return a copy of x with the n-th bit cleared."); static PyObject * GMPy_MPZ_bit_clear_method(PyObject *self, PyObject *other) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(NULL))) return NULL; bit_index = mp_bitcnt_t_From_Integer(other); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { Py_DECREF(result); return NULL; } mpz_set(result->z, MPZ(self)); mpz_clrbit(result->z, bit_index); return (PyObject*)result; } PyDoc_STRVAR(doc_bit_set_function, "bit_set(x, n) -> mpz\n\n" "Return a copy of x with the n-th bit set."); static PyObject * GMPy_MPZ_bit_set_function(PyObject *self, PyObject *args) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL, *tempx = NULL; if (PyTuple_GET_SIZE(args) != 2) goto err; if (!(result = GMPy_MPZ_New(NULL))) return NULL; if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) goto err; bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) goto err_index; mpz_set(result->z, tempx->z); mpz_setbit(result->z, bit_index); Py_DECREF((PyObject*)tempx); return (PyObject*)result; err: TYPE_ERROR("bit_set() requires 'mpz','int' arguments"); err_index: Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } PyDoc_STRVAR(doc_bit_set_method, "x.bit_set(n) -> mpz\n\n" "Return a copy of x with the n-th bit set."); static PyObject * GMPy_MPZ_bit_set_method(PyObject *self, PyObject *other) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(NULL))) return NULL; bit_index = mp_bitcnt_t_From_Integer(other); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { Py_DECREF(result); return NULL; } mpz_set(result->z, MPZ(self)); mpz_setbit(result->z, bit_index); return (PyObject*)result; } PyDoc_STRVAR(doc_bit_flip_function, "bit_flip(x, n) -> mpz\n\n" "Return a copy of x with the n-th bit inverted."); static PyObject * GMPy_MPZ_bit_flip_function(PyObject *self, PyObject *args) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL, *tempx = NULL; if (PyTuple_GET_SIZE(args) != 2) goto err; if (!(result = GMPy_MPZ_New(NULL))) return NULL; if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) goto err; bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) goto err_index; mpz_set(result->z, tempx->z); mpz_combit(result->z, bit_index); Py_DECREF((PyObject*)tempx); return (PyObject*)result; err: TYPE_ERROR("bit_flip() requires 'mpz','int' arguments"); err_index: Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } PyDoc_STRVAR(doc_bit_flip_method, "x.bit_flip(n) -> mpz\n\n" "Return a copy of x with the n-th bit inverted."); static PyObject * GMPy_MPZ_bit_flip_method(PyObject *self, PyObject *other) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(NULL))) return NULL; bit_index = mp_bitcnt_t_From_Integer(other); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { Py_DECREF(result); return NULL; } mpz_set(result->z, MPZ(self)); mpz_combit(result->z, bit_index); return (PyObject*)result; } static PyObject * GMPy_MPZ_Invert_Slot(MPZ_Object *self) { MPZ_Object *result; if ((result = GMPy_MPZ_New(NULL))) mpz_com(result->z, MPZ(self)); return (PyObject*)result; } static PyObject * GMPy_MPZ_And_Slot(PyObject *self, PyObject *other) { MPZ_Object *result; if (CHECK_MPZANY(self)) { if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_New(NULL))) return NULL; mpz_and(result->z, MPZ(self), MPZ(other)); } else { if (!(result = GMPy_MPZ_From_Integer(other, NULL))) return NULL; mpz_and(result->z, MPZ(self), result->z); } } else if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_From_Integer(self, NULL))) return NULL; mpz_and(result->z, result->z, MPZ(other)); } else { Py_RETURN_NOTIMPLEMENTED; } return (PyObject*)result; } static PyObject * GMPy_MPZ_Ior_Slot(PyObject *self, PyObject *other) { MPZ_Object *result; if (CHECK_MPZANY(self)) { if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_New(NULL))) return NULL; mpz_ior(result->z, MPZ(self), MPZ(other)); } else { if (!(result = GMPy_MPZ_From_Integer(other, NULL))) return NULL; mpz_ior(result->z, MPZ(self), result->z); } } else if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_From_Integer(self, NULL))) return NULL; mpz_ior(result->z, result->z, MPZ(other)); } else { Py_RETURN_NOTIMPLEMENTED; } return (PyObject*)result; } static PyObject * GMPy_MPZ_Xor_Slot(PyObject *self, PyObject *other) { MPZ_Object *result; if (CHECK_MPZANY(self)) { if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_New(NULL))) return NULL; mpz_xor(result->z, MPZ(self), MPZ(other)); } else { if (!(result = GMPy_MPZ_From_Integer(other, NULL))) return NULL; mpz_xor(result->z, MPZ(self), result->z); } } else if (CHECK_MPZANY(other)) { if (!(result = GMPy_MPZ_From_Integer(self, NULL))) return NULL; mpz_xor(result->z, result->z, MPZ(other)); } else { Py_RETURN_NOTIMPLEMENTED; } return (PyObject*)result; } static PyObject * GMPy_MPZ_Rshift_Slot(PyObject *self, PyObject *other) { mp_bitcnt_t count; MPZ_Object *result, *tempx; count = mp_bitcnt_t_From_Integer(other); if ((count == (mp_bitcnt_t)(-1)) && PyErr_Occurred()) return NULL; if (!(result = GMPy_MPZ_New(NULL))) return NULL; if (CHECK_MPZANY(self)) { mpz_fdiv_q_2exp(result->z, MPZ(self), count); return (PyObject*)result; } else { if (!(tempx = GMPy_MPZ_From_Integer(self, NULL))) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_fdiv_q_2exp(result->z, tempx->z, count); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } } static PyObject * GMPy_MPZ_Lshift_Slot(PyObject *self, PyObject *other) { mp_bitcnt_t count; MPZ_Object *result, *tempx; count = mp_bitcnt_t_From_Integer(other); if ((count == (mp_bitcnt_t)(-1)) && PyErr_Occurred()) return NULL; if (!(result = GMPy_MPZ_New(NULL))) return NULL; if (CHECK_MPZANY(self)) { mpz_mul_2exp(result->z, MPZ(self), count); return (PyObject*)result; } else { if (!(tempx = GMPy_MPZ_From_Integer(self, NULL))) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_mul_2exp(result->z, tempx->z, count); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } } PyDoc_STRVAR(doc_popcount, "popcount(x) -> int\n\n" "Return the number of 1-bits set in x. If x<0, the number of\n" "1-bits is infinite so -1 is returned in that case."); static PyObject * GMPy_MPZ_popcount(PyObject *self, PyObject *other) { mp_bitcnt_t n; MPZ_Object *tempx; if ((tempx = GMPy_MPZ_From_Integer(other, NULL))) { n = mpz_popcount(tempx->z); Py_DECREF((PyObject*)tempx); if (n == (mp_bitcnt_t)(-1)) return PyLong_FromLong(-1); else return PyIntOrLong_FromMpBitCnt(n); } else { TYPE_ERROR("popcount() requires 'mpz' argument"); return NULL; } } PyDoc_STRVAR(doc_hamdist, "hamdist(x, y) -> int\n\n" "Return the Hamming distance (number of bit-positions where the\n" "bits differ) between integers x and y."); static PyObject * GMPy_MPZ_hamdist(PyObject *self, PyObject *args) { PyObject *result = NULL; MPZ_Object *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) goto err; tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); if (!tempx || !tempy) goto err; result = PyIntOrLong_FromMpBitCnt(mpz_hamdist(tempx->z, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return result; err: TYPE_ERROR("hamdist() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; } gmpy2-2.1.0b3/src/gmpy2_mpz_bitops.h0000664000175000017500000000752713425753153017136 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_bitops.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPZ_BITOPS_H #define GMPY_MPZ_BITOPS_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPZ_bit_length_function(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_bit_length_method(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_bit_mask(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_bit_scan0_function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_scan1_method(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_test_function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_test_method(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_bit_clear_function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_clear_method(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_bit_set_function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_set_method(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_bit_flip_function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_bit_flip_method(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_popcount(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_hamdist(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Invert_Slot(MPZ_Object *self); static PyObject * GMPy_MPZ_And_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Ior_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Xor_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Rshift_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Lshift_Slot(PyObject *self, PyObject *other); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpz_divmod.c0000664000175000017500000003117513425753171017107 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_divmod.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains functions related to division and remainder. */ /* ************************************************************************** * Ceiling division and remainder. ************************************************************************** */ PyDoc_STRVAR(doc_c_divmod, "c_divmod(x, y) -> (quotient, remainder)\n\n" "Return the quotient and remainder of x divided by y. The quotient\n" "is rounded towards +Inf (ceiling rounding) and the remainder will\n" "have the opposite sign of y. x and y must be integers."); static PyObject * GMPy_MPZ_c_divmod(PyObject *self, PyObject *args) { PyObject *result = NULL; MPZ_Object *q = NULL, *r = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_divmod() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(q = GMPy_MPZ_New(NULL)) || !(r = GMPy_MPZ_New(NULL)) || !(result = PyTuple_New(2))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("c_divmod() division by 0"); goto err; } mpz_cdiv_qr(q->z, r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; err: Py_XDECREF(result); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)r); return NULL; } PyDoc_STRVAR(doc_c_div, "c_div(x, y) -> quotient\n\n" "Return the quotient of x divided by y. The quotient is rounded\n" "towards +Inf (ceiling rounding). x and y must be integers."); static PyObject * GMPy_MPZ_c_div(PyObject *self, PyObject *args) { MPZ_Object *q = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_div() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(q = GMPy_MPZ_New(NULL))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("c_div() division by 0"); goto err; } mpz_cdiv_q(q->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)q; err: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)q); return NULL; } PyDoc_STRVAR(doc_c_mod, "c_mod(x, y) -> remainder\n\n" "Return the remainder of x divided by y. The remainder will have\n" "the opposite sign of y. x and y must be integers."); static PyObject * GMPy_MPZ_c_mod(PyObject *self, PyObject *args) { MPZ_Object *r = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_mod() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(r = GMPy_MPZ_New(NULL))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("c_mod() division by 0"); goto err; } mpz_cdiv_r(r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)r; err: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)r); return NULL; } /* ************************************************************************** * Floor division and remainder. ************************************************************************** */ PyDoc_STRVAR(doc_f_divmod, "f_divmod(x, y) -> (quotient, remainder)\n\n" "Return the quotient and remainder of x divided by y. The quotient\n" "is rounded towards -Inf (floor rounding) and the remainder will\n" "have the same sign as y. x and y must be integers."); static PyObject * GMPy_MPZ_f_divmod(PyObject *self, PyObject *args) { PyObject *result = NULL; MPZ_Object *q = NULL, *r = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("f_divmod() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(q = GMPy_MPZ_New(NULL)) || !(r = GMPy_MPZ_New(NULL)) || !(result = PyTuple_New(2))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("f_divmod() division by 0"); goto err; } mpz_fdiv_qr(q->z, r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; err: Py_XDECREF(result); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)r); return NULL; } PyDoc_STRVAR(doc_f_div, "f_div(x, y) -> quotient\n\n" "Return the quotient of x divided by y. The quotient is rounded\n" "towards -Inf (floor rounding). x and y must be integers."); static PyObject * GMPy_MPZ_f_div(PyObject *self, PyObject *args) { MPZ_Object *q = NULL, *tempx = NULL, *tempy = NULL; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("f_div() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(q = GMPy_MPZ_New(NULL))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("f_div() division by 0"); goto err; } mpz_fdiv_q(q->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)q; err: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)q); return NULL; } PyDoc_STRVAR(doc_f_mod, "f_mod(x, y) -> remainder\n\n" "Return the remainder of x divided by y. The remainder will have\n" "the same sign as y. x and y must be integers."); static PyObject * GMPy_MPZ_f_mod(PyObject *self, PyObject *args) { MPZ_Object *r = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("f_mod() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(r = GMPy_MPZ_New(NULL))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("f_mod() division by 0"); goto err; } mpz_fdiv_r(r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)r; err: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)r); return NULL; } /* ************************************************************************** * Truncating division and remainder. ************************************************************************** */ PyDoc_STRVAR(doc_t_divmod, "t_divmod(x, y) -> (quotient, remainder)\n\n" "Return the quotient and remainder of x divided by y. The quotient\n" "is rounded towards zero (truncation) and the remainder will have\n" "the same sign as x. x and y must be integers."); static PyObject * GMPy_MPZ_t_divmod(PyObject *self, PyObject *args) { PyObject *result = NULL; MPZ_Object *q = NULL, *r = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_divmod() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(q = GMPy_MPZ_New(NULL)) || !(r = GMPy_MPZ_New(NULL)) || !(result = PyTuple_New(2))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("t_divmod() division by 0"); goto err; } mpz_tdiv_qr(q->z, r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; err: Py_XDECREF(result); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)r); return NULL; } PyDoc_STRVAR(doc_t_div, "t_div(x, y) -> quotient\n\n" "Return the quotient of x divided by y. The quotient is rounded\n" "towards 0. x and y must be integers."); static PyObject * GMPy_MPZ_t_div(PyObject *self, PyObject *args) { MPZ_Object *q = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_div() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(q = GMPy_MPZ_New(NULL))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("t_div() division by 0"); goto err; } mpz_tdiv_q(q->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)q; err: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)q); return NULL; } PyDoc_STRVAR(doc_t_mod, "t_mod(x, y) -> remainder\n\n" "Return the remainder of x divided by y. The remainder will have\n" "the same sign as x. x and y must be integers."); static PyObject * GMPy_MPZ_t_mod(PyObject *self, PyObject *args) { MPZ_Object *r = NULL, *tempx = NULL, *tempy = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_mod() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(r = GMPy_MPZ_New(NULL))) { goto err; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("t_mod() division by 0"); goto err; } mpz_tdiv_r(r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)r; err: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)r); return NULL; } gmpy2-2.1.0b3/src/gmpy2_mpz_divmod.h0000664000175000017500000000537513425753202017112 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_divmod.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPZ_DIVMOD_H #define GMPY_MPZ_DIVMOD_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPZ_c_divmod(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_c_div(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_c_mod(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_f_divmod(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_f_div(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_f_mod(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_t_divmod(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_t_div(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_t_mod(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpz_divmod2exp.c0000664000175000017500000003034213425753215017700 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_divmod2exp.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file contains functions related to division and remainder by a power * of two. */ /* ************************************************************************** * Ceiling division and remainder by power of two. ************************************************************************** */ PyDoc_STRVAR(doc_c_divmod_2exp, "c_divmod_2exp(x ,n) -> (quotient, remainder)\n\n" "Return the quotient and remainder of x divided by 2**n. The quotient\n" "is rounded towards +Inf (ceiling rounding) and the remainder will\n" "be negative. x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_c_divmod_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; PyObject *result = NULL; MPZ_Object *q = NULL, *r = NULL, *tempx = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_divmod_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(q = GMPy_MPZ_New(NULL)) || !(r = GMPy_MPZ_New(NULL)) || !(result = PyTuple_New(2))) { Py_XDECREF(result); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)r); return NULL; } mpz_cdiv_q_2exp(q->z, tempx->z, nbits); mpz_cdiv_r_2exp(r->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; } PyDoc_STRVAR(doc_c_div_2exp, "c_div_2exp(x, n) -> quotient\n\n" "Returns the quotient of x divided by 2**n. The quotient is rounded\n" "towards +Inf (ceiling rounding). x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_c_div_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *result, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_div_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); result = GMPy_MPZ_New(NULL); if (!tempx || !result) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_cdiv_q_2exp(result->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } PyDoc_STRVAR(doc_c_mod_2exp, "c_mod_2exp(x, n) -> remainder\n\n" "Return the remainder of x divided by 2**n. The remainder will be\n" "negative. x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_c_mod_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *result, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_mod_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); result = GMPy_MPZ_New(NULL); if (!tempx || !result) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_cdiv_r_2exp(result->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } /* ************************************************************************** * Floor division and remainder by power of two. ************************************************************************** */ PyDoc_STRVAR(doc_f_divmod_2exp, "f_divmod_2exp(x, n) -> (quotient, remainder)\n\n" "Return quotient and remainder after dividing x by 2**n. The quotient\n" "is rounded towards -Inf (floor rounding) and the remainder will be\n" "positive. x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_f_divmod_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; PyObject *result; MPZ_Object *q, *r, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("f_divmod_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); q = GMPy_MPZ_New(NULL); r = GMPy_MPZ_New(NULL); result = PyTuple_New(2); if (!tempx || !q || !r || !result) { Py_XDECREF(result); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)r); return NULL; } mpz_fdiv_q_2exp(q->z, tempx->z, nbits); mpz_fdiv_r_2exp(r->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; } PyDoc_STRVAR(doc_f_div_2exp, "f_div_2exp(x, n) -? quotient\n\n" "Return the quotient of x divided by 2**n. The quotient is rounded\n" "towards -Inf (floor rounding). x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_f_div_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *result, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("f_div_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); result = GMPy_MPZ_New(NULL); if (!tempx || !result) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_fdiv_q_2exp(result->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } PyDoc_STRVAR(doc_f_mod_2exp, "f_mod_2exp(x, n) -> remainder\n\n" "Return remainder of x divided by 2**n. The remainder will be\n" "positive. x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_f_mod_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *result, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("f_mod_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); result = GMPy_MPZ_New(NULL); if (!tempx || !result) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_fdiv_r_2exp(result->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } /* ************************************************************************** * Truncating division and remainder by power of two. ************************************************************************** */ PyDoc_STRVAR(doc_t_divmod_2exp, "t_divmod_2exp(x, n) -> (quotient, remaidner)\n\n" "Return the quotient and remainder of x divided by 2**n. The quotient\n" "is rounded towards zero (truncation) and the remainder will have the\n" "same sign as x. x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_t_divmod_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *q, *r, *tempx; PyObject *result; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_divmod_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); q = GMPy_MPZ_New(NULL); r = GMPy_MPZ_New(NULL); result = PyTuple_New(2); if (!tempx || !q || !r || !result) { Py_XDECREF(result); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)r); return NULL; } mpz_tdiv_q_2exp(q->z, tempx->z, nbits); mpz_tdiv_r_2exp(r->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; } PyDoc_STRVAR(doc_t_div_2exp, "t_div_2exp(x, n) -> quotient\n\n" "Return the quotient of x divided by 2**n. The quotient is rounded\n" "towards zero (truncation). n must be >0."); static PyObject * GMPy_MPZ_t_div_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *result, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_div_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); result = GMPy_MPZ_New(NULL); if (!tempx || !result) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_tdiv_q_2exp(result->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } PyDoc_STRVAR(doc_t_mod_2exp, "t_mod_2exp(x, n) -> remainder\n\n" "Return the remainder of x divided by 2**n. The remainder will have\n" "the same sign as x. x must be an integer. n must be >0."); static PyObject * GMPy_MPZ_t_mod_2exp(PyObject *self, PyObject *args) { mp_bitcnt_t nbits; MPZ_Object *result, *tempx; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("t_mod_2exp() requires 'mpz','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); result = GMPy_MPZ_New(NULL); if (!tempx || !result) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpz_tdiv_r_2exp(result->z, tempx->z, nbits); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } gmpy2-2.1.0b3/src/gmpy2_mpz_divmod2exp.h0000664000175000017500000000546213425753231017710 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_divmod2exp.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPZ_DIVMOD2EXP_H #define GMPY_MPZ_DIVMOD2EXP_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPZ_c_divmod_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_c_div_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_c_mod_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_f_divmod_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_f_div_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_f_mod_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_t_divmod_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_t_div_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_t_mod_2exp(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpz_inplace.c0000664000175000017500000002176013452635451017237 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_inplace.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Provides inplace operations for mpz. */ #include static PyObject * GMPy_MPZ_IAdd_Slot(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; if (CHECK_MPZANY(other)) { if ((result = GMPy_MPZ_New(NULL))) { mpz_add(result->z, MPZ(self), MPZ(other)); } return (PyObject*)result; } if (PyLong_CheckExact(other)) { if ((result = GMPy_MPZ_New(NULL))) { switch (Py_SIZE((PyLongObject*)other)) { case -1: mpz_sub_ui(result->z, MPZ(self), ((PyLongObject*)other)->ob_digit[0]); return (PyObject*)result; case 0: mpz_set(result->z, MPZ(self)); return (PyObject*)result; case 1: mpz_add_ui(result->z, MPZ(self), ((PyLongObject*)other)->ob_digit[0]); return (PyObject*)result; default: break; } } else { return NULL; } } if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if ((result = GMPy_MPZ_New(NULL))) { if (!error) { if (temp >= 0) { mpz_add_ui(result->z, MPZ(self), temp); } else { mpz_sub_ui(result->z, MPZ(self), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_add(result->z, MPZ(self), global.tempz); } } return (PyObject*)result; } Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPZ_ISub_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; if (!(rz = GMPy_MPZ_New(NULL))) { return NULL; } if (CHECK_MPZANY(other)) { mpz_sub(rz->z, MPZ(self), MPZ(other)); return (PyObject*)rz; } if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp >= 0) { mpz_sub_ui(rz->z, MPZ(self), temp); } else { mpz_add_ui(rz->z, MPZ(self), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_sub(rz->z, MPZ(self), global.tempz); } return (PyObject*)rz; } Py_DECREF(rz); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPZ_IMul_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; if (!(rz = GMPy_MPZ_New(NULL))) { return NULL; } if (CHECK_MPZANY(other)) { mpz_mul(rz->z, MPZ(self), MPZ(other)); return (PyObject*)rz; } if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { mpz_mul_si(rz->z, MPZ(self), temp); } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_mul(rz->z, MPZ(self), global.tempz); } return (PyObject*)rz; } Py_DECREF(rz); Py_RETURN_NOTIMPLEMENTED; } /* Pympany_floordiv follows the // semantics from Python 3.x. The result is * an mpz when the arguments are mpz or mpq, but the result is an mpf when * the arguments are mpf. */ static PyObject * GMPy_MPZ_IFloorDiv_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; if (!(rz = GMPy_MPZ_New(NULL))) { return NULL; } if (CHECK_MPZANY(other)) { if (mpz_sgn(MPZ(other)) == 0) { ZERO_ERROR("mpz division by zero"); Py_DECREF(rz); return NULL; } mpz_fdiv_q(rz->z, MPZ(self), MPZ(other)); return (PyObject*)rz; } if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp == 0) { ZERO_ERROR("mpz division by zero"); Py_DECREF(rz); return NULL; } else if(temp > 0) { mpz_fdiv_q_ui(rz->z, MPZ(self), temp); } else { mpz_cdiv_q_ui(rz->z, MPZ(self), -temp); mpz_neg(rz->z, rz->z); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_fdiv_q(rz->z, MPZ(self), global.tempz); } return (PyObject*)rz; } Py_DECREF(rz); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPZ_IRem_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; if (!(rz = GMPy_MPZ_New(NULL))) { return NULL; } if (CHECK_MPZANY(other)) { if (mpz_sgn(MPZ(other)) == 0) { ZERO_ERROR("mpz modulo by zero"); Py_DECREF(rz); return NULL; } mpz_fdiv_r(rz->z, MPZ(self), MPZ(other)); return (PyObject*)rz; } if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp > 0) { mpz_fdiv_r_ui(rz->z, MPZ(self), temp); } else if (temp == 0) { Py_DECREF(rz); ZERO_ERROR("mpz modulo by zero"); return NULL; } else { mpz_cdiv_r_ui(rz->z, MPZ(self), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_fdiv_r(rz->z, MPZ(self), global.tempz); } return (PyObject*)rz; } Py_DECREF(rz); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPZ_IRshift_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; mp_bitcnt_t shift; if (IS_INTEGER(other)) { shift = mp_bitcnt_t_From_Integer(other); if (shift == (mp_bitcnt_t)(-1) && PyErr_Occurred()) return NULL; if (!(rz = GMPy_MPZ_New(NULL))) return NULL; mpz_fdiv_q_2exp(rz->z, MPZ(self), shift); return (PyObject *)rz; } Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPZ_ILshift_Slot(PyObject *self, PyObject *other) { MPZ_Object *rz; mp_bitcnt_t shift; if (IS_INTEGER(other)) { shift = mp_bitcnt_t_From_Integer(other); if (shift == (mp_bitcnt_t)(-1) && PyErr_Occurred()) return NULL; if (!(rz = GMPy_MPZ_New(NULL))) return NULL; mpz_mul_2exp(rz->z, MPZ(self), shift); return (PyObject *)rz; } Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPZ_IPow_Slot(PyObject *self, PyObject *other, PyObject *mod) { MPZ_Object *r; mp_bitcnt_t exp; exp = mp_bitcnt_t_From_Integer(other); if (exp == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } if (!(r = GMPy_MPZ_New(NULL))) return NULL; mpz_pow_ui(r->z, MPZ(self), exp); return (PyObject*)r; } gmpy2-2.1.0b3/src/gmpy2_mpz_inplace.h0000664000175000017500000000536613425753256017254 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_inplace.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPZ_INPLACE_H #define GMPY_MPZ_INPLACE_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPZ_IAdd_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_ISub_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_IMul_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_IFloorDiv_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_IRem_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_IRshift_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_ILshift_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_IPow_Slot(PyObject *self, PyObject *other, PyObject *mod); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpz_misc.c0000664000175000017500000013611613463460564016564 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_misc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* return number-of-digits for an mpz in requested base, default 10 */ PyDoc_STRVAR(GMPy_doc_mpz_method_num_digits, "x.num_digits([base]) -> int\n\n" "Return length of string representing the absolute value of x in\n" "the given base. Values for base can range between 2 and 62. The\n" "value returned may be 1 too large."); PyDoc_STRVAR(GMPy_doc_mpz_function_num_digits, "num_digits(x[, base]) -> int\n\n" "Return length of string representing the absolute value of x in\n" "the given base. Values for base can range between 2 and 62. The\n" "value returned may be 1 too large."); static PyObject * GMPy_MPZ_Method_NumDigits(PyObject *self, PyObject *args) { long base = 10; PyObject *result; if (PyTuple_GET_SIZE(args) == 1) { base = PyIntOrLong_AsLong(PyTuple_GET_ITEM(args, 0)); if (base == -1 && PyErr_Occurred()) { return NULL; } } if ((base < 2) || (base > 62)) { VALUE_ERROR("base must be in the interval [2, 62]"); return NULL; } result = PyIntOrLong_FromSize_t(mpz_sizeinbase(MPZ(self), (int)base)); return result; } static PyObject * GMPy_MPZ_Function_NumDigits(PyObject *self, PyObject *args) { long base = 10; Py_ssize_t argc; MPZ_Object *temp; PyObject *result; argc = PyTuple_GET_SIZE(args); if (argc == 0 || argc > 2) { TYPE_ERROR("num_digits() requires 'mpz',['int'] arguments"); return NULL; } if (argc == 2) { base = PyIntOrLong_AsLong(PyTuple_GET_ITEM(args, 1)); if (base == -1 && PyErr_Occurred()) { return NULL; } } if ((base < 2) || (base > 62)) { VALUE_ERROR("base must be in the interval [2, 62]"); return NULL; } if (!(temp = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { return NULL; } result = PyIntOrLong_FromSize_t(mpz_sizeinbase(temp->z, (int)base)); Py_DECREF((PyObject*)temp); return result; } PyDoc_STRVAR(GMPy_doc_mpz_function_iroot, "iroot(x,n) -> (number, boolean)\n\n" "Return the integer n-th root of x and boolean value that is True\n" "iff the root is exact. x >= 0. n > 0."); static PyObject * GMPy_MPZ_Function_Iroot(PyObject *self, PyObject *args) { unsigned long n; int exact; MPZ_Object *root = NULL, *tempx = NULL; PyObject *result = NULL; if ((PyTuple_GET_SIZE(args) != 2) || ((!IS_INTEGER(PyTuple_GET_ITEM(args, 0))) || (!IS_INTEGER(PyTuple_GET_ITEM(args, 1))))) { TYPE_ERROR("iroot() requires 'int','int' arguments"); return NULL; } n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); if ((n == 0) || ((n == (unsigned long)(-1)) && PyErr_Occurred())) { VALUE_ERROR("n must be > 0"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (mpz_sgn(tempx->z) < 0) { VALUE_ERROR("iroot() of negative number"); Py_DECREF((PyObject*)tempx); return NULL; } if (!(result = PyTuple_New(2)) || !(root = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)tempx); Py_XDECREF((PyObject*)root); Py_XDECREF(result); return NULL; /* LCOV_EXCL_STOP */ } exact = mpz_root(root->z, tempx->z, n); Py_DECREF((PyObject*)tempx); PyTuple_SET_ITEM(result, 0, (PyObject*)root); PyTuple_SET_ITEM(result, 1, (PyObject*)PyBool_FromLong(exact)); return result; } PyDoc_STRVAR(GMPy_doc_mpz_function_iroot_rem, "iroot_rem(x,n) -> (number, number)\n\n" "Return a 2-element tuple (y,r), such that y is the integer n-th\n" "root of x and x=y**n + r. x >= 0. n > 0."); static PyObject * GMPy_MPZ_Function_IrootRem(PyObject *self, PyObject *args) { unsigned long n; MPZ_Object *root = NULL, *rem = NULL, *tempx = NULL; PyObject *result = NULL; if ((PyTuple_GET_SIZE(args) != 2) || ((!IS_INTEGER(PyTuple_GET_ITEM(args, 0))) || (!IS_INTEGER(PyTuple_GET_ITEM(args, 1))))) { TYPE_ERROR("iroot_rem() requires 'int','int' arguments"); return NULL; } n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); if ((n == 0) || ((n == (unsigned long)(-1)) && PyErr_Occurred())) { VALUE_ERROR("n must be > 0"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (mpz_sgn(tempx->z) < 0) { VALUE_ERROR("iroot_rem() of negative number"); Py_DECREF((PyObject*)tempx); return NULL; } if (!(result = PyTuple_New(2)) || !(root = GMPy_MPZ_New(NULL)) || !(rem = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)tempx); Py_XDECREF(result); Py_XDECREF((PyObject*)root); Py_XDECREF((PyObject*)rem); return NULL; /* LCOV_EXCL_STOP */ } mpz_rootrem(root->z, rem->z, tempx->z, n); Py_DECREF((PyObject*)tempx); PyTuple_SET_ITEM(result, 0, (PyObject*)root); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } PyDoc_STRVAR(GMPy_doc_mpz_method_ceil, "Ceiling of an mpz returns itself."); static PyObject * GMPy_MPZ_Method_Ceil(PyObject *self, PyObject *other) { Py_INCREF(self); return self; } PyDoc_STRVAR(GMPy_doc_mpz_method_floor, "Floor of an mpz returns itself."); static PyObject * GMPy_MPZ_Method_Floor(PyObject *self, PyObject *other) { Py_INCREF(self); return self; } PyDoc_STRVAR(GMPy_doc_mpz_method_trunc, "Truncating an mpz returns itself."); static PyObject * GMPy_MPZ_Method_Trunc(PyObject *self, PyObject *other) { Py_INCREF(self); return self; } PyDoc_STRVAR(GMPy_doc_mpz_method_round, "Round an mpz to power of 10."); static PyObject * GMPy_MPZ_Method_Round(PyObject *self, PyObject *args) { Py_ssize_t round_digits; MPZ_Object *result; mpz_t temp, rem; if (PyTuple_GET_SIZE(args) == 0) { Py_INCREF(self); return self; } round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } if (round_digits >= 0) { Py_INCREF(self); return self; } /* We can now assume round_digits > 0. */ round_digits = -round_digits; if ((result = GMPy_MPZ_New(NULL))) { if ((unsigned)round_digits >= mpz_sizeinbase(MPZ(self), 10)) { mpz_set_ui(result->z, 0); } else { mpz_init(temp); mpz_init(rem); mpz_ui_pow_ui(temp, 10, round_digits); mpz_fdiv_qr(result->z, rem, MPZ(self), temp); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, temp) > 0) { mpz_add_ui(result->z, result->z, 1); } else if (mpz_cmp(rem, temp) == 0) { if (mpz_odd_p(result->z)) { mpz_add_ui(result->z, result->z, 1); } } mpz_mul(result->z, result->z, temp); mpz_clear(rem); mpz_clear(temp); } } return (PyObject*)result; } static int GMPy_MPZ_NonZero_Slot(MPZ_Object *self) { return mpz_sgn(self->z) != 0; } #if PY_MAJOR_VERSION < 3 /* hex/oct formatting (mpz-only) */ static PyObject * GMPy_MPZ_Oct_Slot(MPZ_Object *self) { return GMPy_PyStr_From_MPZ(self, 8, 0, NULL); } static PyObject * GMPy_MPZ_Hex_Slot(MPZ_Object *self) { return GMPy_PyStr_From_MPZ(self, 16, 0, NULL); } #endif /* Miscellaneous gmpy functions */ PyDoc_STRVAR(GMPy_doc_mpz_function_gcd, "gcd(a, b) -> mpz\n\n" "Return the greatest common divisor of integers a and b."); static PyObject * GMPy_MPZ_Function_GCD(PyObject *self, PyObject *args) { PyObject *arg0, *arg1; MPZ_Object *result = NULL, *tempa = NULL, *tempb = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("gcd() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } arg0 = PyTuple_GET_ITEM(args, 0); arg1 = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(arg0) && MPZ_Check(arg1)) { mpz_gcd(result->z, MPZ(arg0), MPZ(arg1)); } else { if (!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) || !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) { TYPE_ERROR("gcd() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempa); Py_XDECREF((PyObject*)tempb); Py_DECREF((PyObject*)result); return NULL; } mpz_gcd(result->z, tempa->z, tempb->z); Py_DECREF((PyObject*)tempa); Py_DECREF((PyObject*)tempb); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_lcm, "lcm(a, b) -> mpz\n\n" "Return the lowest common multiple of integers a and b."); static PyObject * GMPy_MPZ_Function_LCM(PyObject *self, PyObject *args) { PyObject *arg0, *arg1; MPZ_Object *result = NULL, *tempa = NULL, *tempb = NULL; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("lcm() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } arg0 = PyTuple_GET_ITEM(args, 0); arg1 = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(arg0) && MPZ_Check(arg1)) { mpz_lcm(result->z, MPZ(arg0), MPZ(arg1)); } else { if (!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) || !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) { TYPE_ERROR("lcm() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempa); Py_XDECREF((PyObject*)tempb); Py_DECREF((PyObject*)result); return NULL; } mpz_lcm(result->z, tempa->z, tempb->z); Py_DECREF((PyObject*)tempa); Py_DECREF((PyObject*)tempb); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_gcdext, "gcdext(a, b) - > tuple\n\n" "Return a 3-element tuple (g,s,t) such that\n" " g == gcd(a,b) and g == a*s + b*t"); static PyObject * GMPy_MPZ_Function_GCDext(PyObject *self, PyObject *args) { PyObject *arg0, *arg1, *result = NULL; MPZ_Object *g = NULL, *s = NULL, *t = NULL, *tempa = NULL, *tempb = NULL; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = PyTuple_New(3)) || !(g = GMPy_MPZ_New(NULL)) || !(s = GMPy_MPZ_New(NULL)) || !(t = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)g); Py_XDECREF((PyObject*)s); Py_XDECREF((PyObject*)t); Py_XDECREF(result); return NULL; /* LCOV_EXCL_STOP */ } arg0 = PyTuple_GET_ITEM(args, 0); arg1 = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(arg0) && MPZ_Check(arg1)) { mpz_gcdext(g->z, s->z, t->z, MPZ(arg0), MPZ(arg1)); } else { if(!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) || !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) { TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempa); Py_XDECREF((PyObject*)tempb); Py_DECREF((PyObject*)g); Py_DECREF((PyObject*)s); Py_DECREF((PyObject*)t); Py_DECREF(result); return NULL; } mpz_gcdext(g->z, s->z, t->z, tempa->z, tempb->z); Py_DECREF((PyObject*)tempa); Py_DECREF((PyObject*)tempb); } PyTuple_SET_ITEM(result, 0, (PyObject*)g); PyTuple_SET_ITEM(result, 1, (PyObject*)s); PyTuple_SET_ITEM(result, 2, (PyObject*)t); return result; } PyDoc_STRVAR(GMPy_doc_mpz_function_divm, "divm(a, b, m) -> mpz\n\n" "Return x such that b*x == a mod m. Raises a ZeroDivisionError\n" "exception if no such value x exists."); static PyObject * GMPy_MPZ_Function_Divm(PyObject *self, PyObject *args) { MPZ_Object *result = NULL, *num = NULL, *den = NULL, *mod = NULL; mpz_t numz, denz, modz, gcdz; int ok = 0; if (PyTuple_GET_SIZE(args) != 3) { TYPE_ERROR("divm() requires 'mpz','mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (!(num = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(den = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(mod = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL))) { TYPE_ERROR("divm() requires 'mpz','mpz','mpz' arguments"); Py_XDECREF((PyObject*)num); Py_XDECREF((PyObject*)den); Py_XDECREF((PyObject*)mod); Py_DECREF((PyObject*)result); return NULL; } /* Make copies so we don't destroy the input. */ mpz_init(numz); mpz_init(denz); mpz_init(modz); mpz_set(numz, num->z); mpz_set(denz, den->z); mpz_set(modz, mod->z); Py_DECREF((PyObject*)num); Py_DECREF((PyObject*)den); Py_DECREF((PyObject*)mod); if (mpz_invert(result->z, denz, modz)) { /* inverse exists */ ok = 1; } else { /* last-ditch attempt: do num, den AND mod have a gcd>1 ? */ mpz_init(gcdz); mpz_gcd(gcdz, numz, denz); mpz_gcd(gcdz, gcdz, modz); mpz_divexact(numz, numz, gcdz); mpz_divexact(denz, denz, gcdz); mpz_divexact(modz, modz, gcdz); mpz_clear(gcdz); ok = mpz_invert(result->z, denz, modz); } if (ok) { mpz_mul(result->z, result->z, numz); mpz_mod(result->z, result->z, modz); mpz_clear(numz); mpz_clear(denz); mpz_clear(modz); return (PyObject*)result; } else { ZERO_ERROR("not invertible"); mpz_clear(numz); mpz_clear(denz); mpz_clear(modz); Py_DECREF((PyObject*)result); return NULL; } } PyDoc_STRVAR(GMPy_doc_mpz_function_fac, "fac(n) -> mpz\n\n" "Return the exact factorial of n.\n\n" "See factorial(n) to get the floating-point approximation."); static PyObject * GMPy_MPZ_Function_Fac(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_fac_ui(result->z, n); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_double_fac, "double_fac(n) -> mpz\n\n" "Return the exact double factorial (n!!) of n. The double\n" "factorial is defined as n*(n-2)*(n-4)..."); static PyObject * GMPy_MPZ_Function_DoubleFac(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_2fac_ui(result->z, n); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_primorial, "primorial(n) -> mpz\n\n" "Return the product of all positive prime numbers less than or" "equal to n."); static PyObject * GMPy_MPZ_Function_Primorial(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_primorial_ui(result->z, n); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_multi_fac, "multi_fac(n,m) -> mpz\n\n" "Return the exact m-multi factorial of n. The m-multi" "factorial is defined as n*(n-m)*(n-2m)..."); static PyObject * GMPy_MPZ_Function_MultiFac(PyObject *self, PyObject *args) { MPZ_Object *result = NULL; unsigned long n, m; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("multi_fac() requires 2 integer arguments"); return NULL; } n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0)); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } m = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); if (m == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_mfac_uiui(result->z, n, m); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_fib, "fib(n) -> mpz\n\n" "Return the n-th Fibonacci number."); static PyObject * GMPy_MPZ_Function_Fib(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_fib_ui(result->z, n); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_fib2, "fib2(n) -> tuple\n\n" "Return a 2-tuple with the (n-1)-th and n-th Fibonacci numbers."); static PyObject * GMPy_MPZ_Function_Fib2(PyObject *self, PyObject *other) { PyObject *result = NULL; MPZ_Object *fib1 = NULL, *fib2 = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if (!(result = PyTuple_New(2)) || !(fib1 = GMPy_MPZ_New(NULL)) || !(fib2 = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_XDECREF(result); Py_XDECREF((PyObject*)fib1); Py_XDECREF((PyObject*)fib2); result = NULL; /* LCOV_EXCL_STOP */ } mpz_fib2_ui(fib1->z, fib2->z, n); PyTuple_SET_ITEM(result, 0, (PyObject*)fib1); PyTuple_SET_ITEM(result, 1, (PyObject*)fib2); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_lucas, "lucas(n) -> mpz\n\n" "Return the n-th Lucas number."); static PyObject * GMPy_MPZ_Function_Lucas(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_lucnum_ui(result->z, n); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_lucas2, "lucas2(n) -> tuple\n\n" "Return a 2-tuple with the (n-1)-th and n-th Lucas numbers."); static PyObject * GMPy_MPZ_Function_Lucas2(PyObject *self, PyObject *other) { PyObject *result = NULL; MPZ_Object *luc1 = NULL, *luc2 = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if (!(result = PyTuple_New(2)) || !(luc1 = GMPy_MPZ_New(NULL)) || !(luc2 = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_XDECREF(result); Py_XDECREF((PyObject*)luc1); Py_XDECREF((PyObject*)luc2); result = NULL; /* LCOV_EXCL_STOP */ } mpz_lucnum2_ui(luc1->z, luc2->z, n); PyTuple_SET_ITEM(result, 0, (PyObject*)luc1); PyTuple_SET_ITEM(result, 1, (PyObject*)luc2); return result; } PyDoc_STRVAR(GMPy_doc_mpz_function_bincoef, "bincoef(n, k) -> mpz\n\n" "Return the binomial coefficient ('n choose k'). k >= 0."); PyDoc_STRVAR(GMPy_doc_mpz_function_comb, "comb(n, k) -> mpz\n\n" "Return the number of combinations of 'n things, taking k at a\n" "time'. k >= 0. Same as bincoef(n, k)"); static PyObject * GMPy_MPZ_Function_Bincoef(PyObject *self, PyObject *args) { MPZ_Object *result = NULL, *tempx; unsigned long n, k; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("bincoef() requires two integer arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } k = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); if (k == (unsigned long)(-1) && PyErr_Occurred()) { Py_DECREF((PyObject*)result); return NULL; } n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0)); if (n == (unsigned long)(-1) && PyErr_Occurred()) { /* Since we plan to skip the else clause and continue, * we need to clear the error since we aren't acting on it. */ PyErr_Clear(); } else { /* Use mpz_bin_uiui which should be faster. */ mpz_bin_uiui(result->z, n, k); return (PyObject*)result; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { Py_DECREF((PyObject*)result); return NULL; } mpz_bin_ui(result->z, tempx->z, k); Py_DECREF((PyObject*)tempx); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_isqrt, "isqrt(x) -> mpz\n\n" "Return the integer square root of an integer x. x >= 0."); static PyObject * GMPy_MPZ_Function_Isqrt(PyObject *self, PyObject *other) { MPZ_Object *result; if (CHECK_MPZANY(other)) { if (mpz_sgn(MPZ(other)) < 0) { VALUE_ERROR("isqrt() of negative number"); return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_sqrt(result->z, MPZ(other)); } } else { if (!(result = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("isqrt() requires 'mpz' argument"); return NULL; } if (mpz_sgn(result->z) < 0) { VALUE_ERROR("isqrt() of negative number"); Py_DECREF((PyObject*)result); return NULL; } mpz_sqrt(result->z, result->z); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_isqrt_rem, "isqrt_rem(x) -> tuple\n\n" "Return a 2-element tuple (s,t) such that s=isqrt(x) and t=x-s*s.\n" "x >=0."); static PyObject * GMPy_MPZ_Function_IsqrtRem(PyObject *self, PyObject *other) { MPZ_Object *root = NULL, *rem = NULL, *temp = NULL; PyObject *result; if (!(temp = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("isqrt_rem() requires 'mpz' argument"); return NULL; } if (mpz_sgn(temp->z) < 0) { VALUE_ERROR("isqrt_rem() of negative number"); Py_DECREF((PyObject*)temp); return NULL; } if (!(result = PyTuple_New(2)) || !(root = GMPy_MPZ_New(NULL)) || !(rem = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)temp); Py_XDECREF(result); Py_XDECREF((PyObject*)root); Py_XDECREF((PyObject*)rem); return NULL; /* LCOV_EXCL_STOP */ } mpz_sqrtrem(root->z, rem->z, temp->z); Py_DECREF((PyObject*)temp); PyTuple_SET_ITEM(result, 0, (PyObject*)root); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } PyDoc_STRVAR(GMPy_doc_mpz_function_remove, "remove(x, f) -> tuple\n\n" "Return a 2-element tuple (y,m) such that x=y*(f**m) and f does\n" "not divide y. Remove the factor f from x as many times as\n" "possible. m is the multiplicity f in x. f > 1."); static PyObject * GMPy_MPZ_Function_Remove(PyObject *self, PyObject *args) { MPZ_Object *result = NULL, *tempx = NULL, *tempf = NULL; PyObject *x, *f; size_t multiplicity; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("remove() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } x = PyTuple_GET_ITEM(args, 0); f = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(x) && MPZ_Check(f)) { if (mpz_cmp_si(MPZ(f), 2) < 0) { VALUE_ERROR("factor must be > 1"); Py_DECREF((PyObject*)result); return NULL; } multiplicity = mpz_remove(result->z, MPZ(x), MPZ(f)); return Py_BuildValue("(Nk)", result, multiplicity); } else { if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || !(tempf = GMPy_MPZ_From_Integer(f, NULL))) { TYPE_ERROR("remove() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempf); Py_DECREF((PyObject*)result); return NULL; } if (mpz_cmp_si(MPZ(tempf), 2) < 0) { VALUE_ERROR("factor must be > 1"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempf); Py_DECREF((PyObject*)result); return NULL; } multiplicity = mpz_remove(result->z, tempx->z, tempf->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempf); return Py_BuildValue("(Nk)", result, multiplicity); } } PyDoc_STRVAR(GMPy_doc_mpz_function_invert, "invert(x, m) -> mpz\n\n" "Return y such that x*y == 1 modulo m. Raises ZeroDivisionError if no\n" "inverse exists."); static PyObject * GMPy_MPZ_Function_Invert(PyObject *self, PyObject *args) { PyObject *x, *y; MPZ_Object *result = NULL, *tempx = NULL, *tempy = NULL; int success; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("invert() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(x) && MPZ_Check(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("invert() division by 0"); Py_DECREF((PyObject*)result); return NULL; } success = mpz_invert(result->z, MPZ(x), MPZ(y)); if (!success) { ZERO_ERROR("invert() no inverse exists"); Py_DECREF((PyObject*)result); return NULL; } } else { if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || !(tempy = GMPy_MPZ_From_Integer(y, NULL))) { TYPE_ERROR("invert() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("invert() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF(result); return NULL; } success = mpz_invert(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); if (!success) { ZERO_ERROR("invert() no inverse exists"); Py_DECREF((PyObject*)result); return NULL; } } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_divexact, "divexact(x, y) -> mpz\n\n" "Return the quotient of x divided by y. Faster than standard\n" "division but requires the remainder is zero!"); static PyObject * GMPy_MPZ_Function_Divexact(PyObject *self, PyObject *args) { PyObject *x, *y; MPZ_Object *result, *tempx= NULL, *tempy = NULL; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (MPZ_Check(x) && MPZ_Check(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("divexact() division by 0"); Py_DECREF((PyObject*)result); return NULL; } mpz_divexact(result->z, MPZ(x), MPZ(y)); } else { if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || !(tempy = GMPy_MPZ_From_Integer(y, NULL))) { TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } if (mpz_sgn(MPZ(tempy)) == 0) { ZERO_ERROR("divexact() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpz_divexact(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_is_square, "is_square(x) -> bool\n\n" "Returns True if x is a perfect square, else return False."); static PyObject * GMPy_MPZ_Function_IsSquare(PyObject *self, PyObject *other) { int res; MPZ_Object *tempx; if (MPZ_Check(other)) { res = mpz_perfect_square_p(MPZ(other)); } else { if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_square() requires 'mpz' argument"); return NULL; } else { res = mpz_perfect_square_p(tempx->z); Py_DECREF((PyObject*)tempx); } } if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_method_is_square, "x.is_square() -> bool\n\n" "Returns True if x is a perfect square, else return False."); static PyObject * GMPy_MPZ_Method_IsSquare(PyObject *self, PyObject *other) { int res; res = mpz_perfect_square_p(MPZ(self)); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_function_is_divisible, "is_divisible(x, d) -> bool\n\n" "Returns True if x is divisible by d, else return False."); static PyObject * GMPy_MPZ_Function_IsDivisible(PyObject *self, PyObject *args) { native_ui temp; int error, res; MPZ_Object *tempx, *tempd; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("is_divisible() requires 2 integer arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { return NULL; } temp = GMPy_Integer_AsNative_uiAndError(PyTuple_GET_ITEM(args, 1), &error); if (!error) { res = mpz_divisible_ui_p(tempx->z, temp); Py_DECREF((PyObject*)tempx); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } if (!(tempd = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { TYPE_ERROR("is_divisible() requires 2 integer arguments"); Py_DECREF((PyObject*)tempx); return NULL; } res = mpz_divisible_p(tempx->z, tempd->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempd); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_method_is_divisible, "x.is_divisible(d) -> bool\n\n" "Returns True if x is divisible by d, else return False."); static PyObject * GMPy_MPZ_Method_IsDivisible(PyObject *self, PyObject *other) { native_ui temp; int error, res; MPZ_Object *tempd; temp = GMPy_Integer_AsNative_uiAndError(other, &error); if (!error) { res = mpz_divisible_ui_p(MPZ(self), temp); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } if (!(tempd = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_divisible() requires integer argument"); return NULL; } res = mpz_divisible_p(MPZ(self), tempd->z); Py_DECREF((PyObject*)tempd); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_function_is_congruent, "is_congruent(x, y, m) -> bool\n\n" "Returns True if x is congruent to y modulo m, else return False."); static PyObject * GMPy_MPZ_Function_IsCongruent(PyObject *self, PyObject *args) { int res; MPZ_Object *tempx = NULL, *tempy = NULL, *tempm = NULL; if (PyTuple_GET_SIZE(args) != 3) { TYPE_ERROR("is_congruent() requires 3 integer arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || !(tempm = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL))) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)tempm); TYPE_ERROR("is_congruent() requires 3 integer arguments"); return NULL; } res = mpz_congruent_p(tempx->z, tempy->z, tempm->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)tempm); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_method_is_congruent, "x.is_congruent(y, m) -> bool\n\n" "Returns True if x is congruent to y modulo m, else return False."); static PyObject * GMPy_MPZ_Method_IsCongruent(PyObject *self, PyObject *args) { int res; MPZ_Object *tempy = NULL, *tempm = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("is_congruent() requires 2 integer arguments"); return NULL; } if (!(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempm = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)tempm); TYPE_ERROR("is_congruent() requires 2 integer arguments"); return NULL; } res = mpz_congruent_p(MPZ(self), tempy->z, tempm->z); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)tempm); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_function_is_power, "is_power(x) -> bool\n\n" "Return True if x is a perfect power (there exists a y and an\n" "n > 1, such that x=y**n), else return False."); static PyObject * GMPy_MPZ_Function_IsPower(PyObject *self, PyObject *other) { int res; MPZ_Object* tempx; if (MPZ_Check(other)) { res = mpz_perfect_power_p(MPZ(other)); } else { if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_power() requires 'mpz' argument"); return NULL; } else { res = mpz_perfect_power_p(tempx->z); Py_DECREF((PyObject*)tempx); } } if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_method_is_power, "x.is_power() -> bool\n\n" "Return True if x is a perfect power (there exists a y and an\n" "n > 1, such that x=y**n), else return False."); static PyObject * GMPy_MPZ_Method_IsPower(PyObject *self, PyObject *other) { int res; res = mpz_perfect_power_p(MPZ(self)); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_function_is_prime, "is_prime(x[, n=25]) -> bool\n\n" "Return True if x is _probably_ prime, else False if x is\n" "definitely composite. x is checked for small divisors and up\n" "to n Miller-Rabin tests are performed."); static PyObject * GMPy_MPZ_Function_IsPrime(PyObject *self, PyObject *args) { int i; unsigned long reps = 25; MPZ_Object* tempx; Py_ssize_t argc; argc = PyTuple_GET_SIZE(args); if (argc == 0 || argc > 2) { TYPE_ERROR("is_prime() requires 'mpz'[,'int'] arguments"); return NULL; } if (PyTuple_GET_SIZE(args) == 2) { reps = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); if (reps == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } /* Silently limit n to a reasonable value. */ if (reps > 1000) { reps = 1000; } } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { return NULL; } i = mpz_probab_prime_p(tempx->z, (int)reps); Py_DECREF((PyObject*)tempx); if (i) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_method_is_prime, "x.is_prime([n=25]) -> bool\n\n" "Return True if x is _probably_ prime, else False if x is\n" "definitely composite. x is checked for small divisors and up\n" "to n Miller-Rabin tests are performed."); static PyObject * GMPy_MPZ_Method_IsPrime(PyObject *self, PyObject *args) { int i; unsigned long reps = 25; Py_ssize_t argc; argc = PyTuple_GET_SIZE(args); if (argc > 1) { TYPE_ERROR("is_prime() takes at most 1 argument"); return NULL; } if (PyTuple_GET_SIZE(args) == 1) { reps = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0)); if (reps == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } /* Silently limit n to a reasonable value. */ if (reps > 1000) { reps = 1000; } } i = mpz_probab_prime_p(MPZ(self), (int)reps); if (i) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_function_next_prime, "next_prime(x) -> mpz\n\n" "Return the next _probable_ prime number > x."); static PyObject * GMPy_MPZ_Function_NextPrime(PyObject *self, PyObject *other) { MPZ_Object *result; if(MPZ_Check(other)) { if(!(result = GMPy_MPZ_New(NULL))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } mpz_nextprime(result->z, MPZ(other)); } else { if (!(result = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("next_prime() requires 'mpz' argument"); return NULL; } else { mpz_nextprime(result->z, result->z); } } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_function_jacobi, "jacobi(x, y) -> mpz\n\n" "Return the Jacobi symbol (x|y). y must be odd and >0."); static PyObject * GMPy_MPZ_Function_Jacobi(PyObject *self, PyObject *args) { MPZ_Object *tempx = NULL, *tempy = NULL; long res; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("jacobi() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; } if (mpz_sgn(tempy->z) <= 0 || mpz_even_p(tempy->z)) { VALUE_ERROR("y must be odd and >0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return NULL; } res = (long)(mpz_jacobi(tempx->z, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return PyIntOrLong_FromLong(res); } PyDoc_STRVAR(GMPy_doc_mpz_function_legendre, "legendre(x, y) -> mpz\n\n" "Return the Legendre symbol (x|y). y is assumed to be an odd prime."); static PyObject * GMPy_MPZ_Function_Legendre(PyObject *self, PyObject *args) { MPZ_Object *tempx = NULL, *tempy = NULL; long res; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("legendre() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; } if (mpz_sgn(tempy->z) <= 0 || mpz_even_p(tempy->z)) { VALUE_ERROR("y must be odd, prime, and >0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return NULL; } res = (long)(mpz_legendre(tempx->z, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return PyIntOrLong_FromLong(res); } PyDoc_STRVAR(GMPy_doc_mpz_function_kronecker, "kronecker(x, y) -> mpz\n\n" "Return the Kronecker-Jacobi symbol (x|y)."); static PyObject * GMPy_MPZ_Function_Kronecker(PyObject *self, PyObject *args) { MPZ_Object *tempx = NULL, *tempy = NULL; long res; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("kronecker() requires 'mpz','mpz' arguments"); return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); return NULL; } res = (long)(mpz_kronecker(tempx->z, tempy->z)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return PyIntOrLong_FromLong(res); } PyDoc_STRVAR(GMPy_doc_mpz_function_is_even, "is_even(x) -> bool\n\n" "Return True if x is even, False otherwise."); static PyObject * GMPy_MPZ_Function_IsEven(PyObject *self, PyObject *other) { int res; MPZ_Object *tempx; if (MPZ_Check(other)) { res = mpz_even_p(MPZ(other)); } else { if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_even() requires 'mpz' argument"); return NULL; } else { res = mpz_even_p(tempx->z); Py_DECREF((PyObject*)tempx); } } if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_method_is_even, "x.is_even() -> bool\n\n" "Return True if x is even, False otherwise."); static PyObject * GMPy_MPZ_Method_IsEven(PyObject *self, PyObject *other) { int res; res = mpz_even_p(MPZ(self)); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_function_is_odd, "is_odd(x) -> bool\n\n" "Return True if x is odd, False otherwise."); static PyObject * GMPy_MPZ_Function_IsOdd(PyObject *self, PyObject *other) { int res; MPZ_Object *tempx; if (CHECK_MPZANY(other)) { res = mpz_odd_p(MPZ(other)); } else { if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_odd() requires 'mpz' argument"); return NULL; } else { res = mpz_odd_p(tempx->z); Py_DECREF((PyObject*)tempx); } } if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } PyDoc_STRVAR(GMPy_doc_mpz_method_is_odd, "x.is_odd() -> bool\n\n" "Return True if x is odd, False otherwise."); static PyObject * GMPy_MPZ_Method_IsOdd(PyObject *self, PyObject *other) { int res; res = mpz_odd_p(MPZ(self)); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } /* * Add mapping support to mpz objects. */ static Py_ssize_t GMPy_MPZ_Method_Length(MPZ_Object *self) { return mpz_sizeinbase(self->z, 2); } static PyObject * GMPy_MPZ_Method_SubScript(MPZ_Object *self, PyObject *item) { if (PyIndex_Check(item)) { Py_ssize_t i; i = PyIntOrLong_AsSsize_t(item); if (i == -1 && PyErr_Occurred()) { INDEX_ERROR("argument too large to convert to an index"); return NULL; } if (i < 0) { i += mpz_sizeinbase(self->z, 2); } return PyIntOrLong_FromLong(mpz_tstbit(self->z, i)); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength, cur, i; MPZ_Object *result; #if PY_VERSION_HEX > 0x030200A4 if (PySlice_GetIndicesEx(item, mpz_sizeinbase(self->z, 2), &start, &stop, &step, &slicelength) < 0) { return NULL; } #else if (PySlice_GetIndicesEx((PySliceObject*)item, mpz_sizeinbase(self->z, 2), &start, &stop, &step, &slicelength) < 0) { return NULL; } #endif if ((step < 0 && start < stop) || (step > 0 && start > stop)) { stop = start; } if (!(result = GMPy_MPZ_New(NULL))) { return NULL; } mpz_set_ui(result->z, 0); if (slicelength > 0) { for (cur = start, i = 0; i < slicelength; cur += step, i++) { if(mpz_tstbit(self->z, cur)) { mpz_setbit(result->z, i); } } } return (PyObject*)result; } else { TYPE_ERROR("bit positions must be integers"); return NULL; } } static PyObject * GMPy_MPZ_Attrib_GetNumer(MPZ_Object *self, void *closure) { Py_INCREF((PyObject*)self); return (PyObject*)self; } static PyObject * GMPy_MPZ_Attrib_GetReal(MPZ_Object *self, void *closure) { Py_INCREF((PyObject*)self); return (PyObject*)self; } static PyObject * GMPy_MPZ_Attrib_GetDenom(MPZ_Object *self, void *closure) { MPZ_Object *result; if ((result = GMPy_MPZ_New(NULL))) { mpz_set_ui(result->z, 1); } return (PyObject*)result; } static PyObject * GMPy_MPZ_Attrib_GetImag(MPZ_Object *self, void *closure) { MPZ_Object *result; if ((result = GMPy_MPZ_New(NULL))) { mpz_set_ui(result->z, 0); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_method_sizeof, "x.__sizeof__()\n\n" "Returns the amount of memory consumed by x. Note: deleted mpz objects\n" "are reused and may or may not be resized when a new value is assigned."); static PyObject * GMPy_MPZ_Method_SizeOf(PyObject *self, PyObject *other) { return PyIntOrLong_FromSize_t(sizeof(MPZ_Object) + \ (MPZ(self)->_mp_alloc * sizeof(mp_limb_t))); } /* Note: this particular function is also used for xmpz, mpq, and mpfr. Only * mpc.conjugate() does more that just return another reference to the original * object. */ PyDoc_STRVAR(GMPy_doc_mp_method_conjugate, "x.conjugate() -> number\n\n" "Return the conjugate of x (which is just a new reference to x since x is\n" "not a complex number)."); static PyObject * GMPy_MP_Method_Conjugate(PyObject *self, PyObject *args) { Py_INCREF((PyObject*)self); return (PyObject*)self; } gmpy2-2.1.0b3/src/gmpy2_mpz_misc.h0000664000175000017500000001424413444071152016554 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_misc.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPZ_MISC_H #define GMPY_MPZ_MISC_H #ifdef __cplusplus extern "C" { #endif static int GMPy_MPZ_NonZero_Slot(MPZ_Object *self); static PyObject * GMPy_MPZ_Attrib_GetNumer(MPZ_Object *self, void *closure); static PyObject * GMPy_MPZ_Attrib_GetDenom(MPZ_Object *self, void *closure); static PyObject * GMPy_MPZ_Attrib_GetReal(MPZ_Object *self, void *closure); static PyObject * GMPy_MPZ_Attrib_GetImag(MPZ_Object *self, void *closure); static PyObject * GMPy_MPZ_Method_Ceil(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_Floor(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_Trunc(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_Round(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_NumDigits(PyObject *self, PyObject *args); static Py_ssize_t GMPy_MPZ_Method_Length(MPZ_Object *self); static PyObject * GMPy_MPZ_Method_SubScript(MPZ_Object *self, PyObject *item); static PyObject * GMPy_MPZ_Method_IsSquare(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_IsDivisible(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_IsCongruent(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Method_IsPower(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_IsPrime(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Method_IsEven(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Method_IsOdd(PyObject *self, PyObject *other); static PyObject * GMPy_MP_Method_Conjugate(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_NumDigits(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Iroot(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_IrootRem(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Bincoef(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_GCD(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_LCM(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_GCDext(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Divm(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Fac(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_Primorial(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_DoubleFac(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_MultiFac(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Fib(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_Fib2(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_Lucas(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_Lucas2(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_Isqrt(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_IsqrtRem(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_Remove(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Invert(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Divexact(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_IsSquare(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_IsDivisible(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_IsCongruent(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_IsPower(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_IsPrime(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_NextPrime(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_Jacobi(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Legendre(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_Kronecker(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_Function_IsEven(PyObject *self, PyObject *other); static PyObject * GMPy_MPZ_Function_IsOdd(PyObject *self, PyObject *other); #if PY_MAJOR_VERSION < 3 static PyObject * GMPy_MPZ_Oct_Slot(MPZ_Object *self); static PyObject * GMPy_MPZ_Hex_Slot(MPZ_Object *self); #endif #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mpz_pack.c0000664000175000017500000002066613425753314016545 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_pack.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ************************************************************************** * pack and unpack methods * * Both pack and unpack use a devious trick when stuffing values into the * internal structure of an mpz_t. By setting a bit beyond the range of * interest, we are guaranteed that memory will remain available. When * the bit is cleared, it also triggers normalization of the value by * accounting for leading bits that are zero. ************************************************************************** */ PyDoc_STRVAR(doc_pack, "pack(lst, n) -> mpz\n\n" "Pack a list of integers 'lst' into a single 'mpz' by concatenating\n" "each integer element of 'lst' after padding to length n bits. Raises\n" "an error if any integer is negative or greater than n bits in\n" "length."); static PyObject * GMPy_MPZ_pack(PyObject *self, PyObject *args) { mp_bitcnt_t nbits, total_bits, tempx_bits; Py_ssize_t index, lst_count, i, temp_bits, limb_count; PyObject *lst; mpz_t temp, temp1; MPZ_Object *result, *tempx = 0; CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("pack() requires 'list','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } if (!PyList_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("pack() requires 'list','int' arguments"); return NULL; } if (!(result = GMPy_MPZ_New(context))) return NULL; lst = PyTuple_GET_ITEM(args, 0); lst_count = PyList_GET_SIZE(lst); total_bits = nbits * lst_count; if ((total_bits / lst_count) != nbits) { VALUE_ERROR("result too large to store in an 'mpz'"); return NULL; } mpz_set_ui(result->z, 0); mpz_setbit(result->z, total_bits + (mp_bits_per_limb * 2)); mpz_init(temp); mpz_init(temp1); mpz_set_ui(temp, 0); limb_count = 0; tempx_bits = 0; for (index = 0; index < lst_count; index++) { if (!(tempx = GMPy_MPZ_From_Integer(PyList_GetItem(lst, index), context)) || (mpz_sgn(tempx->z) < 0) || (mpz_sizeinbase(tempx->z,2) > (size_t)nbits)) { TYPE_ERROR("pack() requires list elements be positive integers < 2^n bits"); mpz_clear(temp); Py_XDECREF((PyObject*)tempx); Py_DECREF((PyObject*)result); return NULL; } mpz_mul_2exp(temp1, tempx->z, tempx_bits); mpz_add(temp, temp, temp1); tempx_bits += nbits; i = 0; temp_bits = mpz_sizeinbase(temp, 2) * mpz_sgn(temp); while (tempx_bits >= (mp_bitcnt_t)mp_bits_per_limb) { if (temp_bits > 0) { result->z->_mp_d[limb_count] = mpz_getlimbn(temp, i); } i += 1; tempx_bits -= mp_bits_per_limb; limb_count += 1; temp_bits -= mp_bits_per_limb; } if (temp_bits > 0) { mpz_tdiv_q_2exp(temp, temp, mp_bits_per_limb * i); } else { mpz_set_ui(temp, 0); } Py_DECREF((PyObject*)tempx); } result->z->_mp_d[limb_count] = mpz_getlimbn(temp, 0); mpz_clrbit(result->z, total_bits + (mp_bits_per_limb * 2)); mpz_clear(temp); mpz_clear(temp1); return (PyObject*)result; } PyDoc_STRVAR(doc_unpack, "unpack(x, n) -> list\n\n" "Unpack an integer 'x' into a list of n-bit values. Equivalent to\n" "repeated division by 2**n. Raises error if 'x' is negative."); static PyObject * GMPy_MPZ_unpack(PyObject *self, PyObject *args) { mp_bitcnt_t nbits, total_bits, guard_bit, extra_bits, temp_bits; Py_ssize_t index = 0, lst_count, i, lst_ptr = 0; PyObject *result; mpz_t temp; mp_limb_t extra = 0; MPZ_Object *item, *tempx = NULL; CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("unpack() requires 'int','int' arguments"); return NULL; } nbits = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (nbits == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { return NULL; } if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), context))) { TYPE_ERROR("unpack() requires 'int','int' arguments"); return NULL; } if (mpz_sgn(tempx->z) < 0) { VALUE_ERROR("unpack() requires x >= 0"); return NULL; } if (mpz_sgn(tempx->z) == 0) { total_bits = 0; } else { total_bits = mpz_sizeinbase(tempx->z, 2); } lst_count = total_bits / nbits; if ((total_bits % nbits) || !lst_count) { lst_count += 1; } if (!(result = PyList_New(lst_count))) { Py_DECREF((PyObject*)tempx); return NULL; } if (mpz_sgn(tempx->z) == 0) { if (!(item = GMPy_MPZ_New(context))) { Py_DECREF((PyObject*)tempx); Py_DECREF(result); return NULL; } mpz_set_ui(item->z, 0); PyList_SET_ITEM(result, 0, (PyObject*)item); Py_DECREF((PyObject*)tempx); return result; } mpz_init(temp); guard_bit = nbits + (2 * mp_bits_per_limb); extra_bits = 0; index = 0; while (lst_ptr < lst_count) { i = 0; temp_bits = 0; mpz_set_ui(temp, 0); mpz_setbit(temp, guard_bit); while (temp_bits + extra_bits < nbits) { temp->_mp_d[i++] = mpz_getlimbn(tempx->z, index++); temp_bits += mp_bits_per_limb; } mpz_clrbit(temp, guard_bit); mpz_mul_2exp(temp, temp, extra_bits); if (mpz_sgn(temp) == 0 && extra != 0) { mpz_set_ui(temp, 1); temp->_mp_d[0] = extra; } else { mpn_add_1(temp->_mp_d, temp->_mp_d, mpz_size(temp), extra); } temp_bits += extra_bits; while ((lst_ptr < lst_count) && (temp_bits >= nbits)) { if(!(item = GMPy_MPZ_New(context))) { mpz_clear(temp); Py_DECREF((PyObject*)tempx); Py_DECREF(result); return NULL; } mpz_tdiv_r_2exp(item->z, temp, nbits); PyList_SET_ITEM(result, lst_ptr++, (PyObject*)item); mpz_tdiv_q_2exp(temp, temp, nbits); temp_bits -= nbits; } extra = mpz_getlimbn(temp, 0); extra_bits = temp_bits; } Py_DECREF((PyObject*)tempx); mpz_clear(temp); return result; } gmpy2-2.1.0b3/src/gmpy2_mpz_pack.h0000664000175000017500000000443513425753360016547 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mpz_pack.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MPZ_PACK_H #define GMPY_MPZ_PACK_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_MPZ_pack(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_unpack(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_mul.c0000664000175000017500000004062613425753373015541 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mul.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements the * operator, gmpy2.mul() and context.mul(). * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_Mul(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPZ_Mul_Slot * GMPy_MPQ_Mul_Slot * GMPy_MPFR_Mul_Slot * GMPy_MPC_Mul_Slot * * GMPy_Integer_Mul(Integer, Integer, context|NULL) * GMPy_Rational_Mul(Rational, Rational, context|NULL) * GMPy_Real_Mul(Real, Real, context|NULL) * GMPy_Complex_Mul(Complex, Complex, context|NULL) * * GMPy_Context_Mul(context, args) * */ /* Multiply two Integer objects (see gmpy2_convert.c). If an error occurs, * NULL is returned and an exception is set. If either x or y can't be * converted into an mpz, Py_NotImplemented is returned. */ static PyObject * GMPy_Integer_Mul(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPZ_Check(x)) { if (PyIntOrLong_Check(y)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(y, &error); if (!error) { mpz_mul_si(result->z, MPZ(x), temp); } else { mpz_set_PyIntOrLong(global.tempz, y); mpz_mul(result->z, MPZ(x), global.tempz); } return (PyObject*)result; } if (MPZ_Check(y)) { mpz_mul(result->z, MPZ(x), MPZ(y)); return (PyObject*)result; } } if (MPZ_Check(y)) { if (PyIntOrLong_Check(x)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(x, &error); if (!error) { mpz_mul_si(result->z, MPZ(y), temp); } else { mpz_set_PyIntOrLong(global.tempz, x); mpz_mul(result->z, MPZ(y), global.tempz); } return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { MPZ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPZ_From_Integer(x, context)) || !(tempy = GMPy_MPZ_From_Integer(y, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpz_mul(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Integer_Mul()."); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } /* Implement __mul__ for MPZ_Object. On entry, one of the two arguments must * be an MPZ_Object. If the other object is an Integer, add and return an * MPZ_Object. If the other object isn't an MPZ_Object, call the appropriate * function. If no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPZ_Mul_Slot(PyObject *x, PyObject *y) { if (MPZ_Check(x) && MPZ_Check(y)) { MPZ_Object *result = NULL; if ((result = GMPy_MPZ_New(NULL))) { mpz_mul(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Mul(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Mul(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mul(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mul(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* Multiply two Rational objects (see convert.c/IS_RATIONAL). Returns None and * raises TypeError if both objects are not valid rationals. GMPy_Rational_Mul * is intended to be called from GMPy_Number_Mul. */ static PyObject * GMPy_Rational_Mul(PyObject *x, PyObject *y, CTXT_Object *context) { MPQ_Object *result = NULL; if (!(result = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPQ_Check(x) && MPQ_Check(y)) { mpq_mul(result->q, MPQ(x), MPQ(y)); return (PyObject*)result; } if (IS_RATIONAL(x) && IS_RATIONAL(y)) { MPQ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPQ_From_Number(x, context)) || !(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpq_mul(result->q, tempx->q, tempy->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Rational_Mul()."); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } /* Implement __mul__ for Pympq. On entry, one of the two arguments must * be a Pympq. If the other object is a Rational, add and return a Pympq. * If the other object isn't a Pympq, call the appropriate function. If * no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPQ_Mul_Slot(PyObject *x, PyObject *y) { if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Mul(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mul(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mul(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* Attempt to multiply two numbers and return an mpfr. The code path is * optimized by checking for mpfr objects first. Returns Py_NotImplemented if * both objects are not valid reals. */ static PyObject * GMPy_Real_Mul(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPFR_Check(x) && MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_mul(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } if (MPFR_Check(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_mul_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, y); mpfr_clear_flags(); result->rc = mpfr_mul_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_mul_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy = NULL; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_mul_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_mul_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long temp = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_mul_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, x); mpfr_clear_flags(); result->rc = mpfr_mul_z(result->f, MPFR(y), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(x)) { mpfr_clear_flags(); result->rc = mpfr_mul_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(x)) { MPQ_Object *tempx = NULL; if (!(tempx = GMPy_MPQ_From_Number(x, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_mul_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); goto done; } if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_mul_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context)); goto done; } } if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_mul(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Real_Mul()."); return NULL; /* LCOV_EXCL_STOP */ done: _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } /* Implement __mul__ for Pympfr. On entry, one of the two arguments must * be a Pympfr. If the other object is a Real, add and return a Pympfr. * If the other object isn't a Pympfr, call the appropriate function. If * no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPFR_Mul_Slot(PyObject *x, PyObject *y) { if (MPFR_Check(x) && MPFR_Check(y)) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_mul(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mul(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mul(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* GMPy_Complex_Mul(x, y, context) returns x*y using the provided context. If * an error occurs, NULL is returned and an exception is set. If either x or * y can't be converted to an mpc, then Py_NotImplemented is returned. */ static PyObject * GMPy_Complex_Mul(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPC_Check(x) && MPC_Check(y)) { result->rc = mpc_mul(result->c, MPC(x), MPC(y), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } if (IS_COMPLEX(x) && IS_COMPLEX(y)) { MPC_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context)) || !(tempy = GMPy_MPC_From_Complex(y, 1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } result->rc = mpc_mul(result->c, tempx->c, tempy->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Complex_Mul()."); return NULL; /* LCOV_EXCL_STOP */ } /* GMPy_MPZ_Mul_Slot() is called by mpc.__mul__. It just gets a borrowed reference * to the current context and call Pympc_Mul_Complex(). Since mpc is the last * step of the numeric ladder, the NotImplemented return value from * Pympc_Add_Complex() is correct and is just passed on. */ static PyObject * GMPy_MPC_Mul_Slot(PyObject *x, PyObject *y) { if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mul(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Number_Mul(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Mul(x, y, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Mul(x, y, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Mul(x, y, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Mul(x, y, context); TYPE_ERROR("mul() argument type not supported"); return NULL; } /* Implement context.mul() and gmpy2.mul(). */ PyDoc_STRVAR(GMPy_doc_function_mul, "mul(x, y) -> number\n\n" "Return x * y."); PyDoc_STRVAR(GMPy_doc_context_mul, "context.mul(x, y) -> number\n\n" "Return x * y."); static PyObject * GMPy_Context_Mul(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("mul() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Mul(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_mul.h0000664000175000017500000000564013425753406015540 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_mul.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_MUL_H #define GMPY2_MUL_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_Mul(PyObject *x, PyObject *y, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_Mul(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Rational_Mul(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Real_Mul(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_Mul(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPZ_Mul_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPQ_Mul_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPFR_Mul_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPC_Mul_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_Context_Mul(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_muldiv_2exp.c0000664000175000017500000001607213425753501017171 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_muldiv_2exp.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static PyObject * GMPy_Real_Mul_2exp(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result, *tempx; unsigned long exp = 0; CHECK_CONTEXT(context); exp = c_ulong_From_Integer(y); if (exp == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } result = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); if (!result || !tempx) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpfr_clear_flags(); result->rc = mpfr_mul_2ui(result->f, tempx->f, exp, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Mul_2exp(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result, *tempx; unsigned long exp = 0; CHECK_CONTEXT(context); exp = c_ulong_From_Integer(y); if (exp == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } result = GMPy_MPC_New(0, 0, context); tempx = GMPy_MPC_From_Complex(x, 1, 1, context); if (!result || !tempx) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } result->rc = mpc_mul_2ui(result->c, tempx->c, exp, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_context_mul_2exp, "context.mul_2exp(x, n) -> number\n\n" "Return 'mpfr' or 'mpc' multiplied by 2**n."); PyDoc_STRVAR(GMPy_doc_function_mul_2exp, "mul_2exp(x, n) -> number\n\n" "Return 'mpfr' or 'mpc' multiplied by 2**n."); static PyObject * GMPy_Number_Mul_2exp(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_REAL(x)) return GMPy_Real_Mul_2exp(x, y, context); if (IS_COMPLEX(x)) return GMPy_Complex_Mul_2exp(x, y, context); TYPE_ERROR("mul_2exp() argument type not supported"); return NULL; } static PyObject * GMPy_Context_Mul_2exp(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("mul_2exp() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Mul_2exp(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } /* ======================================================================= */ static PyObject * GMPy_Real_Div_2exp(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result, *tempx; unsigned long exp = 0; CHECK_CONTEXT(context); exp = c_ulong_From_Integer(y); if (exp == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } result = GMPy_MPFR_New(0, context); tempx = GMPy_MPFR_From_Real(x, 1, context); if (!result || !tempx) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } mpfr_clear_flags(); result->rc = mpfr_div_2ui(result->f, tempx->f, exp, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Div_2exp(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result, *tempx; unsigned long exp = 0; CHECK_CONTEXT(context); exp = c_ulong_From_Integer(y); if (exp == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } result = GMPy_MPC_New(0, 0, context); tempx = GMPy_MPC_From_Complex(x, 1, 1, context); if (!result || !tempx) { Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; } result->rc = mpc_div_2ui(result->c, tempx->c, exp, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_context_div_2exp, "context.div_2exp(x, n) -> number\n\n" "Return 'mpfr' or 'mpc' divided by 2**n."); PyDoc_STRVAR(GMPy_doc_function_div_2exp, "div_2exp(x, n) -> number\n\n" "Return 'mpfr' or 'mpc' divided by 2**n."); static PyObject * GMPy_Number_Div_2exp(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_REAL(x)) return GMPy_Real_Div_2exp(x, y, context); if (IS_COMPLEX(x)) return GMPy_Complex_Div_2exp(x, y, context); TYPE_ERROR("div_2exp() argument type not supported"); return NULL; } static PyObject * GMPy_Context_Div_2exp(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("div_2exp() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Div_2exp(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_muldiv_2exp.h0000664000175000017500000000550513425753512017177 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_muldiv_2exp.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_MULDIV_2EXP_H #define GMPY_MULDIV_2EXP_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Real_Mul_2exp(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_Mul_2exp(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Mul_2exp(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Mul_2exp(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Div_2exp(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_Div_2exp(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Div_2exp(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Div_2exp(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_plus.c0000664000175000017500000001126713425753526015726 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_plus.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements __pos__ and context.plus(). * * Public API * ========== * The following function is available as part of GMPY2's C API. If the value * of context is NULL, then the function should use the currently active * context. * * GMPy_Number_Plus(Number, context) * * Private API * =========== * GMPy_MPZ_Plus_Slot * GMPy_MPQ_Plus_Slot * GMPy_MPFR_Plus_Slot * GMPy_MPC_Plus_Slot * * GMPy_Integer_Plus(Integer, context|NULL) * GMPy_Rational_Plus(Rational, context|NULL) * GMPy_Real_Plus(Real, context|NULL) * GMPy_Complex_Plus(Complex, context|NULL) * * GMPy_Context_Plus(context, args) */ static PyObject * GMPy_Integer_Plus(PyObject *x, CTXT_Object *context) { return (PyObject*)GMPy_MPZ_From_Integer(x, context); } static PyObject * GMPy_MPZ_Plus_Slot(MPZ_Object *x) { Py_INCREF((PyObject*)x); return (PyObject*)x; } static PyObject * GMPy_Rational_Plus(PyObject *x, CTXT_Object *context) { return (PyObject*)GMPy_MPQ_From_Rational(x, context); } static PyObject * GMPy_MPQ_Plus_Slot(MPQ_Object *x) { Py_INCREF((PyObject*)x); return (PyObject*)x; } static PyObject * GMPy_Real_Plus(PyObject *x, CTXT_Object *context) { return (PyObject*)GMPy_MPFR_From_Real(x, 0, context); } static PyObject * GMPy_MPFR_Plus_Slot(MPFR_Object *x) { return (PyObject*)GMPy_MPFR_From_MPFR(x, 0, NULL); } static PyObject * GMPy_Complex_Plus(PyObject *x, CTXT_Object *context) { return (PyObject*)GMPy_MPC_From_Complex(x, 0, 0, context); } static PyObject * GMPy_MPC_Plus_Slot(MPC_Object *x) { return (PyObject*)GMPy_MPC_From_MPC(x, 0, 0, NULL); } static PyObject * GMPy_Number_Plus(PyObject *x, CTXT_Object *context) { if (IS_INTEGER(x)) return GMPy_Integer_Plus(x, context); if (IS_RATIONAL_ONLY(x)) return GMPy_Rational_Plus(x, context); if (IS_REAL_ONLY(x)) return GMPy_Real_Plus(x, context); if (IS_COMPLEX_ONLY(x)) return GMPy_Complex_Plus(x, context); TYPE_ERROR("plus() argument type not supported"); return NULL; } /* Implement context.plus(). The following code assumes it used a as method of * a context. */ PyDoc_STRVAR(GMPy_doc_context_plus, "context.plus(x) -> number\n\n" "Return +x, the context is applied to the result."); static PyObject * GMPy_Context_Plus(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("plus() requires 1 argument."); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Plus(PyTuple_GET_ITEM(args, 0), context); } gmpy2-2.1.0b3/src/gmpy2_plus.h0000664000175000017500000000550113425753540015721 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_plus.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_PLUS_H #define GMPY2_PLUS_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_Plus(PyObject *x, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_Plus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Rational_Plus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Real_Plus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Plus(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPZ_Plus_Slot(MPZ_Object *x); static PyObject * GMPy_MPQ_Plus_Slot(MPQ_Object *x); static PyObject * GMPy_MPFR_Plus_Slot(MPFR_Object *x); static PyObject * GMPy_MPC_Plus_Slot(MPC_Object *x); static PyObject * GMPy_Context_Plus(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_pow.c0000664000175000017500000004203513425753552015544 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_pow.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements the ** operator, Python's pow() function, * gmpy2.powmod(), and context.pow(). * * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_Pow(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPANY_Pow_Slot * * GMPy_Integer_Pow(Integer, Integer, Integer|Py_None, context|NULL) * GMPy_Integer_PowMod(Integer, Integer, Integer|Py_None, context|NULL) * GMPy_Rational_Pow(Rational, Rational, context|NULL) * GMPy_Real_Pow(Real, Real, context|NULL) * GMPy_Complex_Pow(Complex, Complex, context|NULL) * * GMPy_Context_Pow(context, args) */ /* Pympz_Pow_Integer is called by GMPy_Number_Pow() after verifying that the * first two arguments are integers, but not necessarily mpz. The third * argument must either be an integer or Py_None. The context argument is not * currently used but may be used in the future. */ /* TODO: refactor to improve performance. * - dont't convert the exponent to an MPZ if there is no modulus */ static PyObject * GMPy_Integer_Pow(PyObject *b, PyObject *e, PyObject *m, CTXT_Object *context) { MPZ_Object *result = NULL, *tempb = NULL, *tempe = NULL, *tempm = NULL; int has_mod; /* Try to parse the modulus value first. */ if (m == Py_None) { has_mod = 0; } else { has_mod = 1; if (!IS_INTEGER(m)) { Py_RETURN_NOTIMPLEMENTED; } else { if (!(tempm = GMPy_MPZ_From_Integer(m, context))) { goto err; } } } result = GMPy_MPZ_New(context); tempb = GMPy_MPZ_From_Integer(b, context); tempe = GMPy_MPZ_From_Integer(e, context); if (!tempb || !tempe || !result) { goto err; } if (!has_mod) { /* When no modulo is present, the exponent must fit in unsigned long. */ unsigned long el; if (mpz_sgn(tempe->z) < 0) { VALUE_ERROR("pow() exponent cannot be negative"); goto err; } /* Catch -1, 0, 1 getting raised to large exponents. */ if (mpz_cmp_si(tempb->z, 0) == 0) { if (mpz_cmp_si(tempe->z, 0) == 0) { mpz_set_ui(result->z, 1); } else { mpz_set_ui(result->z, 0); } goto done; } if (mpz_cmp_si(tempb->z, 1) == 0) { mpz_set_ui(result->z, 1); goto done; } if (mpz_cmp_si(tempb->z, -1) == 0) { if (mpz_even_p(tempe->z)) { mpz_set_ui(result->z, 1); } else { mpz_set_si(result->z, -1); } goto done; } if (!mpz_fits_ulong_p(tempe->z)) { VALUE_ERROR("pow() outrageous exponent"); goto err; } el = (unsigned long) mpz_get_ui(tempe->z); mpz_pow_ui(result->z, tempb->z, el); goto done; } else { /* Modulo is present. */ int sign; mpz_t mm, base, exp; sign = mpz_sgn(tempm->z); if (sign == 0) { VALUE_ERROR("pow() 3rd argument cannot be 0"); goto err; } mpz_init(mm); mpz_abs(mm, tempm->z); /* A negative exponent is allowed if inverse exists. */ if (mpz_sgn(tempe->z) < 0) { mpz_init(base); mpz_init(exp); if (!mpz_invert(base, tempb->z, mm)) { VALUE_ERROR("pow() base not invertible"); mpz_clear(base); mpz_clear(exp); mpz_clear(mm); goto err; } else { mpz_abs(exp, tempe->z); } mpz_powm(result->z, base, exp, mm); mpz_clear(base); mpz_clear(exp); } else { mpz_powm(result->z, tempb->z, tempe->z, mm); } mpz_clear(mm); /* Python uses a rather peculiar convention for negative modulos * If the modulo is negative, result should be in the interval * m < r <= 0 . */ if ((sign < 0) && (mpz_sgn(MPZ(result)) > 0)) { mpz_add(result->z, result->z, tempm->z); } } done: Py_XDECREF((PyObject*)tempb); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempm); return (PyObject*)result; err: Py_XDECREF((PyObject*)tempb); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempm); Py_DECREF((PyObject*)result); return NULL; } static PyObject * GMPy_Rational_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context) { MPQ_Object *tempbq = NULL, *resultq = NULL; MPZ_Object *tempez = NULL; int bsign; long tempexp; if (mod != Py_None) { TYPE_ERROR("pow() 3rd argument not allowed unless all arguments are integers"); return NULL; } /* Only support mpq**int. Everything else gets converted to mpf. */ if (IS_RATIONAL(base) && IS_INTEGER(exp)) { resultq = GMPy_MPQ_New(context); tempbq = GMPy_MPQ_From_Rational(base, context); tempez = GMPy_MPZ_From_Integer(exp, context); if (!resultq || !tempbq || !tempez) { Py_XDECREF((PyObject*)resultq); Py_XDECREF((PyObject*)tempbq); Py_XDECREF((PyObject*)tempez); return NULL; } if (!mpz_fits_slong_p(tempez->z)) { VALUE_ERROR("mpq.pow() outrageous exponent"); Py_DECREF((PyObject*)resultq); Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return NULL; } tempexp = (long) mpz_get_si(tempez->z); if (tempexp == 0) { mpq_set_si(resultq->q, 1, 1); Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return (PyObject*)resultq; } bsign = mpq_sgn(tempbq->q); if (tempexp < 0) { if (bsign == 0) { ZERO_ERROR("pow() 0 base to negative exponent"); Py_DECREF((PyObject*)resultq); Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return NULL; } if (bsign < 0) { mpz_neg(mpq_numref(resultq->q), mpq_denref(tempbq->q)); } else { mpz_set(mpq_numref(resultq->q), mpq_denref(tempbq->q)); } mpz_abs(mpq_denref(resultq->q), mpq_numref(tempbq->q)); tempexp = -tempexp; } else { mpq_set(resultq->q, tempbq->q); } if (tempexp > 1) { mpz_pow_ui(mpq_numref(resultq->q), mpq_numref(resultq->q), tempexp); mpz_pow_ui(mpq_denref(resultq->q), mpq_denref(resultq->q), tempexp); } Py_DECREF((PyObject*)tempbq); Py_DECREF((PyObject*)tempez); return (PyObject*)resultq; } else { return GMPy_Real_Pow(base, exp, Py_None, context); } } static PyObject * GMPy_Real_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context) { MPFR_Object *tempb = NULL, *tempe = NULL, *result = NULL; MPZ_Object *tempz = NULL; MPC_Object *mpc_result = NULL; if (mod != Py_None) { TYPE_ERROR("pow() 3rd argument not allowed unless all arguments are integers"); return NULL; } CHECK_CONTEXT(context); result = GMPy_MPFR_New(0, context); tempb = GMPy_MPFR_From_Real(base, 1, context); if (!result || !tempb) { goto err; } mpfr_clear_flags(); if (PyIntOrLong_Check(exp)) { int error; long temp_exp = GMPy_Integer_AsLongAndError(exp, &error); if (!error) { result->rc = mpfr_pow_si(result->f, tempb->f, temp_exp, GET_MPFR_ROUND(context)); } else { mpz_t tempzz; mpz_init(tempzz); mpz_set_PyIntOrLong(tempzz, exp); result->rc = mpfr_pow_z(result->f, tempb->f, tempzz, GET_MPFR_ROUND(context)); mpz_clear(tempzz); } } else if (IS_INTEGER(exp)) { if (!(tempz = GMPy_MPZ_From_Integer(exp, context))) { goto err; } result->rc = mpfr_pow_z(result->f, tempb->f, tempz->z, GET_MPFR_ROUND(context)); } else { if (!(tempe = GMPy_MPFR_From_Real(exp, 1, context))) { goto err; } result->rc = mpfr_pow(result->f, tempb->f, tempe->f, GET_MPFR_ROUND(context)); } /* If the result is NaN, check if a complex result works. */ if (mpfr_nanflag_p() && context->ctx.allow_complex) { mpc_result = (MPC_Object*)GMPy_Complex_Pow(base, exp, Py_None, context); if (!mpc_result || MPC_IS_NAN_P(mpc_result)) { Py_XDECREF((PyObject*)mpc_result); context->ctx.invalid = 1; GMPY_INVALID("pow() invalid operation"); goto err; } /* return a valid complex result */ Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempb); Py_XDECREF((PyObject*)result); return (PyObject*)mpc_result; } _GMPy_MPFR_Cleanup(&result, context); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempb); return (PyObject*)result; err: Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempb); return NULL; } static PyObject * GMPy_Complex_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context) { MPC_Object *tempb = NULL, *tempe = NULL, *result= NULL; MPFR_Object *tempf = NULL; MPZ_Object *tempz = NULL; if (mod != Py_None) { TYPE_ERROR("pow() 3rd argument not allowed unless all arguments are integers"); return NULL; } CHECK_CONTEXT(context); result = GMPy_MPC_New(0, 0, context); tempb = GMPy_MPC_From_Complex(base, 1, 1, context); if (!result || !tempb) { goto err; } mpfr_clear_flags(); if (PyIntOrLong_Check(exp)) { int error; long temp_exp = GMPy_Integer_AsLongAndError(exp, &error); if (!error) { result->rc = mpc_pow_si(result->c, tempb->c, temp_exp, GET_MPC_ROUND(context)); } else { mpz_t tempzz; mpz_init(tempzz); mpz_set_PyIntOrLong(tempzz, exp); result->rc = mpc_pow_z(result->c, tempb->c, tempzz, GET_MPC_ROUND(context)); mpz_clear(tempzz); } } else if (IS_INTEGER(exp)) { if (!(tempz = GMPy_MPZ_From_Integer(exp, context))) { goto err; } result->rc = mpc_pow_z(result->c, tempb->c, tempz->z, GET_MPC_ROUND(context)); } else if (IS_REAL(exp)) { if (!(tempf = GMPy_MPFR_From_Real(exp, 1, context))) { goto err; } result->rc = mpc_pow_fr(result->c, tempb->c, tempf->f, GET_MPC_ROUND(context)); } else { if (!(tempe = GMPy_MPC_From_Complex(exp, 1, 1, context))) { goto err; } result->rc = mpc_pow(result->c, tempb->c, tempe->c, GET_MPC_ROUND(context)); } _GMPy_MPC_Cleanup(&result, context); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempf); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempb); return (PyObject*)result; err: Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempz); Py_XDECREF((PyObject*)tempf); Py_XDECREF((PyObject*)tempe); Py_XDECREF((PyObject*)tempb); return NULL; } PyDoc_STRVAR(GMPy_doc_integer_powmod, "powmod(x, y, m) -> mpz\n\n" "Return (x**y) mod m. Same as the three argument version of Python's\n" "built-in pow(), but converts all three arguments to mpz."); static PyObject * GMPy_Integer_PowMod(PyObject *self, PyObject *args) { PyObject *x, *y, *m; if (PyTuple_GET_SIZE(args) != 3) { TYPE_ERROR("powmod() requires 3 arguments."); return NULL; } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); m = PyTuple_GET_ITEM(args, 2); if (IS_INTEGER(x) && IS_INTEGER(y) && IS_INTEGER(m)) return GMPy_Integer_Pow(x, y, m, NULL); TYPE_ERROR("powmod() argument types not supported"); return NULL; } static PyObject * GMPy_Number_Pow(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Pow(x, y, z, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Pow(x, y, z, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Pow(x, y, z, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Pow(x, y, z, context); TYPE_ERROR("pow() argument type not supported"); return NULL; } PyDoc_STRVAR(GMPy_doc_context_pow, "context.pow(x, y) -> number\n\n" "Return x ** y."); static PyObject * GMPy_Context_Pow(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("pow() requires 2 arguments."); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Pow(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), Py_None, context); } static PyObject * GMPy_MPANY_Pow_Slot(PyObject *base, PyObject *exp, PyObject *mod) { if (IS_INTEGER(base) && IS_INTEGER(exp)) return GMPy_Integer_Pow(base, exp, mod, NULL); if (IS_RATIONAL(base) && IS_RATIONAL(exp)) return GMPy_Rational_Pow(base, exp, mod, NULL); if (IS_REAL(base) && IS_REAL(exp)) return GMPy_Real_Pow(base, exp, mod, NULL); if (IS_COMPLEX(base) && IS_COMPLEX(exp)) return GMPy_Complex_Pow(base, exp, mod, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_MPFR_Pow_Slot(PyObject *base, PyObject *exp, PyObject *mod) { if (MPFR_Check(base) && (PyIntOrLong_Check(exp)) && (mod == Py_None)) { MPFR_Object *result = NULL; int error = 0; long temp_exp; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); temp_exp = GMPy_Integer_AsLongAndError(exp, &error); if (!error) { result->rc = mpfr_pow_si(result->f, MPFR(base), temp_exp, GET_MPFR_ROUND(context)); } else { mpz_t tempzz; mpz_init(tempzz); mpz_set_PyIntOrLong(tempzz, exp); result->rc = mpfr_pow_z(result->f, MPFR(base), tempzz, GET_MPFR_ROUND(context)); mpz_clear(tempzz); } _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } if (IS_REAL(base) && IS_REAL(exp)) return GMPy_Real_Pow(base, exp, mod, NULL); if (IS_COMPLEX(base) && IS_COMPLEX(exp)) return GMPy_Complex_Pow(base, exp, mod, NULL); Py_RETURN_NOTIMPLEMENTED; } gmpy2-2.1.0b3/src/gmpy2_pow.h0000664000175000017500000000573513425753563015561 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_pow.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_POW_H #define GMPY2_POW_H #ifdef __cplusplus extern "C" { #endif /* Private API */ static PyObject * GMPy_MPANY_Pow_Slot(PyObject *base, PyObject *exp, PyObject *mod); static PyObject * GMPy_MPFR_Pow_Slot(PyObject *base, PyObject *exp, PyObject *mod); static PyObject * GMPy_Integer_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context); static PyObject * GMPy_Rational_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context); static PyObject * GMPy_Real_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context); static PyObject * GMPy_Complex_Pow(PyObject *base, PyObject *exp, PyObject *mod, CTXT_Object *context); static PyObject * GMPy_Integer_PowMod(PyObject *self, PyObject *args); static PyObject * GMPy_Context_Pow(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Pow(PyObject *x, PyObject *y, PyObject *z, CTXT_Object *context); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_predicate.c0000664000175000017500000003421313425753604016674 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_predicate.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* To work with the MPC_IS_ macros, NAN, INF, FINITE, and ZERO are * all upper-case. */ PyDoc_STRVAR(GMPy_doc_function_is_nan, "is_nan(x) -> boolean\n\n" "Return True if x is NaN (Not-A-Number)."); PyDoc_STRVAR(GMPy_doc_context_is_nan, "context.is_nan(x) -> boolean\n\n" "Return True if x is NaN (Not-A-Number)."); PyDoc_STRVAR(GMPy_doc_method_is_nan, "x.is_nan() -> boolean\n\n" "Return True if x is NaN (Not-A-Number)."); static PyObject * GMPy_Real_Is_NAN(PyObject *x, CTXT_Object *context) { MPFR_Object *tempx; int res; if (MPFR_Check(x)) { res = mpfr_nan_p(MPFR(x)); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } res = mpfr_nan_p(tempx->f); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPFR_Is_NAN_Method(PyObject *self, PyObject *args) { return GMPy_Real_Is_NAN(self, NULL); } static PyObject * GMPy_Complex_Is_NAN(PyObject *x, CTXT_Object *context) { MPC_Object *tempx; int res; if (MPC_Check(x)) { res = MPC_IS_NAN_P(x); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } res = MPC_IS_NAN_P(tempx); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPC_Is_NAN_Method(PyObject *self, PyObject *args) { return GMPy_Complex_Is_NAN(self, NULL); } /* This creates the following functions: * GMPy_Number_Is_NAN(x, context) * GMPy_Context_Is_NAN(self, other) * * They assume the following functions have been defined above: * GMPy_Real_Is_NAN(x, context) * GMPy_Complex_Is_NAN(x, context) * * In addition, the following function should also be defined: * GMPy_Real_Is_NAN_Method(self, noargs) * GMPy_Complex_Is_NAN_Method(self, noargs) */ GMPY_MPFR_MPC_UNIOP_TEMPLATE(Is_NAN, is_nan); PyDoc_STRVAR(GMPy_doc_function_is_infinite, "is_infinite(x) -> boolean\n\n" "Return True if x is +Infinity or -Infinity. If x is an mpc, return True\n" "if either x.real or x.imag is infinite. "); PyDoc_STRVAR(GMPy_doc_context_is_infinite, "context.is_infinite(x) -> boolean\n\n" "Return True if x is +Infinity or -Infinity. If x is an mpc, return True\n" "if either x.real or x.imag is infinite."); PyDoc_STRVAR(GMPy_doc_method_is_infinite, "x.is_infinite() -> boolean\n\n" "Return True if x is +Infinity or -Infinity. If x is an mpc, return True\n" "if either x.real or x.imag is infinite."); static PyObject * GMPy_Real_Is_Infinite(PyObject *x, CTXT_Object *context) { MPFR_Object *tempx; int res; if (MPFR_Check(x)) { res = mpfr_inf_p(MPFR(x)); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } res = mpfr_inf_p(tempx->f); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPFR_Is_Infinite_Method(PyObject *self, PyObject *args) { return GMPy_Real_Is_Infinite(self, NULL); } static PyObject * GMPy_Complex_Is_Infinite(PyObject *x, CTXT_Object *context) { MPC_Object *tempx; int res; if (MPC_Check(x)) { res = MPC_IS_INF_P(x); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } res = MPC_IS_INF_P(tempx); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPC_Is_Infinite_Method(PyObject *self, PyObject *args) { return GMPy_Complex_Is_Infinite(self, NULL); } GMPY_MPFR_MPC_UNIOP_TEMPLATE(Is_Infinite, is_infinite); PyDoc_STRVAR(GMPy_doc_function_is_finite, "is_finite(x) -> boolean\n\n" "Return True if x is an actual number (i.e. non NaN or Infinity). If x is\n" "an mpc, return True if both x.real and x.imag are finite."); PyDoc_STRVAR(GMPy_doc_context_is_finite, "context.is_finite(x) -> boolean\n\n" "Return True if x is an actual number (i.e. non NaN or Infinity). If x is\n" "an mpc, return True if both x.real and x.imag are finite."); PyDoc_STRVAR(GMPy_doc_method_is_finite, "x.is_finite() -> boolean\n\n" "Return True if x is an actual number (i.e. non NaN or Infinity). If x is\n" "an mpc, return True if both x.real and x.imag are finite."); static PyObject * GMPy_Real_Is_Finite(PyObject *x, CTXT_Object *context) { MPFR_Object *tempx; int res; if (MPFR_Check(x)) { res = mpfr_number_p(MPFR(x)); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } res = mpfr_number_p(tempx->f); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPFR_Is_Finite_Method(PyObject *self, PyObject *args) { return GMPy_Real_Is_Finite(self, NULL); } static PyObject * GMPy_Complex_Is_Finite(PyObject *x, CTXT_Object *context) { MPC_Object *tempx; int res; if (MPC_Check(x)) { res = MPC_IS_FINITE_P(x); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } res = MPC_IS_FINITE_P(tempx); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPC_Is_Finite_Method(PyObject *self, PyObject *args) { return GMPy_Complex_Is_Finite(self, NULL); } GMPY_MPFR_MPC_UNIOP_TEMPLATE(Is_Finite, is_finite); PyDoc_STRVAR(GMPy_doc_function_is_zero, "is_zero(x) -> boolean\n\n" "Return True if x is equal to 0. If x is an mpc, return True if both x.real\n" "and x.imag are equal to 0."); PyDoc_STRVAR(GMPy_doc_context_is_zero, "context.is_zero(x) -> boolean\n\n" "Return True if x is equal to 0. If x is an mpc, return True if both x.real\n" "and x.imag are equal to 0."); PyDoc_STRVAR(GMPy_doc_method_is_zero, "x.is_zero() -> boolean\n\n" "Return True if x is equal to 0. If x is an mpc, return True if both x.real\n" "and x.imag are equal to 0."); static PyObject * GMPy_Real_Is_Zero(PyObject *x, CTXT_Object *context) { MPFR_Object *tempx; int res; if (MPFR_Check(x)) { res = mpfr_zero_p(MPFR(x)); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } res = mpfr_zero_p(tempx->f); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPFR_Is_Zero_Method(PyObject *self, PyObject *args) { return GMPy_Real_Is_Zero(self, NULL); } static PyObject * GMPy_Complex_Is_Zero(PyObject *x, CTXT_Object *context) { MPC_Object *tempx; int res; if (MPC_Check(x)) { res = MPC_IS_ZERO_P(x); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } res = MPC_IS_ZERO_P(tempx); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPC_Is_Zero_Method(PyObject *self, PyObject *args) { return GMPy_Complex_Is_Zero(self, NULL); } GMPY_MPFR_MPC_UNIOP_TEMPLATE(Is_Zero, is_zero); PyDoc_STRVAR(GMPy_doc_function_is_signed, "is_signed(x) -> boolean\n\n" "Return True if the sign bit of x is set."); PyDoc_STRVAR(GMPy_doc_context_is_signed, "context.is_signed(x) -> boolean\n\n" "Return True if the sign bit of x is set."); PyDoc_STRVAR(GMPy_doc_method_is_signed, "x.is_signed() -> boolean\n\n" "Return True if the sign bit of x is set."); static PyObject * GMPy_Real_Is_Signed(PyObject *x, CTXT_Object *context) { MPFR_Object *tempx; int res; if (MPFR_Check(x)) { res = mpfr_signbit(MPFR(x)); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } res = mpfr_signbit(tempx->f); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPFR_Is_Signed_Method(PyObject *self, PyObject *args) { return GMPy_Real_Is_Signed(self, NULL); } GMPY_MPFR_UNIOP_TEMPLATE(Is_Signed, is_signed); PyDoc_STRVAR(GMPy_doc_function_is_regular, "is_regular(x) -> boolean\n\n" "Return True if x is not zero, NaN, or Infinity; False otherwise."); PyDoc_STRVAR(GMPy_doc_context_is_regular, "context.is_regular(x) -> boolean\n\n" "Return True if x is not zero, NaN, or Infinity; False otherwise."); PyDoc_STRVAR(GMPy_doc_method_is_regular, "x.is_regular() -> boolean\n\n" "Return True if x is not zero, NaN, or Infinity; False otherwise."); static PyObject * GMPy_Real_Is_Regular(PyObject *x, CTXT_Object *context) { MPFR_Object *tempx; int res; if (MPFR_Check(x)) { res = mpfr_regular_p(MPFR(x)); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } res = mpfr_regular_p(tempx->f); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPFR_Is_Regular_Method(PyObject *self, PyObject *args) { return GMPy_Real_Is_Regular(self, NULL); } GMPY_MPFR_UNIOP_TEMPLATE(Is_Regular, is_regular); PyDoc_STRVAR(GMPy_doc_function_is_integer, "is_integer(x) -> boolean\n\n" "Return True if x is an integer; False otherwise."); PyDoc_STRVAR(GMPy_doc_context_is_integer, "context.is_integer(x) -> boolean\n\n" "Return True if x is an integer; False otherwise."); PyDoc_STRVAR(GMPy_doc_method_is_integer, "x.is_integer() -> boolean\n\n" "Return True if x is an integer; False otherwise."); static PyObject * GMPy_Real_Is_Integer(PyObject *x, CTXT_Object *context) { MPFR_Object *tempx; int res; if (MPFR_Check(x)) { res = mpfr_integer_p(MPFR(x)); } else { CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } res = mpfr_integer_p(tempx->f); Py_DECREF((PyObject*)tempx); } if (res) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * GMPy_MPFR_Is_Integer_Method(PyObject *self, PyObject *args) { return GMPy_Real_Is_Integer(self, NULL); } GMPY_MPFR_UNIOP_TEMPLATE(Is_Integer, is_integer); PyDoc_STRVAR(GMPy_doc_function_is_lessgreater, "is_lessgreater(x,y) -> boolean\n\n" "Return True if x > y or x < y. Return False if x == y or either x\n" "and/or y is NaN."); static PyObject * GMPy_Real_Is_LessGreater(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx, *tempy; int res; CHECK_CONTEXT(context); tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { return NULL; } res = mpfr_lessgreater_p(tempx->f, tempy->f); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } GMPY_MPFR_BINOP_TEMPLATE(Is_LessGreater, is_lessgreater) PyDoc_STRVAR(GMPy_doc_function_is_unordered, "is_unordered(x,y) -> boolean\n\n" "Return True if either x and/or y is NaN."); static PyObject * GMPy_Real_Is_Unordered(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *tempx, *tempy; int res; CHECK_CONTEXT(context); tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { return NULL; } res = mpfr_unordered_p(tempx->f, tempy->f); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; } GMPY_MPFR_BINOP_TEMPLATE(Is_Unordered, is_unordered) gmpy2-2.1.0b3/src/gmpy2_predicate.h0000664000175000017500000001253213425753615016703 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_predicate.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_PREDICATE_H #define GMPY_PREDICATE_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Real_Is_NAN(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Is_NAN_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Complex_Is_NAN(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPC_Is_NAN_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Is_NAN(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Is_NAN(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Is_Infinite(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Is_Infinite_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Complex_Is_Infinite(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPC_Is_Infinite_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Is_Infinite(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Is_Infinite(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Is_Finite(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Is_Finite_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Complex_Is_Finite(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPC_Is_Finite_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Is_Finite(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Is_Finite(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Is_Zero(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Is_Zero_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Complex_Is_Zero(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPC_Is_Zero_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Is_Zero(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Is_Zero(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Is_Signed(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Is_Signed_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Is_Signed(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Is_Signed(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Is_Regular(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Is_Regular_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Is_Regular(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Is_Regular(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Is_Integer(PyObject *x, CTXT_Object *context); static PyObject * GMPy_MPFR_Is_Integer_Method(PyObject *self, PyObject *args); static PyObject * GMPy_Number_Is_Integer(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Is_Integer(PyObject *self, PyObject *other); static PyObject * GMPy_Real_Is_LessGreater(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Is_LessGreater(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Is_LessGreater(PyObject *self, PyObject *args); static PyObject * GMPy_Real_Is_Unordered(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Number_Is_Unordered(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Context_Is_Unordered(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_random.c0000664000175000017500000003247513425753630016223 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_random.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static RandomState_Object * GMPy_RandomState_New(void) { RandomState_Object *result; if ((result = PyObject_New(RandomState_Object, &RandomState_Type))) { gmp_randinit_default(result->state); } return result; }; static void GMPy_RandomState_Dealloc(RandomState_Object *self) { gmp_randclear(self->state); PyObject_Del(self); }; static PyObject * GMPy_RandomState_Repr(RandomState_Object *self) { return Py_BuildValue("s", ""); }; PyDoc_STRVAR(GMPy_doc_random_state_factory, "random_state([seed]) -> object\n\n" "Return new object containing state information for the random number\n" "generator. An optional integer can be specified as the seed value."); static PyObject * GMPy_RandomState_Factory(PyObject *self, PyObject *args) { RandomState_Object *result; MPZ_Object *temp; if (!(result = GMPy_RandomState_New())) { return NULL; } if (PyTuple_GET_SIZE(args) == 0) { gmp_randseed_ui(result->state, 0); } else if (PyTuple_GET_SIZE(args) == 1) { if (!(temp = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args,0), NULL))) { Py_DECREF((PyObject*)result); TYPE_ERROR("seed must be an integer"); return NULL; } gmp_randseed(result->state, temp->z); Py_DECREF((PyObject*)temp); } else { Py_DECREF((PyObject*)result); TYPE_ERROR("random_state() requires 0 or 1 integer arguments"); return NULL; } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_urandomb_function, "mpz_urandomb(random_state, bit_count) -> mpz\n\n" "Return uniformly distributed random integer between 0 and\n" "2**bit_count-1."); static PyObject * GMPy_MPZ_urandomb_Function(PyObject *self, PyObject *args) { MPZ_Object *result; mp_bitcnt_t len; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("mpz_urandomb() requires 2 arguments"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpz_urandomb() requires 'random_state' and 'bit_count' arguments"); return NULL; } len = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (len == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { TYPE_ERROR("mpz_urandomb() requires 'random_state' and 'bit_count' arguments"); return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_urandomb(result->z, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), len); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_rrandomb_function, "mpz_rrandomb(random_state, bit_count) -> mpz\n\n" "Return a random integer between 0 and 2**bit_count-1 with long\n" "sequences of zeros and one in its binary representation."); static PyObject * GMPy_MPZ_rrandomb_Function(PyObject *self, PyObject *args) { MPZ_Object *result; mp_bitcnt_t len; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("mpz_rrandomb() requires 2 arguments"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpz_rrandomb() requires 'random_state' and 'bit_count' arguments"); return NULL; } len = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (len == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { TYPE_ERROR("mpz_rrandomb() requires 'random_state' and 'bit_count' arguments"); return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_rrandomb(result->z, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), len); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpz_random_function, "mpz_random(random_state, int) -> mpz\n\n" "Return uniformly distributed random integer between 0 and n-1."); static PyObject * GMPy_MPZ_random_Function(PyObject *self, PyObject *args) { MPZ_Object *result, *temp; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("mpz_random() requires 2 arguments"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpz_random() requires 'random_state' and 'int' arguments"); return NULL; } if (!(temp = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { TYPE_ERROR("mpz_random() requires 'random_state' and 'int' arguments"); return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_urandomm(result->z, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), temp->z); } Py_DECREF((PyObject*)temp); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpfr_random_function, "mpfr_random(random_state) -> mpfr\n\n" "Return uniformly distributed number between [0,1]."); static PyObject * GMPy_MPFR_random_Function(PyObject *self, PyObject *args) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("mpfr_random() requires 1 argument"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpfr_random() requires 'random_state' argument"); return NULL; } if ((result = GMPy_MPFR_New(0, context))) { mpfr_urandom(result->f, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), GET_MPFR_ROUND(context)); } return (PyObject*)result; } #if MPFR_VERSION_MAJOR > 3 PyDoc_STRVAR(GMPy_doc_mpfr_nrandom_function, "mpfr_nrandom(random_state) -> (mpfr)\n\n" "Return a random number with gaussian distribution."); static PyObject * GMPy_MPFR_nrandom_Function(PyObject *self, PyObject *args) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("mpfr_nrandom() requires 1 argument"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpfr_nrandom() requires 'random_state' argument"); return NULL; } if ((result = GMPy_MPFR_New(0, context))) { mpfr_nrandom(result->f, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), GET_MPFR_ROUND(context)); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_mpfr_grandom_function, "mpfr_grandom(random_state) -> (mpfr, mpfr)\n\n" "Return two random numbers with gaussian distribution."); static PyObject * GMPy_MPFR_grandom_Function(PyObject *self, PyObject *args) { MPFR_Object *result1, *result2; PyObject *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("mpfr_grandom() requires 1 argument"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpfr_grandom() requires 'random_state' argument"); return NULL; } result1 = GMPy_MPFR_New(0, context); result2 = GMPy_MPFR_New(0, context); if (!result1 || !result2) { Py_XDECREF((PyObject*)result1); Py_XDECREF((PyObject*)result2); return NULL; } mpfr_nrandom(result1->f, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), GET_MPFR_ROUND(context)); mpfr_nrandom(result2->f, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), GET_MPFR_ROUND(context)); result = Py_BuildValue("(NN)", (PyObject*)result1, (PyObject*)result2); if (!result) { Py_DECREF((PyObject*)result1); Py_DECREF((PyObject*)result2); } return result; } #else PyDoc_STRVAR(GMPy_doc_mpfr_grandom_function, "mpfr_grandom(random_state) -> (mpfr, mpfr)\n\n" "Return two random numbers with gaussian distribution."); static PyObject * GMPy_MPFR_grandom_Function(PyObject *self, PyObject *args) { MPFR_Object *result1, *result2; PyObject *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("mpfr_grandom() requires 1 argument"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpfr_grandom() requires 'random_state' argument"); return NULL; } result1 = GMPy_MPFR_New(0, context); result2 = GMPy_MPFR_New(0, context); if (!result1 || !result2) { Py_XDECREF((PyObject*)result1); Py_XDECREF((PyObject*)result2); return NULL; } mpfr_grandom(result1->f, result2->f, RANDOM_STATE(PyTuple_GET_ITEM(args, 0)), GET_MPFR_ROUND(context)); result = Py_BuildValue("(NN)", (PyObject*)result1, (PyObject*)result2); if (!result) { Py_DECREF((PyObject*)result1); Py_DECREF((PyObject*)result2); } return result; } #endif PyDoc_STRVAR(GMPy_doc_mpc_random_function, "mpc_random(random_state) -> mpc\n\n" "Return uniformly distributed number in the unit square [0,1]x[0,1]."); static PyObject * GMPy_MPC_random_Function(PyObject *self, PyObject *args) { MPC_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyTuple_GET_SIZE(args) != 1) { TYPE_ERROR("mpfc_random() requires 1 argument"); return NULL; } if (!RandomState_Check(PyTuple_GET_ITEM(args, 0))) { TYPE_ERROR("mpc_random() requires 'random_state' argument"); return NULL; } if ((result = GMPy_MPC_New(0, 0, context))) { mpc_urandom(result->c, RANDOM_STATE(PyTuple_GET_ITEM(args, 0))); } return (PyObject*)result; } static PyTypeObject RandomState_Type = { #ifdef PY3 PyVarObject_HEAD_INIT(0, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "gmpy2 random state", /* tp_name */ sizeof(RandomState_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) GMPy_RandomState_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_RandomState_Repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "GMPY2 Random number generator state", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ }; gmpy2-2.1.0b3/src/gmpy2_random.h0000664000175000017500000000655313425753642016231 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_random.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_RANDOM_H #define GMPY_RANDOM_H #ifdef __cplusplus extern "C" { #endif /* gmpy_random C API extension header file. * * Provide support random number state. * * Version 2.00, December 2011 (created) casevh * * This file is expected to be included from gmpy.h */ static PyTypeObject RandomState_Type; #define RANDOM_STATE(obj) (((RandomState_Object *)(obj))->state) #define RandomState_Check(v) (((PyObject*)v)->ob_type == &RandomState_Type) static RandomState_Object * GMPy_RandomState_New(void); static void GMPy_RandomState_Dealloc(RandomState_Object *self); static PyObject * GMPy_RandomState_Repr(RandomState_Object *self); static PyObject * GMPy_RandomState_Factory(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_urandomb_Function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_rrandomb_Function(PyObject *self, PyObject *args); static PyObject * GMPy_MPZ_random_Function(PyObject *self, PyObject *args); static PyObject * GMPy_MPFR_random_Function(PyObject *self, PyObject *args); #if MPFR_VERSION_MAJOR > 3 static PyObject * GMPy_MPFR_nrandom_Function(PyObject *self, PyObject *args); #endif static PyObject * GMPy_MPFR_grandom_Function(PyObject *self, PyObject *args); static PyObject * GMPy_MPC_random_Function(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_richcompare.c0000664000175000017500000002761313425753657017246 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_richcompare.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static PyObject *_cmp_to_object(int c, int op) { PyObject *result; switch (op) { case Py_LT: c = c < 0; break; case Py_LE: c = c <= 0; break; case Py_EQ: c = c == 0; break; case Py_NE: c = c != 0; break; case Py_GT: c = c > 0; break; case Py_GE: c = c >= 0; break; } result = c ? Py_True : Py_False; Py_INCREF(result); return result; } static PyObject * GMPy_RichCompare_Slot(PyObject *a, PyObject *b, int op) { int c; PyObject *tempa = NULL, *tempb = NULL, *result = NULL; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (CHECK_MPZANY(a)) { if (PyIntOrLong_Check(b)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(b, &error); if (!error) { c = mpz_cmp_si(MPZ(a), temp); } else { mpz_set_PyIntOrLong(global.tempz, b); c = mpz_cmp(MPZ(a), global.tempz); } return _cmp_to_object(c, op); } if (CHECK_MPZANY(b)) { return _cmp_to_object(mpz_cmp(MPZ(a), MPZ(b)), op); } if (IS_INTEGER(b)) { if (!(tempb = (PyObject*)GMPy_MPZ_From_Integer(b, context))) { return NULL; } c = mpz_cmp(MPZ(a), MPZ(tempb)); Py_DECREF(tempb); return _cmp_to_object(c, op); } if (IS_RATIONAL(b)) { tempa = (PyObject*)GMPy_MPQ_From_Rational(a, context); tempb = (PyObject*)GMPy_MPQ_From_Rational(b, context); if (!tempa || !tempb) { Py_XDECREF(a); Py_XDECREF(b); return NULL; } c = mpq_cmp(MPQ(tempa), MPQ(tempb)); Py_DECREF(tempa); Py_DECREF(tempb); return _cmp_to_object(c, op); } if (PyFloat_Check(b)) { double d = PyFloat_AS_DOUBLE(b); if (Py_IS_NAN(d)) { result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else if (Py_IS_INFINITY(d)) { if (d < 0.0) return _cmp_to_object(1, op); else return _cmp_to_object(-1, op); } else { return _cmp_to_object(mpz_cmp_d(MPZ(a), d), op); } } } if (MPQ_Check(a)) { if (MPQ_Check(b)) { return _cmp_to_object(mpq_cmp(MPQ(a), MPQ(b)), op); } if (IS_RATIONAL(b)) { if (!(tempb = (PyObject*)GMPy_MPQ_From_Rational(b, context))) { return NULL; } c = mpq_cmp(MPQ(a), MPQ(tempb)); Py_DECREF(tempb); return _cmp_to_object(c, op); } if (PyFloat_Check(b)) { double d = PyFloat_AS_DOUBLE(b); if (Py_IS_NAN(d)) { result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else if (Py_IS_INFINITY(d)) { if (d < 0.0) return _cmp_to_object(1, op); else return _cmp_to_object(-1, op); } else { if (!(tempb = (PyObject*)GMPy_MPQ_New(context))) { return NULL; } mpq_set_d(MPQ(tempb), d); c = mpq_cmp(MPQ(a), MPQ(tempb)); Py_DECREF(tempb); return _cmp_to_object(c, op); } } } if (MPFR_Check(a)) { if (MPFR_Check(b)) { mpfr_clear_flags(); c = mpfr_cmp(MPFR(a), MPFR(b)); if (mpfr_erangeflag_p()) { /* Set erange and check if an exception should be raised. */ context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { return _cmp_to_object(c, op); } } if (PyFloat_Check(b)) { double d = PyFloat_AS_DOUBLE(b); mpfr_clear_flags(); c = mpfr_cmp_d(MPFR(a), d); if (mpfr_erangeflag_p()) { /* Set erange and check if an exception should be raised. */ context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { return _cmp_to_object(c, op); } } if (IS_INTEGER(b)) { if (!(tempb = (PyObject*)GMPy_MPZ_From_Integer(b, context))) { return NULL; } mpfr_clear_flags(); c = mpfr_cmp_z(MPFR(a), MPZ(tempb)); Py_DECREF(tempb); if (mpfr_erangeflag_p()) { /* Set erange and check if an exception should be raised. */ context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { return _cmp_to_object(c, op); } } if (IS_RATIONAL(b)) { if (!(tempb = (PyObject*)GMPy_MPQ_From_Rational(b, context))) { return NULL; } mpfr_clear_flags(); c = mpfr_cmp_q(MPFR(a), MPQ(tempb)); Py_DECREF(tempb); if (mpfr_erangeflag_p()) { /* Set erange and check if an exception should be raised. */ context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { return _cmp_to_object(c, op); } } if (IS_REAL(b)) { if (!(tempb = (PyObject*)GMPy_MPFR_From_Real(b, 1, context))) { return NULL; } mpfr_clear_flags(); c = mpfr_cmp(MPFR(a), MPFR(tempb)); Py_DECREF(tempb); if (mpfr_erangeflag_p()) { /* Set erange and check if an exception should be raised. */ context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { return _cmp_to_object(c, op); } } } if (MPC_Check(a)) { if (!(op == Py_EQ || op == Py_NE)) { TYPE_ERROR("no ordering relation is defined for complex numbers"); return NULL; } if (MPC_Check(b)) { mpfr_clear_flags(); c = mpc_cmp(MPC(a), MPC(b)); if (mpfr_erangeflag_p()) { /* Set erange and check if an exception should be raised. */ context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { return _cmp_to_object(c, op); } } if (PyComplex_Check(b)) { if (!(tempb = (PyObject*)GMPy_MPC_From_PyComplex(b, 1, 1, context))) { return NULL; } mpfr_clear_flags(); c = mpc_cmp(MPC(a), MPC(tempb)); Py_DECREF(tempb); if (mpfr_erangeflag_p()) { /* Set erange and check if an exception should be raised. */ context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { return _cmp_to_object(c, op); } } /* a.imag must be 0 or else all further comparisons will be NE */ if (!mpfr_zero_p(mpc_imagref(MPC(a)))) { /* if a.real is NaN, possibly raise exception */ if (mpfr_nan_p(mpc_realref(MPC(a)))) { context->ctx.erange = 1; if (context->ctx.traps & TRAP_ERANGE) { GMPY_ERANGE("comparison with NaN"); return NULL; } } result = (op == Py_NE) ? Py_True : Py_False; Py_INCREF(result); return result; } else { if (!(tempb = (PyObject*)GMPy_MPFR_New(mpfr_get_prec(mpc_realref(MPC(a))), context))) { return NULL; } mpc_real(MPFR(tempb), MPC(a), GET_MPFR_ROUND(context)); result = GMPy_RichCompare_Slot(tempb, b, op); Py_DECREF(tempb); return result; } } Py_RETURN_NOTIMPLEMENTED; } gmpy2-2.1.0b3/src/gmpy2_richcompare.h0000664000175000017500000000442713425753673017247 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_richcompare.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_RICHCOMPARE_H #define GMPY_RICHCOMPARE_H #ifdef __cplusplus extern "C" { #endif /* Forward declarations begin here. */ static PyObject * GMPy_RichCompare_Slot(PyObject *a, PyObject *b, int op); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_sign.c0000664000175000017500000000765313425753710015702 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_sign.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ static PyObject * GMPy_Integer_Sign(PyObject *x, CTXT_Object *context) { long res; MPZ_Object *tempx; if (!(tempx = GMPy_MPZ_From_Integer(x, context))) { return NULL; } else { res = mpz_sgn(tempx->z); Py_DECREF((PyObject*)tempx); return PyIntOrLong_FromLong(res); } } static PyObject * GMPy_Rational_Sign(PyObject *x, CTXT_Object *context) { long res; MPQ_Object *tempx; if (!(tempx = GMPy_MPQ_From_Rational(x, context))) { return NULL; } else { res = mpq_sgn(tempx->q); Py_DECREF((PyObject*)tempx); return PyIntOrLong_FromLong(res); } } static PyObject * GMPy_Real_Sign(PyObject *x, CTXT_Object *context) { long sign; MPFR_Object *tempx; PyObject *result; CHECK_CONTEXT(context); if (!(tempx = GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } else { mpfr_clear_flags(); sign = mpfr_sgn(tempx->f); Py_DECREF((PyObject*)tempx); result = PyIntOrLong_FromLong(sign); GMPY_CHECK_ERANGE(result, context, "sign() of invalid value (NaN)"); return result; } } static PyObject * GMPy_Number_Sign(PyObject *x, CTXT_Object *context) { if (IS_INTEGER(x)) return GMPy_Integer_Sign(x, context); else if (IS_RATIONAL_ONLY(x)) return GMPy_Rational_Sign(x, context); else if (IS_REAL_ONLY(x)) return GMPy_Real_Sign(x, context); TYPE_ERROR("sign() argument type not supported"); return NULL; } PyDoc_STRVAR(GMPy_doc_function_sign, "sign(x) -> number\n\n" "Return -1 if x < 0, 0 if x == 0, or +1 if x >0."); static PyObject * GMPy_Context_Sign(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Sign(other, context); } gmpy2-2.1.0b3/src/gmpy2_sign.h0000664000175000017500000000477113425753724015712 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_mpany.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_SIGN_H #define GMPY_SIGN_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Integer_Sign(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Rational_Sign(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Real_Sign(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Sign(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Sign(PyObject *self, PyObject *other); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_square.c0000664000175000017500000001477013425753736016250 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_square.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_Square(Number, Number, context|NULL) * * Private API * =========== * GMPy_Integer_Square(Integer, Integer, context|NULL) * GMPy_Rational_Square(Rational, Rational, context|NULL) * GMPy_Real_Square(Real, Real, context|NULL) * GMPy_Complex_Square(Complex, Complex, context|NULL) * * GMPy_Context_Square(context, args) * */ static PyObject * _GMPy_MPZ_Square(PyObject *x, CTXT_Object *context) { MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(context))) { return NULL; } mpz_mul(result->z, MPZ(x), MPZ(x)); return (PyObject*)result; } static PyObject * GMPy_Integer_Square(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; if (!(tempx = (PyObject*)GMPy_MPZ_From_Integer(x, context))) { return NULL; } result = _GMPy_MPZ_Square(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPQ_Square(PyObject *x, CTXT_Object *context) { MPQ_Object *result; if (!(result = GMPy_MPQ_New(context))) { return NULL; } mpq_mul(result->q, MPQ(x), MPQ(x)); return (PyObject*)result; } static PyObject * GMPy_Rational_Square(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; if (!(tempx = (PyObject*)GMPy_MPQ_From_Rational(x, context))) { return NULL; } result = _GMPy_MPQ_Square(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPFR_Square(PyObject *x, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { return NULL; } mpfr_clear_flags(); mpfr_sqr(result->f, MPFR(x), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Real_Square(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPFR_From_Real(x, 1, context))) { return NULL; } result = _GMPy_MPFR_Square(tempx, context); Py_DECREF(tempx); return result; } static PyObject * _GMPy_MPC_Square(PyObject *x, CTXT_Object *context) { MPC_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { return NULL; } mpc_sqr(result->c, MPC(x), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_Complex_Square(PyObject *x, CTXT_Object *context) { PyObject *result, *tempx; CHECK_CONTEXT(context); if (!(tempx = (PyObject*)GMPy_MPC_From_Complex(x, 1, 1, context))) { return NULL; } result = _GMPy_MPC_Square(tempx, context); Py_DECREF(tempx); return result; } PyDoc_STRVAR(GMPy_doc_function_square, "square(x) -> number\n\n" "Return x * x. If x is an integer, then the result is an 'mpz'.\n" "If x is a rational, then the result is an 'mpq'. If x is a float,\n" "then the result is an 'mpfr'. If x is a complex number, then the\n" "result is an 'mpc'."); PyDoc_STRVAR(GMPy_doc_context_square, "context.square(x) -> number\n\n" "Return x * x. If x is an integer, then the result is an 'mpz'.\n" "If x is a rational, then the result is an 'mpq'. If x is a float,\n" "then the result is an 'mpfr'. If x is a complex number, then the\n" "result is an 'mpc'."); static PyObject * GMPy_Number_Square(PyObject *x, CTXT_Object *context) { if (MPZ_Check(x)) return _GMPy_MPZ_Square(x, context); if (MPQ_Check(x)) return _GMPy_MPQ_Square(x, context); if (MPFR_Check(x)) return _GMPy_MPFR_Square(x, context); if (MPC_Check(x)) return _GMPy_MPC_Square(x, context); if (IS_INTEGER(x)) return GMPy_Integer_Square(x, context); if (IS_RATIONAL(x)) return GMPy_Rational_Square(x, context); if (IS_REAL(x)) return GMPy_Real_Square(x, context); if (IS_COMPLEX(x)) return GMPy_Complex_Square(x, context); TYPE_ERROR("square() argument type not supported"); return NULL; } static PyObject * GMPy_Context_Square(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Square(other, context); } gmpy2-2.1.0b3/src/gmpy2_square.h0000664000175000017500000000512313425753750016241 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_square.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_SQUARE_H #define GMPY2_SQUARE_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Integer_Square(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Rational_Square(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Real_Square(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Complex_Square(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Number_Square(PyObject *x, CTXT_Object *context); static PyObject * GMPy_Context_Square(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_sub.c0000664000175000017500000004267213425753766015546 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_sub.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements the - operator, gmpy2.add(), and context.sub(). * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_Sub(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPZ_Sub_Slot * GMPy_MPQ_Sub_Slot * GMPy_MPFR_Sub_Slot * GMPy_MPC_Sub_Slot * * GMPy_Integer_Sub(Integer, Integer, context|NULL) * GMPy_Rational_Sub(Rational, Rational, context|NULL) * GMPy_Real_Sub(Real, Real, context|NULL) * GMPy_Complex_Sub(Complex, Complex, context|NULL) * * GMPy_Context_Sub(context, args) * */ /* Subtract two Integer objects (see gmpy2_convert.c). If an error occurs, * NULL is returned and an exception is set. If either x or y can't be * converted into an mpz, Py_NotImplemented is returned. */ static PyObject * GMPy_Integer_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPZ_Check(x)) { if (PyIntOrLong_Check(y)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(y, &error); if (!error) { if (temp >= 0) { mpz_sub_ui(result->z, MPZ(x), temp); } else { mpz_add_ui(result->z, MPZ(x), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, y); mpz_sub(result->z, MPZ(x), global.tempz); } return (PyObject*)result; } if (MPZ_Check(y)) { mpz_sub(result->z, MPZ(x), MPZ(y)); return (PyObject*)result; } } if (MPZ_Check(y)) { if (PyIntOrLong_Check(x)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(x, &error); if (!error) { if (temp >= 0) { mpz_ui_sub(result->z, temp, MPZ(y)); } else { mpz_add_ui(result->z, MPZ(y), -temp); mpz_neg(result->z, result->z); } } else { mpz_set_PyIntOrLong(global.tempz, x); mpz_sub(result->z, global.tempz, MPZ(y)); } return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { MPZ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPZ_From_Integer(x, context)) || !(tempy = GMPy_MPZ_From_Integer(y, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpz_sub(result->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Integer_Sub()."); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } /* Implement __sub__ for MPZ_Object. On entry, one of the two arguments must * be an MPZ_Object. If the other object is an Integer, add and return an * MPZ_Object. If the other object isn't an MPZ_Object, call the appropriate * function. If no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPZ_Sub_Slot(PyObject *x, PyObject *y) { if (MPZ_Check(x) && MPZ_Check(y)) { MPZ_Object *result = NULL; if ((result = GMPy_MPZ_New(NULL))) { mpz_sub(result->z, MPZ(x), MPZ(y)); } return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Sub(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Sub(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Sub(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Sub(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* Subtract two Rational objects (see gmpy2_convert.h). Returns None and * raises TypeError if both objects are not valid rationals. Pympq_Sub_Rational * is intended to be called from GMPy_Number_Sub(). */ static PyObject * GMPy_Rational_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { MPQ_Object *result = NULL; if (!(result = GMPy_MPQ_New(context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPQ_Check(x) && MPQ_Check(y)) { mpq_sub(result->q, MPQ(x), MPQ(y)); return (PyObject*)result; } if (IS_RATIONAL(x) && IS_RATIONAL(y)) { MPQ_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPQ_From_Number(x, context)) || !(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpq_sub(result->q, tempx->q, tempy->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Rational_Sub()."); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } /* Implement __sub__ for MPQ_Object. On entry, one of the two arguments must * be an MPQ_Object. If the other object is a Rational, subtrace and return * an MPQ_Object. If the other object isn't an MPQ_Object, call the * appropriate function. If no appropriate function can be found, return * NotImplemented. */ static PyObject * GMPy_MPQ_Sub_Slot(PyObject *x, PyObject *y) { if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Sub(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Sub(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Sub(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* GMPy_Real_Sub(x, y, context) returns x-y using the provided context. If * provided context is NULL, then the current context is used. If an error * occurs, NULL is returned and an exception is set. If either x or y can't * be converted to an mpfr, then Py_NotImplemented is returned. * GMPy_Real_Sub() will not try to promote the result to a different type * (i.e. mpc). * * GMPy_mpfr_sub_fast(x, y) is the entry point for mpfr.__sub__. */ static PyObject * GMPy_Real_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPFR_Check(x) && MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_sub(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } if (MPFR_Check(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_sub_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, y); mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy = NULL; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_sub_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_sub_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long temp = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_sub_si(result->f, MPFR(y), temp, GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, x); mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(y), global.tempz, GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(x)) { mpfr_clear_flags(); result->rc = mpfr_sub_z(result->f, MPFR(y), MPZ(x), GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(x)) { MPQ_Object *tempx = NULL; if (!(tempx = GMPy_MPQ_From_Number(x, context))) { /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_sub_q(result->f, MPFR(y), tempx->q, GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); goto done; } if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_sub_d(result->f, MPFR(y), PyFloat_AS_DOUBLE(x), GET_MPFR_ROUND(context)); mpfr_neg(result->f, result->f, GET_MPFR_ROUND(context)); goto done; } } if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPFR_From_Real(x, 1, context)) || !(tempy = GMPy_MPFR_From_Real(y, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } mpfr_clear_flags(); result->rc = mpfr_sub(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Real_Sub()."); return NULL; /* LCOV_EXCL_STOP */ done: _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } /* Implement __sub__ for Pympfr. On entry, one of the two arguments must * be a Pympfr. If the other object is a Real, add and return a Pympfr. * If the other object isn't a Pympfr, call the appropriate function. If * no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPFR_Sub_Slot(PyObject *x, PyObject *y) { if (MPFR_Check(x) && MPFR_Check(y)) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_sub(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Sub(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Sub(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* GMPy_Complex_Sub(x, y, context) returns x-y using the provided context. If * context is NULL, then the current context is used. If an error occurs, NULL * is returned and an exception is set. If either x or y can't be converted to * an mpc, then Py_NotImplemented is returned. */ static PyObject * GMPy_Complex_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPC_Check(x) && MPC_Check(y)) { result->rc = mpc_sub(result->c, MPC(x), MPC(y), GET_MPC_ROUND(context)); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } if (IS_COMPLEX(x) && IS_COMPLEX(y)) { MPC_Object *tempx = NULL, *tempy = NULL; if (!(tempx = GMPy_MPC_From_Complex(x, 1, 1, context)) || !(tempy = GMPy_MPC_From_Complex(y, 1, 1, context))) { /* LCOV_EXCL_START */ Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; /* LCOV_EXCL_STOP */ } result->rc = mpc_sub(result->c, tempx->c, tempy->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } /* LCOV_EXCL_START */ Py_DECREF((PyObject*)result); SYSTEM_ERROR("Internal error in GMPy_Complex_Sub()."); return NULL; /* LCOV_EXCL_STOP */ } /* Pympc_sub_fast() is called by mpc.__sub__. It just gets a borrowed reference * to the current context and call Pympc_Add_Complex(). Since mpc is the last * step of the numeric ladder, the NotImplemented return value from * Pympc_Sub_Complex() is correct and is just passed on. */ static PyObject * GMPy_MPC_Sub_Slot(PyObject *x, PyObject *y) { if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Sub(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Number_Sub(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_Sub(x, y, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_Sub(x, y, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_Sub(x, y, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_Sub(x, y, context); TYPE_ERROR("sub() argument type not supported"); return NULL; } /* Implement context.sub() and gmpy2.sub(). */ PyDoc_STRVAR(GMPy_doc_sub, "sub(x, y) -> number\n\n" "Return x - y."); PyDoc_STRVAR(GMPy_doc_context_sub, "context.sub(x, y) -> number\n\n" "Return x - y."); static PyObject * GMPy_Context_Sub(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("sub() requires 2 arguments"); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_Sub(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_sub.h0000664000175000017500000000564013425753776015546 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_sub.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_SUB_H #define GMPY2_SUB_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_Sub(PyObject *x, PyObject *y, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_Sub(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Rational_Sub(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Real_Sub(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_Sub(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPZ_Sub_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPQ_Sub_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPFR_Sub_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPC_Sub_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_Context_Sub(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_truediv.c0000664000175000017500000003425113425754010016410 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_truediv.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* This file implements the / operator, gmpy2.div() and context.div(). * * Public API * ========== * The following function is available as part of GMPY2's C API. A NULL value * for context implies the function should use the currently active context. * * GMPy_Number_TrueDiv(Number, Number, context|NULL) * * Private API * =========== * GMPy_MPZ_TrueDiv_Slot * GMPy_MPQ_TrueDiv_Slot * GMPy_MPFR_TrueDiv_Slot * GMPy_MPC_TrueDiv_Slot * * GMPy_Integer_TrueDiv(Integer, Integer, context|NULL) * GMPy_Rational_TrueDiv(Rational, Rational, context|NULL) * GMPy_Real_TrueDiv(Real, Real, context|NULL) * GMPy_Complex_TrueDiv(Complex, Complex, context|NULL) * * GMPy_Context_TrueDiv(context, args) * */ /* Multiply two Integer objects (see gmpy2_convert.c). If an error occurs, * NULL is returned and an exception is set. If either x or y can't be * converted into an mpz, Py_NotImplemented is returned. */ /* Divide two Integer objects (see convert.c/isInteger) using true division. * If an error occurs, NULL is returned and an exception is set. If either x * or y can't be converted into an mpz, Py_NotImplemented is returned. */ static PyObject * GMPy_Integer_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPZ_Object *tempx, *tempy; mpq_t tempq; MPFR_Object *result; CHECK_CONTEXT(context); if (GET_DIV_MODE(context)) return GMPy_Rational_TrueDiv(x, y, context); if (!(result = GMPy_MPFR_New(0, context))) return NULL; if (IS_INTEGER(x) && IS_INTEGER(y)) { tempx = GMPy_MPZ_From_Integer(x, context); tempy = GMPy_MPZ_From_Integer(y, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Integer to mpz"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpq_init(tempq); mpq_set_num(tempq, tempx->z); mpq_set_den(tempq, tempy->z); mpq_canonicalize(tempq); mpfr_clear_flags(); result->rc = mpfr_set_q(result->f, tempq, GET_MPFR_ROUND(context)); mpq_clear(tempq); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; } /* Implement true division for MPZ_Object. On entry, one of the two arguments * must be an MPZ_Object. If the other object is an Integer, return an * MPZ_Object. If the other object isn't an MPZ_Object, call the appropriate * function. If no appropriate function can be found, return NotImplemented. */ static PyObject * GMPy_MPZ_TrueDiv_Slot(PyObject *x, PyObject *y) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_TrueDiv(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_TrueDiv(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_TrueDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_TrueDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } #ifdef PY2 static PyObject * GMPy_MPZ_Div2_Slot(PyObject *x, PyObject *y) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_FloorDiv(x, y, NULL); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_TrueDiv(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_TrueDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_TrueDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } #endif static PyObject * GMPy_Rational_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPQ_Object *result, *tempx = NULL, *tempy = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPQ_New(context))) return NULL; if (MPQ_Check(x) && MPQ_Check(y)) { if (mpq_sgn(MPQ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpq_div(result->q, MPQ(x), MPQ(y)); return (PyObject*)result; } if (IS_RATIONAL(x) && IS_RATIONAL(y)) { tempx = GMPy_MPQ_From_Number(x, context); tempy = GMPy_MPQ_From_Number(y, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Rational to mpq"); goto error; } if (mpq_sgn(tempy->q) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpq_div(result->q, tempx->q, tempy->q); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); return (PyObject*)result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } static PyObject * GMPy_MPQ_TrueDiv_Slot(PyObject *x, PyObject *y) { if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_TrueDiv(x, y, NULL); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_TrueDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_TrueDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } /* Attempt true division of two numbers and return an mpfr. The code path is * optimized by checking for mpfr objects first. Returns Py_NotImplemented if * both objects are not valid reals. */ static PyObject * GMPy_Real_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPFR_Object *result; CHECK_CONTEXT(context); if (!(result = GMPy_MPFR_New(0, context))) { /* LCOV_EXCL_START */ return NULL; /* LCOV_EXCL_STOP */ } if (MPFR_Check(x) && MPFR_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_div(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } if (MPFR_Check(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_div_si(result->f, MPFR(x), temp, GET_MPFR_ROUND(context)); goto done; } else { mpz_set_PyIntOrLong(global.tempz, y); mpfr_clear_flags(); result->rc = mpfr_div_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context)); goto done; } } if (CHECK_MPZANY(y)) { mpfr_clear_flags(); result->rc = mpfr_div_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context)); goto done; } if (IS_RATIONAL(y)) { MPQ_Object *tempy; if (!(tempy = GMPy_MPQ_From_Number(y, context))) { Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_div_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempy); goto done; } if (PyFloat_Check(y)) { mpfr_clear_flags(); result->rc = mpfr_div_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context)); goto done; } } if (MPFR_Check(y)) { if (PyIntOrLong_Check(x)) { int error; long temp = GMPy_Integer_AsLongAndError(x, &error); if (!error) { mpfr_clear_flags(); result->rc = mpfr_si_div(result->f, temp, MPFR(y), GET_MPFR_ROUND(context)); goto done; } } /* Since mpfr_z_div does not exist, this combination is handled at the * end by converting x to an mpfr. Ditto for rational.*/ if (PyFloat_Check(x)) { mpfr_clear_flags(); result->rc = mpfr_d_div(result->f, PyFloat_AS_DOUBLE(x), MPFR(y), GET_MPFR_ROUND(context)); goto done; } } if (IS_REAL(x) && IS_REAL(y)) { MPFR_Object *tempx, *tempy; tempx = GMPy_MPFR_From_Real(x, 1, context); tempy = GMPy_MPFR_From_Real(y, 1, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } mpfr_clear_flags(); result->rc = mpfr_div(result->f, tempx->f, tempy->f, GET_MPFR_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; done: _GMPy_MPFR_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_MPFR_TrueDiv_Slot(PyObject *x, PyObject *y) { if (MPFR_Check(x) && MPFR_Check(y)) { MPFR_Object *result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if ((result = GMPy_MPFR_New(0, context))) { mpfr_clear_flags(); result->rc = mpfr_div(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context)); _GMPy_MPFR_Cleanup(&result, context); } return (PyObject*)result; } if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_TrueDiv(x, y, NULL); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_TrueDiv(x, y, NULL); Py_RETURN_NOTIMPLEMENTED; } static PyObject * GMPy_Complex_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context) { MPC_Object *result = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPC_New(0, 0, context))) return NULL; if (MPC_Check(x) && MPC_Check(y)) { if (MPC_IS_ZERO_P(y)) { context->ctx.divzero = 1; if (context->ctx.traps & TRAP_DIVZERO) { GMPY_DIVZERO("'mpc' division by zero"); Py_DECREF((PyObject*)result); return NULL; } } result->rc = mpc_div(result->c, MPC(x), MPC(y), GET_MPC_ROUND(context)); goto done; } if (IS_COMPLEX(x) && IS_COMPLEX(y)) { MPC_Object *tempx, *tempy; tempx = GMPy_MPC_From_Complex(x, 1, 1, context); tempy = GMPy_MPC_From_Complex(y, 1, 1, context); if (!tempx || !tempy) { Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)result); return NULL; } result->rc = mpc_div(result->c, tempx->c, tempy->c, GET_MPC_ROUND(context)); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); goto done; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; done: _GMPy_MPC_Cleanup(&result, context); return (PyObject*)result; } static PyObject * GMPy_MPC_TrueDiv_Slot(PyObject *x, PyObject *y) { return GMPy_Complex_TrueDiv(x, y, NULL); } PyDoc_STRVAR(GMPy_doc_truediv, "div(x, y) -> number\n\n" "Return x / y; uses true division."); static PyObject * GMPy_Number_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context) { if (IS_INTEGER(x) && IS_INTEGER(y)) return GMPy_Integer_TrueDiv(x, y, context); if (IS_RATIONAL(x) && IS_RATIONAL(y)) return GMPy_Rational_TrueDiv(x, y, context); if (IS_REAL(x) && IS_REAL(y)) return GMPy_Real_TrueDiv(x, y, context); if (IS_COMPLEX(x) && IS_COMPLEX(y)) return GMPy_Complex_TrueDiv(x, y, context); TYPE_ERROR("div() argument type not supported"); return NULL; } PyDoc_STRVAR(GMPy_doc_context_truediv, "context.div(x, y) -> number\n\n" "Return x / y; uses true division."); static PyObject * GMPy_Context_TrueDiv(PyObject *self, PyObject *args) { CTXT_Object *context = NULL; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("div() requires 2 arguments."); return NULL; } if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } return GMPy_Number_TrueDiv(PyTuple_GET_ITEM(args, 0), PyTuple_GET_ITEM(args, 1), context); } gmpy2-2.1.0b3/src/gmpy2_truediv.h0000664000175000017500000000572013425754023016420 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_truediv.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY2_TRUEDIV_H #define GMPY2_TRUEDIV_H #ifdef __cplusplus extern "C" { #endif /* Public API */ static PyObject * GMPy_Number_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context); /* Private API */ static PyObject * GMPy_Integer_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Rational_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Real_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_Complex_TrueDiv(PyObject *x, PyObject *y, CTXT_Object *context); static PyObject * GMPy_MPZ_TrueDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPQ_TrueDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPFR_TrueDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_MPC_TrueDiv_Slot(PyObject *x, PyObject *y); static PyObject * GMPy_Context_TrueDiv(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_types.h0000664000175000017500000001055213525427233016102 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_types.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_TYPES_H #define GMPY_TYPES_H #ifdef __cplusplus extern "C" { #endif typedef struct { PyObject_HEAD mpz_t z; Py_hash_t hash_cache; } MPZ_Object; typedef struct { PyObject_HEAD mpz_t z; } XMPZ_Object; typedef struct { PyObject_HEAD mpq_t q; Py_hash_t hash_cache; } MPQ_Object; typedef struct { PyObject_HEAD mpfr_t f; Py_hash_t hash_cache; int rc; } MPFR_Object; typedef struct { PyObject_HEAD mpc_t c; Py_hash_t hash_cache; int rc; } MPC_Object; typedef struct { PyObject_HEAD gmp_randstate_t state; } RandomState_Object; typedef struct { mpfr_prec_t mpfr_prec; /* current precision in bits, for MPFR */ mpfr_rnd_t mpfr_round; /* current rounding mode for float (MPFR) */ mpfr_exp_t emax; /* maximum exponent */ mpfr_exp_t emin; /* minimum exponent */ int subnormalize; /* if 1, subnormalization is performed */ int underflow; /* did an underflow occur? */ int overflow; /* did an overflow occur? */ int inexact; /* was the result inexact? */ int invalid; /* invalid operation (i.e. NaN)? */ int erange; /* did a range error occur? */ int divzero; /* divided by zero? */ int traps; /* if 0, do not trap any exceptions */ /* if not 0, then raise traps per bits above */ mpfr_prec_t real_prec; /* current precision in bits, for Re(MPC) */ mpfr_prec_t imag_prec; /* current precision in bits, for Im(MPC) */ mpfr_rnd_t real_round; /* current rounding mode for Re(MPC) */ mpfr_rnd_t imag_round; /* current rounding mode for Im(MPC) */ int allow_complex; /* if 1, allow mpfr functions to return an mpc */ int rational_division; /* if 1, mpz/mpz returns an mpq result */ } gmpy_context; typedef struct { PyObject_HEAD gmpy_context ctx; #ifndef WITHOUT_THREADS PyThreadState *tstate; #endif } CTXT_Object; typedef struct { PyObject_HEAD CTXT_Object *new_context; /* Context that will be returned when * __enter__ is called. */ CTXT_Object *old_context; /* Context that will restored when * __exit__ is called. */ } CTXT_Manager_Object; #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_vector.c0000664000175000017500000001437013425754064016241 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_vector.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* The following code was a test case for creating a gmpy2 function that would * apply an MPFR function to all the elements of a list. It was slightly faster * than map(gmpy2.list, <>) but not enough to justify the effort. The * code is left for possible future use. */ PyDoc_STRVAR(GMPy_doc_function_vector, "vector(iterable) -> list\n\n" "Template for applying a function to an iterable."); PyDoc_STRVAR(GMPy_doc_context_vector, "vector(iterable) -> list\n\n" "Template for applying a function to an iterable."); static PyObject * GMPy_Context_Vector(PyObject *self, PyObject *other) { PyObject *result, *tempres; Py_ssize_t i, seq_length; CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } if (!(other = PySequence_List(other))) { TYPE_ERROR("argument must be an iterable"); return NULL; } /* other contains a new list containing all the values from the * iterable. Create a list to store the results. */ seq_length = PyList_GET_SIZE(other); if (!(result = PyList_New(seq_length))) { Py_DECREF(other); return NULL; } /* Iterate through the list. */ for (i=0; i < seq_length; i++) { if (!(tempres = GMPy_Number_Sin(PyList_GET_ITEM(other, i), context))) { Py_DECREF(other); Py_DECREF(result); TYPE_ERROR("all items in iterable must be numbers"); return NULL; } if (PyList_SetItem(result, i, tempres) < 0) { Py_DECREF(other); Py_DECREF(result); return NULL; } } Py_DECREF(other); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_function_vector2, "vector2(iterable, iterable) -> list\n\n" "Template for applying a function to a pair of iterables."); PyDoc_STRVAR(GMPy_doc_context_vector2, "vector2(iterable) -> list\n\n" "Template for applying a function to a pair of iterables."); static PyObject * GMPy_Context_Vector2(PyObject *self, PyObject *args) { PyObject *arg1, *arg2, *result; MPFR_Object *tempres; Py_ssize_t i, seq_length; CTXT_Object *context = NULL; if (self && CTXT_Check(self)) { context = (CTXT_Object*)self; } else { CHECK_CONTEXT(context); } if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("vector2() requires 2 arguments"); return NULL; } if (!(arg1 = PySequence_List(PyTuple_GET_ITEM(args, 0)))) { TYPE_ERROR("argument must be an iterable"); return NULL; } if (!(arg2 = PySequence_List(PyTuple_GET_ITEM(args, 1)))) { Py_DECREF(arg1); TYPE_ERROR("argument must be an iterable"); return NULL; } /* other contains a new list containing all the values from the * iterable. Create a list to store the results. */ if (PyList_GET_SIZE(arg1) != PyList_GET_SIZE(arg2)) { Py_DECREF(arg1); Py_DECREF(arg2); TYPE_ERROR("arguments must be the same length"); return NULL; } seq_length = PyList_GET_SIZE(arg1); if (!(result = PyList_New(seq_length))) { Py_DECREF(arg1); Py_DECREF(arg2); return NULL; } /* Iterate through the list. */ for (i=0; i < seq_length; i++) { //~ if (!(tempres = GMPy_Number_Mul(PyList_GET_ITEM(arg1, i), //~ PyList_GET_ITEM(arg2, i), //~ context))) { //~ Py_DECREF(arg1); //~ Py_DECREF(arg2); //~ Py_DECREF(result); //~ TYPE_ERROR("all items in iterable must be numbers"); //~ return NULL; //~ } tempres = GMPy_MPFR_New(0, context); tempres->rc = mpfr_mul(tempres->f, MPFR(PyList_GET_ITEM(arg1, i)), MPFR(PyList_GET_ITEM(arg2, i)), GET_MPFR_ROUND(context)); if (PyList_SetItem(result, i, (PyObject*)tempres) < 0) { Py_DECREF(arg1); Py_DECREF(arg2); Py_DECREF(result); return NULL; } } Py_DECREF(arg1); Py_DECREF(arg2); return (PyObject*)result; } gmpy2-2.1.0b3/src/gmpy2_vector.h0000664000175000017500000000445213425754077016252 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_vector.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_VECTOR_H #define GMPY_VECTOR_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_Context_Vector(PyObject *self, PyObject *other); static PyObject * GMPy_Context_Vector2(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_xmpz.c0000664000175000017500000003261313444071152015724 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_xmpz.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_xmpz, "xmpz() -> xmpz(0)\n\n" " If no argument is given, return xmpz(0).\n\n" "xmpz(n) -> xmpz\n\n" " Return an 'xmpz' object with a numeric value 'n' (truncating n\n" " to its integer part if it's a Fraction, 'mpq', float or 'mpfr').\n\n" "xmpz(s[, base=0]):\n\n" " Return an 'xmpz' object from a string 's' made of digits in the\n" " given base. If base=0, binary, octal, or hex Python strings\n" " are recognized by leading 0b, 0o, or 0x characters, otherwise\n" " the string is assumed to be decimal. Values for base can range\n" " between 2 and 62.\n\n" " Note: 'xmpz' is a mutable integer. It can be faster when used\n" " for augmented assignment (+=, *=, etc.). 'xmpz' objects cannot\n" " be used as dictionary keys. The use of 'mpz' objects is recommended\n" " in most cases."); #ifdef PY3 static PyNumberMethods GMPy_XMPZ_number_methods = { (binaryfunc) GMPy_MPZ_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPZ_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPZ_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPZ_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPZ_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_XMPZ_Neg_Slot, /* nb_negative */ (unaryfunc) GMPy_XMPZ_Pos_Slot, /* nb_positive */ (unaryfunc) GMPy_XMPZ_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_XMPZ_NonZero_Slot, /* nb_bool */ (unaryfunc) GMPy_XMPZ_Com_Slot, /* nb_invert */ (binaryfunc) GMPy_MPZ_Lshift_Slot, /* nb_lshift */ (binaryfunc) GMPy_MPZ_Rshift_Slot, /* nb_rshift */ (binaryfunc) GMPy_MPZ_And_Slot, /* nb_and */ (binaryfunc) GMPy_MPZ_Xor_Slot, /* nb_xor */ (binaryfunc) GMPy_MPZ_Ior_Slot, /* nb_or */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_int */ 0, /* nb_reserved */ (unaryfunc) GMPy_MPZ_Float_Slot, /* nb_float */ (binaryfunc) GMPy_XMPZ_IAdd_Slot, /* nb_inplace_add */ (binaryfunc) GMPy_XMPZ_ISub_Slot, /* nb_inplace_subtract */ (binaryfunc) GMPy_XMPZ_IMul_Slot, /* nb_inplace_multiply */ (binaryfunc) GMPy_XMPZ_IRem_Slot, /* nb_inplace_remainder */ (ternaryfunc) GMPy_XMPZ_IPow_Slot, /* nb_inplace_power */ (binaryfunc) GMPy_XMPZ_ILshift_Slot, /* nb_inplace_lshift */ (binaryfunc) GMPy_XMPZ_IRshift_Slot, /* nb_inplace_rshift */ (binaryfunc) GMPy_XMPZ_IAnd_Slot, /* nb_inplace_and */ (binaryfunc) GMPy_XMPZ_IXor_Slot, /* nb_inplace_xor */ (binaryfunc) GMPy_XMPZ_IIor_Slot, /* nb_inplace_or */ (binaryfunc) GMPy_MPZ_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPZ_TrueDiv_Slot, /* nb_true_divide */ (binaryfunc) GMPy_XMPZ_IFloorDiv_Slot, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_index */ }; #else static PyNumberMethods GMPy_XMPZ_number_methods = { (binaryfunc) GMPy_MPZ_Add_Slot, /* nb_add */ (binaryfunc) GMPy_MPZ_Sub_Slot, /* nb_subtract */ (binaryfunc) GMPy_MPZ_Mul_Slot, /* nb_multiply */ (binaryfunc) GMPy_MPZ_Div2_Slot, /* nb_divide */ (binaryfunc) GMPy_MPZ_Mod_Slot, /* nb_remainder */ (binaryfunc) GMPy_MPZ_DivMod_Slot, /* nb_divmod */ (ternaryfunc) GMPy_MPANY_Pow_Slot, /* nb_power */ (unaryfunc) GMPy_XMPZ_Neg_Slot, /* nb_negative */ (unaryfunc) GMPy_XMPZ_Pos_Slot, /* nb_positive */ (unaryfunc) GMPy_XMPZ_Abs_Slot, /* nb_absolute */ (inquiry) GMPy_XMPZ_NonZero_Slot, /* nb_bool */ (unaryfunc) GMPy_XMPZ_Com_Slot, /* nb_invert */ (binaryfunc) GMPy_MPZ_Lshift_Slot, /* nb_lshift */ (binaryfunc) GMPy_MPZ_Rshift_Slot, /* nb_rshift */ (binaryfunc) GMPy_MPZ_And_Slot, /* nb_and */ (binaryfunc) GMPy_MPZ_Xor_Slot, /* nb_xor */ (binaryfunc) GMPy_MPZ_Ior_Slot, /* nb_or */ 0, /* nb_coerce */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_int */ (unaryfunc) GMPy_MPZ_Long_Slot, /* nb_long */ (unaryfunc) GMPy_MPZ_Float_Slot, /* nb_float */ (unaryfunc) GMPy_XMPZ_Oct_Slot, /* nb_oct */ (unaryfunc) GMPy_XMPZ_Hex_Slot, /* nb_hex */ (binaryfunc) GMPy_XMPZ_IAdd_Slot, /* nb_inplace_add */ (binaryfunc) GMPy_XMPZ_ISub_Slot, /* nb_inplace_subtract */ (binaryfunc) GMPy_XMPZ_IMul_Slot, /* nb_inplace_multiply */ 0, /* nb_inplace_divide */ (binaryfunc) GMPy_XMPZ_IRem_Slot, /* nb_inplace_remainder */ (ternaryfunc) GMPy_XMPZ_IPow_Slot, /* nb_inplace_power */ (binaryfunc) GMPy_XMPZ_ILshift_Slot, /* nb_inplace_lshift */ (binaryfunc) GMPy_XMPZ_IRshift_Slot, /* nb_inplace_rshift */ (binaryfunc) GMPy_XMPZ_IAnd_Slot, /* nb_inplace_and */ (binaryfunc) GMPy_XMPZ_IXor_Slot, /* nb_inplace_xor */ (binaryfunc) GMPy_XMPZ_IIor_Slot, /* nb_inplace_or */ (binaryfunc) GMPy_MPZ_FloorDiv_Slot, /* nb_floor_divide */ (binaryfunc) GMPy_MPZ_TrueDiv_Slot, /* nb_true_divide */ (binaryfunc) GMPy_XMPZ_IFloorDiv_Slot, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ (unaryfunc) GMPy_MPZ_Int_Slot, /* nb_index */ }; #endif static PyMappingMethods GMPy_XMPZ_mapping_methods = { (lenfunc)GMPy_XMPZ_Method_Length, (binaryfunc)GMPy_XMPZ_Method_SubScript, (objobjargproc)GMPy_XMPZ_Method_AssignSubScript }; static PyGetSetDef GMPy_XMPZ_getseters[] = { { "numerator", (getter)GMPy_XMPZ_Attrib_GetNumer, NULL, "the numerator of a rational number in lowest terms", NULL }, { "denominator", (getter)GMPy_XMPZ_Attrib_GetDenom, NULL, "the denominator of a rational number in lowest terms", NULL }, { "real", (getter)GMPy_XMPZ_Attrib_GetReal, NULL, "the real part of a complex number", NULL }, { "denominator", (getter)GMPy_XMPZ_Attrib_GetImag, NULL, "the imaginary part of a complex number", NULL }, {NULL} }; static PyMethodDef GMPy_XMPZ_methods [] = { { "__format__", GMPy_MPZ_Format, METH_VARARGS, GMPy_doc_mpz_format }, { "__sizeof__", GMPy_XMPZ_Method_SizeOf, METH_NOARGS, GMPy_doc_xmpz_method_sizeof }, { "bit_clear", GMPy_MPZ_bit_clear_method, METH_O, doc_bit_clear_method }, { "bit_flip", GMPy_MPZ_bit_flip_method, METH_O, doc_bit_flip_method }, { "bit_length", GMPy_MPZ_bit_length_method, METH_NOARGS, doc_bit_length_method }, { "bit_scan0", GMPy_MPZ_bit_scan0_method, METH_VARARGS, doc_bit_scan0_method }, { "bit_scan1", GMPy_MPZ_bit_scan1_method, METH_VARARGS, doc_bit_scan1_method }, { "bit_set", GMPy_MPZ_bit_set_method, METH_O, doc_bit_set_method }, { "bit_test", GMPy_MPZ_bit_test_method, METH_O, doc_bit_test_method }, { "conjugate", GMPy_MP_Method_Conjugate, METH_NOARGS, GMPy_doc_mp_method_conjugate }, { "copy", GMPy_XMPZ_Method_Copy, METH_NOARGS, GMPy_doc_xmpz_method_copy }, { "digits", GMPy_XMPZ_Digits_Method, METH_VARARGS, GMPy_doc_mpz_digits_method }, { "iter_bits", (PyCFunction)GMPy_XMPZ_Method_IterBits, METH_VARARGS | METH_KEYWORDS, GMPy_doc_xmpz_method_iter_bits }, { "iter_clear", (PyCFunction)GMPy_XMPZ_Method_IterClear, METH_VARARGS | METH_KEYWORDS, GMPy_doc_xmpz_method_iter_clear }, { "iter_set", (PyCFunction)GMPy_XMPZ_Method_IterSet, METH_VARARGS | METH_KEYWORDS, GMPy_doc_xmpz_method_iter_set }, { "make_mpz", GMPy_XMPZ_Method_MakeMPZ, METH_NOARGS, GMPy_doc_xmpz_method_make_mpz }, { "num_digits", GMPy_MPZ_Method_NumDigits, METH_VARARGS, GMPy_doc_mpz_method_num_digits }, { NULL, NULL, 1 } }; static PyTypeObject XMPZ_Type = { /* PyObject_HEAD_INIT(&PyType_Type) */ #ifdef PY3 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "xmpz", /* tp_name */ sizeof(XMPZ_Object), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor) GMPy_XMPZ_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_XMPZ_Repr_Slot, /* tp_repr */ &GMPy_XMPZ_number_methods, /* tp_as_number */ 0, /* tp_as_sequence */ &GMPy_XMPZ_mapping_methods, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ (reprfunc) GMPy_XMPZ_Str_Slot, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ #ifdef PY3 Py_TPFLAGS_DEFAULT, /* tp_flags */ #else Py_TPFLAGS_HAVE_INDEX|Py_TPFLAGS_HAVE_RICHCOMPARE| \ Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_CLASS| \ Py_TPFLAGS_HAVE_INPLACEOPS, #endif GMPy_doc_xmpz, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ (richcmpfunc)&GMPy_RichCompare_Slot, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ 0, /* tp_iter */ 0, /* tp_iternext */ GMPy_XMPZ_methods, /* tp_methods */ 0, /* tp_members */ GMPy_XMPZ_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ GMPy_XMPZ_NewInit, /* tp_new */ 0, /* tp_free */ }; gmpy2-2.1.0b3/src/gmpy2_xmpz.h0000664000175000017500000000510613425754140015732 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_xmpz.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_XMPZ_H #define GMPY_XMPZ_H #ifdef __cplusplus extern "C" { #endif static PyTypeObject XMPZ_Type; #define XMPZ(obj) (((XMPZ_Object*)(obj))->z) #define XMPZ_Check(v) (((PyObject*)v)->ob_type == &XMPZ_Type) #define CHECK_MPZANY(v) (MPZ_Check(v) || XMPZ_Check(v)) typedef struct { PyObject_HEAD XMPZ_Object *bitmap; mp_bitcnt_t start, stop; int iter_type; } GMPy_Iter_Object; static PyTypeObject GMPy_Iter_Type; #define GMPy_Iter_Check(v) (((PyObject*)v)->ob_type == &GMPy_Iter_Type) #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_xmpz_inplace.c0000664000175000017500000002243213425754150017422 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * gmpy2_xmpz_inplace.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Provides inplace mutating operations for xmpz. */ #include /* Inplace xmpz addition. */ static PyObject * GMPy_XMPZ_IAdd_Slot(PyObject *self, PyObject *other) { /* Try to make mpz + small_int faster */ if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp >= 0) { mpz_add_ui(MPZ(self), MPZ(self), temp); } else { mpz_sub_ui(MPZ(self), MPZ(self), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_add(MPZ(self), MPZ(self), global.tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { mpz_add(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace mpz subtraction. */ static PyObject * GMPy_XMPZ_ISub_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp >= 0) { mpz_sub_ui(MPZ(self), MPZ(self), temp); } else { mpz_add_ui(MPZ(self), MPZ(self), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_sub(MPZ(self), MPZ(self), global.tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { mpz_sub(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace xmpz multiplication. */ static PyObject * GMPy_XMPZ_IMul_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { mpz_mul_si(MPZ(self), MPZ(self), temp); } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_mul(MPZ(self), MPZ(self), global.tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { mpz_mul(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Pympany_floordiv follows the // semantics from Python 3.x. The result is * an mpz when the arguments are mpz or mpq, but the result is an mpf when * the arguments are mpf. */ static PyObject * GMPy_XMPZ_IFloorDiv_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp == 0) { ZERO_ERROR("xmpz division by zero"); return NULL; } else if(temp > 0) { mpz_fdiv_q_ui(MPZ(self), MPZ(self), temp); } else { mpz_cdiv_q_ui(MPZ(self), MPZ(self), -temp); mpz_neg(MPZ(self), MPZ(self)); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_fdiv_q(MPZ(self), MPZ(self), global.tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { if (mpz_sgn(MPZ(other)) == 0) { ZERO_ERROR("xmpz division by zero"); return NULL; } mpz_fdiv_q(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace xmpz remainder. */ static PyObject * GMPy_XMPZ_IRem_Slot(PyObject *self, PyObject *other) { if (PyIntOrLong_Check(other)) { int error; native_si temp = GMPy_Integer_AsNative_siAndError(other, &error); if (!error) { if (temp > 0) { mpz_fdiv_r_ui(MPZ(self), MPZ(self), temp); } else if (temp == 0) { ZERO_ERROR("xmpz modulo by zero"); return NULL; } else { mpz_cdiv_r_ui(MPZ(self), MPZ(self), -temp); } } else { mpz_set_PyIntOrLong(global.tempz, other); mpz_fdiv_r(MPZ(self), MPZ(self), global.tempz); } Py_INCREF(self); return self; } if (CHECK_MPZANY(other)) { if(mpz_sgn(MPZ(other)) == 0) { ZERO_ERROR("xmpz modulo by zero"); return NULL; } mpz_fdiv_r(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace xmpz rshift. */ static PyObject * GMPy_XMPZ_IRshift_Slot(PyObject *self, PyObject *other) { mp_bitcnt_t shift; if (IS_INTEGER(other)) { shift = mp_bitcnt_t_From_Integer(other); if (shift == (mp_bitcnt_t)(-1) && PyErr_Occurred()) return NULL; mpz_fdiv_q_2exp(MPZ(self), MPZ(self), shift); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace xmpz lshift. */ static PyObject * GMPy_XMPZ_ILshift_Slot(PyObject *self, PyObject *other) { mp_bitcnt_t shift; if (IS_INTEGER(other)) { shift = mp_bitcnt_t_From_Integer(other); if (shift == (mp_bitcnt_t)(-1) && PyErr_Occurred()) return NULL; mpz_mul_2exp(MPZ(self), MPZ(self), shift); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace xmpz_pow. */ static PyObject * GMPy_XMPZ_IPow_Slot(PyObject *self, PyObject *other, PyObject *mod) { mp_bitcnt_t exp; exp = mp_bitcnt_t_From_Integer(other); if (exp == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } mpz_pow_ui(MPZ(self), MPZ(self), exp); Py_INCREF((PyObject*)self); return (PyObject*)self; } /* Inplace xmpz and. */ static PyObject * GMPy_XMPZ_IAnd_Slot(PyObject *self, PyObject *other) { if (CHECK_MPZANY(other)) { mpz_and(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } if (PyIntOrLong_Check(other)) { mpz_set_PyIntOrLong(global.tempz, other); mpz_and(MPZ(self), MPZ(self), global.tempz); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace xmpz xor. */ static PyObject * GMPy_XMPZ_IXor_Slot(PyObject *self, PyObject *other) { if(CHECK_MPZANY(other)) { mpz_xor(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } if(PyIntOrLong_Check(other)) { mpz_set_PyIntOrLong(global.tempz, other); mpz_xor(MPZ(self), MPZ(self), global.tempz); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } /* Inplace xmpz or. */ static PyObject * GMPy_XMPZ_IIor_Slot(PyObject *self, PyObject *other) { if(CHECK_MPZANY(other)) { mpz_ior(MPZ(self), MPZ(self), MPZ(other)); Py_INCREF(self); return self; } if(PyIntOrLong_Check(other)) { mpz_set_PyIntOrLong(global.tempz, other); mpz_ior(MPZ(self), MPZ(self), global.tempz); Py_INCREF(self); return self; } Py_RETURN_NOTIMPLEMENTED; } gmpy2-2.1.0b3/src/gmpy2_xmpz_inplace.h0000664000175000017500000000573013425754162017434 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_xmpz_inplace.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_XMPZ_INPLACE_H #define GMPY_XMPZ_INPLACE_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPy_XMPZ_IAdd_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_ISub_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_IMul_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_IFloorDiv_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_IRem_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_IRshift_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_ILshift_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_IPow_Slot(PyObject *self, PyObject *other, PyObject *mod); static PyObject * GMPy_XMPZ_IAnd_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_IXor_Slot(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_IIor_Slot(PyObject *self, PyObject *other); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy2_xmpz_misc.c0000664000175000017500000004574213444071152016746 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_xmpz_misc.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(GMPy_doc_xmpz_function_xbit_mask, "xbit_mask(n) -> xmpz\n\n" "Return an 'xmpz' exactly n bits in length with all bits set.\n"); static PyObject * GMPy_XMPZ_Function_XbitMask(PyObject *self, PyObject *other) { Py_ssize_t i = 0; XMPZ_Object* result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); i = ssize_t_From_Integer(other); if (i == -1 && PyErr_Occurred()) { TYPE_ERROR("xbit_mask() requires 'int' argument"); return NULL; } if (i < 0) { VALUE_ERROR("mask length must be >= 0"); return NULL; } if (!(result = GMPy_XMPZ_New(context))) { return NULL; } mpz_set_ui(result->z, 1); mpz_mul_2exp(result->z, result->z, i); mpz_sub_ui(result->z, result->z, 1); return (PyObject*)result; } static PyObject * GMPy_XMPZ_Abs_Slot(XMPZ_Object *x) { mpz_abs(x->z, x->z); Py_RETURN_NONE; } static PyObject * GMPy_XMPZ_Neg_Slot(XMPZ_Object *x) { mpz_neg(x->z, x->z); Py_RETURN_NONE; } static PyObject * GMPy_XMPZ_Pos_Slot(XMPZ_Object *x) { Py_RETURN_NONE; } static int GMPy_XMPZ_NonZero_Slot(XMPZ_Object *x) { return mpz_sgn(x->z) != 0; } /* BIT OPERATIONS */ static PyObject * GMPy_XMPZ_Com_Slot(XMPZ_Object *x) { mpz_com(x->z, x->z); Py_RETURN_NONE; } #if PY_MAJOR_VERSION < 3 /* hex/oct formatting (mpz-only) */ static PyObject * GMPy_XMPZ_Oct_Slot(XMPZ_Object *self) { CTXT_Object *context = NULL; CHECK_CONTEXT(context); return GMPy_PyStr_From_XMPZ(self, 8, 0, context); } static PyObject * GMPy_XMPZ_Hex_Slot(XMPZ_Object *self) { CTXT_Object *context = NULL; CHECK_CONTEXT(context); return GMPy_PyStr_From_XMPZ(self, 16, 0, context); } #endif PyDoc_STRVAR(GMPy_doc_xmpz_method_make_mpz, "xmpz.make_mpz() -> mpz\n\n" "Return an mpz by converting an 'xmpz' to an 'mpz' as quickly as\n" "possible.\n\n" "NOTE: Optimized for speed so the original xmpz is set to 0!"); static PyObject * GMPy_XMPZ_Method_MakeMPZ(PyObject *self, PyObject *other) { MPZ_Object* result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPZ_New(context))) { return NULL; } mpz_swap(result->z, MPZ(self)); mpz_set_ui(MPZ(self), 0); return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_xmpz_method_copy, "xmpz.copy() -> xmpz\n\n" "Return a copy of an xmpz."); static PyObject * GMPy_XMPZ_Method_Copy(PyObject *self, PyObject *other) { CTXT_Object *context = NULL; CHECK_CONTEXT(context); return (PyObject*)GMPy_XMPZ_From_XMPZ((XMPZ_Object*)self, context); } /* * Add mapping support to xmpz objects. */ static Py_ssize_t GMPy_XMPZ_Method_Length(XMPZ_Object *obj) { return mpz_sizeinbase(obj->z, 2); } static PyObject * GMPy_XMPZ_Method_SubScript(XMPZ_Object* self, PyObject* item) { CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyIndex_Check(item)) { Py_ssize_t i; i = PyIntOrLong_AsSsize_t(item); if (i == -1 && PyErr_Occurred()) { INDEX_ERROR("argument too large to be converted to an index"); return NULL; } if (i < 0) { i += mpz_sizeinbase(self->z, 2); } return PyIntOrLong_FromLong(mpz_tstbit(self->z, i)); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength, cur, i; MPZ_Object *result; #if PY_VERSION_HEX > 0x030200A4 if (PySlice_GetIndicesEx(item, mpz_sizeinbase(self->z, 2), &start, &stop, &step, &slicelength) < 0) { return NULL; } #else if (PySlice_GetIndicesEx((PySliceObject*)item, mpz_sizeinbase(self->z, 2), &start, &stop, &step, &slicelength) < 0) { return NULL; } #endif if ((step < 0 && start < stop) || (step > 0 && start > stop)) { stop = start; } if (!(result = GMPy_MPZ_New(context))) { return NULL; } mpz_set_ui(result->z, 0); if (slicelength > 0) { for (cur = start, i = 0; i < slicelength; cur += step, i++) { if (mpz_tstbit(self->z, cur)) { mpz_setbit(result->z, i); } } } return (PyObject*)result; } else { TYPE_ERROR("bit positions must be integers"); return NULL; } } static int GMPy_XMPZ_Method_AssignSubScript(XMPZ_Object* self, PyObject* item, PyObject* value) { CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (PyIndex_Check(item)) { Py_ssize_t bit_value, i; i = PyIntOrLong_AsSsize_t(item); if (i == -1 && PyErr_Occurred()) { INDEX_ERROR("argument too large to be converted to an index"); return -1; } if (i < 0) { i += mpz_sizeinbase(self->z, 2); } bit_value = PyIntOrLong_AsSsize_t(value); if (bit_value == -1 && PyErr_Occurred()) { VALUE_ERROR("bit value must be 0 or 1"); return -1; } if (bit_value == 1) { mpz_setbit(self->z, i); return 0; } else if (bit_value == 0) { mpz_clrbit(self->z, i); return 0; } else { VALUE_ERROR("bit value must be 0 or 1"); return -1; } } else if (PySlice_Check(item)) { Py_ssize_t cur, i, seq_len, start, stop, step, slicelength, temp; seq_len = mpz_sizeinbase(self->z, 2); if (((PySliceObject*)item)->stop != Py_None) { /* If a fixed endpoint is specified, and the endpoint is greater * than the length of the xmpz object, allow the underlying xmpz * object to be made larger. */ temp = PyIntOrLong_AsSsize_t(((PySliceObject*)item)->stop); if (temp == -1 && PyErr_Occurred()) { return 0; } if (temp > seq_len) { seq_len = temp; } } #if PY_VERSION_HEX > 0x030200A4 if (PySlice_GetIndicesEx(item, seq_len, &start, &stop, &step, &slicelength) < 0) { return -1; } #else if (PySlice_GetIndicesEx((PySliceObject*)item, seq_len, &start, &stop, &step, &slicelength) < 0) { return -1; } #endif if ((step < 0 && start < stop) || (step > 0 && start > stop)) { stop = start; } if (value == NULL) { TYPE_ERROR("deleting bits not supported"); return -1; } else { int bit; MPZ_Object *tempx; if (!(tempx = GMPy_MPZ_From_Integer(value, context))) { VALUE_ERROR("must specify bit sequence as an integer"); return -1; } if (mpz_sgn(tempx->z) == 0) { for (cur = start, i = 0; i < slicelength; cur += step, i++) { mpz_clrbit(self->z, cur); } } else if (!(mpz_cmp_si(tempx->z, -1))) { for (cur = start + (slicelength-1) * step, i = 0; i < slicelength; cur -= step, i++) { mpz_setbit(self->z, cur); } } else { for (cur = start, i = 0; i < slicelength; cur += step, i++) { bit = mpz_tstbit(tempx->z, i); if (bit) mpz_setbit(self->z, cur); else mpz_clrbit(self->z, cur); } } Py_DECREF((PyObject*)tempx); } return 0; } else { TYPE_ERROR("bit positions must be integers"); return -1; } return -1; } /* Implement a multi-purpose iterator object that iterates over the bits in * an xmpz. Three different iterators can be created: * 1) xmpz.iter_bits(start=0, stop=-1) will return True/False for each bit * position in the xmpz, beginning with bit 'start'. If stop is specified, * the xmpz will be padded with 0-bits (False) until stop is reached. * 2) xmpz.iter_set(start=0, stop=-1, scale=1, offset=0) will return * (scale*bit_position + offset) when bit_position is set, beginning at * 'start', ending at 'stop'. * 3) xmpz.iter_clear(start=0, stop=-1, scale=1, offset=0) will return * (scale*bit_position + offset) when bit_position is clear, beginning at * 'start', ending at 'stop'. * */ static GMPy_Iter_Object * GMPy_Iter_New(void) { GMPy_Iter_Object *result; if ((result = PyObject_New(GMPy_Iter_Object, &GMPy_Iter_Type))) { result->bitmap = NULL; result->start = 0; result->stop = (mp_bitcnt_t)-1; result->iter_type = 1; } return result; }; static void GMPy_Iter_Dealloc(GMPy_Iter_Object *self) { Py_XDECREF((PyObject*)self->bitmap); PyObject_Del(self); }; static PyObject * GMPy_Iter_Next(GMPy_Iter_Object *self) { PyObject *result = 0; mp_bitcnt_t temp, current_stop; if (self->stop == (mp_bitcnt_t)(-1)) current_stop = mpz_sizeinbase(self->bitmap->z, 2); else current_stop = self->stop; switch (self->iter_type) { case 1: if (self->start >= current_stop) PyErr_SetNone(PyExc_StopIteration); else { temp = mpz_tstbit(self->bitmap->z, self->start); self->start += 1; result = temp ? Py_True : Py_False; Py_INCREF(result); } break; case 2: if (self->start >= current_stop) PyErr_SetNone(PyExc_StopIteration); else { temp = mpz_scan1(self->bitmap->z, self->start); if (temp == (mp_bitcnt_t)(-1)) PyErr_SetNone(PyExc_StopIteration); else { self->start = temp + 1; result = PyIntOrLong_FromSsize_t(temp); } } break; case 3: if (self->start >= current_stop) PyErr_SetNone(PyExc_StopIteration); else { temp = mpz_scan0(self->bitmap->z, self->start); if (temp >= current_stop) PyErr_SetNone(PyExc_StopIteration); else { self->start = temp + 1; result = PyIntOrLong_FromSsize_t(temp); } } break; default: SYSTEM_ERROR("Illegal iter_type in gmpy2.Iterator."); } return result; } static PyObject * GMPy_Iter_Repr(GMPy_Iter_Object *self) { return Py_BuildValue("s", ""); }; PyDoc_STRVAR(GMPy_doc_xmpz_method_iter_bits, "xmpz.iter_bits(start=0, stop=-1) -> iterator\n\n" "Return True or False for each bit position in 'xmpz' beginning at\n" "'start'. If a positive value is specified for 'stop', iteration is\n" "continued until 'stop' is reached. If a negative value is specified,\n" "iteration is continued until the last 1-bit. Note: the value of the\n" "underlying xmpz object can change during iteration."); static PyObject * GMPy_XMPZ_Method_IterBits(PyObject *self, PyObject *args, PyObject *kwargs) { GMPy_Iter_Object *result; Py_ssize_t start = 0, stop = -1; static char *kwlist[] = {"start", "stop", NULL }; if (!(result = GMPy_Iter_New())) { return NULL; } if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "|nn", kwlist, &start, &stop))) { Py_XDECREF((PyObject*)result); return NULL; } result->iter_type = 1; result->bitmap = (XMPZ_Object*)self; Py_INCREF(self); result->start = start; result->stop = stop; return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_xmpz_method_iter_set, "xmpz.iter_set(start=0, stop=-1) -> iterator\n\n" "Return an iterator yielding the bit position for every bit that\n" "is set in 'xmpz', beginning at 'start'. If a positive value is\n" "specified for 'stop', iteration is continued until 'stop' is\n" "reached. To match the behavior of slicing, 'stop' is not included.\n" "If a negative value is specified, iteration is continued until\n" "the last 1-bit. Note: the value of the underlying xmpz object can\n" "change during iteration."); static PyObject * GMPy_XMPZ_Method_IterSet(PyObject *self, PyObject *args, PyObject *kwargs) { GMPy_Iter_Object *result; Py_ssize_t start = 0, stop = -1; static char *kwlist[] = {"start", "stop", NULL }; if (!(result = GMPy_Iter_New())) { return NULL; } if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "|nn", kwlist, &start, &stop))) { Py_XDECREF((PyObject*)result); return NULL; } result->iter_type = 2; result->bitmap = (XMPZ_Object*)self; Py_INCREF(self); result->start = start; result->stop = stop; return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_xmpz_method_iter_clear, "xmpz.iter_clear(start=0, stop=-1) -> iterator\n\n" "Return every bit position that is clear in 'xmpz', beginning at\n" "'start'. If a positive value is specified for 'stop', iteration\n" "is continued until 'stop' is reached. If a negative value is specified,\n" "iteration is continued until the last 1-bit. Note: the value of the\n" "underlying xmpz object can change during iteration."); static PyObject * GMPy_XMPZ_Method_IterClear(PyObject *self, PyObject *args, PyObject *kwargs) { GMPy_Iter_Object *result; Py_ssize_t start = 0, stop = -1; static char *kwlist[] = {"start", "stop", NULL }; if (!(result = GMPy_Iter_New())) { return NULL; } if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "|nn", kwlist, &start, &stop))) { Py_XDECREF((PyObject*)result); return NULL; } result->iter_type = 3; result->bitmap = (XMPZ_Object*)self; Py_INCREF(self); result->start = start; result->stop = stop; return (PyObject*)result; } static PyObject * GMPy_XMPZ_Attrib_GetNumer(XMPZ_Object *self, void *closure) { Py_INCREF((PyObject*)self); return (PyObject*)self; } static PyObject * GMPy_XMPZ_Attrib_GetReal(XMPZ_Object *self, void *closure) { Py_INCREF((PyObject*)self); return (PyObject*)self; } static PyObject * GMPy_XMPZ_Attrib_GetDenom(XMPZ_Object *self, void *closure) { XMPZ_Object *result; if ((result = GMPy_XMPZ_New(NULL))) { mpz_set_ui(result->z, 1); } return (PyObject*)result; } static PyObject * GMPy_XMPZ_Attrib_GetImag(XMPZ_Object *self, void *closure) { XMPZ_Object *result; if ((result = GMPy_XMPZ_New(NULL))) { mpz_set_ui(result->z, 0); } return (PyObject*)result; } PyDoc_STRVAR(GMPy_doc_xmpz_method_sizeof, "x.__sizeof__()\n\n" "Returns the amount of memory consumed by x. Note: deleted xmpz objects\n" "are reused and may or may not be resized when a new value is assigned."); static PyObject * GMPy_XMPZ_Method_SizeOf(PyObject *self, PyObject *other) { return PyIntOrLong_FromSize_t(sizeof(XMPZ_Object) + \ (MPZ(self)->_mp_alloc * sizeof(mp_limb_t))); } static PyTypeObject GMPy_Iter_Type = { #ifdef PY3 PyVarObject_HEAD_INIT(0, 0) #else PyObject_HEAD_INIT(0) 0, /* ob_size */ #endif "gmpy2 iterator", /* tp_name */ sizeof(GMPy_Iter_Object), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor) GMPy_Iter_Dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc) GMPy_Iter_Repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "GMPY2 Iterator Object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset*/ PyObject_SelfIter, /* tp_iter */ (iternextfunc)GMPy_Iter_Next, /* tp_iternext */ }; gmpy2-2.1.0b3/src/gmpy2_xmpz_misc.h0000664000175000017500000001000413444071152016732 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy2_xmpz_misc.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * * 2008, 2009 Alex Martelli * * * * Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, * * 2015, 2016, 2017, 2018, 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_XMPZ_MISC_H #define GMPY_XMPZ_MISC_H #ifdef __cplusplus extern "C" { #endif static int GMPy_XMPZ_NonZero_Slot(XMPZ_Object *x); static PyObject * GMPy_XMPZ_Function_XbitMask(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_Abs_Slot(XMPZ_Object *x); static PyObject * GMPy_XMPZ_Neg_Slot(XMPZ_Object *x); static PyObject * GMPy_XMPZ_Pos_Slot(XMPZ_Object *x); static PyObject * GMPy_XMPZ_Com_Slot(XMPZ_Object *x); static PyObject * GMPy_XMPZ_Method_MakeMPZ(PyObject *self, PyObject *other); static PyObject * GMPy_XMPZ_Method_Copy(PyObject *self, PyObject *other); static Py_ssize_t GMPy_XMPZ_Method_Length(XMPZ_Object *obj); static PyObject * GMPy_XMPZ_Method_SubScript(XMPZ_Object* self, PyObject* item); static int GMPy_XMPZ_Method_AssignSubScript(XMPZ_Object* self, PyObject* item, PyObject* value); static PyObject * GMPy_XMPZ_Attrib_GetNumer(XMPZ_Object *self, void *closure); static PyObject * GMPy_XMPZ_Attrib_GetDenom(XMPZ_Object *self, void *closure); static PyObject * GMPy_XMPZ_Attrib_GetReal(XMPZ_Object *self, void *closure); static PyObject * GMPy_XMPZ_Attrib_GetImag(XMPZ_Object *self, void *closure); static GMPy_Iter_Object * GMPy_Iter_New(void); static void GMPy_Iter_Dealloc(GMPy_Iter_Object *self); static PyObject * GMPy_Iter_Next(GMPy_Iter_Object *self); static PyObject * GMPy_Iter_Repr(GMPy_Iter_Object *self); static PyObject * GMPy_XMPZ_Method_IterBits(PyObject *self, PyObject *args, PyObject *kwargs); static PyObject * GMPy_XMPZ_Method_IterSet(PyObject *self, PyObject *args, PyObject *kwargs); static PyObject * GMPy_XMPZ_Method_IterClear(PyObject *self, PyObject *args, PyObject *kwargs); static PyObject * GMPy_XMPZ_Method_SizeOf(PyObject *self, PyObject *other); #if PY_MAJOR_VERSION < 3 /* hex/oct formatting (mpz-only) */ static PyObject * GMPy_XMPZ_Oct_Slot(XMPZ_Object *self); static PyObject * GMPy_XMPZ_Hex_Slot(XMPZ_Object *self); #endif #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy_mpz_lucas.c0000664000175000017500000004410313425754250016644 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_mpz_lucas.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2011 David Cleaver * * * * Copyright 2012, 2013, 2014, 2015, 2016, 2017, 2018, * * 2019 Case Van Horsen * * * * The original file is available at: * * * * * * Modified by Case Van Horsen for inclusion into GMPY2. * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PyDoc_STRVAR(doc_mpz_lucasu, "lucasu(p,q,k) -> mpz\n\n" "Return the k-th element of the Lucas U sequence defined by p,q.\n" "p*p - 4*q must not equal 0; k must be greater than or equal to 0."); static PyObject * GMPY_mpz_lucasu(PyObject *self, PyObject *args) { /* Adaptation of algorithm found in http://joye.site88.net/papers/JQ96lucas.pdf * calculate u[k] of Lucas U sequence for p,q. * Note: p^2-4q=0 is not tested, not a proper Lucas sequence!! */ MPZ_Object *result = NULL, *p = NULL, *q = NULL, *k = NULL; size_t s = 0, j = 0; mpz_t uh, vl, vh, ql, qh, tmp; if (PyTuple_Size(args) != 3) { TYPE_ERROR("lucasu() requires 3 integer arguments"); return NULL; } mpz_init(uh); mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); k = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL); if (!p || !q || !k) { TYPE_ERROR("lucasu() requires 3 integer arguments"); goto cleanup; } /* Check if p*p - 4*q == 0. */ mpz_mul(tmp, p->z, p->z); mpz_mul_ui(qh, q->z, 4); mpz_sub(tmp, tmp, qh); if (mpz_sgn(tmp) == 0) { VALUE_ERROR("invalid values for p,q in lucasu()"); goto cleanup; } /* Check if k < 0. */ if (mpz_sgn(k->z) < 0) { VALUE_ERROR("invalid value for k in lucasu()"); goto cleanup; } mpz_set_si(uh, 1); mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp, 0); s = mpz_scan1(k->z, 0); for (j = mpz_sizeinbase(k->z,2)-1; j >= s+1; j--) { /* ql = ql*qh */ mpz_mul(ql, ql, qh); if (mpz_tstbit(k->z,j) == 1) { /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vh */ mpz_mul(uh, uh, vh); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* vh = vh*vh - 2*qh */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); } else { /* qh = ql */ mpz_set(qh, ql); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vh = vh*vl - p*ql */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); /* vl = vl*vl - 2*ql */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* uh = uh*vl */ mpz_mul(uh, uh, vl); /* vl = vl*vl - 2*ql */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); /* ql = ql*ql */ mpz_mul(ql, ql, ql); } if (!(result = GMPy_MPZ_New(NULL))) goto cleanup; /* uh contains our return value */ mpz_set(result->z, uh); cleanup: mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)k); return (PyObject*)result; } PyDoc_STRVAR(doc_mpz_lucasu_mod, "lucasu_mod(p,q,k,n) -> mpz\n\n" "Return the k-th element of the Lucas U sequence defined by p,q (mod n).\n" "p*p - 4*q must not equal 0; k must be greater than or equal to 0;\n" "n must be greater than 0."); static PyObject * GMPY_mpz_lucasu_mod(PyObject *self, PyObject *args) { /* Adaptation of algorithm found in http://joye.site88.net/papers/JQ96lucas.pdf * calculate u[k] (modulo n) of Lucas U sequence for p,q. * Note: p^2-4q=0 is not tested, not a proper Lucas sequence!! */ MPZ_Object *result = NULL, *p = NULL, *q = NULL, *k = NULL, *n = NULL; size_t s = 0, j = 0; mpz_t uh, vl, vh, ql, qh, tmp; if (PyTuple_Size(args) != 4) { TYPE_ERROR("lucasu_mod() requires 4 integer arguments"); return NULL; } mpz_init(uh); mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); k = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 3), NULL); if (!p || !q || !k || !n) { TYPE_ERROR("lucasu_mod() requires 4 integer arguments"); goto cleanup; } /* Check if p*p - 4*q == 0. */ mpz_mul(tmp, p->z, p->z); mpz_mul_ui(qh, q->z, 4); mpz_sub(tmp, tmp, qh); if (mpz_sgn(tmp) == 0) { VALUE_ERROR("invalid values for p,q in lucasu_mod()"); goto cleanup; } /* Check if k < 0. */ if (mpz_sgn(k->z) < 0) { VALUE_ERROR("invalid value for k in lucasu_mod()"); goto cleanup; } /* Check if n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("invalid value for n in lucasu_mod()"); goto cleanup; } mpz_set_si(uh, 1); mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp, 0); s = mpz_scan1(k->z, 0); for (j = mpz_sizeinbase(k->z,2)-1; j >= s+1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n->z); if (mpz_tstbit(k->z,j) == 1) { /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vh (mod n) */ mpz_mul(uh, uh, vh); mpz_mod(uh, uh, n->z); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); } else { /* qh = ql */ mpz_set(qh, ql); /* uh = uh*vl - ql (mod n) */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); mpz_mod(uh, uh, n->z); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* uh = uh*vl (mod n) */ mpz_mul(uh, uh, vl); mpz_mod(uh, uh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n->z); } if (!(result = GMPy_MPZ_New(NULL))) goto cleanup; /* uh contains our return value */ mpz_mod(result->z, uh, n->z); cleanup: mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)k); Py_XDECREF((PyObject*)n); return (PyObject*)result; } PyDoc_STRVAR(doc_mpz_lucasv, "lucasv(p,q,k) -> mpz\n\n" "Return the k-th element of the Lucas V sequence defined by p,q.\n" "p*p - 4*q must not equal 0; k must be greater than or equal to 0."); static PyObject * GMPY_mpz_lucasv(PyObject *self, PyObject *args) { /* Adaptation of algorithm found in http://joye.site88.net/papers/JQ96lucas.pdf * calculate v[k] of Lucas V sequence for p,q. * Note: p^2-4q=0 is not tested, not a proper Lucas sequence!! */ MPZ_Object *result = NULL, *p = NULL, *q = NULL, *k = NULL; size_t s = 0, j = 0; mpz_t vl, vh, ql, qh, tmp; if (PyTuple_Size(args) != 3) { TYPE_ERROR("lucasv() requires 3 integer arguments"); return NULL; } mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); k = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL); if (!p || !q || !k) { TYPE_ERROR("lucasv() requires 3 integer arguments"); goto cleanup; } /* Check if p*p - 4*q == 0. */ mpz_mul(tmp, p->z, p->z); mpz_mul_ui(qh, q->z, 4); mpz_sub(tmp, tmp, qh); if (mpz_sgn(tmp) == 0) { VALUE_ERROR("invalid values for p,q in lucasv()"); goto cleanup; } /* Check if k < 0. */ if (mpz_sgn(k->z) < 0) { VALUE_ERROR("invalid value for k in lucasv()"); goto cleanup; } mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp,0); s = mpz_scan1(k->z, 0); for (j = mpz_sizeinbase(k->z,2)-1; j >= s+1; j--) { /* ql = ql*qh */ mpz_mul(ql, ql, qh); if (mpz_tstbit(k->z,j) == 1) { /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* vh = vh*vh - 2*qh */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); } else { /* qh = ql */ mpz_set(qh, ql); /* vh = vh*vl - p*ql */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); /* vl = vl*vl - 2*ql */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* vl = vl*vl - 2*ql */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); /* ql = ql*ql */ mpz_mul(ql, ql, ql); } if (!(result = GMPy_MPZ_New(NULL))) goto cleanup; /* vl contains our return value */ mpz_set(result->z, vl); cleanup: mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)k); return (PyObject*)result; } PyDoc_STRVAR(doc_mpz_lucasv_mod, "lucasv_mod(p,q,k,n) -> mpz\n\n" "Return the k-th element of the Lucas V sequence defined by p,q (mod n).\n" "p*p - 4*q must not equal 0; k must be greater than or equal to 0;\n" "n must be greater than 0."); static PyObject * GMPY_mpz_lucasv_mod(PyObject *self, PyObject *args) { /* Adaptation of algorithm found in http://joye.site88.net/papers/JQ96lucas.pdf * calculate v[k] (modulo n) of Lucas V sequence for p,q. * Note: p^2-4q=0 is not tested, not a proper Lucas sequence!! */ MPZ_Object *result = NULL, *p = NULL, *q = NULL, *k = NULL, *n = NULL; size_t s = 0, j = 0; mpz_t vl, vh, ql, qh, tmp; if (PyTuple_Size(args) != 4) { TYPE_ERROR("lucasv_mod() requires 4 integer arguments"); return NULL; } mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); k = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 3), NULL); if (!p || !q || !k || !n) { TYPE_ERROR("lucasv_mod() requires 4 integer arguments"); goto cleanup; } /* Check if p*p - 4*q == 0. */ mpz_mul(tmp, p->z, p->z); mpz_mul_ui(qh, q->z, 4); mpz_sub(tmp, tmp, qh); if (mpz_sgn(tmp) == 0) { VALUE_ERROR("invalid values for p,q in lucasv_mod()"); goto cleanup; } /* Check if k < 0. */ if (mpz_sgn(k->z) < 0) { VALUE_ERROR("invalid value for k in lucasv_mod()"); goto cleanup; } /* Check if n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("invalid value for n in lucasv_mod()"); goto cleanup; } mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp,0); s = mpz_scan1(k->z, 0); for (j = mpz_sizeinbase(k->z,2)-1; j >= s+1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n->z); if (mpz_tstbit(k->z,j) == 1) { /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); } else { /* qh = ql */ mpz_set(qh, ql); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n->z); } if (!(result = GMPy_MPZ_New(NULL))) goto cleanup; /* vl contains our return value */ mpz_mod(result->z, vl, n->z); cleanup: mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)k); Py_XDECREF((PyObject*)n); return (PyObject*)result; } gmpy2-2.1.0b3/src/gmpy_mpz_lucas.h0000664000175000017500000000435613425754313016657 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_mpz_lucas.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2012, 2013, 2014, 2015, 2016, 2017, 2018, * * 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_LUCAS_H #define GMPY_LUCAS_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPY_mpz_lucasu(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_lucasu_mod(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_lucasv(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_lucasv_mod(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/gmpy_mpz_prp.c0000664000175000017500000013002513425754352016340 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_mpz_prp.c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2011 David Cleaver * * * * Copyright 2012, 2013, 2014, 2015, 2016, 2017, 2018, * * 2019 Case Van Horsen * * * * The original file is available at: * * * * * * Modified by Case Van Horsen for inclusion into GMPY2. * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ****************************************************************** * mpz_prp: (also called a Fermat probable prime) * A "probable prime" to the base a is a number n such that, * (a,n)=1 and a^(n-1) = 1 mod n * ******************************************************************/ PyDoc_STRVAR(doc_mpz_is_fermat_prp, "is_fermat_prp(n,a) -> boolean\n\n" "Return True if n is a Fermat probable prime to the base a.\n" "Assuming:\n" " gcd(n,a) == 1\n" "Then a Fermat probable prime requires:\n" " a**(n-1) == 1 (mod n)"); static PyObject * GMPY_mpz_is_fermat_prp(PyObject *self, PyObject *args) { MPZ_Object *a = NULL, *n = NULL; PyObject *result = NULL; mpz_t res, nm1; if (PyTuple_Size(args) != 2) { TYPE_ERROR("is_fermat_prp() requires 2 integer arguments"); return NULL; } mpz_init(res); mpz_init(nm1); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); if (!a || !n) { TYPE_ERROR("is_fermat_prp() requires 2 integer arguments"); goto cleanup; } /* Require a >= 2. */ if (mpz_cmp_ui(a->z, 2) < 0) { VALUE_ERROR("is_fermat_prp() requires 'a' greater than or equal to 2"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_fermat_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ /* Should n even raise an exception? */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* Check gcd(a,n) */ mpz_gcd(res, n->z, a->z); if (mpz_cmp_ui(res, 1) > 0) { VALUE_ERROR("is_fermat_prp() requires gcd(n,a) == 1"); goto cleanup; } mpz_set(nm1, n->z); mpz_sub_ui(nm1, nm1, 1); mpz_powm(res, a->z, nm1, n->z); if (mpz_cmp_ui(res, 1) == 0) result = Py_True; else result = Py_False; cleanup: Py_XINCREF(result); mpz_clear(res); mpz_clear(nm1); Py_XDECREF((PyObject*)a); Py_XDECREF((PyObject*)n); return result; } /* ************************************************************************* * mpz_euler_prp: (also called a Solovay-Strassen probable prime) * An "Euler probable prime" to the base a is an odd composite number n with, * (a,n)=1 such that a^((n-1)/2)=(a/n) mod n [(a/n) is the Jacobi symbol] * *************************************************************************/ PyDoc_STRVAR(doc_mpz_is_euler_prp, "is_euler_prp(n,a) -> boolean\n\n" "Return True if n is an Euler (also known as Solovay-Strassen)\n" "probable prime to the base a.\n" "Assuming:\n" " gcd(n,a) == 1\n" " n is odd\n" "Then an Euler probable prime requires:\n" " a**((n-1)/2) == 1 (mod n)"); static PyObject * GMPY_mpz_is_euler_prp(PyObject *self, PyObject *args) { MPZ_Object *a = NULL, *n = NULL; PyObject *result = NULL; mpz_t res, exp; int ret; if (PyTuple_Size(args) != 2) { TYPE_ERROR("is_euler_prp() requires 2 integer arguments"); return NULL; } mpz_init(res); mpz_init(exp); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); if (!a || !n) { TYPE_ERROR("is_euler_prp() requires 2 integer arguments"); goto cleanup; } /* Require a >= 2. */ if (mpz_cmp_ui(a->z, 2) < 0) { VALUE_ERROR("is_euler_prp() requires 'a' greater than or equal to 2"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_euler_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* Check gcd(a,b) */ mpz_gcd(res, n->z, a->z); if (mpz_cmp_ui(res, 1) > 0) { VALUE_ERROR("is_euler_prp() requires gcd(n,a) == 1"); goto cleanup; } mpz_set(exp, n->z); mpz_sub_ui(exp, exp, 1); mpz_divexact_ui(exp, exp, 2); mpz_powm(res, a->z, exp, n->z); /* reuse exp to calculate jacobi(a,n) mod n */ ret = mpz_jacobi(a->z,n->z); mpz_set(exp, n->z); if (ret == -1) mpz_sub_ui(exp, exp, 1); else if (ret == 1) mpz_add_ui(exp, exp, 1); mpz_mod(exp, exp, n->z); if (mpz_cmp(res, exp) == 0) result = Py_True; else result = Py_False; cleanup: Py_XINCREF(result); mpz_clear(res); mpz_clear(exp); Py_XDECREF((PyObject*)a); Py_XDECREF((PyObject*)n); return result; } /* ********************************************************************************************* * mpz_sprp: (also called a Miller-Rabin probable prime) * A "strong probable prime" to the base a is an odd composite n = (2^r)*s+1 with s odd such that * either a^s == 1 mod n, or a^((2^t)*s) == -1 mod n, for some integer t, with 0 <= t < r. * *********************************************************************************************/ PyDoc_STRVAR(doc_mpz_is_strong_prp, "is_strong_prp(n,a) -> boolean\n\n" "Return True if n is an strong (also known as Miller-Rabin)\n" "probable prime to the base a.\n" "Assuming:\n" " gcd(n,a) == 1\n" " n is odd\n" " n = s*(2**r) + 1, with s odd\n" "Then a strong probable prime requires one of the following is true:\n" " a**s == 1 (mod n)\n" " or\n" " a**(s*(2**t)) == -1 (mod n) for some t, 0 <= t < r."); static PyObject * GMPY_mpz_is_strong_prp(PyObject *self, PyObject *args) { MPZ_Object *a = NULL, *n = NULL; PyObject *result = NULL; mpz_t s, nm1, mpz_test; mp_bitcnt_t r = 0; if (PyTuple_Size(args) != 2) { TYPE_ERROR("is_strong_prp() requires 2 integer arguments"); return NULL; } mpz_init(s); mpz_init(nm1); mpz_init(mpz_test); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); a = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); if (!a || !n) { TYPE_ERROR("is_strong_prp() requires 2 integer arguments"); goto cleanup; } /* Require a >= 2. */ if (mpz_cmp_ui(a->z, 2) < 0) { VALUE_ERROR("is_strong_prp() requires 'a' greater than or equal to 2"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_strong_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* Check gcd(a,b) */ mpz_gcd(s, n->z, a->z); if (mpz_cmp_ui(s, 1) > 0) { VALUE_ERROR("is_strong_prp() requires gcd(n,a) == 1"); goto cleanup; } mpz_set(nm1, n->z); mpz_sub_ui(nm1, nm1, 1); /* Find s and r satisfying: n-1=(2^r)*s, s odd */ r = mpz_scan1(nm1, 0); mpz_fdiv_q_2exp(s, nm1, r); /* Check a^((2^t)*s) mod n for 0 <= t < r */ mpz_powm(mpz_test, a->z, s, n->z); if ((mpz_cmp_ui(mpz_test, 1) == 0) || (mpz_cmp(mpz_test, nm1) == 0)) { result = Py_True; goto cleanup; } while (--r) { /* mpz_test = mpz_test^2%n */ mpz_mul(mpz_test, mpz_test, mpz_test); mpz_mod(mpz_test, mpz_test, n->z); if (mpz_cmp(mpz_test, nm1) == 0) { result = Py_True; goto cleanup; } } result = Py_False; cleanup: Py_XINCREF(result); mpz_clear(s); mpz_clear(nm1); mpz_clear(mpz_test); Py_XDECREF((PyObject*)a); Py_XDECREF((PyObject*)n); return result; } /* ************************************************************************* * mpz_fibonacci_prp: * A "Fibonacci probable prime" with parameters (P,Q), P > 0, Q=+/-1, is a * composite n for which V_n == P mod n * [V is the Lucas V sequence with parameters P,Q] * *************************************************************************/ PyDoc_STRVAR(doc_mpz_is_fibonacci_prp, "is_fibonacci_prp(n,p,q) -> boolean\n\n" "Return True if n is an Fibonacci probable prime with parameters (p,q).\n" "Assuming:\n" " n is odd\n" " p > 0, q = +/-1\n" " p*p - 4*q != 0\n" "Then a Fibonacci probable prime requires:\n" " lucasv(p,q,n) == p (mod n)."); static PyObject * GMPY_mpz_is_fibonacci_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL, *p = NULL, *q = NULL; PyObject *result = NULL; mpz_t pmodn, zP; /* used for calculating the Lucas V sequence */ mpz_t vl, vh, ql, qh, tmp; mp_bitcnt_t s = 0, j = 0; if (PyTuple_Size(args) != 3) { TYPE_ERROR("is_fibonacci_prp() requires 3 integer arguments"); return NULL; } mpz_init(pmodn); mpz_init(zP); mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL); if (!n || !p || !q) { TYPE_ERROR("is_fibonacci_prp() requires 3 integer arguments"); goto cleanup; } /* Check if p*p - 4*q == 0. */ mpz_mul(tmp, p->z, p->z); mpz_mul_ui(qh, q->z, 4); mpz_sub(tmp, tmp, qh); if (mpz_sgn(tmp) == 0) { VALUE_ERROR("invalid values for p,q in is_fibonacci_prp()"); goto cleanup; } /* Verify q = +/-1 */ if ((mpz_cmp_si(q->z, 1) && mpz_cmp_si(q->z, -1)) || (mpz_sgn(p->z) <= 0)) { VALUE_ERROR("invalid values for p,q in is_fibonacci_prp()"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_fibonacci_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } mpz_set(zP, p->z); mpz_mod(pmodn, zP, n->z); /* mpz_lucasvmod(res, p, q, n, n); */ mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp,0); s = mpz_scan1(n->z, 0); for (j = mpz_sizeinbase(n->z,2)-1; j >= s+1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n->z); if (mpz_tstbit(n->z,j) == 1) { /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); } else { /* qh = ql */ mpz_set(qh, ql); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n->z); } /* vl contains our return value */ mpz_mod(vl, vl, n->z); if (mpz_cmp(vl, pmodn) == 0) result = Py_True; else result = Py_False; cleanup: Py_XINCREF(result); mpz_clear(pmodn); mpz_clear(zP); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)n); return result; } /* ******************************************************************************* * mpz_lucas_prp: * A "Lucas probable prime" with parameters (P,Q) is a composite n with D=P^2-4Q, * (n,2QD)=1 such that U_(n-(D/n)) == 0 mod n [(D/n) is the Jacobi symbol] * *******************************************************************************/ PyDoc_STRVAR(doc_mpz_is_lucas_prp, "is_lucas_prp(n,p,q) -> boolean\n\n" "Return True if n is a Lucas probable prime with parameters (p,q).\n" "Assuming:\n" " n is odd\n" " D = p*p - 4*q, D != 0\n" " gcd(n, 2*q*D) == 1\n" "Then a Lucas probable prime requires:\n" " lucasu(p,q,n - Jacobi(D,n)) == 0 (mod n)"); static PyObject * GMPY_mpz_is_lucas_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL, *p = NULL, *q = NULL; PyObject *result = NULL; mpz_t zD, res, index; /* used for calculating the Lucas U sequence */ mpz_t uh, vl, vh, ql, qh, tmp; mp_bitcnt_t s = 0, j = 0; int ret; if (PyTuple_Size(args) != 3) { TYPE_ERROR("is_lucas_prp() requires 3 integer arguments"); return NULL; } mpz_init(zD); mpz_init(res); mpz_init(index); mpz_init(uh); mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL); if (!n || !p || !q) { TYPE_ERROR("is_lucas_prp() requires 3 integer arguments"); goto cleanup; } /* Check if p*p - 4*q == 0. */ mpz_mul(zD, p->z, p->z); mpz_mul_ui(tmp, q->z, 4); mpz_sub(zD, zD, tmp); if (mpz_sgn(zD) == 0) { VALUE_ERROR("invalid values for p,q in is_lucas_prp()"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_lucas_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* Check GCD */ mpz_mul(res, zD, q->z); mpz_mul_ui(res, res, 2); mpz_gcd(res, res, n->z); if ((mpz_cmp(res, n->z) != 0) && (mpz_cmp_ui(res, 1) > 0)) { VALUE_ERROR("is_lucas_prp() requires gcd(n,2*q*D) == 1"); goto cleanup; } /* index = n-(D/n), where (D/n) is the Jacobi symbol */ mpz_set(index, n->z); ret = mpz_jacobi(zD, n->z); if (ret == -1) mpz_add_ui(index, index, 1); else if (ret == 1) mpz_sub_ui(index, index, 1); /* mpz_lucasumod(res, p, q, index, n); */ mpz_set_si(uh, 1); mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp,0); s = mpz_scan1(index, 0); for (j = mpz_sizeinbase(index,2)-1; j >= s+1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n->z); if (mpz_tstbit(index,j) == 1) { /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vh (mod n) */ mpz_mul(uh, uh, vh); mpz_mod(uh, uh, n->z); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); } else { /* qh = ql */ mpz_set(qh, ql); /* uh = uh*vl - ql (mod n) */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); mpz_mod(uh, uh, n->z); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); for (j = 1; j <= s; j++) { /* uh = uh*vl (mod n) */ mpz_mul(uh, uh, vl); mpz_mod(uh, uh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n->z); } /* uh contains our return value */ mpz_mod(res, uh, n->z); if (mpz_cmp_ui(res, 0) == 0) result = Py_True; else result = Py_False; cleanup: Py_XINCREF(result); mpz_clear(zD); mpz_clear(res); mpz_clear(index); mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)n); return result; } /* ********************************************************************************************* * mpz_stronglucas_prp: * A "strong Lucas probable prime" with parameters (P,Q) is a composite n = (2^r)*s+(D/n), where * s is odd, D=P^2-4Q, and (n,2QD)=1 such that either U_s == 0 mod n or V_((2^t)*s) == 0 mod n * for some t, 0 <= t < r. [(D/n) is the Jacobi symbol] * *********************************************************************************************/ PyDoc_STRVAR(doc_mpz_is_stronglucas_prp, "is_strong_lucas_prp(n,p,q) -> boolean\n\n" "Return True if n is a strong Lucas probable prime with parameters (p,q).\n" "Assuming:\n" " n is odd\n" " D = p*p - 4*q, D != 0\n" " gcd(n, 2*q*D) == 1\n" " n = s*(2**r) + Jacobi(D,n), s odd\n" "Then a strong Lucas probable prime requires:\n" " lucasu(p,q,s) == 0 (mod n)\n" " or\n" " lucasv(p,q,s*(2**t)) == 0 (mod n) for some t, 0 <= t < r"); static PyObject * GMPY_mpz_is_stronglucas_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL, *p= NULL, *q = NULL; PyObject *result = NULL; mpz_t zD, s, nmj, res; /* these are needed for the LucasU and LucasV part of this function */ mpz_t uh, vl, vh, ql, qh, tmp; mp_bitcnt_t r = 0, j = 0; int ret = 0; if (PyTuple_Size(args) != 3) { TYPE_ERROR("is_strong_lucas_prp() requires 3 integer arguments"); return NULL; } mpz_init(zD); mpz_init(s); mpz_init(nmj); mpz_init(res); mpz_init(uh); mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); q = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL); if (!n || !p || !q) { TYPE_ERROR("is_strong_lucas_prp() requires 3 integer arguments"); goto cleanup; } /* Check if p*p - 4*q == 0. */ mpz_mul(zD, p->z, p->z); mpz_mul_ui(tmp, q->z, 4); mpz_sub(zD, zD, tmp); if (mpz_sgn(zD) == 0) { VALUE_ERROR("invalid values for p,q in is_strong_lucas_prp()"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_strong_lucas_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* Check GCD */ mpz_mul(res, zD, q->z); mpz_mul_ui(res, res, 2); mpz_gcd(res, res, n->z); if ((mpz_cmp(res, n->z) != 0) && (mpz_cmp_ui(res, 1) > 0)) { VALUE_ERROR("is_strong_lucas_prp() requires gcd(n,2*q*D) == 1"); goto cleanup; } /* nmj = n - (D/n), where (D/n) is the Jacobi symbol */ mpz_set(nmj, n->z); ret = mpz_jacobi(zD, n->z); if (ret == -1) mpz_add_ui(nmj, nmj, 1); else if (ret == 1) mpz_sub_ui(nmj, nmj, 1); r = mpz_scan1(nmj, 0); mpz_fdiv_q_2exp(s, nmj, r); /* make sure U_s == 0 mod n or V_((2^t)*s) == 0 mod n, for some t, 0 <= t < r */ mpz_set_si(uh, 1); mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp,0); for (j = mpz_sizeinbase(s,2)-1; j >= 1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n->z); if (mpz_tstbit(s,j) == 1) { /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vh (mod n) */ mpz_mul(uh, uh, vh); mpz_mod(uh, uh, n->z); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); } else { /* qh = ql */ mpz_set(qh, ql); /* uh = uh*vl - ql (mod n) */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); mpz_mod(uh, uh, n->z); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_mul(qh, ql, q->z); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); mpz_mod(uh, uh, n->z); mpz_mod(vl, vl, n->z); /* uh contains LucasU_s and vl contains LucasV_s */ if ((mpz_cmp_ui(uh, 0) == 0) || (mpz_cmp_ui(vl, 0) == 0)) { result = Py_True; goto cleanup; } for (j = 1; j < r; j++) { /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n->z); if (mpz_cmp_ui(vl, 0) == 0) { result = Py_True; goto cleanup; } } result = Py_False; cleanup: Py_XINCREF(result); mpz_clear(zD); mpz_clear(s); mpz_clear(nmj); mpz_clear(res); mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)q); Py_XDECREF((PyObject*)n); return result; } /* ******************************************************************************************* * mpz_extrastronglucas_prp: * Let U_n = LucasU(p,1), V_n = LucasV(p,1), and D=p^2-4. * An "extra strong Lucas probable prime" to the base p is a composite n = (2^r)*s+(D/n), where * s is odd and (n,2D)=1, such that either U_s == 0 mod n or V_s == +/-2 mod n, or * V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1 [(D/n) is the Jacobi symbol] * *******************************************************************************************/ PyDoc_STRVAR(doc_mpz_is_extrastronglucas_prp, "is_extra_strong_lucas_prp(n,p) -> boolean\n\n" "Return True if n is an extra strong Lucas probable prime with parameters\n" "(p,1). Assuming:\n" " n is odd\n" " D = p*p - 4, D != 0\n" " gcd(n, 2*D) == 1\n" " n = s*(2**r) + Jacobi(D,n), s odd\n" "Then an extra strong Lucas probable prime requires:\n" " lucasu(p,1,s) == 0 (mod n)\n" " or\n" " lucasv(p,1,s) == +/-2 (mod n)\n" " or\n" " lucasv(p,1,s*(2**t)) == 0 (mod n) for some t, 0 <= t < r"); static PyObject * GMPY_mpz_is_extrastronglucas_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL, *p = NULL; PyObject *result = NULL; mpz_t zD, s, nmj, nm2, res; /* these are needed for the LucasU and LucasV part of this function */ mpz_t uh, vl, vh, ql, qh, tmp; mp_bitcnt_t r = 0, j = 0; int ret = 0; if (PyTuple_Size(args) != 2) { TYPE_ERROR("is_extra_strong_lucas_prp() requires 2 integer arguments"); return NULL; } mpz_init(zD); mpz_init(s); mpz_init(nmj); mpz_init(nm2); mpz_init(res); mpz_init(uh); mpz_init(vl); mpz_init(vh); mpz_init(ql); mpz_init(qh); mpz_init(tmp); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); p = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); if (!n || !p) { TYPE_ERROR("is_extra_strong_lucas_prp() requires 2 integer arguments"); goto cleanup; } /* Check if p*p - 4 == 0. */ mpz_mul(zD, p->z, p->z); mpz_sub_ui(zD, zD, 4); if (mpz_sgn(zD) == 0) { VALUE_ERROR("invalid value for p in is_extra_strong_lucas_prp()"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_extra_strong_lucas_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* Check GCD */ mpz_mul_ui(res, zD, 2); mpz_gcd(res, res, n->z); if ((mpz_cmp(res, n->z) != 0) && (mpz_cmp_ui(res, 1) > 0)) { VALUE_ERROR("is_extra_strong_lucas_prp() requires gcd(n,2*D) == 1"); goto cleanup; } /* nmj = n - (D/n), where (D/n) is the Jacobi symbol */ mpz_set(nmj, n->z); ret = mpz_jacobi(zD, n->z); if (ret == -1) mpz_add_ui(nmj, nmj, 1); else if (ret == 1) mpz_sub_ui(nmj, nmj, 1); r = mpz_scan1(nmj, 0); mpz_fdiv_q_2exp(s, nmj, r); mpz_set(nm2, n->z); mpz_sub_ui(nm2, nm2, 2); /* make sure that either U_s == 0 mod n or V_s == +/-2 mod n, or */ /* V_((2^t)*s) == 0 mod n for some t with 0 <= t < r-1 */ mpz_set_si(uh, 1); mpz_set_si(vl, 2); mpz_set(vh, p->z); mpz_set_si(ql, 1); mpz_set_si(qh, 1); mpz_set_si(tmp,0); for (j = mpz_sizeinbase(s,2)-1; j >= 1; j--) { /* ql = ql*qh (mod n) */ mpz_mul(ql, ql, qh); mpz_mod(ql, ql, n->z); if (mpz_tstbit(s,j) == 1) { /* qh = ql*q */ mpz_set(qh, ql); /* uh = uh*vh (mod n) */ mpz_mul(uh, uh, vh); mpz_mod(uh, uh, n->z); /* vl = vh*vl - p*ql (mod n) */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* vh = vh*vh - 2*qh (mod n) */ mpz_mul(vh, vh, vh); mpz_mul_si(tmp, qh, 2); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); } else { /* qh = ql */ mpz_set(qh, ql); /* uh = uh*vl - ql (mod n) */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); mpz_mod(uh, uh, n->z); /* vh = vh*vl - p*ql (mod n) */ mpz_mul(vh, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vh, vh, tmp); mpz_mod(vh, vh, n->z); /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); } } /* ql = ql*qh */ mpz_mul(ql, ql, qh); /* qh = ql*q */ mpz_set(qh, ql); /* uh = uh*vl - ql */ mpz_mul(uh, uh, vl); mpz_sub(uh, uh, ql); /* vl = vh*vl - p*ql */ mpz_mul(vl, vh, vl); mpz_mul(tmp, ql, p->z); mpz_sub(vl, vl, tmp); /* ql = ql*qh */ mpz_mul(ql, ql, qh); mpz_mod(uh, uh, n->z); mpz_mod(vl, vl, n->z); /* uh contains LucasU_s and vl contains LucasV_s */ if ((mpz_cmp_ui(uh, 0) == 0) || (mpz_cmp_ui(vl, 0) == 0) || (mpz_cmp(vl, nm2) == 0) || (mpz_cmp_si(vl, 2) == 0)) { result = Py_True; goto cleanup; } for (j = 1; j < r-1; j++) { /* vl = vl*vl - 2*ql (mod n) */ mpz_mul(vl, vl, vl); mpz_mul_si(tmp, ql, 2); mpz_sub(vl, vl, tmp); mpz_mod(vl, vl, n->z); /* ql = ql*ql (mod n) */ mpz_mul(ql, ql, ql); mpz_mod(ql, ql, n->z); if (mpz_cmp_ui(vl, 0) == 0) { result = Py_True; goto cleanup; } } result = Py_False; cleanup: Py_XINCREF(result); mpz_clear(zD); mpz_clear(s); mpz_clear(nmj); mpz_clear(nm2); mpz_clear(res); mpz_clear(uh); mpz_clear(vl); mpz_clear(vh); mpz_clear(ql); mpz_clear(qh); mpz_clear(tmp); Py_XDECREF((PyObject*)p); Py_XDECREF((PyObject*)n); return result; } /* *********************************************************************************************** * mpz_selfridge_prp: * A "Lucas-Selfridge probable prime" n is a "Lucas probable prime" using Selfridge parameters of: * Find the first element D in the sequence {5, -7, 9, -11, 13, ...} such that Jacobi(D,n) = -1 * Then use P=1 and Q=(1-D)/4 in the Lucas probable prime test. * Make sure n is not a perfect square, otherwise the search for D will only stop when D=n. * ***********************************************************************************************/ PyDoc_STRVAR(doc_mpz_is_selfridge_prp, "is_selfridge_prp(n) -> boolean\n\n" "Return True if n is a Lucas probable prime with Selfidge parameters\n" "(p,q). The Selfridge parameters are chosen by finding the first\n" "element D in the sequence {5, -7, 9, -11, 13, ...} such that\n" "Jacobi(D,n) == -1. Then let p=1 and q = (1-D)/4. Then perform\n" "a Lucas probable prime test."); static PyObject * GMPY_mpz_is_selfridge_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL; PyObject *result = NULL, *temp = NULL; long d = 5, p = 1, q = 0, max_d = 1000000; int jacobi = 0; mpz_t zD; if (PyTuple_Size(args) != 1) { TYPE_ERROR("is_selfridge_prp() requires 1 integer argument"); return NULL; } mpz_init(zD); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); if (!n) { TYPE_ERROR("is_selfridge_prp() requires 1 integer argument"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_selfridge_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } mpz_set_ui(zD, d); while (1) { jacobi = mpz_jacobi(zD, n->z); /* if jacobi == 0, d is a factor of n, therefore n is composite... */ /* if d == n, then either n is either prime or 9... */ if (jacobi == 0) { if ((mpz_cmpabs(zD, n->z) == 0) && (mpz_cmp_ui(zD, 9) != 0)) { result = Py_True; goto cleanup; } else { result = Py_False; goto cleanup; } } if (jacobi == -1) break; /* if we get to the 5th d, make sure we aren't dealing with a square... */ if (d == 13) { if (mpz_perfect_square_p(n->z)) { result = Py_False; goto cleanup; } } if (d < 0) { d *= -1; d += 2; } else { d += 2; d *= -1; } /* make sure we don't search forever */ if (d >= max_d) { VALUE_ERROR("appropriate value for D cannot be found in is_selfridge_prp()"); goto cleanup; } mpz_set_si(zD, d); } q = (1-d)/4; /* Since "O" is used, the refcount for n is incremented so deleting * temp will not delete n. */ temp = Py_BuildValue("Oll", n, p, q); if (!temp) goto cleanup; result = GMPY_mpz_is_lucas_prp(NULL, temp); Py_DECREF(temp); goto return_result; cleanup: Py_XINCREF(result); return_result: mpz_clear(zD); Py_DECREF((PyObject*)n); return result; } /* ********************************************************************************************************* * mpz_strongselfridge_prp: * A "strong Lucas-Selfridge probable prime" n is a "strong Lucas probable prime" using Selfridge parameters of: * Find the first element D in the sequence {5, -7, 9, -11, 13, ...} such that Jacobi(D,n) = -1 * Then use P=1 and Q=(1-D)/4 in the strong Lucas probable prime test. * Make sure n is not a perfect square, otherwise the search for D will only stop when D=n. * **********************************************************************************************************/ PyDoc_STRVAR(doc_mpz_is_strongselfridge_prp, "is_strong_selfridge_prp(n) -> boolean\n\n" "Return True if n is a strong Lucas probable prime with Selfidge\n" "parameters (p,q). The Selfridge parameters are chosen by finding\n" "the first element D in the sequence {5, -7, 9, -11, 13, ...} such\n" "that Jacobi(D,n) == -1. Then let p=1 and q = (1-D)/4. Then perform\n" "a strong Lucas probable prime test."); static PyObject * GMPY_mpz_is_strongselfridge_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL; PyObject *result = NULL, *temp = NULL; long d = 5, p = 1, q = 0, max_d = 1000000; int jacobi = 0; mpz_t zD; if (PyTuple_Size(args) != 1) { TYPE_ERROR("is_strong_selfridge_prp() requires 1 integer argument"); return NULL; } mpz_init(zD); n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); if (!n) { TYPE_ERROR("is_strong_selfridge_prp() requires 1 integer argument"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_strong_selfridge_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } mpz_set_ui(zD, d); while (1) { jacobi = mpz_jacobi(zD, n->z); /* if jacobi == 0, d is a factor of n, therefore n is composite... */ /* if d == n, then either n is either prime or 9... */ if (jacobi == 0) { if ((mpz_cmpabs(zD, n->z) == 0) && (mpz_cmp_ui(zD, 9) != 0)) { result = Py_True; goto cleanup; } else { result = Py_False; goto cleanup; } } if (jacobi == -1) break; /* if we get to the 5th d, make sure we aren't dealing with a square... */ if (d == 13) { if (mpz_perfect_square_p(n->z)) { result = Py_False; goto cleanup; } } if (d < 0) { d *= -1; d += 2; } else { d += 2; d *= -1; } /* make sure we don't search forever */ if (d >= max_d) { VALUE_ERROR("appropriate value for D cannot be found in is_strong_selfridge_prp()"); goto cleanup; } mpz_set_si(zD, d); } q = (1-d)/4; /* Since "O" is used, the refcount for n is incremented so deleting * temp will not delete n. */ temp = Py_BuildValue("Oll", n, p, q); if (!temp) goto cleanup; result = GMPY_mpz_is_stronglucas_prp(NULL, temp); Py_DECREF(temp); goto return_result; cleanup: Py_XINCREF(result); return_result: mpz_clear(zD); Py_DECREF((PyObject*)n); return result; } /* ********************************************************************************** * mpz_bpsw_prp: * A "Baillie-Pomerance-Selfridge-Wagstaff probable prime" is a composite n such that * n is a strong probable prime to the base 2 and * n is a Lucas probable prime using the Selfridge parameters. * **********************************************************************************/ PyDoc_STRVAR(doc_mpz_is_bpsw_prp, "is_bpsw_prp(n) -> boolean\n\n" "Return True if n is a Baillie-Pomerance-Selfridge-Wagstaff probable \n" "prime. A BPSW probable prime passes the is_strong_prp() test with base\n" "2 and the is_selfridge_prp() test.\n"); static PyObject * GMPY_mpz_is_bpsw_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL; PyObject *result = NULL, *temp = NULL; if (PyTuple_Size(args) != 1) { TYPE_ERROR("is_bpsw_prp() requires 1 integer argument"); return NULL; } n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); if (!n) { TYPE_ERROR("is_bpsw_prp() requires 1 integer argument"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_bpsw_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* "O" is used to increment the reference to n so deleting temp won't * delete n. */ temp = Py_BuildValue("Oi", n, 2); if (!temp) goto cleanup; result = GMPY_mpz_is_strong_prp(NULL, temp); Py_DECREF(temp); if (result == Py_False) goto return_result; /* Remember to ignore the preceding result */ Py_DECREF(result); temp = Py_BuildValue("(O)", n); if (!temp) goto cleanup; result = GMPY_mpz_is_selfridge_prp(NULL, temp); Py_DECREF(temp); goto return_result; cleanup: Py_XINCREF(result); return_result: Py_DECREF((PyObject*)n); return result; } /* **************************************************************************************** * mpz_strongbpsw_prp: * A "strong Baillie-Pomerance-Selfridge-Wagstaff probable prime" is a composite n such that * n is a strong probable prime to the base 2 and * n is a strong Lucas probable prime using the Selfridge parameters. * ****************************************************************************************/ PyDoc_STRVAR(doc_mpz_is_strongbpsw_prp, "is_strong_bpsw_prp(n) -> boolean\n\n" "Return True if n is a strong Baillie-Pomerance-Selfridge-Wagstaff\n" "probable prime. A strong BPSW probable prime passes the is_strong_prp()\n" "test with base and the is_strong_selfridge_prp() test.\n"); static PyObject * GMPY_mpz_is_strongbpsw_prp(PyObject *self, PyObject *args) { MPZ_Object *n = NULL; PyObject *result = NULL, *temp = NULL; if (PyTuple_Size(args) != 1) { TYPE_ERROR("is_strong_bpsw_prp() requires 1 integer argument"); return NULL; } n = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); if (!n) { TYPE_ERROR("is_strong_bpsw_prp() requires 1 integer argument"); goto cleanup; } /* Require n > 0. */ if (mpz_sgn(n->z) <= 0) { VALUE_ERROR("is_strong_bpsw_prp() requires 'n' be greater than 0"); goto cleanup; } /* Check for n == 1 */ if (mpz_cmp_ui(n->z, 1) == 0) { result = Py_False; goto cleanup; } /* Handle n even. */ if (mpz_divisible_ui_p(n->z, 2)) { if (mpz_cmp_ui(n->z, 2) == 0) result = Py_True; else result = Py_False; goto cleanup; } /* "O" is used to increment the reference to n so deleting temp won't * delete n. */ temp = Py_BuildValue("Oi", n, 2); if (!temp) goto cleanup; result = GMPY_mpz_is_strong_prp(NULL, temp); Py_DECREF(temp); if (result == Py_False) goto return_result; /* Remember to ignore the preceding result */ Py_DECREF(result); temp = Py_BuildValue("(O)", n); if (!temp) goto cleanup; result = GMPY_mpz_is_selfridge_prp(NULL, temp); Py_DECREF(temp); goto return_result; cleanup: Py_XINCREF(result); return_result: Py_DECREF((PyObject*)n); return result; } gmpy2-2.1.0b3/src/gmpy_mpz_prp.h0000664000175000017500000000537113425754405016351 0ustar casecase00000000000000/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * gmpy_mpz_prp.h * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * * libraries. * * * * Copyright 2012, 2013, 2014, 2015, 2016, 2017, 2018, * * 2019 Case Van Horsen * * * * This file is part of GMPY2. * * * * GMPY2 is free software: you can redistribute it and/or modify it under * * the terms of the GNU Lesser General Public License as published by the * * Free Software Foundation, either version 3 of the License, or (at your * * option) any later version. * * * * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * * License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with GMPY2; if not, see * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef GMPY_PRP_H #define GMPY_PRP_H #ifdef __cplusplus extern "C" { #endif static PyObject * GMPY_mpz_is_fermat_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_euler_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_strong_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_fibonacci_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_lucas_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_stronglucas_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_extrastronglucas_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_selfridge_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_strongselfridge_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_bpsw_prp(PyObject *self, PyObject *args); static PyObject * GMPY_mpz_is_strongbpsw_prp(PyObject *self, PyObject *args); #ifdef __cplusplus } #endif #endif gmpy2-2.1.0b3/src/mpz_pylong.c0000664000175000017500000001647213170047220016006 0ustar casecase00000000000000/* mpz <-> pylong conversion and "pythonhash" for mpz * * Originally written for sage (http://sagemath.org) by Gonzalo Tornari­a * . If you improve on these functions, please * contribute them back to sage by posting to sage-devel@googlegroups.com * or by sending an email to the original author. * * Integration with gmpy2 by Case Van Horsen . * * License: LGPL v2 or later * */ /* This file created by merging mpn_pylong and mpz_pylong. Permission * was granted by the original author to make this code available under * the LGPLv2+ license. */ /* This code assumes that SHIFT < GMP_NUMB_BITS */ #if PyLong_SHIFT >= GMP_NUMB_BITS #error "Python limb larger than GMP limb !!!" #endif #ifndef ABS #define ABS(a) (((a) < 0) ? -(a) : (a)) #endif /* Use these "portable" (I hope) sizebits functions. * We could implement this in terms of count_leading_zeros from GMP, * but it is not exported! */ static const unsigned char __sizebits_tab[128] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 }; #if GMP_LIMB_BITS > 64 #error "word size > 64 unsupported" #endif static inline size_t mpn_sizebits(mp_ptr up, size_t un) { size_t cnt; mp_limb_t x; if (un==0) return 0; cnt = (un - 1) * GMP_NUMB_BITS; x = up[un - 1]; #if GMP_LIMB_BITS > 32 if ((x >> 32) != 0) { x >>= 32; cnt += 32; } #endif #if GMP_LIMB_BITS > 16 if ((x >> 16) != 0) { x >>= 16; cnt += 16; } #endif #if GMP_LIMB_BITS > 8 if ((x >> 8) != 0) { x >>= 8; cnt += 8; } #endif return cnt + ((x & 0x80) ? 8 : __sizebits_tab[x]); } static inline size_t pylong_sizebits(digit *digits, size_t size) { size_t cnt; digit x; if (size==0) return 0; cnt = (size - 1) * PyLong_SHIFT; x = digits[size - 1]; #if PyLong_SHIFT > 32 if ((x >> 32) != 0) { x >>= 32; cnt += 32; } #endif #if PyLong_SHIFT > 16 if ((x >> 16) != 0) { x >>= 16; cnt += 16; } #endif #if PyLong_SHIFT > 8 if ((x >> 8) != 0) { x >>= 8; cnt += 8; } #endif return cnt + ((x & 0x80) ? 8 : __sizebits_tab[x]); } /* mpn -> pylong conversion */ size_t mpn_pylong_size (mp_ptr up, size_t un) { return (mpn_sizebits(up, un) + PyLong_SHIFT - 1) / PyLong_SHIFT; } /* this is based from GMP code in mpn/get_str.c */ /* Assume digits points to a chunk of size size * where size >= mpn_pylong_size(up, un) */ void mpn_get_pylong (digit *digits, size_t size, mp_ptr up, size_t un) { mp_limb_t n1, n0; size_t i; ssize_t bit_pos; /* point past the allocated chunk */ digit *s = digits + size; /* input length 0 is special ! */ if (un == 0) { while (size) digits[--size] = 0; return; } i = un - 1; n1 = up[i]; bit_pos = size * PyLong_SHIFT - i * GMP_NUMB_BITS; for (;;) { bit_pos -= PyLong_SHIFT; while (bit_pos >= 0) { *--s = (n1 >> bit_pos) & PyLong_MASK; bit_pos -= PyLong_SHIFT; } if (i == 0) break; n0 = (n1 << -bit_pos) & PyLong_MASK; n1 = up[--i]; bit_pos += GMP_NUMB_BITS; *--s = (digit)(n0 | (n1 >> bit_pos)); } } /* pylong -> mpn conversion */ size_t mpn_size_from_pylong (digit *digits, size_t size) { return (pylong_sizebits(digits, size) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; } void mpn_set_pylong(mp_ptr up, size_t un, digit *digits, size_t size) { mp_limb_t n1, d; size_t i; ssize_t bit_pos; /* point past the allocated chunk */ digit * s = digits + size; /* input length 0 is special ! */ if (size == 0) { while (un) up[--un] = 0; return; } i = un - 1; n1 = 0; bit_pos = size * PyLong_SHIFT - i * GMP_NUMB_BITS; for (;;) { bit_pos -= PyLong_SHIFT; while (bit_pos >= 0) { d = (mp_limb_t) *--s; n1 |= (d << bit_pos) & GMP_NUMB_MASK; bit_pos -= PyLong_SHIFT; } if (i == 0) break; d = (mp_limb_t) *--s; /* add some high bits of d; maybe none if bit_pos=-SHIFT */ up[i--] = n1 | (d & PyLong_MASK) >> -bit_pos; bit_pos += GMP_NUMB_BITS; n1 = (d << bit_pos) & GMP_NUMB_MASK; } up[0] = n1; } /************************************************************/ /* Hashing functions */ #define LONG_BIT_SHIFT (8*sizeof(long) - PyLong_SHIFT) /* * for an mpz, this number has to be multiplied by the sign * also remember to catch -1 and map it to -2 ! */ long mpn_pythonhash (mp_ptr up, mp_size_t un) { mp_limb_t n1, n0; mp_size_t i; ssize_t bit_pos; long x = 0; /* input length 0 is special ! */ if (un == 0) return 0; i = un - 1; n1 = up[i]; { size_t bits; bits = mpn_sizebits(up, un) + PyLong_SHIFT - 1; bits -= bits % PyLong_SHIFT; /* position of the MSW in base 2^SHIFT, counted from the MSW in * the GMP representation (in base 2^GMP_NUMB_BITS) */ bit_pos = bits - i * GMP_NUMB_BITS; } for (;;) { while (bit_pos >= 0) { /* Force a native long #-bits (32 or 64) circular shift */ x = ((x << PyLong_SHIFT) & ~(long)PyLong_MASK) | ((x >> LONG_BIT_SHIFT) & (long)PyLong_MASK); /* Shifting to the right by more than wordsize bits * actually shifts by (wordsize % 32) bits -- which is * *not* the intended behavior here. */ if (bit_pos <= 8*sizeof(mp_limb_t)) x += (n1 >> bit_pos) & (long)PyLong_MASK; bit_pos -= PyLong_SHIFT; } i--; if (i < 0) break; n0 = (n1 << -bit_pos) & (long)PyLong_MASK; n1 = up[i]; bit_pos += GMP_NUMB_BITS; /* Force a native long #-bits (32 or 64) circular shift */ x = ((x << PyLong_SHIFT) & ~(long)PyLong_MASK) | ((x >> LONG_BIT_SHIFT) & (long)PyLong_MASK); x += (long)(n0 | (n1 >> bit_pos)); bit_pos -= PyLong_SHIFT; } return x; } /* mpz python hash */ long mpz_pythonhash(mpz_srcptr z) { long x = mpn_pythonhash(z->_mp_d, ABS(z->_mp_size)); if (z->_mp_size < 0) x = -x; if (x == -1) x = -2; return x; } /* mpz -> pylong conversion */ PyObject * mpz_get_PyLong(mpz_srcptr z) { size_t size = mpn_pylong_size(z->_mp_d, ABS(z->_mp_size)); PyLongObject *lptr = PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size); if (lptr != NULL) { mpn_get_pylong(lptr->ob_digit, size, z->_mp_d, ABS(z->_mp_size)); if (z->_mp_size < 0) Py_SIZE(lptr) = -(Py_SIZE(lptr)); } return (PyObject*)lptr; } /* pylong -> mpz conversion */ void mpz_set_PyIntOrLong(mpz_ptr z, PyObject *lsrc) { register PyLongObject *lptr = (PyLongObject*)lsrc; ssize_t size; #ifdef PY2 if (PyInt_Check(lsrc)) { mpz_set_si(z, PyInt_AS_LONG(lsrc)); return; } #endif size = (ssize_t)mpn_size_from_pylong(lptr->ob_digit, ABS(Py_SIZE(lptr))); if (z->_mp_alloc < size) _mpz_realloc(z, (mp_size_t)size); mpn_set_pylong(z->_mp_d, size, lptr->ob_digit, ABS(Py_SIZE(lptr))); z->_mp_size = (int)(Py_SIZE(lptr) < 0 ? -size : size); return; } gmpy2-2.1.0b3/test/0000775000175000017500000000000013530663166013637 5ustar casecase00000000000000gmpy2-2.1.0b3/test/gmpy_test.py0000664000175000017500000000055413105222070016207 0ustar casecase00000000000000from __future__ import print_function import sys print("\nImportant test information!\n") print("Please use 'test/runtests.py' to run the new test suite.\n") if sys.version_info[0] == 3: print("Please use 'test3/gmpy_test.py' to run legacy tests with Python 3.x.\n") else: print("Please use 'test2/gmpy_test.py' to run legacy tests with Python 2.x.\n") gmpy2-2.1.0b3/test/runtests.py0000664000175000017500000001345413461370120016073 0ustar casecase00000000000000from __future__ import print_function, division import sys import os import glob import doctest from doctest import DocTestParser, Example, SKIP import gmpy2 # ***************************************************************************** # Test strategy # ------------- # Tests are divided into two different categories: # # 1) The 'txt' files contain doctest style tests. These tests should cover # basic functionality for all functions/types. # 2) The 'py' files contain Python code that perform extensive tests, but # may not test every function. # # If run by a debug build of Python, the test suite can be repeated multiple # times to search for memory leaks. # # NOTE: IF THE LAST TEST IN A BLOCK OF TESTS GENERATES AN EXCEPTION, THE # REFERENCE COUNTING IN A DEBUG BUILD GETS CONFUSED. ALWAYS ENSURE THAT # AT LEAST ONE VALID TEST IS PERFORMED AFTER AN EXCEPTION IS RAISED! # # ***************************************************************************** # Check if this is a debug build of Python. try: sys.gettotalrefcount() debug = True except AttributeError: debug = False # Change repeat to the number of times to repeat each test. Combined with a # debug build, this can help identify memory leaks. if debug: try: repeat = abs(int(sys.argv[1])) except: repeat = 1 else: repeat = 1 # If mpc version < 1.1.0 gmpy2.root_of_unity is defined and gmpy2.cmp_abs # doesn't manage complex parameters. # We create a doctest flag to skip a doctest when mpc version is < 1.1.0 SKIP_MPC_LESS_THAN_110 = doctest.register_optionflag("SKIP_MPC_LESS_THAN_110") mpc_version_110 = 'root_of_unity' in dir(gmpy2) # True if mpc version >= 1.1.0 SKIP_IN_DEBUG_MODE = doctest.register_optionflag("SKIP_IN_DEBUG_MODE") class Gmpy2DocTestParser(DocTestParser): def parse(self, *args, **kwargs): examples = DocTestParser.parse(self, *args, **kwargs) for example in examples: if not isinstance(example, Example): continue if not mpc_version_110 and SKIP_MPC_LESS_THAN_110 in example.options: example.options[SKIP] = True if debug and SKIP_IN_DEBUG_MODE in example.options: example.options[SKIP] = True return examples parser = Gmpy2DocTestParser() print() print("Unit tests for gmpy2 {0} with Python {1}".format(gmpy2.version(), sys.version.split()[0])) print(" Mutliple-precision library: {0}".format(gmpy2.mp_version())) print(" Floating-point library: {0}".format(gmpy2.mpfr_version())) print(" Complex library: {0}".format(gmpy2.mpc_version())) print(" Caching Values: (Cache size) {0}".format(gmpy2.get_cache()[0])) print(" Caching Values: (Size in limbs) {0}".format(gmpy2.get_cache()[1])) print() if sys.version.startswith('3.1'): print("Due to differences in formatting of exceptions and Python 3.x, there") print("will be test failures for exception handling when the tests are run") print("with Python 3.1. The doctest module in Python 3.2 and later does not") print("have this issue.") print() input("Press ENTER to continue.. ") print() mpz_doctests = ["test_mpz_create.txt", "test_mpz.txt", "test_mpz_io.txt", "test_mpz_pack_unpack.txt", "test_misc.txt"] mpq_doctests = ["test_mpq.txt"] mpfr_doctests = ["test_mpfr_create.txt", "test_mpfr.txt", "test_mpfr_trig.txt", "test_mpfr_min_max.txt", "test_context.txt", "test_mpfr_subnormalize.txt"] # Some tests may differ between MPFR3 and MPFR4. mpfr_major_version = gmpy2.mpfr_version().split()[1].split('.')[0] mpfr_version_tests = [os.path.basename(i) for i in glob.glob(os.path.join(os.path.dirname(__file__), "test_mpfr" + mpfr_major_version + "*.txt"))] mpc_doctests = ["test_mpc_create.txt", "test_mpc.txt", "test_mpc_trig.txt"] gmpy2_tests = [os.path.basename(i) for i in glob.glob(os.path.join(os.path.dirname(__file__), "test_gmpy2*.txt"))] # The following tests will only pass on Python 3.2+. py32_doctests = ["test_py32_hash.txt"] failed = 0 attempted = 0 all_doctests = gmpy2_tests + mpz_doctests + mpq_doctests all_doctests += mpfr_doctests + mpfr_version_tests all_doctests += mpc_doctests if sys.version >= "3.2": all_doctests += py32_doctests for test in sorted(all_doctests): if test.endswith("py2.txt") and sys.version >= "3": continue if test.endswith("py3.txt") and sys.version < "3": continue for r in range(repeat): result = doctest.testfile(test, globs=globals(), optionflags=doctest.IGNORE_EXCEPTION_DETAIL | doctest.NORMALIZE_WHITESPACE | doctest.REPORT_NDIFF, parser=parser) print("Results for: {0:25}".format(test.split(".")[0]), end="") print(" Attempted: {1:4d} Failed: {0:4d}".format(*result), end="") if debug: print(" RefCount: {0:6d}".format(sys.gettotalrefcount())) else: print() failed += result[0] attempted += result[1] if repeat > 1: print() print() print(" Summary - Attempted: {0:4d} Failed: {1:4d}".format(attempted, failed)) print() print("Running external test programs.") print("Running {0:30} ".format("test_pack.py"), end="") import test_pack if test_pack.test(): print("successful") attempted += 1 else: print("failed") failed += 1 print("Running {0:30} ".format("test_mpz_args.py"), end="") import test_mpz_args if test_mpz_args.test(): print("successful") attempted += 1 else: print("failed") failed += 1 if failed: sys.exit(1) else: sys.exit(0) gmpy2-2.1.0b3/test/supportclasses.py0000664000175000017500000000164113452510275017300 0ustar casecase00000000000000import gmpy2 class Z: def __mpz__(self): return gmpy2.mpz(2) class Q: def __mpz__(self): return gmpy2.mpz(1) def __mpq__(self): return gmpy2.mpq(3,2) class R: def __mpfr__(self): return gmpy2.mpfr(1.5) class Cx: def __mpfr__(self): return gmpy2.mpfr(1.5) def __mpc__(self): return gmpy2.mpc(42,67) z = Z() q = Q() r = R() cx = Cx() class A: def __mpz__(self): return gmpy2.mpz(1) def __mpq__(self): return gmpy2.mpq(3,2) def __mpfr__(self): return gmpy2.mpfr(1.5) def __mpc__(self): return gmpy2.mpc(42,67) class B: def __mpz__(self): return 'hello' def __mpq__(self): return 'hello' def __mpfr__(self): return 'hello' def __mpc__(self): return 'hello' class C: pass class D: def __mpz__(self): raise TypeError def __mpq__(self): raise TypeError def __mpfr__(self): raise TypeError def __mpc__(self): raise TypeError a = A() b = B() c = C() d = D() gmpy2-2.1.0b3/test/supportclasses.pyc0000664000175000017500000001064713461371257017456 0ustar casecase00000000000000ó ½ª\c@sðddlZddd„ƒYZddd„ƒYZddd„ƒYZddd „ƒYZeƒZeƒZeƒZeƒZd dd „ƒYZ d dd „ƒYZ ddd„ƒYZ ddd„ƒYZ e ƒZ e ƒZe ƒZe ƒZdS(iÿÿÿÿNtZcBseZd„ZRS(cCs tjdƒS(Ni(tgmpy2tmpz(tself((s-/home/case/github/gmpy/test/supportclasses.pyt__mpz__t(t__name__t __module__R(((s-/home/case/github/gmpy/test/supportclasses.pyRstQcBseZd„Zd„ZRS(cCs tjdƒS(Ni(RR(R((s-/home/case/github/gmpy/test/supportclasses.pyRRcCstjddƒS(Nii(Rtmpq(R((s-/home/case/github/gmpy/test/supportclasses.pyt__mpq__R(RRRR (((s-/home/case/github/gmpy/test/supportclasses.pyRs tRcBseZd„ZRS(cCs tjdƒS(Ngø?(Rtmpfr(R((s-/home/case/github/gmpy/test/supportclasses.pyt__mpfr__ R(RRR (((s-/home/case/github/gmpy/test/supportclasses.pyR stCxcBseZd„Zd„ZRS(cCs tjdƒS(Ngø?(RR (R((s-/home/case/github/gmpy/test/supportclasses.pyR RcCstjddƒS(Ni*iC(Rtmpc(R((s-/home/case/github/gmpy/test/supportclasses.pyt__mpc__ R(RRR R(((s-/home/case/github/gmpy/test/supportclasses.pyR s tAcBs,eZd„Zd„Zd„Zd„ZRS(cCs tjdƒS(Ni(RR(R((s-/home/case/github/gmpy/test/supportclasses.pyRRcCstjddƒS(Nii(RR (R((s-/home/case/github/gmpy/test/supportclasses.pyR RcCs tjdƒS(Ngø?(RR (R((s-/home/case/github/gmpy/test/supportclasses.pyR RcCstjddƒS(Ni*iC(RR(R((s-/home/case/github/gmpy/test/supportclasses.pyRR(RRRR R R(((s-/home/case/github/gmpy/test/supportclasses.pyRs   tBcBs,eZd„Zd„Zd„Zd„ZRS(cCsdS(Nthello((R((s-/home/case/github/gmpy/test/supportclasses.pyRRcCsdS(NR((R((s-/home/case/github/gmpy/test/supportclasses.pyR RcCsdS(NR((R((s-/home/case/github/gmpy/test/supportclasses.pyR RcCsdS(NR((R((s-/home/case/github/gmpy/test/supportclasses.pyRR(RRRR R R(((s-/home/case/github/gmpy/test/supportclasses.pyRs   tCcBseZRS((RR(((s-/home/case/github/gmpy/test/supportclasses.pyRstDcBs,eZd„Zd„Zd„Zd„ZRS(cCs t‚dS(N(t TypeError(R((s-/home/case/github/gmpy/test/supportclasses.pyR RcCs t‚dS(N(R(R((s-/home/case/github/gmpy/test/supportclasses.pyR !RcCs t‚dS(N(R(R((s-/home/case/github/gmpy/test/supportclasses.pyR "RcCs t‚dS(N(R(R((s-/home/case/github/gmpy/test/supportclasses.pyR#R(RRRR R R(((s-/home/case/github/gmpy/test/supportclasses.pyRs   (((((((((RRRR RtztqtrtcxRRRRtatbtctd(((s-/home/case/github/gmpy/test/supportclasses.pyts        gmpy2-2.1.0b3/test/test_abs.txt0000664000175000017500000001714713170047220016201 0ustar casecase00000000000000Absolute value ============== Test abs() and context.abs(). >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> a=mpz(123) >>> b=abs(a) >>> a is b True >>> a=xmpz(123) >>> b=abs(a) >>> a is b False >>> a=mpz(-123) >>> b=abs(a) >>> b mpz(123) >>> a is b False >>> a mpz(-123) >>> a=mpq(12,7) >>> b=abs(a) >>> a is b True >>> a=mpq(-12,7) >>> b=abs(a) >>> b mpq(12,7) >>> a mpq(-12,7) >>> a=xmpz(-123) >>> b=abs(a) >>> b >>> a xmpz(123) >>> b is None True >>> b = abs(a) >>> b is None True >>> a=mpfr(1.0) >>> b=abs(a) >>> a is b False >>> abs(mpfr(1, precision=100)) mpfr('1.0') >>> ctx = gmpy2.get_context() >>> ctx.clear_flags() >>> abs(mpfr('nan')) mpfr('nan') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=True, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> ctx.clear_flags() >>> abs(mpfr('inf')) mpfr('inf') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> ctx.clear_flags() >>> abs(mpfr('-inf')) mpfr('inf') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> abs(mpc(-1,0)) mpfr('1.0') >>> abs(-1+0j) 1.0 >>> abs(mpc(1,1)) mpfr('1.4142135623730951') >>> ctx=gmpy2.get_context() >>> ctx.clear_flags() >>> mpc('nan+0j') mpc('nan+0.0j') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=True, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> abs(mpc('nan+0j')) mpfr('nan') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=True, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> ctx.clear_flags() >>> abs(mpc('nanj')) mpfr('nan') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=True, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> ctx.clear_flags() >>> abs(mpc('inf+10j')) mpfr('inf') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> ctx.clear_flags() >>> abs(mpc('-infj')) mpfr('inf') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> a=mpc('nan+infj') >>> ctx.clear_flags() >>> abs(a) mpfr('inf') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> a=mpc('-inf+nanj') >>> ctx.clear_flags() >>> abs(a) mpfr('inf') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False, guard_bits=0, convert_exact=False, mpfr_divmod_exact=False) >>> ctx=gmpy2.context() >>> ctx.abs(-1) mpz(1) >>> ctx.abs(0) mpz(0) >>> ctx.abs(1) mpz(1) >>> ctx.abs(mpz(8)) mpz(8) >>> ctx.abs(mpz(-8)) mpz(8) >>> ctx.abs(-1.0) mpfr('1.0') >>> ctx.abs(mpfr(-2)) mpfr('2.0') >>> ctx.abs(2+3j) mpfr('3.6055512754639891') >>> ctx.abs(mpc(2+3j)) mpfr('3.6055512754639891') gmpy2-2.1.0b3/test/test_context.txt0000664000175000017500000002703213356026702017122 0ustar casecase00000000000000Test context handling --------------------- >>> import gmpy2 >>> from gmpy2 import mpfr,mpc,get_context,set_context,ieee,context,local_context Test ieee() ----------- >>> ieee(32) context(precision=24, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=128, emin=-148, subnormalize=True, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> ieee(64) context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1024, emin=-1073, subnormalize=True, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> ieee(128) context(precision=113, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=16384, emin=-16493, subnormalize=True, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> gmpy2.ieee(256) context(precision=237, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=262144, emin=-262377, subnormalize=True, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> gmpy2.ieee(-1) Traceback (most recent call last): File "", line 1, in ValueError: bitwidth must be 16, 32, 64, 128; or must be greater than 128 and divisible by 32. >>> gmpy2.ieee("a") Traceback (most recent call last): File "", line 1, in TypeError: ieee() requires 'int' argument >>> set_context(ieee(32)) >>> gmpy2.const_pi().digits(2) ('110010010000111111011011', 2, 24) >>> set_context(ieee(64)) >>> gmpy2.const_pi().digits(2) ('11001001000011111101101010100010001000010110100011000', 2, 53) >>> set_context(ieee(128)) >>> gmpy2.const_pi().digits(2) ('11001001000011111101101010100010001000010110100011000010001101001100010011000110011000101000101110000000110111000', 2, 113) Test context() -------------- >>> context() context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> context(precision=100) context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> context(real_prec=100) context(precision=53, real_prec=100, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> context(real_prec=100,imag_prec=200) context(precision=53, real_prec=100, imag_prec=200, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) Test get_context() ------------------ >>> set_context(context()) >>> get_context() context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> a=get_context() >>> a.precision=100 >>> a context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> get_context() context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> b=a.copy() >>> b.precision=200 >>> b context(precision=200, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> a context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> get_context() context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) Test local_context() -------------------- >>> set_context(context()) >>> with local_context() as ctx: ... print(ctx.precision) ... ctx.precision+=20 ... print(ctx.precision) ... 53 73 >>> get_context() context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> with local_context(ieee(64)) as ctx: ... print(ctx) ... context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1024, emin=-1073, subnormalize=True, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> get_context() context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> with get_context() as ctx: ... print(ctx.precision) ... ctx.precision+=100 ... print(ctx.precision) ... 53 153 >>> get_context() context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> with local_context(precision=200) as ctx: ... print(ctx.precision) ... ctx.precision+=100 ... print(ctx.precision) ... 200 300 >>> get_context() context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) gmpy2-2.1.0b3/test/test_gmpy2_abs.txt0000664000175000017500000000410413170047220017304 0ustar casecase00000000000000Absolute value ============== Test abs() and context.abs(). >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> from fractions import Fraction as F >>> a=mpz(123) >>> b=abs(a) >>> a is b True >>> a=xmpz(123) >>> b=abs(a) >>> a is b False >>> a=mpz(-123) >>> b=abs(a) >>> b mpz(123) >>> a is b False >>> a mpz(-123) >>> a=mpq(12,7) >>> b=abs(a) >>> a is b True >>> a=mpq(-12,7) >>> b=abs(a) >>> b mpq(12,7) >>> a mpq(-12,7) >>> a=xmpz(-123) >>> b=abs(a) >>> b >>> a xmpz(123) >>> b is None True >>> b = abs(a) >>> b is None True >>> a=mpfr(1.0) >>> b=abs(a) >>> a is b False >>> abs(mpfr(1, precision=100)) mpfr('1.0') >>> ctx = gmpy2.get_context() >>> ctx.clear_flags() >>> abs(mpfr('nan')) mpfr('nan') >>> ctx.invalid True >>> ctx.clear_flags() >>> abs(mpfr('inf')) mpfr('inf') >>> ctx.overflow False >>> ctx.clear_flags() >>> abs(mpfr('-inf')) mpfr('inf') >>> ctx.overflow False >>> abs(mpc(-1,0)) mpfr('1.0') >>> abs(-1+0j) 1.0 >>> abs(mpc(1,1)) mpfr('1.4142135623730951') >>> ctx=gmpy2.get_context() >>> ctx.clear_flags() >>> mpc('nan+0j') mpc('nan+0.0j') >>> ctx.invalid True >>> abs(mpc('nan+0j')) mpfr('nan') >>> ctx.invalid True >>> ctx.clear_flags() >>> abs(mpc('nanj')) mpfr('nan') >>> ctx.invalid True >>> ctx.clear_flags() >>> abs(mpc('inf+10j')) mpfr('inf') >>> ctx.overflow False >>> ctx.clear_flags() >>> abs(mpc('-infj')) mpfr('inf') >>> ctx.overflow False >>> a = mpc('nan+infj') >>> ctx.clear_flags() >>> abs(a) mpfr('inf') >>> ctx.overflow False >>> ctx.invalid False >>> a=mpc('-inf+nanj') >>> ctx.clear_flags() >>> abs(a) mpfr('inf') >>> ctx.overflow False >>> ctx.invalid False >>> ctx=gmpy2.context() >>> ctx.abs('a') Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> ctx.abs(-1) mpz(1) >>> ctx.abs(0) mpz(0) >>> ctx.abs(1) mpz(1) >>> ctx.abs(mpz(8)) mpz(8) >>> ctx.abs(mpz(-8)) mpz(8) >>> ctx.abs(-1.0) mpfr('1.0') >>> ctx.abs(mpfr(-2)) mpfr('2.0') >>> ctx.abs(2+3j) mpfr('3.6055512754639891') >>> ctx.abs(mpc(2+3j)) mpfr('3.6055512754639891') >>> ctx.abs(F(1,2)) mpq(1,2) >>> ctx.abs(F(-1,2)) mpq(1,2) gmpy2-2.1.0b3/test/test_gmpy2_add.txt0000664000175000017500000000675113452510502017302 0ustar casecase00000000000000Test gmpy2 Addition =================== Test all code in the file gmpy2_add.c. >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> from supportclasses import * >>> from decimal import Decimal as D >>> from fractions import Fraction as F >>> a = mpz(123) >>> b = mpz(456) >>> c = 12345678901234567890 Test integer operations ----------------------- >>> a+1 mpz(124) >>> a+(-1) mpz(122) >>> 1+a mpz(124) >>> (-1)+a mpz(122) >>> print(a+c) 12345678901234568013 >>> print(c+a) 12345678901234568013 >>> print(a+(-c)) -12345678901234567767 >>> print((-c)+a) -12345678901234567767 >>> a+b mpz(579) >>> b+a mpz(579) >>> a+(-b) mpz(-333) >>> (-b)+a mpz(-333) >>> a+z mpz(125) >>> ctx=gmpy2.context() >>> ctx.add(a,b) == a+b True >>> ctx.add(c,c) == c+c True >>> ctx.add(1, 1) mpz(2) >>> ctx.add(mpfr(1), mpfr(1)) mpfr('2.0') >>> ctx.add(a, 1) mpz(124) >>> ctx.add(1, a) mpz(124) >>> ctx.add(a, mpq(0)) mpq(123,1) >>> ctx.add(a, mpfr(0)) mpfr('123.0') >>> ctx.add(a, mpc(0)) mpc('123.0+0.0j') >>> ctx.add(1) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> ctx.add(1,2,3) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> gmpy2.add(1,1) mpz(2) >>> a+'b' Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 'b'+a Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** Test rational operations ------------------------ >>> mpq(1,2) + F(3,2) mpq(2,1) >>> F(1,2) + mpq(3,2) mpq(2,1) >>> mpq(1,2) + mpq(3,2) mpq(2,1) >>> mpq(1,2) + 0 mpq(1,2) >>> mpq(1,2) + mpz(1) mpq(3,2) >>> mpq(1,2) + (-1) mpq(-1,2) >>> 1 + mpq(1,2) mpq(3,2) >>> mpz(1) + mpq(1,2) mpq(3,2) >>> mpq(1,2) + mpz(1) mpq(3,2) >>> mpq(1,1) + mpc(0) mpc('1.0+0.0j') >>> mpc(0) + mpq(1,1) mpc('1.0+0.0j') >>> mpq(1,2) + z mpq(5,2) >>> mpq(1,2) + q mpq(2,1) >>> ctx=gmpy2.context() >>> ctx.add(mpq(1,2), mpq(3,2)) mpq(2,1) >>> ctx.add(mpq(1,2), F(3,2)) mpq(2,1) >>> ctx.add(F(1,2), mpq(3,2)) mpq(2,1) >>> ctx.add(F(1,2), F(3,2)) mpq(2,1) >>> ctx.add(1,'a') Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> mpq(1,2) + 'a' Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 'a' + mpq(1,2) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** Test real operations -------------------- >>> mpfr(1) + 1 mpfr('2.0') >>> 1 + mpfr(1) mpfr('2.0') >>> mpfr(1) + mpz(1) mpfr('2.0') >>> mpz(1) + mpfr(1) mpfr('2.0') >>> mpfr(1) + mpfr(1) mpfr('2.0') >>> mpfr(1) + mpq(1,1) mpfr('2.0') >>> mpq(1,1) + mpfr(1) mpfr('2.0') >>> mpfr(1) + F(1,1) mpfr('2.0') >>> F(1,1) + mpfr(1) mpfr('2.0') >>> mpfr(1) + 1.0 mpfr('2.0') >>> 1.0 + mpfr(1) mpfr('2.0') >>> mpfr(0) + (1 << 100) == mpfr('1p100', base=2) True >>> (1 << 100) + mpfr(0) == mpfr('1p100', base=2) True >>> mpfr(1) + z mpfr('3.0') >>> mpfr(0.5) + q mpfr('2.0') >>> mpfr(1.5) + r mpfr('3.0') Test complex operations ----------------------- >>> mpc(1,2) + 'a' Traceback (most recent call last): ... TypeError: >>> mpfr(1) + mpc(1,2) mpc('2.0+2.0j') >>> mpc(1,2) + mpfr(1) mpc('2.0+2.0j') >>> mpc(1,2) + 1+0j mpc('2.0+2.0j') >>> 1+0j + mpc(1,2) mpc('2.0+2.0j') >>> mpc(1,2) + cx mpc('43.0+69.0j') >>> mpc(1,2) + r mpc('2.5+2.0j') >>> mpc(1,2) + q mpc('2.5+2.0j') >>> mpc(1,2) + z mpc('3.0+2.0j') gmpy2-2.1.0b3/test/test_gmpy2_binary.txt0000664000175000017500000001266113170047220020032 0ustar casecase00000000000000Test gmpy2_binary.c =================== >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc, to_binary, from_binary >>> gmpy2.mpz_from_old_binary(b'\x15\xcd[\x07') mpz(123456789) >>> gmpy2.mpz_from_old_binary(b'\x15\xcd[\x07\xff') mpz(-123456789) >>> gmpy2.mpz_from_old_binary(1) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> gmpy2.mpq_from_old_binary(b'\x01\x00\x00\x00)\x98') mpq(41,152) >>> gmpy2.mpq_from_old_binary(b'\x01\x00\x00\x80)\x98') mpq(-41,152) >>> gmpy2.mpq_from_old_binary(1) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> gmpy2.mpq_from_old_binary(b'aa') Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> gmpy2.mpq_from_old_binary(b'aaaaaaaaa') Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> gmpy2.mpfr_from_old_binary(b'\x085\x00\x00\x00\x02\x00\x00\x0009\xac\xcc\xcc\xcc\xcc\xcc\xd0') mpfr('12345.674999999999') >>> gmpy2.mpfr_from_old_binary(b'\t5\x00\x00\x00\x02\x00\x00\x0009\xac\xcc\xcc\xcc\xcc\xcc\xd0') mpfr('-12345.674999999999') >>> gmpy2.mpfr_from_old_binary(b'\n5\x00\x00\x00\x06\x00\x00\x00\x01\x14\xb3\x7fKQ\xf7\x0en') mpfr('1.5e-17') >>> gmpy2.mpfr_from_old_binary(1) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> gmpy2.mpfr_from_old_binary(b'aaaaa') Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> gmpy2.mpfr_from_old_binary(b'\x04') mpfr('0.0') >>> from_binary(to_binary(xmpz(1))) xmpz(1) >>> from_binary(to_binary(xmpz(0))) xmpz(0) >>> from_binary(to_binary(xmpz(-1))) xmpz(-1) >>> from_binary(to_binary(xmpz(1234567890123456789))) xmpz(1234567890123456789) >>> from_binary(1) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> from_binary(b'a') Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> from_binary(to_binary(mpz(1))) mpz(1) >>> from_binary(to_binary(mpz(0))) mpz(0) >>> from_binary(to_binary(mpz(-1))) mpz(-1) >>> from_binary(to_binary(mpz(1234567890123456789))) mpz(1234567890123456789) >>> x=mpq(0,1);x==from_binary(to_binary(x)) True >>> x=mpq(1,1);x==from_binary(to_binary(x)) True >>> x=mpq(-1,2);x==from_binary(to_binary(x)) True >>> x=mpq(123456789123456789,9876);x==from_binary(to_binary(x)) True >>> x=mpfr("0");x==from_binary(to_binary(x)) True >>> x=mpfr("1");x==from_binary(to_binary(x)) True >>> x=mpfr("-1");x==from_binary(to_binary(x)) True >>> x=mpfr("inf");x==from_binary(to_binary(x)) True >>> x=mpfr("-inf");x==from_binary(to_binary(x)) True >>> x=mpfr("nan");gmpy2.is_nan(from_binary(to_binary(x))) True >>> x=mpfr(1.345);x==from_binary(to_binary(x)) True >>> x=mpfr("1.345e1000");x==from_binary(to_binary(x)) True >>> x=mpfr("-1.345e1000");x==from_binary(to_binary(x)) True >>> x=mpfr("1.345e-1000");x==from_binary(to_binary(x)) True >>> x=mpfr("-1.345e-1000");x==from_binary(to_binary(x)) True >>> x=mpfr("1e1234567890123456789");x=from_binary(to_binary(x)) >>> x.rc 1 >>> x=mpfr("-1e1234567890123456789");x=from_binary(to_binary(x)) >>> x.rc -1 >>> x=gmpy2.const_pi() >>> x.rc -1 >>> y=from_binary(to_binary(x)) >>> x==y True >>> y.rc -1 >>> x=gmpy2.const_pi(precision=104) >>> x.rc 1 >>> y=from_binary(to_binary(x)) >>> x==y True >>> y.rc 1 >>> gmpy2.get_context().precision=20 >>> x=gmpy2.const_pi();x==from_binary(to_binary(x)) True >>> gmpy2.get_context().precision=100 >>> x=gmpy2.const_pi();x==from_binary(to_binary(x)) True >>> gmpy2.get_context().precision=200 >>> x=mpfr(gmpy2.const_pi());x==from_binary(to_binary(x)) True >>> gmpy2.get_context().precision=200 >>> x=gmpy2.const_pi() >>> gmpy2.get_context().precision=300 >>> x=from_binary(to_binary(x)) >>> x.precision 200 >>> gmpy2.set_context(gmpy2.context()) >>> x=mpc("0+0j");x==from_binary(to_binary(x)) True >>> x=mpc("1+0j");x==from_binary(to_binary(x)) True >>> x=mpc("-1+0j");x==from_binary(to_binary(x)) True >>> x=mpc("0+1j");x==from_binary(to_binary(x)) True >>> x=mpc("0-1j");x==from_binary(to_binary(x)) True >>> x=mpc("inf+0j");x==from_binary(to_binary(x)) True >>> x=mpc("0+infj");x==from_binary(to_binary(x)) True >>> x=mpc("inf-infj");x==from_binary(to_binary(x)) True >>> x=mpc("inf+nanj") >>> y=from_binary(to_binary(x)) >>> x.real==y.real True >>> gmpy2.is_nan(y.imag) True >>> x=mpc("-inf+0j");x==from_binary(to_binary(x)) True >>> x=mpc("0-infj");x==from_binary(to_binary(x)) True >>> x=mpc("-inf-infj");x==from_binary(to_binary(x)) True >>> x=mpc("-inf+nanj") >>> y=from_binary(to_binary(x)) >>> x.real==y.real True >>> gmpy2.is_nan(y.imag) True >>> x=mpc("nan+0j") >>> y=from_binary(to_binary(x)) >>> x.imag==y.imag True >>> gmpy2.is_nan(y.real) True >>> x=mpc("0+nanj") >>> y=from_binary(to_binary(x)) >>> x.real==y.real True >>> gmpy2.is_nan(y.imag) True >>> x=mpc("nan-infj") >>> y=from_binary(to_binary(x)) >>> x.imag==y.imag True >>> gmpy2.is_nan(y.real) True >>> x=mpc("nan+nanj") >>> y=from_binary(to_binary(x)) >>> gmpy2.is_nan(y.real) True >>> gmpy2.is_nan(y.imag) True >>> gmpy2.get_context().real_prec=100 >>> gmpy2.get_context().imag_prec=110 >>> from_binary(to_binary(mpc("1.3-4.7j"))) mpc('1.2999999999999999999999999999994-4.7000000000000000000000000000000025j',(100,110)) >>> gmpy2.set_context(gmpy2.context()) gmpy2-2.1.0b3/test/test_gmpy2_cmp.txt0000664000175000017500000000432013461370120017317 0ustar casecase00000000000000gmpy2 cmp and cmp_abs ===================== >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc, cmp, cmp_abs, nan, inf, zero MPZ Test comparisons -------------------- >>> cmp(0,mpz(0)), cmp(1,mpz(0)), cmp(0,mpz(1)), cmp(-1,mpz(0)), cmp(0,mpz(-1)) (0, 1, -1, -1, 1) >>> cmp_abs(mpz(0),0), cmp_abs(mpz(1),0), cmp_abs(mpz(0),1), cmp_abs(mpz(-1),0), cmp_abs(mpz(0), -1) (0, 1, -1, 1, -1) >>> a=mpz(-10) >>> cmp_abs(a,0) 1 >>> a mpz(-10) >>> cmp_abs(100,a) 1 >>> a mpz(-10) MPQ Test comparisons -------------------- >>> cmp(mpq(1,2), mpq(1,2)), cmp(mpq(-1,2), mpq(1,2)), cmp(mpq(1,2), mpq(-1,2)) (0, -1, 1) >>> cmp(0, mpq(1,2)), cmp(mpq(1,2), 0) (-1, 1) >>> cmp_abs(mpq(1,2), mpq(1,3)), cmp_abs(mpq(-1,2), mpq(1,3)), cmp_abs(mpq(1,2),mpq(-1,3)) (1, 1, 1) >>> cmp_abs(mpq(1,4), mpq(1,3)), cmp_abs(mpq(-1,4), mpq(1,3)), cmp_abs(mpq(1,4),mpq(-1,3)) (-1, -1, -1) MPFR Test comparisons --------------------- >>> cmp(mpfr(0), mpfr(0)), cmp(mpfr(0), mpz(0)), cmp(mpfr(0), mpq(0,1)) (0, 0, 0) >>> cmp(zero(-1), zero(-1)), cmp(zero(1), zero(-1)), cmp(zero(-1), zero(1)) (0, 0, 0) >>> cmp(mpfr(1), mpfr(0)), cmp(mpfr(1), mpz(0)), cmp(mpfr(1), mpq(0,1)) (1, 1, 1) >>> cmp(mpfr(-1), mpfr(0)), cmp(mpfr(-1), mpz(0)), cmp(mpfr(-1), mpq(0,1)) (-1, -1, -1) >>> cmp(nan(), mpfr(0)), cmp(nan(), mpz(0)), cmp(nan(), mpq(0,1)) (0, 0, 0) >>> gmpy2.get_context().clear_flags() >>> cmp(nan(), 1) 0 >>> gmpy2.get_context().erange True >>> cmp_abs(mpfr(-1), mpfr(0)), cmp_abs(mpfr(-1), mpz(0)), cmp_abs(mpfr(-1), mpq(0,1)) (1, 1, 1) >>> cmp_abs(mpfr(0), mpfr(-1)), cmp_abs(mpz(0), mpfr(-1)), cmp_abs(mpq(0,1), mpfr(-1)) (-1, -1, -1) MPC Test comparisons -------------------- >>> cmp(mpc(1,2), mpc(3,4)) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> cmp_abs(mpc(1,2), mpc(3,4)) # doctest: +SKIP_MPC_LESS_THAN_110 -1 >>> cmp_abs(mpc(1,2), mpc(1,2)) # doctest: +SKIP_MPC_LESS_THAN_110 0 >>> cmp_abs(mpc(3,4), mpc(1,2)) # doctest: +SKIP_MPC_LESS_THAN_110 1 >>> gmpy2.get_context().clear_flags() >>> nan() mpfr('nan') >>> gmpy2.get_context().erange False >>> cmp_abs(mpc(nan(),1), mpc(4.5)) # doctest: +SKIP_MPC_LESS_THAN_110 0 >>> gmpy2.get_context().erange # doctest: +SKIP_MPC_LESS_THAN_110 True gmpy2-2.1.0b3/test/test_gmpy2_comp.txt0000664000175000017500000001006313452502047017504 0ustar casecase00000000000000gmpy2 numbers comparisons ========================= >>> import gmpy2 as G >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> a = mpz(123) >>> b = mpz(456) >>> q = mpq(4, 5) MPZ Test comparisons -------------------- >>> c=G.mpz(a) >>> a mpz(123) >>> b mpz(456) >>> c is a True >>> c==a True >>> c>a False >>> c>> a>b False >>> a>> not G.mpz(0) True >>> not a False >>> G.mpz(1) == None False >>> G.mpz(1) == '1' False >>> G.mpz(1) == 'abc' False >>> [G.mpz(23), None].count(None) 1 >>> a == q, a != q, a > q, a >= q, a < q, a <= q (False, True, True, True, False, False) >>> q = mpq(123, 1) >>> a == q, a != q, a > q, a >= q, a < q, a <= q (True, False, False, True, False, True) Test MPZ comparisons with NaN/Inf --------------------------------- >>> G.context().trap_divzero == False True >>> f = float('inf') >>> a == f, a != f, a > f, a >= f, a < f, a <= f (False, True, False, False, True, True) >>> f == a, f != a, f > a, f >= a, f < a, f <= a (False, True, True, True, False, False) >>> f = float('-inf') >>> a == f, a != f, a > f, a >= f, a < f, a <= f (False, True, True, True, False, False) >>> f == a, f != a, f > a, f >= a, f < a, f <= a (False, True, False, False, True, True) >>> f = float('nan') >>> a == f, a != f, a > f, a >= f, a < f, a <= f (False, True, False, False, False, False) >>> f == a, f != a, f > a, f >= a, f < a, f <= a (False, True, False, False, False, False) >>> r = mpfr('inf') >>> a == r, a != r, a > r, a >= r, a < r, a <= r (False, True, False, False, True, True) >>> r = mpfr('-inf') >>> a == r, a != r, a > r, a >= r, a < r, a <= r (False, True, True, True, False, False) >>> r = mpfr('nan') >>> a == r, a != r, a > r, a >= r, a < r, a <= r (False, True, False, False, False, False) MPQ Tests comparisons --------------------- >>> q = mpq(4, 5) >>> q == a, q != a, q > a, q >= a, q < a, q <= a (False, True, False, False, True, True) >>> mpq(246,2) != a False >>> f = float(0.7) >>> q == f, q != f, q > f, q >= f, q < f, q <= f (False, True, True, True, False, False) >>> f = float('nan') >>> q == f, q != f, q > f, q >= f, q < f, q <= f (False, True, False, False, False, False) >>> f = float('inf') >>> q == f, q != f, q > f, q >= f, q < f, q <= f (False, True, False, False, True, True) >>> f = -f >>> q == f, q != f, q > f, q >= f, q < f, q <= f (False, True, True, True, False, False) Tests MPFR comparisons ---------------------- >>> r = mpfr('inf') >>> q = mpq('45/7') >>> f = float(0.7) >>> r2 = mpfr(454.6) >>> r == a, r != a, r > a, r >= a, r < a, r <= a (False, True, True, True, False, False) >>> r = mpfr('-inf') >>> r == a, r != a, r > a, r >= a, r < a, r <= a (False, True, False, False, True, True) >>> r = mpfr('nan') >>> r == a, r != a, r > a, r >= a, r < a, r <= a (False, True, False, False, False, False) >>> r == q, r != q, r > q, r >= q, r < q, r <= q (False, True, False, False, False, False) >>> r == f, r != f, r > f, r >= f, r < f, r <= f (False, True, False, False, False, False) >>> r == r2, r != r2, r > r2, r >= r2, r < r2, r <= r2 (False, True, False, False, False, False) >>> r = mpfr(126.5) >>> r == a, r != a, r > a, r >= a, r < a, r <= a (False, True, True, True, False, False) >>> r == q, r != q, r > q, r >= q, r < q, r <= q (False, True, True, True, False, False) >>> f = float(126.5) >>> r == f, r != f, r > f, r >= f, r < f, r <= f (True, False, False, True, False, True) >>> r == r2, r != r2, r > r2, r >= r2, r < r2, r <= r2 (False, True, False, False, True, True) Tests MPC comparisons --------------------- >>> c = mpc(4.5,6) >>> c == a, c != a (False, True) >>> c < a Traceback (most recent call last): File "", line 1, in TypeError: no ordering relation is defined for complex numbers >>> cnan = mpc(mpfr('nan'), 6) >>> c == cnan, c != cnan (False, True) >>> c > cnan Traceback (most recent call last): File "", line 1, in TypeError: no ordering relation is defined for complex numbers >>> cx = complex(4.5,6) >>> c == cx, c != cx (True, False) >>> c > cx Traceback (most recent call last): File "", line 1, in TypeError: no ordering relation is defined for complex numbers >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_const.txt0000664000175000017500000000650713170047220017676 0ustar casecase00000000000000Constants ========= >>> import gmpy2 >>> gmpy2.const_pi() mpfr('3.1415926535897931') >>> gmpy2.const_pi(100) mpfr('3.1415926535897932384626433832793',100) >>> gmpy2.const_pi(100,200) Traceback (most recent call last): File "", line 1, in TypeError: function takes at most 1 argument (2 given) >>> gmpy2.const_pi(prec=100) Traceback (most recent call last): File "", line 1, in TypeError: 'prec' is an invalid keyword argument for this function >>> gmpy2.const_pi(precision=100) mpfr('3.1415926535897932384626433832793',100) >>> gmpy2.ieee(32).const_pi() mpfr('3.14159274',24) >>> gmpy2.ieee(32).const_pi(100) Traceback (most recent call last): File "", line 1, in TypeError: const_pi() takes no arguments (1 given) >>> gmpy2.ieee(128).const_pi() mpfr('3.1415926535897932384626433832795028',113) >>> gmpy2.const_log2() mpfr('0.69314718055994529') >>> gmpy2.const_log2(100) mpfr('0.69314718055994530941723212145798',100) >>> gmpy2.const_log2(100,200) Traceback (most recent call last): File "", line 1, in TypeError: function takes at most 1 argument (2 given) >>> gmpy2.const_log2(prec=100) Traceback (most recent call last): File "", line 1, in TypeError: 'prec' is an invalid keyword argument for this function >>> gmpy2.const_log2(precision=100) mpfr('0.69314718055994530941723212145798',100) >>> gmpy2.ieee(32).const_log2() mpfr('0.693147182',24) >>> gmpy2.ieee(32).const_log2(100) Traceback (most recent call last): File "", line 1, in TypeError: const_log2() takes no arguments (1 given) >>> gmpy2.ieee(128).const_log2() mpfr('0.693147180559945309417232121458176575',113) >>> gmpy2.const_catalan() mpfr('0.91596559417721901') >>> gmpy2.const_catalan(100) mpfr('0.91596559417721901505460351493252',100) >>> gmpy2.const_catalan(100,200) Traceback (most recent call last): File "", line 1, in TypeError: function takes at most 1 argument (2 given) >>> gmpy2.const_catalan(prec=100) Traceback (most recent call last): File "", line 1, in TypeError: 'prec' is an invalid keyword argument for this function >>> gmpy2.const_catalan(precision=100) mpfr('0.91596559417721901505460351493252',100) >>> gmpy2.ieee(32).const_catalan() mpfr('0.915965617',24) >>> gmpy2.ieee(32).const_catalan(100) Traceback (most recent call last): File "", line 1, in TypeError: const_catalan() takes no arguments (1 given) >>> gmpy2.ieee(128).const_catalan() mpfr('0.915965594177219015054603514932384146',113) >>> gmpy2.const_euler() mpfr('0.57721566490153287') >>> gmpy2.const_euler(100) mpfr('0.57721566490153286060651209008234',100) >>> gmpy2.const_euler(100,200) Traceback (most recent call last): File "", line 1, in TypeError: function takes at most 1 argument (2 given) >>> gmpy2.const_euler(prec=100) Traceback (most recent call last): File "", line 1, in TypeError: 'prec' is an invalid keyword argument for this function >>> gmpy2.const_euler(precision=100) mpfr('0.57721566490153286060651209008234',100) >>> gmpy2.ieee(32).const_euler() mpfr('0.577215672',24) >>> gmpy2.ieee(32).const_euler(100) Traceback (most recent call last): File "", line 1, in TypeError: const_euler() takes no arguments (1 given) >>> gmpy2.ieee(128).const_euler() mpfr('0.577215664901532860606512090082402471',113) gmpy2-2.1.0b3/test/test_gmpy2_constructors.txt0000664000175000017500000000354113461370120021314 0ustar casecase00000000000000Test constructors via special methods ===================================== >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from supportclasses import * Test mpz conversion ------------------- >>> x = mpz(a) >>> isinstance(x, mpz) True >>> x == 1 True >>> mpz(b) Traceback (most recent call last): ... TypeError: object of type 'str' can not be interpreted as mpz >>> mpz(c) Traceback (most recent call last): ... TypeError: mpz() requires numeric or string argument >>> 1 1 Test mpq conversion ------------------- >>> x = mpq(a) >>> isinstance(x, mpq) True >>> 2*x == 3 True >>> mpq(z, z) mpq(1,1) >>> class Three: ... def __mpz__(self): return mpz(3) ... >>> mpq(z, Three()) mpq(2,3) >>> mpq(b) Traceback (most recent call last): ... TypeError: object of type 'str' can not be interpreted as mpq >>> mpq(c) Traceback (most recent call last): ... TypeError: mpq() requires numeric or string argument >>> 1 1 Test mpfr conversion -------------------- >>> x = mpfr(a) >>> isinstance(x, mpfr) True >>> x == 1.5 True >>> mpfr(b) Traceback (most recent call last): ... TypeError: object of type 'str' can not be interpreted as mpc >>> mpfr(c) Traceback (most recent call last): ... TypeError: mpfr() requires numeric or string argument >>> 1 1 Test mpc conversion -------------------- >>> x = mpc(a) >>> isinstance(x, mpc) True >>> x == 42+67j True >>> mpc(b) Traceback (most recent call last): ... TypeError: object of type 'str' can not be interpreted as mpc >>> mpc(c) Traceback (most recent call last): ... TypeError: mpc() requires numeric or string argument >>> 1 1 Test special methods raising errors -------------------- >>> mpz(d) Traceback (most recent call last): ... TypeError >>> mpq(d) Traceback (most recent call last): ... TypeError >>> mpfr(d) Traceback (most recent call last): ... TypeError >>> mpc(d) Traceback (most recent call last): ... TypeError >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_convert.txt0000664000175000017500000000653213444070732020236 0ustar casecase00000000000000Test conversion code to/from GMP ================================ >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc, xmpz >>> from fractions import Fraction Test conversion to/from MPZ --------------------------- >>> float(mpz(1)) 1.0 >>> float(mpz(99**199)) Traceback (most recent call last): File "", line 1, in OverflowError: ** message detail varies ** >>> mpz(gmpy2.xmpz(1)) mpz(1) Test conversion to/from XMPZ ---------------------------- >>> xmpz('5') xmpz(5) >>> xmpz('5') xmpz(5) >>> xmpz('not') Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> xmpz(-3.5) xmpz(-3) >>> xmpz(float('inf')) Traceback (most recent call last): File "", line 1, in OverflowError: 'xmpz' does not support Infinity >>> xmpz(mpz(100)) xmpz(100) >>> xmpz(xmpz(100)) xmpz(100) >>> xmpz(mpq(30,2)) xmpz(15) >>> str(xmpz(100)) '100' Test conversion to/from MPQ --------------------------- >>> mpq(u'2/3') mpq(2,3) >>> mpq(b'2/3') mpq(2,3) >>> mpq('2,3') Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpq('2/a') Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpq('2.3') mpq(23,10) >>> mpq('2.3/10') Traceback (most recent call last): File "", line 1, in ValueError: illegal string: both . and / found >>> mpq(4.5) mpq(9,2) >>> mpq(float('inf')) Traceback (most recent call last): File "", line 1, in OverflowError: 'mpq' does not support Infinity >>> mpq(xmpz(15)) mpq(15,1) >>> mpq(mpfr(4.5)) mpq(9,2) >>> mpq(dict()) Traceback (most recent call last): File "", line 1, in TypeError: mpq() requires numeric or string argument >>> float(mpq(1,2)) 0.5 >>> int(mpq(15,2)) 7 Test conversion to/from MPFR ---------------------------- >>> mpz(mpfr('inf')) Traceback (most recent call last): File "", line 1, in OverflowError: 'mpz' does not support Infinity >>> mpz(mpfr(5.51)) mpz(6) >>> xmpz(mpfr('inf')) Traceback (most recent call last): File "", line 1, in OverflowError: 'xmpz' does not support Infinity >>> xmpz(mpfr(5.51)) xmpz(6) >>> mpq(mpfr('inf')) Traceback (most recent call last): File "", line 1, in OverflowError: can not convert Infinity to MPQ >>> mpq(mpfr(4.5)) mpq(9,2) >>> mpq(mpfr(0)) mpq(0,1) >>> int(mpfr(5.3)) 5 >>> float(mpfr(5.3)) 5.3 >>> str(float('5.656')) '5.656' Test conversion to/from MPC --------------------------- >>> mpc(mpfr(5.6), precision=(0,0)) mpc('5.5999999999999996+0.0j') >>> mpc(Fraction(4,5)) mpc('0.80000000000000004+0.0j') >>> mpc(b'5+6j') mpc('5.0+6.0j') >>> mpc(u'5+6j') mpc('5.0+6.0j') >>> mpc(u'\xc3') Traceback (most recent call last): File "", line 1, in ValueError: string contains non-ASCII characters >>> mpc('notanumber') Traceback (most recent call last): File "", line 1, in ValueError: invalid string in mpc() >>> mpc(u'\0') Traceback (most recent call last): File "", line 1, in ValueError: string without NULL characters expected >>> mpc('(5+6j)') mpc('5.0+6.0j') >>> mpc(' 5+6j ') mpc('5.0+6.0j') >>> mpc('5+6ji') Traceback (most recent call last): File "", line 1, in ValueError: invalid string in mpc() >>> str(mpc(5,6)) '5.0+6.0j' >>> mpc(4,5).__complex__() (4+5j) gmpy2-2.1.0b3/test/test_gmpy2_divmod.txt0000664000175000017500000000470713244654531020045 0ustar casecase00000000000000Test divmod ============ >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> from decimal import Decimal as D >>> from fractions import Fraction as F >>> a = mpz(123) >>> b = mpz(456) >>> c = 12345678901234567890 Test integer operations ----------------------- >>> divmod(mpz(123),'a') Traceback (most recent call last): ... TypeError: >>> divmod(mpq(1,2),'a') Traceback (most recent call last): ... TypeError: >>> divmod(mpfr(1),'a') Traceback (most recent call last): ... TypeError: >>> divmod(mpc(1),'a') Traceback (most recent call last): ... TypeError: >>> ctx=gmpy2.context() >>> ctx.divmod('a',456) Traceback (most recent call last): ... TypeError: >>> ctx.divmod(a,mpc(456)) Traceback (most recent call last): ... TypeError: >>> ctx.divmod(mpc(1,2),mpc(3,4)) Traceback (most recent call last): ... TypeError: >>> ctx.divmod(mpfr(2),mpfr(1)) (mpfr('2.0'), mpfr('0.0')) >>> ctx.divmod(mpq(3,2),mpq(3,7)) (mpz(3), mpq(3,14)) >>> ctx.divmod(1,2,3) Traceback (most recent call last): ... TypeError: >>> ctx.divmod(456, 0) Traceback (most recent call last): ... ZeroDivisionError: >>> ctx.divmod(a,b) (mpz(0), mpz(123)) >>> ctx.divmod(123,456) (mpz(0), mpz(123)) >>> divmod(mpz(1), mpc(1,2)) Traceback (most recent call last): ... TypeError: >>> divmod(mpq(1,2), mpc(1,2)) Traceback (most recent call last): ... TypeError: >>> divmod(mpfr(1), mpc(1,2)) Traceback (most recent call last): ... TypeError: >>> divmod(mpc(1,2), mpc(1,2)) Traceback (most recent call last): ... TypeError: >>> divmod(mpfr(1.2), mpfr(0.7)) (mpfr('1.0'), mpfr('0.5')) >>> ctx=gmpy2.ieee(64) >>> gmpy2.set_context(ctx) >>> divmod(mpz(123),'a') Traceback (most recent call last): ... TypeError: >>> divmod(mpq(1,2),'a') Traceback (most recent call last): ... TypeError: >>> divmod(mpfr(1),'a') Traceback (most recent call last): ... TypeError: >>> divmod(mpc(1),'a') Traceback (most recent call last): ... TypeError: >>> ctx=gmpy2.context() >>> ctx.divmod('a',456) Traceback (most recent call last): ... TypeError: >>> ctx.divmod(a,mpc(456)) Traceback (most recent call last): ... TypeError: >>> ctx.divmod(mpc(1,2),mpc(3,4)) Traceback (most recent call last): ... TypeError: >>> ctx.divmod(456, 0) Traceback (most recent call last): ... ZeroDivisionError: >>> divmod(mpfr(1.2), mpfr(0.7)) (mpfr('1.0'), mpfr('0.5')) >>> ctx.clear_flags() >>> ctx.divzero False >>> divmod(mpfr(1.2), mpfr(0)) (mpfr('nan'), mpfr('nan')) >>> >>> gmpy2.set_context(gmpy2.context()) gmpy2-2.1.0b3/test/test_gmpy2_floordiv.txt0000664000175000017500000001114513452502175020376 0ustar casecase00000000000000Test gmpy2's floordiv ===================== >>> import gmpy2 >>> ctx = gmpy2.get_context() >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> from fractions import Fraction >>> a, b = mpz(45), mpz(6) >>> r, r2 = mpfr(45), mpfr(3.1) >>> q, q2 = mpq(118,18), mpq(3,2) >>> pyq, pyq2 = Fraction(118,18), Fraction(3,2) >>> c, c2 = mpc(51, 65), mpc(4, 6) Tests integer floordiv ---------------------- >>> ctx.floor_div(a, 6) mpz(7) >>> ctx.floor_div(a, b) mpz(7) >>> ctx.floor_div(a, 0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div(a, mpz(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div(45, b) mpz(7) >>> ctx.floor_div(45, 0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div(45, mpz(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div() Traceback (most recent call last): File "", line 1, in TypeError: floor_div() requires 2 arguments >>> gmpy2.floor_div(4,5,6) Traceback (most recent call last): File "", line 1, in TypeError: floor_div() requires 2 arguments >>> a // b mpz(7) >>> a // 0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> a // mpz(0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div(a, q2) mpz(30) >>> ctx.floor_div(a, r2) mpfr('14.0') >>> ctx.floor_div(a, c) Traceback (most recent call last): File "", line 1, in TypeError: can't take floor of complex number >>> a // b mpz(7) >>> a // q mpz(6) >>> a // r2 mpfr('14.0') >>> a // c2 Traceback (most recent call last): File "", line 1, in TypeError: can't take floor of complex number >>> a // 'not' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for //: 'mpz' and 'str' >>> 1 1 Rational floor_div ------------------ >>> ctx.floor_div(q, q2) mpz(4) >>> ctx.floor_div(q, pyq2) mpz(4) >>> ctx.floor_div(q, pyq) mpz(1) >>> ctx.floor_div(pyq, q2) mpz(4) >>> ctx.floor_div(pyq, pyq2) mpz(4) >>> ctx.floor_div(pyq, q) mpz(1) >>> ctx.floor_div(q, mpq(0,1)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div(q, Fraction(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div(pyq, mpq(0,1)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.floor_div(pyq, Fraction(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> q // b mpz(1) >>> q // q2 mpz(4) >>> q // r2 mpfr('2.0') >>> q // c2 Traceback (most recent call last): File "", line 1, in TypeError: can't take floor of complex number >>> q // 'not' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for //: 'mpq' and 'str' >>> 1 1 Real floor_div -------------- >>> ctx.floor_div(r, r2) mpfr('14.0') >>> ctx.floor_div(r, r2) mpfr('14.0') >>> ctx.floor_div(r, 3.1) mpfr('14.0') >>> ctx.floor_div(r, 4) mpfr('11.0') >>> ctx.floor_div(r, b) mpfr('7.0') >>> ctx.floor_div(r, q2) mpfr('30.0') >>> ctx.floor_div(r, pyq2) mpfr('30.0') >>> ctx.floor_div(r, 0) mpfr('inf') >>> ctx.floor_div(r, mpz(0)) mpfr('inf') >>> ctx.floor_div(45.0, r2) mpfr('14.0') >>> ctx.floor_div(45.0, r2) mpfr('14.0') >>> ctx.floor_div(45.0, 3.1) mpfr('14.0') >>> ctx.floor_div(45.0, 4) mpfr('11.0') >>> ctx.floor_div(45.0, b) mpfr('7.0') >>> ctx.floor_div(45.0, q2) mpfr('30.0') >>> ctx.floor_div(45.0, pyq2) mpfr('30.0') >>> ctx.floor_div(45.0, 0) mpfr('inf') >>> ctx.floor_div(45.0, mpz(0)) mpfr('inf') >>> ctx.floor_div(45, r2) mpfr('14.0') >>> ctx.floor_div(r, 'not') Traceback (most recent call last): File "", line 1, in TypeError: floor_div() argument type not supported >>> r // b mpfr('7.0') >>> r // q2 mpfr('30.0') >>> r // r2 mpfr('14.0') >>> r // c2 Traceback (most recent call last): File "", line 1, in TypeError: can't take floor of complex number >>> r // 'not' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for //: 'mpfr' and 'str' >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_format.txt0000664000175000017500000001732013452503000020027 0ustar casecase00000000000000Tests for gmpy2_format.c ======================== >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> import gmpy2 >>> z1, z2 = mpz(-3), mpz(5) >>> r, r1, r2 = mpfr(5.6), mpfr(-3), mpfr(5) >>> q = mpq(2/3) Tests mpz format ---------------- >>> z1.__format__('<5') '-3 ' >>> z2.__format__('>+5') ' +5' >>> z1.__format__('5+') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> z2.__format__('>-4') ' 5' >>> z1.__format__('<-4') '-3 ' >>> z1.__format__('>4-') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> z1.__format__('<4 ') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> z1.__format__('#x') '-0x3' >>> z1.__format__('#o') '-0o3' >>> z1.__format__('>5#') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> z1.__format__('~') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> 1 1 Tests mpfr format ----------------- >>> r1.__format__('<30') '-3.000000 ' >>> r2.__format__('>+20') ' +5.000000' >>> r2.__format__('>-15') ' 5.000000' >>> r1.__format__('>-15') ' -3.000000' >>> r.__format__('U') '5.600000' >>> r.__format__('U-') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> r.__format__('Z') '5.599999' >>> r.__format__('Z+') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> r.__format__('+Z') '+5.599999' >>> r.__format__('Z ') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> r.__format__('.10f') '5.6000000000' >>> r.__format__('.10f.') '5.6000000000' >>> r.__format__('Z.') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> r.__format__('->') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> r.__format__('YZ') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> 1 1 Tests mpc format ---------------- >>> c = mpc(mpq(1/3), 5) >>> c.__format__() Traceback (most recent call last): File "", line 1, in TypeError: function takes exactly 1 argument (0 given) >>> c.__format__('>20') ' 0.333333+5.000000j' >>> c.__format__('<20') '0.333333+5.000000j ' >>> c.__format__('^20') ' 0.333333+5.000000j ' >>> c.__format__('<20', 'xx') Traceback (most recent call last): File "", line 1, in TypeError: function takes exactly 1 argument (2 given) >>> c.__format__('<<20') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> c.__format__('>+20') ' +0.333333+5.000000j' >>> c.__format__('+^20') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> c.__format__('.10f') '0.3333333333+5.0000000000j' >>> c.__format__('Z.10f') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> c.__format__('Z 10') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> c.__format__('Z') '0.333333+5.000000j' >>> c.__format__('U') '0.333334+5.000000j' >>> c.__format__('PU') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> c.__format__('UP') '0.333334+5.000000j' >>> c.__format__('PP') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> c.__format__('G') '0.333333+5.0j' >>> c.__format__('M') '(0.333333 5.000000)' >>> c.__format__('b') '1.0101010101010101010101010101010101010101010101010101p-2+1.01p+2j' >>> c.__format__('a') '0x5.5555555555554p-4+0x5p+0j' >>> c.__format__('e') '3.3333333333333331e-01+5e+00j' >>> mpc(-1.0, -2.0).__format__('M') '(-1.000000 -2.000000)' Tests mpz digits method ----------------------- >>> z1.digits() '-3' >>> z1.digits(2) '-11' >>> z1.digits(8) '-3' >>> mpz(15).digits(16) 'f' >>> z1.digits(0) Traceback (most recent call last): File "", line 1, in ValueError: base must be in the interval 2 ... 62 >>> z1.digits(1) Traceback (most recent call last): File "", line 1, in ValueError: base must be in the interval 2 ... 62 >>> 1 1 Tests xmpz digits method ----------------------- >>> x = xmpz(6) >>> x.digits() '6' >>> x.digits(2) # doctest: +ELLIPSIS '...110' >>> x.digits(8) # doctest: +ELLIPSIS '...6' >>> x.digits(16) '0x6' >>> xmpz(30).digits(16) '0x1e' >>> x.digits(0) Traceback (most recent call last): File "", line 1, in ValueError: base must be in the interval 2 ... 62 >>> x.digits(63) Traceback (most recent call last): File "", line 1, in ValueError: base must be in the interval 2 ... 62 >>> 1 1 Tests mpfr digits method ------------------------ >>> r.digits() ('55999999999999996', 1, 53) >>> r.digits(2) ('10110011001100110011001100110011001100110011001100110', 3, 53) >>> r.digits(2,54) ('101100110011001100110011001100110011001100110011001100', 3, 53) >>> r.digits(10,54) ('559999999999999964472863211994990706443786621093750000', 1, 53) >>> r2.digits(2) ('10100000000000000000000000000000000000000000000000000', 3, 53) >>> r2.digits(2,5,6) Traceback (most recent call last): File "", line 1, in TypeError: function takes at most 2 arguments (3 given) >>> r.digits(0) Traceback (most recent call last): File "", line 1, in ValueError: base must be in the interval [2,62] >>> 1 1 Tests mpc digits method ----------------------- >>> c.digits(8) (('2525252525252525250', 0, 53), ('5000000000000000000', 1, 53)) >>> c.digits(8, 2) (('25', 0, 53), ('50', 1, 53)) >>> c.digits(8, -2) Traceback (most recent call last): File "", line 1, in ValueError: digits must be 0 or >= 2 >>> c.digits(0) Traceback (most recent call last): File "", line 1, in ValueError: base must be in the interval [2,62] >>> 1 1 Tests mpq digits method ----------------------- >>> q.digits() '6004799503160661/9007199254740992' >>> q.digits(16) '0x15555555555555/0x20000000000000' >>> q.digits(16,5) Traceback (most recent call last): File "", line 1, in TypeError: function takes at most 1 argument (2 given) >>> q.digits(0) Traceback (most recent call last): File "", line 1, in ValueError: base must be in the interval 2 ... 62 >>> 1 1 Tests context digits -------------------- >>> gmpy2.digits() Traceback (most recent call last): File "", line 1, in TypeError: digits() requires at least one argument >>> gmpy2.digits(5, 5, 4, 5) Traceback (most recent call last): File "", line 1, in TypeError: digits() accepts at most three arguments >>> gmpy2.digits(z2) '5' >>> gmpy2.digits(z2, 2) '101' >>> gmpy2.digits(z2, 2, 5) Traceback (most recent call last): File "", line 1, in TypeError: function takes at most 1 argument (2 given) >>> gmpy2.digits(mpq(3,5)) '3/5' >>> gmpy2.digits(mpq(3,5), 4) '3/11' >>> gmpy2.digits(mpfr(3,5), 4) ('300', 1, 5) >>> gmpy2.digits(mpfr(3,5), 4, 5) ('30000', 1, 5) >>> gmpy2.digits(complex(5,5), 4, 5) (('11000', 2, 53), ('11000', 2, 53)) >>> gmpy2.digits('string', 4, 5) Traceback (most recent call last): File "", line 1, in TypeError: digits() argument type not supported >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_fused.txt0000664000175000017500000000146313363134335017662 0ustar casecase00000000000000Test gmpy2 fused multiply/add functions ======================================= >>> import gmpy2 >>> from gmpy2 import ieee, mpz, mpq, mpfr, mpc, fma, fms >>> fma(2,3,4) mpz(10) >>> fma(2,3,-4) mpz(2) >>> fma(2.0,3,-4) mpfr('2.0') >>> fma(2,3.0,-4) mpfr('2.0') >>> fma(2,3,-4.0) mpfr('2.0') >>> fma(2,mpfr(3),-4.0) mpfr('2.0') >>> fma(mpc(2),mpfr(3),-4.0) mpc('2.0+0.0j') >>> fms(2,3,4) mpz(2) >>> fms(2,3,-4) mpz(10) >>> ieee(128).fma(7,1/7,-1) mpfr('-5.55111512312578270211815834045410156e-17',113) >>> ieee(128).fma(7,mpq(1,7),-1) mpq(0,1) >>> fma(1,2,"r") Traceback (most recent call last): File "", line 1, in TypeError: fma() argument type not supported >>> fma(1,2,mpq(3,4)) mpq(11,4) >>> fms(1,2,mpq(3,4)) mpq(5,4) >>> fms(1,mpfr(2),3) mpfr('-1.0') >>> fms(1,mpc(2),3) mpc('-1.0+0.0j') gmpy2-2.1.0b3/test/test_gmpy2_lucas.txt0000664000175000017500000000247213425750522017665 0ustar casecase00000000000000Test gmpy2 Lucas Functions ========================== >>> import gmpy2 >>> from gmpy2 import mpz # Test lucasu >>> import gmpy2 >>> from gmpy2 import mpz >>> gmpy2.lucasu(2,4,1) mpz(1) >>> gmpy2.lucasu(2,1,1) Traceback (most recent call last): ... ValueError: >>> gmpy2.lucasu(2,4,8) mpz(128) >>> gmpy2.lucasu('a',4,8) Traceback (most recent call last): ... TypeError: >>> gmpy2.lucasu(2,'b',8) Traceback (most recent call last): ... TypeError: >>> gmpy2.lucasu(2,4,None) Traceback (most recent call last): ... TypeError: >>> gmpy2.lucasu(mpz(2), mpz(1), mpz(7)) Traceback (most recent call last): ... ValueError: >>> gmpy2.lucasu_mod(3,2,5,7) mpz(3) >>> gmpy2.lucasu_mod(3,2,555,777777777) mpz(387104641) >>> gmpy2.lucasu_mod(2,1,555,777777777) Traceback (most recent call last): ... ValueError: >>> gmpy2.lucasv(2,1,4) Traceback (most recent call last): ... ValueError: >>> gmpy2.lucasv('a',1,2) Traceback (most recent call last): ... TypeError: >>> gmpy2.lucasv(4,'b',2) Traceback (most recent call last): ... TypeError: >>> gmpy2.lucasv(4,3,'c') Traceback (most recent call last): ... TypeError: >>> gmpy2.lucasv(4,3,7) mpz(2188) >>> gmpy2.lucasv(4,3,8) mpz(6562) >>> gmpy2.lucasv_mod(4,3,55,123456) mpz(35788) >>> gmpy2.lucasv_mod(4,3,56,123456) mpz(107362) >>> gmpy2.lucasv_mod(4,3,57,123456) mpz(75172) gmpy2-2.1.0b3/test/test_gmpy2_math.txt0000664000175000017500000002262313444603111017477 0ustar casecase00000000000000Tests for functions and methods of gmpy2_math.c =============================================== Note: tests for trigonometric operations are in files test_mpfr_trig.txt and test_mpc_trig.txt. >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> import gmpy2 >>> ctx = gmpy2.get_context() >>> ctx.log(mpfr(2)) mpfr('0.69314718055994529') >>> ctx.log(mpfr(1)) mpfr('0.0') >>> gmpy2.log10(mpfr(10)) mpfr('1.0') >>> ctx.exp(10.5) mpfr('36315.502674246636') >>> gmpy2.exp(mpfr(1)) mpfr('2.7182818284590451') Tests sqrt ---------- >>> gmpy2.sqrt(float(25)) mpfr('5.0') >>> 19.5 ** 2 380.25 >>> ctx.sqrt(mpfr(380.25)) mpfr('19.5') >>> ctx.allow_complex = True >>> ctx.sqrt(mpfr(-380.25)) mpc('0.0+19.5j') >>> ctx.allow_complex = False >>> ctx.sqrt(mpfr(-380.25)) mpfr('nan') >>> ctx.sqrt(complex(16,4)) mpc('4.0306589103067649+0.4961967868047123j') >>> ctx.sqrt(mpc(16,4)) mpc('4.0306589103067649+0.4961967868047123j') >>> gmpy2.rec_sqrt(mpfr('380.25')) mpfr('0.05128205128205128') Tests root ---------- >>> ctx.rootn(5.5) Traceback (most recent call last): File "", line 1, in TypeError: rootn() requires 2 arguments >>> ctx.rootn(mpc(4,1), 4) Traceback (most recent call last): File "", line 1, in TypeError: rootn() argument type not supported >>> ctx.rootn(mpfr(25), 4) mpfr('2.2360679774997898') >>> ctx.rootn(mpfr(25), 4.0) Traceback (most recent call last): File "", line 1, in TypeError: rootn() argument type not supported >>> ctx.root(mpfr(25)) Traceback (most recent call last): File "", line 1, in TypeError: root() requires 2 arguments Tests other binary operations ----------------------------- >>> gmpy2.jn(43.2, 5) mpfr('-0.11672089168206982') >>> gmpy2.jn(43.2, 1.2) Traceback (most recent call last): File "", line 1, in TypeError: jn() argument type not supported >>> gmpy2.yn(43.2, 5) mpfr('-0.034805474763124698') >>> gmpy2.yn(43.2, 5.5) Traceback (most recent call last): File "", line 1, in TypeError: yn() argument type not supported >>> gmpy2.agm(mpc(4,4), 5) Traceback (most recent call last): File "", line 1, in TypeError: agm() argument type not supported >>> gmpy2.fmod(mpfr(25), mpfr(2.5)) mpfr('0.0') >>> gmpy2.fmod(mpfr(25), 5.0) mpfr('0.0') >>> gmpy2.fmod(mpfr(25)) Traceback (most recent call last): File "", line 1, in TypeError: fmod() requires 2 arguments Tests round2 ------------ >>> r = mpfr(1.65656565) >>> gmpy2.round2(r, 2) mpfr('1.5',2) >>> gmpy2.round2(r, 5) mpfr('1.69',5) >>> gmpy2.round2(r) mpfr('1.6565656499999999') >>> gmpy2.round2(mpq('1/3')) mpfr('0.33333333333333331') >>> gmpy2.round2(mpq('1/3'), 30) mpfr('0.33333333349',30) >>> gmpy2.round2(r, -5) Traceback (most recent call last): File "", line 1, in ValueError: invalid precision >>> gmpy2.round2(mpc(4, 4), 5) Traceback (most recent call last): File "", line 1, in TypeError: round2() argument type not supported >>> gmpy2.round2(mpz(5), 5) mpfr('5.0',5) >>> gmpy2.round2(5, 6, 5) Traceback (most recent call last): File "", line 1, in TypeError: round2() requires 1 or 2 arguments >>> gmpy2.round2() Traceback (most recent call last): File "", line 1, in TypeError: round2() requires 1 or 2 arguments Tests reldiff ( abs(x-y)/x ) ---------------------------- >>> gmpy2.reldiff(mpfr(2.5), mpfr(17.5)) mpfr('6.0') Tests modf ---------- >>> r, r2 = mpfr('5.6'), mpfr(5.4) >>> f = 0.6 >>> gmpy2.modf(r, r2) Traceback (most recent call last): File "", line 1, in TypeError: modf() takes exactly one argument (2 given) >>> gmpy2.modf(0.8) (mpfr('0.0'), mpfr('0.80000000000000004')) >>> gmpy2.modf(r) (mpfr('5.0'), mpfr('0.59999999999999964')) >>> gmpy2.modf(-r2) (mpfr('-5.0'), mpfr('-0.40000000000000036')) Tests remquo ------------ >>> gmpy2.remquo() Traceback (most recent call last): File "", line 1, in TypeError: remquo() requires 2 arguments >>> gmpy2.remquo(r) Traceback (most recent call last): File "", line 1, in TypeError: remquo() requires 2 arguments >>> gmpy2.remquo(r, f) (mpfr('0.19999999999999984'), 9) >>> gmpy2.remquo(r, r2) (mpfr('0.19999999999999929'), 1) Tests frexp ----------- >>> gmpy2.frexp() Traceback (most recent call last): File "", line 1, in TypeError: frexp() takes exactly one argument (0 given) >>> gmpy2.frexp(r, r2) Traceback (most recent call last): File "", line 1, in TypeError: frexp() takes exactly one argument (2 given) >>> gmpy2.frexp(r) (3, mpfr('0.69999999999999996')) >>> gmpy2.frexp(r2) (3, mpfr('0.67500000000000004')) >>> gmpy2.frexp(f) (0, mpfr('0.59999999999999998')) Tests next_toward ----------------- >>> gmpy2.next_toward() Traceback (most recent call last): File "", line 1, in TypeError: next_toward() requires 2 arguments >>> gmpy2.next_toward(r) Traceback (most recent call last): File "", line 1, in TypeError: next_toward() requires 2 arguments >>> gmpy2.next_toward(r, r2) mpfr('5.5999999999999988') >>> gmpy2.next_toward(r, f) mpfr('5.5999999999999988') Tests next_above ----------------- >>> gmpy2.next_above() Traceback (most recent call last): File "", line 1, in TypeError: next_above() takes exactly one argument (0 given) >>> gmpy2.next_above(r, r2) Traceback (most recent call last): File "", line 1, in TypeError: next_above() takes exactly one argument (2 given) >>> gmpy2.next_above(r) mpfr('5.6000000000000005') >>> gmpy2.next_above(r2) mpfr('5.4000000000000012') >>> gmpy2.next_above(f) mpfr('0.60000000000000009') Tests factorial --------------- >>> gmpy2.factorial(mpz(5)) mpfr('120.0') >>> gmpy2.factorial(r) mpfr('720.0') >>> gmpy2.factorial(r2) mpfr('120.0') >>> ctx.factorial(4) mpfr('24.0') >>> gmpy2.factorial(-r) Traceback (most recent call last): File "", line 1, in ValueError: factorial() of negative number >>> gmpy2.factorial(mpc(4,5)) Traceback (most recent call last): File "", line 1, in TypeError: factorial() requires 'int' argument Tests fsum ---------- >>> gmpy2.fsum([]) mpfr('0.0') >>> gmpy2.fsum([4, 5, 6]) mpfr('15.0') >>> gmpy2.fsum(range(13)) mpfr('78.0') >>> gmpy2.fsum(r) Traceback (most recent call last): File "", line 1, in TypeError: argument must be an iterable Tests round, floor ceil and trunc --------------------------------- >>> gmpy2.rint(r) mpfr('6.0') >>> gmpy2.rint(r2) mpfr('5.0') >>> gmpy2.rint_ceil(r) mpfr('6.0') >>> gmpy2.rint_ceil(r2) mpfr('6.0') >>> gmpy2.rint_ceil(f) mpfr('1.0') >>> gmpy2.rint_floor(r) mpfr('5.0') >>> gmpy2.rint_floor(r2) mpfr('5.0') >>> gmpy2.rint_floor(f) mpfr('0.0') >>> gmpy2.rint_round(r) mpfr('6.0') >>> gmpy2.rint_round(r2) mpfr('5.0') >>> gmpy2.rint_round(f) mpfr('1.0') >>> gmpy2.rint_trunc(r) mpfr('5.0') >>> gmpy2.rint_trunc(r2) mpfr('5.0') >>> gmpy2.rint_trunc(f) mpfr('0.0') >>> gmpy2.ceil(r) mpfr('6.0') >>> gmpy2.ceil(r2) mpfr('6.0') >>> gmpy2.ceil(f) mpfr('1.0') >>> gmpy2.floor(r) mpfr('5.0') >>> gmpy2.floor(r2) mpfr('5.0') >>> gmpy2.floor(f) mpfr('0.0') >>> gmpy2.trunc(r) mpfr('5.0') >>> gmpy2.trunc(r2) mpfr('5.0') >>> gmpy2.trunc(f) mpfr('0.0') >>> gmpy2.round_away(r) mpfr('6.0') >>> gmpy2.round_away(r2) mpfr('5.0') >>> gmpy2.round_away(f) mpfr('1.0') Tests exp functions ------------------- >>> gmpy2.exp2(r) mpfr('48.502930128332729') >>> gmpy2.exp10(r) mpfr('398107.17055349692') >>> gmpy2.exp2(r2) mpfr('42.224253144732629') >>> gmpy2.exp10(r2) mpfr('251188.6431509582') >>> gmpy2.exp2(f) mpfr('1.515716566510398') >>> gmpy2.exp10(f) mpfr('3.9810717055349722') >>> gmpy2.expm1(r) mpfr('269.42640742615254') >>> gmpy2.expm1(r2) mpfr('220.40641620418717') >>> gmpy2.expm1(f) mpfr('0.82211880039050889') >>> gmpy2.eint(r) mpfr('63.101785974299247') Tests gamma functions --------------------- >>> gmpy2.gamma(r) mpfr('61.55391500628923') >>> gmpy2.lngamma(r) mpfr('4.1199134575335288') >>> gmpy2.digamma(r) mpfr('1.6308319195144647') >>> gmpy2.lgamma() Traceback (most recent call last): File "", line 1, in TypeError: lgamma() takes exactly one argument (0 given) >>> gmpy2.lgamma(r, r2) Traceback (most recent call last): File "", line 1, in TypeError: lgamma() takes exactly one argument (2 given) >>> gmpy2.lgamma(r) (mpfr('4.1199134575335288'), 1) >>> gmpy2.lgamma(mpfr('nan')) (mpfr('nan'), 1) >>> gmpy2.lgamma(mpfr('inf')) (mpfr('inf'), 1) Tests Bessel functions ---------------------- >>> gmpy2.j0(r) mpfr('0.026970884685114358') >>> gmpy2.j1(r) mpfr('-0.33433283629100752') >>> gmpy2.y0(r) mpfr('-0.33544418124531583') >>> gmpy2.y1(r) mpfr('-0.056805614399479849') Other tests ----------- >>> gmpy2.frac(r) mpfr('0.59999999999999964') >>> gmpy2.frac(r2) mpfr('0.40000000000000036') >>> gmpy2.frac(f) mpfr('0.59999999999999998') >>> gmpy2.cbrt(r) mpfr('1.7758080034852013') >>> gmpy2.cbrt(r2) mpfr('1.7544106429277198') >>> gmpy2.cbrt(f) mpfr('0.84343266530174921') >>> gmpy2.log2(r) mpfr('2.4854268271702415') >>> gmpy2.log2(r2) mpfr('2.4329594072761065') >>> gmpy2.log2(f) mpfr('-0.73696559416620622') >>> gmpy2.log1p(r) mpfr('1.8870696490323797') >>> gmpy2.log1p(r2) mpfr('1.8562979903656263') >>> gmpy2.log1p(f) mpfr('0.47000362924573552') >>> gmpy2.li2(r) mpfr('1.6186578451141254') >>> gmpy2.zeta(r) mpfr('1.02337547922703') >>> gmpy2.erf(r) mpfr('0.99999999999999767') >>> gmpy2.erfc(r) mpfr('2.382836284583028e-15') >>> gmpy2.ai(r) mpfr('2.6500613296849995e-05') >>> gmpy2.remainder(mpfr(5), mpfr(3.2)) mpfr('-1.4000000000000004') gmpy2-2.1.0b3/test/test_gmpy2_minus.txt0000664000175000017500000000101613444070732017701 0ustar casecase00000000000000Test gmpy2_minus.c ================== >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> import gmpy2 >>> from fractions import Fraction >>> ctx = gmpy2.get_context() >>> ctx.minus(mpz(5)) mpz(-5) >>> ctx.minus(mpq(4,5)) mpq(-4,5) >>> ctx.minus(mpfr(4,5)) mpfr('-4.0') >>> ctx.minus(mpfr('inf')) mpfr('-inf') >>> ctx.minus(mpc(15,3)) mpc('-15.0-3.0j') >>> ctx.minus(65) mpz(-65) >>> ctx.minus(5.5) mpfr('-5.5') >>> ctx.minus(Fraction(2,3)) mpq(-2,3) >>> ctx.minus(complex(15,3)) mpc('-15.0-3.0j') >>> - mpc(5,5) mpc('-5.0-5.0j') gmpy2-2.1.0b3/test/test_gmpy2_mpfr_misc.txt0000664000175000017500000001051613476476230020542 0ustar casecase00000000000000Test gmpy2_mpfr_misc ==================== >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> ctx = gmpy2.get_context() >>> a = mpfr('123.456') >>> r = mpfr(4.55) >>> gmpy2.f2q('a') Traceback (most recent call last): .... TypeError: f2q() argument types not supported >>> gmpy2.f2q(1,2,3,4) Traceback (most recent call last): .... TypeError: f2q() requires 1 or 2 arguments >>> gmpy2.f2q(a,0.1) mpz(123) >>> gmpy2.f2q(a,0.01) mpz(123) >>> gmpy2.f2q(a,0.001) mpq(247,2) >>> gmpy2.f2q(a,0.0001) mpq(1358,11) >>> gmpy2.f2q(a,0.00001) mpq(7037,57) >>> gmpy2.f2q(a,0.000001) mpq(15432,125) >>> gmpy2.f2q(a,0.0000001) mpq(15432,125) >>> gmpy2.f2q(a) mpq(15432,125) >>> gmpy2.free_cache() >>> gmpy2.get_emin_min() in (-4611686018427387903, -1073741823) True >>> gmpy2.get_emax_max() in (4611686018427387903, 1073741823) True >>> mprec = gmpy2.get_max_precision() >>> gmpy2.get_exp(mpfr(5.232)) 3 >>> gmpy2.get_exp(0) Traceback (most recent call last): File "", line 1, in TypeError: get_exp() requires 'mpfr' argument >>> gmpy2.get_exp(mpfr('inf')) 0 >>> gmpy2.get_exp(mpfr(0)) 0 >>> gmpy2.set_exp(r, 4) mpfr('9.0999999999999996') >>> gmpy2.set_exp(r, mpz(4)) Traceback (most recent call last): File "", line 1, in TypeError: set_exp() requires 'mpfr', 'integer' arguments >>> gmpy2.set_sign(r, False) mpfr('4.5499999999999998') >>> gmpy2.set_sign(r, True) mpfr('-4.5499999999999998') >>> gmpy2.set_sign(mpz(5), True) Traceback (most recent call last): File "", line 1, in TypeError: set_sign() requires 'mpfr', 'boolean' arguments >>> gmpy2.set_sign(r, 'oiio') Traceback (most recent call last): File "", line 1, in TypeError: set_sign() requires 'mpfr', 'boolean' arguments >>> 1 1 >>> gmpy2.copy_sign(mpfr(4), mpfr(-2)) mpfr('-4.0') >>> gmpy2.copy_sign(mpfr(4), True) Traceback (most recent call last): File "", line 1, in TypeError: copy_sign() requires 'mpfr', 'mpfr' arguments >>> 1 1 >>> nan = gmpy2.nan(); nan mpfr('nan') >>> inf = gmpy2.inf(); inf mpfr('inf') >>> gmpy2.inf(-5) mpfr('-inf') >>> gmpy2.inf(mpfr(30)) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.inf(mpz(-30)) mpfr('-inf') >>> nan.as_integer_ratio() Traceback (most recent call last): File "", line 1, in ValueError: Cannot pass NaN to mpfr.as_integer_ratio. >>> inf.as_integer_ratio() Traceback (most recent call last): File "", line 1, in OverflowError: Cannot pass Infinity to mpfr.as_integer_ratio. >>> mpfr(1.5).as_integer_ratio() (mpz(3), mpz(2)) >>> r.as_mantissa_exp() (mpz(5122844576133939), mpz(-50)) >>> inf.as_mantissa_exp() Traceback (most recent call last): File "", line 1, in OverflowError: Cannot pass Infinity to mpfr.as_mantissa_exp. >>> nan.as_mantissa_exp() Traceback (most recent call last): File "", line 1, in ValueError: Cannot pass NaN to mpfr.as_mantissa_exp. >>> mpfr(0).as_mantissa_exp() (mpz(0), mpz(1)) >>> r.as_simple_fraction() mpq(91,20) >>> r.as_simple_fraction() mpq(91,20) >>> r.as_simple_fraction(precision=100) Traceback (most recent call last): File "", line 1, in ValueError: Requested precision out-of-bounds. >>> r.as_simple_fraction(nosense=10) Traceback (most recent call last): File "", line 1, in TypeError: 'nosense' is an invalid keyword argument for this function >>> 1 1 >>> r.imag mpfr('0.0') >>> r.real mpfr('4.5499999999999998') >>> not mpfr(0) True >>> not mpfr(1) False >>> r.conjugate() mpfr('4.5499999999999998') >>> gmpy2.check_range(r) mpfr('4.5499999999999998') >>> ctx = gmpy2.get_context() >>> ctx.check_range(r) mpfr('4.5499999999999998') >>> ctx.check_range(mpz(5)) Traceback (most recent call last): File "", line 1, in TypeError: check_range() argument types not supported >>> 1 1 >>> r.__round__(1) mpfr('4.5') >>> mpfr('5.1').__round__() mpz(5) >>> nan.__round__() Traceback (most recent call last): File "", line 1, in ValueError: 'mpz' does not support NaN >>> inf.__round__() Traceback (most recent call last): File "", line 1, in OverflowError: 'mpz' does not support Infinity >>> r.__round__(4,5) Traceback (most recent call last): File "", line 1, in TypeError: __round__() requires 0 or 1 argument >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_mpq_misc.txt0000664000175000017500000000365613476476303020403 0ustar casecase00000000000000Test file gmpy2_mpq_misc.c ========================== >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from fractions import Fraction Tests numer and denom --------------------- >>> q = mpq('4/5') >>> pyq = Fraction(4, 5) >>> q.numerator mpz(4) >>> q.denominator mpz(5) >>> gmpy2.numer(q) mpz(4) >>> gmpy2.denom(q) mpz(5) >>> gmpy2.numer(6.2) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpq >>> gmpy2.denom(5.6) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpq >>> gmpy2.denom(mpfr(5)) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpq >>> gmpy2.numer(pyq) mpz(4) >>> gmpy2.denom(pyq) mpz(5) Tests qdiv ---------- >>> gmpy2.qdiv(q) mpq(4,5) >>> gmpy2.qdiv(pyq) mpq(4,5) >>> gmpy2.qdiv(5) mpz(5) >>> gmpy2.qdiv(mpc(4, 5)) Traceback (most recent call last): File "", line 1, in TypeError: qdiv() requires 1 or 2 integer or rational arguments >>> gmpy2.qdiv(4, 5, 4) Traceback (most recent call last): File "", line 1, in TypeError: qdiv() requires 1 or 2 integer or rational arguments >>> gmpy2.qdiv(4, 5.6) Traceback (most recent call last): File "", line 1, in TypeError: qdiv() requires 1 or 2 integer or rational arguments >>> gmpy2.qdiv(q, 2) mpq(2,5) >>> gmpy2.qdiv(10, q) mpq(25,2) >>> gmpy2.qdiv(1) mpz(1) Tests rational floor, ceil, trunc --------------------------------- >>> mpq('7/2').__trunc__() mpz(3) >>> mpq('7/2').__ceil__() mpz(4) >>> mpq('7/2').__floor__() mpz(3) Tests round ----------- >>> mpq('7/2').__round__() mpz(4) >>> q.__round__(4) mpq(4,5) >>> q.__round__(4, 2) Traceback (most recent call last): File "", line 1, in TypeError: Too many arguments for __round__() Tests non zero operator ----------------------- >>> not q False >>> not mpq('0/5') True gmpy2-2.1.0b3/test/test_gmpy2_mpq_misc_py2.txt0000664000175000017500000000021413444603111021140 0ustar casecase00000000000000Test file gmpy2_mpq_misc.c python2 ================================== >>> import gmpy2 >>> gmpy2.mpq(7,3).__round__(4.5) mpq(23333,10000) gmpy2-2.1.0b3/test/test_gmpy2_mpq_misc_py3.txt0000664000175000017500000000037313452507557021167 0ustar casecase00000000000000Test file gmpy2_mpq_misc.c python3 ================================== >>> import gmpy2 >>> gmpy2.mpq(7,3).__round__(4.5) Traceback (most recent call last): File "", line 1, in TypeError: __round__() requires 'int' argument >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_mpz_bitops.txt0000664000175000017500000001725213452637300020744 0ustar casecase00000000000000Tests for gmpy2_mpz_bitops ========================== >>> from gmpy2 import mpz, mpq, mpfr >>> import gmpy2 Test bit_length --------------- >>> mpz(0).bit_length() 0 >>> mpz(1).bit_length() 1 >>> mpz(5).bit_length() 3 >>> mpz(8).bit_length() 4 >>> gmpy2.bit_length(mpz(10**30)) 100 >>> gmpy2.bit_length(56) 6 >>> gmpy2.bit_length(mpfr(4.0)) Traceback (most recent call last): File "", line 1, in TypeError: bit_length() requires 'mpz' argument >>> 1 1 Test bit_mask ------------- >>> gmpy2.bit_mask(mpz(0)) mpz(0) >>> gmpy2.bit_mask(mpz(4)) mpz(15) >>> gmpy2.bit_mask(mpz(3)) mpz(7) >>> gmpy2.bit_mask(mpz(16)) mpz(65535) >>> gmpy2.bit_mask(8) mpz(255) >>> gmpy2.bit_mask(-1) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test bit_scan0 -------------- >>> mpz(6).bit_scan0() 0 >>> mpz(7).bit_scan0() 3 >>> mpz(8).bit_scan0(2) 2 >>> mpz(7).bit_scan0(2) 3 >>> mpz(7).bit_scan0(-2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.bit_scan0(mpz(7), 2) 3 >>> gmpy2.bit_scan0(mpz(8), 2) 2 >>> gmpy2.bit_scan0(8) 0 >>> gmpy2.bit_scan0() Traceback (most recent call last): File "", line 1, in TypeError: bit_scan0() requires 'mpz',['int'] arguments >>> gmpy2.bit_scan0(mpz(7), 2.5) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.bit_scan0(mpz(7), 2, 5) Traceback (most recent call last): File "", line 1, in TypeError: bit_scan0() requires 'mpz',['int'] arguments >>> gmpy2.bit_scan0(7.5, 0) Traceback (most recent call last): File "", line 1, in TypeError: bit_scan0() requires 'mpz',['int'] arguments >>> gmpy2.bit_scan0(8, -2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test bit_scan1 -------------- >>> mpz(7).bit_scan1() 0 >>> mpz(8).bit_scan1() 3 >>> mpz(7).bit_scan1(2) 2 >>> mpz(7).bit_scan1(-2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.bit_scan1(7) 0 >>> gmpy2.bit_scan1(8) 3 >>> gmpy2.bit_scan1(7, 2) 2 >>> gmpy2.bit_scan1(mpz(7), 2, 5) Traceback (most recent call last): File "", line 1, in TypeError: bit_scan1() requires 'mpz',['int'] arguments >>> gmpy2.bit_scan1() Traceback (most recent call last): File "", line 1, in TypeError: bit_scan1() requires 'mpz',['int'] arguments >>> gmpy2.bit_scan1(mpz(6), 2.5) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.bit_scan1(7.5, 0) Traceback (most recent call last): File "", line 1, in TypeError: bit_scan1() requires 'mpz',['int'] arguments >>> gmpy2.bit_scan1(8, -1) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test bit_test ------------- >>> mpz(7).bit_test(2) True >>> mpz(8).bit_test(2) False >>> mpz(-8).bit_test(2) False >>> mpz(8).bit_test(-2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.bit_test(mpz(7), 2) True >>> gmpy2.bit_test(mpz(8), 2) False >>> gmpy2.bit_test() Traceback (most recent call last): File "", line 1, in TypeError: bit_test() requires 'mpz','int' arguments >>> gmpy2.bit_test(mpz(7), 2.5) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.bit_test(7.5, 2) Traceback (most recent call last): File "", line 1, in TypeError: bit_test() requires 'mpz','int' arguments >>> gmpy2.bit_test(8, -2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test bit_clear -------------- >>> mpz(7).bit_clear(0) mpz(6) >>> mpz(7).bit_clear(2) mpz(3) >>> mpz(8).bit_clear(2) mpz(8) >>> mpz(8).bit_clear(-1) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.bit_clear(4, 2) mpz(0) >>> gmpy2.bit_clear() Traceback (most recent call last): File "", line 1, in TypeError: bit_clear() requires 'mpz','int' arguments >>> gmpy2.bit_clear(7.2, 2) Traceback (most recent call last): File "", line 1, in TypeError: bit_clear() requires 'mpz','int' arguments >>> gmpy2.bit_clear(mpz(4), 2.5) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.bit_clear(4, -2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test bit_set ------------ >>> mpz(4).bit_set(0) mpz(5) >>> mpz(7).bit_set(3) mpz(15) >>> mpz(0).bit_set(2) mpz(4) >>> mpz(0).bit_set(-2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.bit_set(8, 1) mpz(10) >>> gmpy2.bit_set(0) Traceback (most recent call last): File "", line 1, in TypeError: bit_set() requires 'mpz','int' arguments >>> gmpy2.bit_set() Traceback (most recent call last): File "", line 1, in TypeError: bit_set() requires 'mpz','int' arguments >>> gmpy2.bit_set(8.5, 1) Traceback (most recent call last): File "", line 1, in TypeError: bit_set() requires 'mpz','int' arguments >>> gmpy2.bit_set(8, 1.5) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.bit_set(8, -1) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test bit_flip ------------- >>> mpz(4).bit_flip(2) mpz(0) >>> mpz(4).bit_flip(1) mpz(6) >>> mpz(0).bit_flip(3) mpz(8) >>> mpz(5).bit_flip(-3) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.bit_flip(mpz(7), mpz(1)) mpz(5) >>> gmpy2.bit_flip(mpz(7), 2) mpz(3) >>> gmpy2.bit_flip() Traceback (most recent call last): File "", line 1, in TypeError: bit_flip() requires 'mpz','int' arguments >>> gmpy2.bit_flip(4.5, 2) Traceback (most recent call last): File "", line 1, in TypeError: bit_flip() requires 'mpz','int' arguments >>> gmpy2.bit_flip(4, 2.5) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.bit_flip(mpz(7), -2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test and operator ----------------- >>> mpz(0) and mpz(7) mpz(0) >>> mpz(7) and mpz(0) mpz(0) >>> mpz(7) and mpz(5) mpz(5) >>> mpz(0) and 5 mpz(0) >>> mpz(7) and 5.2 5.2 >>> mpz(7) and None Test popcount ------------- >>> gmpy2.popcount(-65) == -1 True >>> gmpy2.popcount(7) 3 >>> gmpy2.popcount(8) 1 >>> gmpy2.popcount(15) 4 >>> gmpy2.popcount(mpz(0)) 0 >>> gmpy2.popcount(4.5) Traceback (most recent call last): File "", line 1, in TypeError: popcount() requires 'mpz' argument >>> 1 1 Test hamdist ------------ >>> gmpy2.hamdist(mpz(5), mpz(7)) 1 >>> gmpy2.hamdist(mpz(0), mpz(7)) 3 >>> gmpy2.hamdist(mpz(0), 7) 3 >>> gmpy2.hamdist(mpq(14,2), 5) Traceback (most recent call last): File "", line 1, in TypeError: hamdist() requires 'mpz','mpz' arguments >>> gmpy2.hamdist(5,6,5) Traceback (most recent call last): File "", line 1, in TypeError: hamdist() requires 'mpz','mpz' arguments >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_mpz_divmod.txt0000664000175000017500000000713513170047220020716 0ustar casecase00000000000000Test gmpy2_mpz_divmod.c ===================== >>> import gmpy2 >>> from gmpy2 import mpz >>> a = mpz(123) >>> b = mpz(456) Test c_divmod ------------- >>> gmpy2.c_divmod(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_divmod(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.c_divmod(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.c_divmod(b,a) (mpz(4), mpz(-36)) >>> gmpy2.c_divmod(b,-a) (mpz(-3), mpz(87)) >>> gmpy2.c_divmod(-b,a) (mpz(-3), mpz(-87)) >>> gmpy2.c_divmod(-b,-a) (mpz(4), mpz(36)) Test c_div ---------- >>> gmpy2.c_div(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_div(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.c_div(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.c_div(b,a) mpz(4) >>> gmpy2.c_div(b,-a) mpz(-3) >>> gmpy2.c_div(-b,a) mpz(-3) >>> gmpy2.c_div(-b,-a) mpz(4) Test c_mod ---------- >>> gmpy2.c_mod(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_mod(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.c_mod(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.c_mod(b,a) mpz(-36) >>> gmpy2.c_mod(b,-a) mpz(87) >>> gmpy2.c_mod(-b,a) mpz(-87) >>> gmpy2.c_mod(-b,-a) mpz(36) Test f_divmod ------------- >>> gmpy2.f_divmod(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_divmod(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.f_divmod(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.f_divmod(b,a) (mpz(3), mpz(87)) >>> gmpy2.f_divmod(b,-a) (mpz(-4), mpz(-36)) >>> gmpy2.f_divmod(-b,a) (mpz(-4), mpz(36)) >>> gmpy2.f_divmod(-b,-a) (mpz(3), mpz(-87)) Test f_div ---------- >>> gmpy2.f_div(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_div(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.f_div(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.f_div(b,a) mpz(3) >>> gmpy2.f_div(b,-a) mpz(-4) >>> gmpy2.f_div(-b,a) mpz(-4) >>> gmpy2.f_div(-b,-a) mpz(3) Test f_mod ---------- >>> gmpy2.f_mod(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_mod(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.f_mod(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.f_mod(b,a) mpz(87) >>> gmpy2.f_mod(b,-a) mpz(-36) >>> gmpy2.f_mod(-b,a) mpz(36) >>> gmpy2.f_mod(-b,-a) mpz(-87) Test t_divmod ------------- >>> gmpy2.t_divmod(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_divmod(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.t_divmod(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.t_divmod(b,a) (mpz(3), mpz(87)) >>> gmpy2.t_divmod(b,-a) (mpz(-3), mpz(87)) >>> gmpy2.t_divmod(-b,a) (mpz(-3), mpz(-87)) >>> gmpy2.t_divmod(-b,-a) (mpz(3), mpz(-87)) Test t_div ---------- >>> gmpy2.t_div(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_div(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.t_div(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.t_div(b,a) mpz(3) >>> gmpy2.t_div(b,-a) mpz(-3) >>> gmpy2.t_div(-b,a) mpz(-3) >>> gmpy2.t_div(-b,-a) mpz(3) Test t_mod ---------- >>> gmpy2.t_mod(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_mod(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.t_mod(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.t_mod(b,a) mpz(87) >>> gmpy2.t_mod(b,-a) mpz(87) >>> gmpy2.t_mod(-b,a) mpz(-87) >>> gmpy2.t_mod(-b,-a) mpz(-87) gmpy2-2.1.0b3/test/test_gmpy2_mpz_divmod2exp.txt0000664000175000017500000001056513170047220021516 0ustar casecase00000000000000Test gmpy2_mpz_divmod.c ===================== >>> import gmpy2 >>> from gmpy2 import mpz >>> a = mpz(123456) Test c_divmod_2exp ------------------ >>> gmpy2.c_divmod_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_divmod_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.c_divmod_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_divmod_2exp(a,-16) Traceback (most recent call last): ... ValueError: >>> gmpy2.c_divmod_2exp(a,0) (mpz(123456), mpz(0)) >>> gmpy2.c_divmod_2exp(a,16) (mpz(2), mpz(-7616)) >>> gmpy2.c_divmod_2exp(-a,16) (mpz(-1), mpz(-57920)) Test c_div_2exp --------------- >>> gmpy2.c_div_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_div_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.c_div_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_div_2exp(a, -16) Traceback (most recent call last): ... ValueError: >>> gmpy2.c_div_2exp(a,0) mpz(123456) >>> gmpy2.c_div_2exp(a,16) mpz(2) >>> gmpy2.c_div_2exp(-a,16) mpz(-1) Test c_mod_2exp --------------- >>> gmpy2.c_mod_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_mod_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.c_mod_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.c_mod_2exp(a, -16) Traceback (most recent call last): ... ValueError: >>> gmpy2.c_mod_2exp(a,0) mpz(0) >>> gmpy2.c_mod_2exp(a,16) mpz(-7616) >>> gmpy2.c_mod_2exp(-a,16) mpz(-57920) Test f_divmod_2exp ------------------ >>> gmpy2.f_divmod_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_divmod_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.f_divmod_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_divmod_2exp(a,-16) Traceback (most recent call last): ... ValueError: >>> gmpy2.f_divmod_2exp(a,0) (mpz(123456), mpz(0)) >>> gmpy2.f_divmod_2exp(a,16) (mpz(1), mpz(57920)) >>> gmpy2.f_divmod_2exp(-a,16) (mpz(-2), mpz(7616)) Test f_div_2exp --------------- >>> gmpy2.f_div_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_div_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.f_div_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_div_2exp(a, -16) Traceback (most recent call last): ... ValueError: >>> gmpy2.f_div_2exp(a,0) mpz(123456) >>> gmpy2.f_div_2exp(a,16) mpz(1) >>> gmpy2.f_div_2exp(-a,16) mpz(-2) Test f_mod_2exp --------------- >>> gmpy2.f_mod_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_mod_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.f_mod_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.f_mod_2exp(a, -16) Traceback (most recent call last): ... ValueError: >>> gmpy2.f_mod_2exp(a,0) mpz(0) >>> gmpy2.f_mod_2exp(a,16) mpz(57920) >>> gmpy2.f_mod_2exp(-a,16) mpz(7616) Test t_divmod_2exp ------------------ >>> gmpy2.t_divmod_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_divmod_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.t_divmod_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_divmod_2exp(a,-16) Traceback (most recent call last): ... ValueError: >>> gmpy2.t_divmod_2exp(a,0) (mpz(123456), mpz(0)) >>> gmpy2.t_divmod_2exp(a,16) (mpz(1), mpz(57920)) >>> gmpy2.t_divmod_2exp(-a,16) (mpz(-1), mpz(-57920)) Test t_div_2exp --------------- >>> gmpy2.t_div_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_div_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.t_div_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_div_2exp(a, -16) Traceback (most recent call last): ... ValueError: >>> gmpy2.t_div_2exp(a,0) mpz(123456) >>> gmpy2.t_div_2exp(a,16) mpz(1) >>> gmpy2.t_div_2exp(-a,16) mpz(-1) Test t_mod_2exp --------------- >>> gmpy2.t_mod_2exp(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_mod_2exp(1, 'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.t_mod_2exp('a', 16) Traceback (most recent call last): ... TypeError: >>> gmpy2.t_mod_2exp(a, -16) Traceback (most recent call last): ... ValueError: >>> gmpy2.t_mod_2exp(a,0) mpz(0) >>> gmpy2.t_mod_2exp(a,16) mpz(57920) >>> gmpy2.t_mod_2exp(-a,16) mpz(-57920) gmpy2-2.1.0b3/test/test_gmpy2_mpz_inplace.txt0000664000175000017500000000737513452635476021100 0ustar casecase00000000000000Tests for gmpy2_mpz_inplace functions ====================================== >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpfr Test iadd operator ------------------ >>> x = mpz(5) >>> x += mpz(6); x mpz(11) >>> x += 7; x mpz(18) >>> x += -6; x mpz(12) >>> x += 0; x mpz(12) >>> x += mpfr(2.5); x mpfr('14.5') Test isub operator ------------------ >>> x = mpz(7) >>> x -= mpz(1); x mpz(6) >>> x -= 1; x mpz(5) >>> x -= xmpz(7); x mpz(-2) >>> x -= -5; x mpz(3) >>> x -= -mpfr(5); x mpfr('8.0') Test imul operator ------------------ >>> x = mpz(2) >>> x *= mpz(2); x mpz(4) >>> x *= 2; x mpz(8) >>> x *= xmpz(3); x mpz(24) >>> x *= -1; x mpz(-24) >>> x *= mpfr(-0.5); x mpfr('12.0') Test ifloordiv operator ----------------------- >>> x = mpz(49) >>> x //= mpz(3); x mpz(16) >>> x //= xmpz(3); x mpz(5) >>> x //= 2; x mpz(2) >>> x //= mpz(0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: mpz division by zero >>> x //= 0; Traceback (most recent call last): File "", line 1, in ZeroDivisionError: mpz division by zero >>> x mpz(2) >>> x //= mpfr(-0.5); x mpfr('-4.0') >>> x = mpz(11) >>> x //= -5; x mpz(-3) Test imod operator ------------------ >>> x = mpz(45) >>> x %= mpz(18); x mpz(9) >>> x %= xmpz(2); x mpz(1) >>> x = mpz(40) >>> x %= 21; x mpz(19) >>> x %= 0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: mpz modulo by zero >>> x mpz(19) >>> x %= mpz(0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: mpz modulo by zero >>> x %= -9; x mpz(-8) >>> x %= mpfr(10); x mpfr('2.0') Test irshift and ilshift operators ---------------------------------- >>> x = mpz(63) >>> x >>= mpz(63); x mpz(0) >>> x = mpz(63) >>> x >>= mpz(1); x mpz(31) >>> x >>= xmpz(2); x mpz(7) >>> x >>= 1; x mpz(3) >>> x <<= mpz(2); x mpz(12) >>> x <<= mpz(1); x mpz(24) >>> x <<= 0; x mpz(24) >>> x >>= mpfr(2) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> x <<= mpfr(2) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> x >>= -1 Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> x <<= -5 Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test ipow operator ------------------ >>> x = mpz(5) >>> x **= mpz(2); x mpz(25) >>> x **= xmpz(2); x mpz(625) >>> x **= -2 Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for ** or pow(): 'mpz' and 'int' >>> x **= 2; x mpz(390625) >>> x **= mpfr(2) Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for ** or pow(): 'mpz' and 'mpfr' >>> 1 1 Test iand operator ------------------ >>> x = mpz(7) >>> x &= mpz(5); x mpz(5) >>> x &= xmpz(4); x mpz(4) >>> x &= 9; x mpz(0) >>> x = mpz(4) >>> x &= 12; x mpz(4) >>> x &= mpfr(4) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpz >>> 1 1 Test ior operator ----------------- >>> x = mpz(0) >>> x |= mpz(1) >>> x mpz(1) >>> x |= mpz(0) >>> x mpz(1) >>> x = mpz(0) >>> x |= mpz(0); x mpz(0) >>> x |= 5; x mpz(5) >>> x |= mpfr(3) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpz >>> 1 1 Test ixor operator ------------------ >>> x = mpz(1) >>> x ^= mpz(0); x mpz(1) >>> x ^= xmpz(1); x mpz(0) >>> x ^= 1; x mpz(1) >>> x ^= mpfr(0) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpz >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_mpz_misc.txt0000664000175000017500000003207313476476341020411 0ustar casecase00000000000000Test gmpy2_mpz_misc.c ===================== >>> import gmpy2 >>> from gmpy2 import mpz >>> import math >>> a = mpz(123) >>> b = mpz(456) Test num_digits --------------- >>> mpz(123456).num_digits() 6 >>> mpz(123456).num_digits(2) 17 >>> mpz(123456).num_digits(-1) Traceback (most recent call last): ... ValueError: >>> mpz(123456).num_digits(9999999999999999999999999999999999) Traceback (most recent call last): ... OverflowError: >>> mpz(123456).num_digits(100) Traceback (most recent call last): ... ValueError: >>> gmpy2.num_digits(123456,-1,7) Traceback (most recent call last): ... TypeError: >>> gmpy2.num_digits(123456,-1) Traceback (most recent call last): ... ValueError: >>> gmpy2.num_digits('123456') Traceback (most recent call last): ... TypeError: >>> gmpy2.num_digits(123456,100) Traceback (most recent call last): ... ValueError: >>> gmpy2.num_digits(123456,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.num_digits(123456) 6 >>> gmpy2.num_digits(123456,2) 17 Test round (__round__) ---------------------- >>> round(mpz(123456),'a') Traceback (most recent call last): ... TypeError: >>> round(mpz(123456),'a',4) Traceback (most recent call last): ... TypeError: Test bool --------- >>> bool(mpz(100)) True >>> bool(mpz(0)) False >>> bool(mpz(-100)) True Test gcd -------- >>> gmpy2.gcd(1,2,3) Traceback (most recent call last): ... TypeError: >>> gmpy2.gcd(1,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.gcd(123,456) mpz(3) >>> gmpy2.gcd(a,b) mpz(3) Test lcm -------- >>> gmpy2.lcm(1,2,3) Traceback (most recent call last): ... TypeError: >>> gmpy2.lcm(1,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.lcm(a,b) mpz(18696) >>> gmpy2.lcm(123,456) mpz(18696) Test gcdext ----------- >>> gmpy2.gcdext(1,2,3) Traceback (most recent call last): ... TypeError: >>> gmpy2.gcdext(1,'a') Traceback (most recent call last): ... TypeError: >>> temp=gmpy2.gcdext(a,b) >>> temp[0]==a*temp[1]+b*temp[2] True >>> temp=gmpy2.gcdext(123,456) >>> temp[0]==a*temp[1]+b*temp[2] True >>> del temp Test divm --------- >>> gmpy2.divm(b,a,20) mpz(12) >>> gmpy2.divm(a,b,100,5) Traceback (innermost last): ... TypeError: >>> gmpy2.divm(a,b,'a') Traceback (innermost last): ... TypeError: >>> gmpy2.divm(a,b,100) Traceback (innermost last): ... ZeroDivisionError: >>> gmpy2.divm(6,12,14) mpz(4) >>> gmpy2.divm(0,1,2) mpz(0) >>> gmpy2.divm(4,8,20) mpz(3) Test fac -------- >>> gmpy2.fac(-7) Traceback (most recent call last): ... ValueError: >>> gmpy2.fac('a') Traceback (most recent call last): ... TypeError: >>> gmpy2.fac(7) mpz(5040) Test double_fac --------------- >>> gmpy2.double_fac(-7) Traceback (most recent call last): ... ValueError: >>> gmpy2.double_fac('a') Traceback (most recent call last): ... TypeError: >>> gmpy2.double_fac(7) mpz(105) >>> gmpy2.double_fac(7) * gmpy2.double_fac(8) mpz(40320) >>> gmpy2.fac(8) mpz(40320) Test primorial -------------- >>> gmpy2.primorial(-7) Traceback (most recent call last): ... ValueError: >>> gmpy2.primorial('a') Traceback (most recent call last): ... TypeError: >>> gmpy2.primorial(7) mpz(210) Test multi_fac -------------- >>> gmpy2.multi_fac(-7) Traceback (most recent call last): ... TypeError: >>> gmpy2.multi_fac(7,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.multi_fac(7,-1) Traceback (most recent call last): ... ValueError: >>> gmpy2.multi_fac(-7,1) Traceback (most recent call last): ... ValueError: >>> gmpy2.multi_fac('a') Traceback (most recent call last): ... TypeError: >>> gmpy2.multi_fac(10) Traceback (most recent call last): ... TypeError: >>> gmpy2.multi_fac(10,11,12) Traceback (most recent call last): ... TypeError: >>> gmpy2.multi_fac(17,4) mpz(9945) Test fib -------- >>> gmpy2.fib(-2) Traceback (most recent call last): ... ValueError: >>> gmpy2.fib(17) mpz(1597) Test fib2 --------- >>> gmpy2.fib2(-2) Traceback (most recent call last): ... ValueError: >>> gmpy2.fib2(17) (mpz(1597), mpz(987)) Test lucas ---------- >>> gmpy2.lucas(-2) Traceback (most recent call last): ... ValueError: >>> gmpy2.lucas(17) mpz(3571) Test lucas2 ----------- >>> gmpy2.lucas2(-2) Traceback (most recent call last): ... ValueError: >>> gmpy2.lucas2(17) (mpz(3571), mpz(2207)) Test bincoef ------------ >>> gmpy2.bincoef(1) Traceback (most recent call last): ... TypeError: >>> gmpy2.bincoef(1,2,3) Traceback (most recent call last): ... TypeError: >>> for i in range(10): ... print(gmpy2.bincoef(10,i)) ... 1 10 45 120 210 252 210 120 45 10 Test comb --------- >>> gmpy2.comb(3,-1) Traceback (most recent call last): ... ValueError: >>> gmpy2.comb('a',4) Traceback (most recent call last): ... TypeError: >>> gmpy2.comb(8,4) mpz(70) Test isqrt ---------- >>> print(gmpy2.isqrt(a)) 11 >>> print(gmpy2.isqrt(123)) 11 >>> gmpy2.isqrt(-1) Traceback (most recent call last): ... ValueError: >>> gmpy2.isqrt(mpz(-1)) Traceback (most recent call last): ... ValueError: >>> gmpy2.isqrt('a') Traceback (most recent call last): ... TypeError: Test isqrt_rem -------------- >>> print(gmpy2.isqrt_rem(a)) (mpz(11), mpz(2)) >>> print(gmpy2.isqrt_rem(b)) (mpz(21), mpz(15)) >>> gmpy2.isqrt_rem(-1) Traceback (most recent call last): ... ValueError: >>> gmpy2.isqrt_rem(mpz(-1)) Traceback (most recent call last): ... ValueError: >>> gmpy2.isqrt_rem('a') Traceback (most recent call last): ... TypeError: >>> gmpy2.isqrt_rem(mpz(-1)) Traceback (most recent call last): ... ValueError: Test remove ----------- >>> gmpy2.remove(a,2) (mpz(123), 0) >>> gmpy2.remove(a,mpz(2)) (mpz(123), 0) >>> gmpy2.remove(a,3) (mpz(41), 1) >>> gmpy2.remove(b,2) (mpz(57), 3) >>> gmpy2.remove(b,3) (mpz(152), 1) >>> gmpy2.remove(b,1) Traceback (most recent call last): ... ValueError: >>> gmpy2.remove(b,mpz(1)) Traceback (most recent call last): ... ValueError: >>> gmpy2.remove(b,0) Traceback (most recent call last): ... ValueError: >>> gmpy2.remove(b,789) (mpz(456), 0) >>> gmpy2.remove(b,-3) Traceback (most recent call last): File "", line 1, in ValueError: >>> gmpy2.remove(b,float('NaN')) Traceback (most recent call last): File "", line 1, in TypeError: >>> gmpy2.remove(3,-1) Traceback (most recent call last): ... ValueError: >>> gmpy2.remove(3) Traceback (innermost last): ... TypeError: >>> gmpy2.remove() Traceback (innermost last): ... TypeError: Test invert ----------- >>> gmpy2.invert(a,100) mpz(87) >>> gmpy2.invert(a,mpz(100)) mpz(87) >>> gmpy2.invert(b,mpz(100)) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.invert(b,mpz(0)) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.invert(3) Traceback (innermost last): ... TypeError: >>> gmpy2.invert() Traceback (innermost last): ... TypeError: >>> gmpy2.invert(456,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.invert(456,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.invert(456,100) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.invert(123,100) mpz(87) Test divexact ------------- >>> gmpy2.divexact(2) Traceback (innermost last): ... TypeError: >>> gmpy2.divexact(2, 'a') Traceback (innermost last): ... TypeError: >>> gmpy2.divexact(a,0) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.divexact(a,mpz(0)) Traceback (most recent call last): ... ZeroDivisionError: >>> gmpy2.divexact(123,0) Traceback (most recent call last): ... ZeroDivisionError: >>> aa=gmpy2.mpz('1234567912345678912345679') >>> bb=gmpy2.mpz('789789789789789789789789') >>> cc=aa*bb >>> print(gmpy2.divexact(cc,aa)) 789789789789789789789789 >>> aa=1234567912345678912345679 >>> bb=789789789789789789789789 >>> cc=aa*bb >>> print(gmpy2.divexact(cc,aa)) 789789789789789789789789 >>> del aa,bb,cc Test is_square -------------- >>> gmpy2.is_square('a') Traceback (innermost last): ... TypeError: >>> gmpy2.is_square(mpz(9)) True >>> gmpy2.is_square(10) False >>> mpz(16).is_square() True >>> mpz(17).is_square() False Test is_divisible ----------------- >>> gmpy2.is_divisible() Traceback (innermost last): ... TypeError: >>> gmpy2.is_divisible('a',2) Traceback (innermost last): ... TypeError: >>> gmpy2.is_divisible(2,'a') Traceback (innermost last): ... TypeError: >>> gmpy2.is_divisible(12,2) True >>> gmpy2.is_divisible(12,7) False >>> mpz(12).is_divisible(2) True >>> mpz(12).is_divisible(7) False >>> gmpy2.is_divisible(mpz(123456789123456789123456789),123456789123456789123456789) True >>> gmpy2.is_divisible(mpz(1234567891234567891234567897),123456789123456789123456789) False >>> mpz(12).is_divisible('a') Traceback (innermost last): ... TypeError: >>> mpz(123456789123456789123456789).is_divisible(123456789123456789123456789) True >>> mpz(1234567891234567891234567897).is_divisible(123456789123456789123456789) False Test is_congruent ----------------- >>> gmpy2.is_congruent(1) Traceback (innermost last): ... TypeError: >>> gmpy2.is_congruent(1,'a',3) Traceback (innermost last): ... TypeError: >>> gmpy2.is_congruent(7*3+2, 7*11+2, 7) True >>> gmpy2.is_congruent(7*3+2, 7*11+5, 7) False >>> mpz(7*3+2).is_congruent(1) Traceback (innermost last): ... TypeError: >>> mpz(7*3+2).is_congruent('a',7) Traceback (innermost last): ... TypeError: >>> mpz(7*3+2).is_congruent(7*11+2,7) True >>> mpz(7*3+2).is_congruent(7*11+5,7) False Test is_power ------------- >>> gmpy2.is_power() Traceback (most recent call last): ... TypeError: >>> gmpy2.is_power('a') Traceback (most recent call last): ... TypeError: >>> a.is_power() False >>> mpz(123**11).is_power() True >>> gmpy2.is_power(a) False >>> gmpy2.is_power(99*99*99) True >>> gmpy2.is_power(99*98) False Test is_prime ------------- >>> gmpy2.is_prime(3,-3) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_prime() Traceback (most recent call last): ... TypeError: >>> gmpy2.is_prime(1,2,3) Traceback (most recent call last): ... TypeError: >>> gmpy2.is_prime('a') Traceback (most recent call last): ... TypeError: >>> gmpy2.is_prime(12345) False >>> gmpy2.is_prime(80**81 + 81**80) True >>> gmpy2.is_prime(80**81 + 81**80, 10000) True >>> mpz(129).is_prime(1,2) Traceback (most recent call last): ... TypeError: >>> mpz(129).is_prime(-7) Traceback (most recent call last): ... ValueError: >>> mpz(129).is_prime(10000) False >>> mpz(80**81 + 81**80).is_prime() True >>> mpz(1234567890).is_prime() False Test next_prime --------------- >>> gmpy2.next_prime('a') Traceback (most recent call last): ... TypeError: >>> gmpy2.next_prime(mpz(2)) mpz(3) >>> gmpy2.next_prime(2) mpz(3) >>> gmpy2.next_prime(2357*7069-1) == 2357*7069 False Test iroot ---------- >>> gmpy2.iroot(1,2,3) Traceback (innermost last): ... TypeError: >>> gmpy2.iroot(-9,2) Traceback (innermost last): ... ValueError: >>> gmpy2.iroot(9,0) Traceback (innermost last): ... ValueError: >>> for i in range(5): ... print(gmpy2.iroot(a,i+1),gmpy2.iroot(b,i+1)) ... (mpz(123), True) (mpz(456), True) (mpz(11), False) (mpz(21), False) (mpz(4), False) (mpz(7), False) (mpz(3), False) (mpz(4), False) (mpz(2), False) (mpz(3), False) >>> gmpy2.iroot(9,2) (mpz(3), True) Test iroot_rem -------------- >>> gmpy2.iroot_rem(1,2,3) Traceback (innermost last): ... TypeError: >>> gmpy2.iroot_rem(-9,2) Traceback (innermost last): ... ValueError: >>> gmpy2.iroot_rem(9,0) Traceback (innermost last): ... ValueError: >>> gmpy2.iroot_rem(a,2) (mpz(11), mpz(2)) >>> gmpy2.iroot_rem(a,3) (mpz(4), mpz(59)) >>> gmpy2.iroot_rem(a*a,2) (mpz(123), mpz(0)) Test is_even ------------ >>> gmpy2.is_even('a') Traceback (innermost last): ... TypeError: >>> gmpy2.is_even(a) False >>> gmpy2.is_even(b) True >>> a.is_even() False >>> b.is_even() True >>> gmpy2.is_even(11) False >>> gmpy2.is_even(14) True Test is_odd ----------- >>> gmpy2.is_odd('a') Traceback (innermost last): ... TypeError: >>> gmpy2.is_odd(a) True >>> gmpy2.is_odd(b) False >>> a.is_odd() True >>> b.is_odd() False >>> gmpy2.is_odd(11) True >>> gmpy2.is_odd(14) False Test jacobi ----------- >>> gmpy2.jacobi('a', 10) Traceback (innermost last): ... TypeError: >>> gmpy2.jacobi(10,-3) Traceback (most recent call last): ... ValueError: >>> gmpy2.jacobi(3) Traceback (innermost last): ... TypeError: >>> gmpy2.jacobi() Traceback (innermost last): ... TypeError: >>> gmpy2.jacobi(10,3) 1 Test kronecker -------------- >>> gmpy2.kronecker('a', 10) Traceback (innermost last): ... TypeError: >>> gmpy2.kronecker(10,3) 1 >>> gmpy2.kronecker(10,-3) 1 >>> gmpy2.kronecker(3) Traceback (innermost last): ... TypeError: >>> gmpy2.kronecker() Traceback (innermost last): ... TypeError: >>> aaa = 10**20 >>> bbb = aaa+39 >>> gmpy2.jacobi(aaa,bbb) 1 >>> gmpy2.legendre(aaa,bbb) 1 >>> gmpy2.kronecker(aaa,bbb) 1 >>> del aaa,bbb Test legendre ------------- >>> gmpy2.legendre('a', 10) Traceback (innermost last): ... TypeError: >>> gmpy2.legendre(10,3) 1 >>> gmpy2.legendre(10,-3) Traceback (most recent call last): ... ValueError: >>> gmpy2.legendre(3) Traceback (innermost last): ... TypeError: >>> gmpy2.legendre() Traceback (innermost last): ... TypeError: Test __length__ --------------- >>> len(mpz(0)) 1 >>> len(mpz(1)) 1 >>> len(mpz(17)) 5 Test numerator -------------- >>> a.numerator mpz(123) Test denominator ---------------- >>> a.denominator mpz(1) gmpy2-2.1.0b3/test/test_gmpy2_mpz_misc_py2.txt0000664000175000017500000000152513244654531021171 0ustar casecase00000000000000Test gmpy2_mpz_misc_py2.c ========================= # Test Python 2.x specific behavior for mpz objects. >>> import gmpy2 >>> from gmpy2 import mpz >>> import math >>> a = mpz(123) >>> b = mpz(456) Test math.ceil (__ceil__) ------------------------- >>> math.ceil(a) 123.0 >>> math.ceil(a) is a False Test math.floor (__floor__) --------------------------- >>> math.floor(a) 123.0 >>> math.floor(a) is a False Test math.trunc (__trunc__) --------------------------- >>> math.trunc(a) mpz(123) >>> math.trunc(a) is a True Test round (__round__) ---------------------- >>> round(mpz(123456), 2) 123456.0 >>> round(mpz(123456), -22) 0.0 >>> round(mpz(123456), -2) 123500.0 >>> round(mpz(123456), -1) 123460.0 >>> round(mpz(123455), -1) 123460.0 >>> round(mpz(123454), -1) 123450.0 >>> round(mpz(123445), -1) 123450.0 >>> round(mpz(123445)) 123445.0 gmpy2-2.1.0b3/test/test_gmpy2_mpz_misc_py3.txt0000664000175000017500000000156013244654531021171 0ustar casecase00000000000000Test gmpy2_mpz_misc_py3.c ========================= # Test Python 3.x specific behavior for mpz objects. >>> import gmpy2 >>> from gmpy2 import mpz >>> import math >>> a = mpz(123) >>> b = mpz(456) Test math.ceil (__ceil__) ------------------------- >>> math.ceil(a) mpz(123) >>> math.ceil(a) is a True Test math.floor (__floor__) --------------------------- >>> math.floor(a) mpz(123) >>> math.floor(a) is a True Test math.trunc (__trunc__) --------------------------- >>> math.trunc(a) mpz(123) >>> math.trunc(a) is a True Test round (__round__) ---------------------- >>> round(mpz(123456), 2) mpz(123456) >>> round(mpz(123456), -22) mpz(0) >>> round(mpz(123456), -2) mpz(123500) >>> round(mpz(123456), -1) mpz(123460) >>> round(mpz(123455), -1) mpz(123460) >>> round(mpz(123454), -1) mpz(123450) >>> round(mpz(123445), -1) mpz(123440) >>> round(mpz(123445)) mpz(123445) gmpy2-2.1.0b3/test/test_gmpy2_mul.txt0000664000175000017500000000615313452511374017353 0ustar casecase00000000000000Test gmpy2 Multiplication ========================= Test all code in the file gmpy2_sub.c. >>> import gmpy2 as gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> from supportclasses import * >>> from decimal import Decimal as D >>> from fractions import Fraction as F >>> a = mpz(123) >>> b = mpz(456) >>> c = 12345678901234567890 Test integer operations ----------------------- >>> mpz(2) * z mpz(4) >>> gmpy2.mul(2,1) mpz(2) >>> ctx=gmpy2.context() >>> ctx.mul(a,b) == a*b True >>> ctx.mul(c,c) == c*c True >>> ctx.mul(a, mpq(1)) mpq(123,1) >>> ctx.mul(a, mpfr(1)) mpfr('123.0') >>> ctx.mul(a, mpc(1)) mpc('123.0+0.0j') >>> ctx.mul(1) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> ctx.mul(1,2,3) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 1 1 Test rational operations ------------------------ >>> mpq(1,2) * F(3,2) mpq(3,4) >>> F(1,2) * mpq(3,2) mpq(3,4) >>> mpq(1,2) * mpq(3,2) mpq(3,4) >>> mpq(1,2) * 0 mpq(0,1) >>> mpq(1,2) * mpz(1) mpq(1,2) >>> mpq(1,2) * (-1) mpq(-1,2) >>> mpq(1,1) * mpc(1,0) mpc('1.0+0.0j') >>> mpc(1,0) * mpq(1,1) mpc('1.0+0.0j') >>> mpq(1,2) * z mpq(1,1) >>> mpq(1,2) * q mpq(3,4) >>> ctx=gmpy2.context() >>> ctx.mul(mpq(1,2), mpq(3,2)) mpq(3,4) >>> ctx.mul(mpq(1,2), F(3,2)) mpq(3,4) >>> ctx.mul(F(1,2), mpq(3,2)) mpq(3,4) >>> ctx.mul(F(1,2), F(3,2)) mpq(3,4) >>> ctx.mul(1,'a') Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 1 1 >>> mpq(1,2) * 'a' Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 'a' * mpq(1,2) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 1 1 Test real operations -------------------- >>> mpfr(10) * 1 mpfr('10.0') >>> 10 * mpfr(1) mpfr('10.0') >>> mpfr(10) * mpz(1) mpfr('10.0') >>> mpz(10) * mpfr(1) mpfr('10.0') >>> mpfr(10) * mpfr(1) mpfr('10.0') >>> mpfr(10) * mpq(1,1) mpfr('10.0') >>> mpq(10,1) * mpfr(1) mpfr('10.0') >>> mpfr(10) * F(1,1) mpfr('10.0') >>> F(10,1) * mpfr(1) mpfr('10.0') >>> mpfr(10) * 1.0 mpfr('10.0') >>> 10.0 * mpfr(1) mpfr('10.0') >>> mpfr(1) * c == mpfr(c) True >>> c * mpfr(1) == mpfr(c) True >>> mpfr(10) * z mpfr('20.0') >>> mpfr(10) * q mpfr('15.0') >>> mpfr(10) * r mpfr('15.0') >>> mpfr(10) * 'a' Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 'a' * mpfr(10) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 1 1 Test complex operations ----------------------- >>> mpc(1,2) * 'a' Traceback (most recent call last): ... TypeError: ** message detail varies ** >>> mpfr(1) * mpc(1,2) mpc('1.0+2.0j') >>> mpc(1,2) * mpfr(1) mpc('1.0+2.0j') >>> mpc(1,2) * mpfr(-1) mpc('-1.0-2.0j') >>> mpc(1,2) * (1+0j) mpc('1.0+2.0j') >>> (1+0j) * mpc(1,2) mpc('1.0+2.0j') >>> mpc(1,2) * z mpc('2.0+4.0j') >>> mpc(1,2) * q mpc('1.5+3.0j') >>> mpc(1,2) * r mpc('1.5+3.0j') >>> mpc(1,2) * cx mpc('-92.0+151.0j') gmpy2-2.1.0b3/test/test_gmpy2_muldiv_2exp.txt0000664000175000017500000000402413452511423021002 0ustar casecase00000000000000Test gmpy2_muldiv_2exp.c ======================== >>> import gmpy2 >>> ctx = gmpy2.get_context() >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> r = mpfr(7.6) >>> z = mpz(3) >>> c = mpc(4,4) Tests multiplication -------------------- >>> gmpy2.mul_2exp(r, z) mpfr('60.799999999999997') >>> gmpy2.mul_2exp(r, 3) mpfr('60.799999999999997') >>> gmpy2.mul_2exp(r, -5) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.mul_2exp(z, r) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.mul_2exp('not', 5) Traceback (most recent call last): File "", line 1, in TypeError: mul_2exp() argument type not supported >>> ctx.mul_2exp(r, z, 45) Traceback (most recent call last): File "", line 1, in TypeError: mul_2exp() requires 2 arguments >>> ctx.mul_2exp(c, z) mpc('32.0+32.0j') >>> ctx.mul_2exp(c, -5) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> ctx.mul_2exp(r, 0) mpfr('7.5999999999999996') Tests division -------------- >>> gmpy2.div_2exp(r, z) mpfr('0.94999999999999996') >>> gmpy2.div_2exp(r, 3) mpfr('0.94999999999999996') >>> gmpy2.div_2exp(r, -5) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> gmpy2.div_2exp(z, r) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> gmpy2.div_2exp('not', 5) Traceback (most recent call last): File "", line 1, in TypeError: div_2exp() argument type not supported >>> ctx.div_2exp(r, z, 45) Traceback (most recent call last): File "", line 1, in TypeError: div_2exp() requires 2 arguments >>> ctx.div_2exp(c, z) mpc('0.5+0.5j') >>> ctx.div_2exp(c, -5) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_plus.txt0000664000175000017500000000136513444070732017540 0ustar casecase00000000000000Test gmpy2_plus.c ================= >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from fractions import Fraction >>> ctx = gmpy2.get_context() >>> ctx.plus(5) mpz(5) >>> ctx.plus(-5) mpz(-5) >>> ctx.plus(Fraction(4,5)) mpq(4,5) >>> ctx.plus(4.5) mpfr('4.5') >>> ctx.plus(complex(5.2,5)) mpc('5.2000000000000002+5.0j') >>> ctx.plus(mpz(421)) mpz(421) >>> ctx.plus('invalid') Traceback (most recent call last): File "", line 1, in TypeError: plus() argument type not supported >>> ctx.plus() Traceback (most recent call last): File "", line 1, in TypeError: plus() requires 1 argument. >>> + mpz(421) mpz(421) >>> + mpq('4/5') mpq(4,5) >>> + mpfr('inf') mpfr('inf') >>> + mpc(65.0, 45) mpc('65.0+45.0j') gmpy2-2.1.0b3/test/test_gmpy2_pow.txt0000664000175000017500000000605313452511473017362 0ustar casecase00000000000000Test gmpy2 Power ================ >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc, powmod >>> from fractions import Fraction >>> ctx = gmpy2.get_context() Test integer power ------------------ >>> z1, z2 = mpz(5), mpz(2) >>> z1 ** z2 mpz(25) >>> ctx.pow(z1, z2) mpz(25) >>> z1 ** -z2 Traceback (most recent call last): File "", line 1, in ValueError: pow() exponent cannot be negative >>> z1 ** 0 mpz(1) >>> mpz(0) ** 32 mpz(0) >>> mpz(-1) ** 32 mpz(1) >>> mpz(1) ** mpz(324) mpz(1) >>> mpz(0) ** 0 mpz(1) >>> mpz(-1) ** 3 mpz(-1) >>> z1 ** 2 == pow(z1, 2) True >>> pow(z1, 2, 19) mpz(6) >>> pow(z1, -2, 19) mpz(16) >>> pow(mpz(0), -2, 19) Traceback (most recent call last): File "", line 1, in ValueError: pow() base not invertible >>> pow(z1, 2, -19) mpz(-13) >>> pow(5, 2, 0) Traceback (most recent call last): File "", line 1, in ValueError: pow() 3rd argument cannot be 0 >>> ctx.pow(z1, 'invalid') Traceback (most recent call last): File "", line 1, in TypeError: pow() argument type not supported >>> 1 1 Test rational power ------------------- >>> q = mpq(2,3) >>> q ** 2 mpq(4,9) >>> q ** 0 mpq(1,1) >>> q ** -5 mpq(243,32) >>> ctx.pow(Fraction(2,3),2) == q ** 2 True >>> mpq(-5,8) ** 5 mpq(-3125,32768) >>> q ** mpq(4,5) mpfr('0.72298118079846574') >>> pow(q, 5, 2) Traceback (most recent call last): File "", line 1, in TypeError: pow() 3rd argument not allowed unless all arguments are integers >>> 1 1 Test real number power ---------------------- >>> r1, r2 = mpfr(5.0), mpfr(2.5) >>> r1 ** mpz(2) mpfr('25.0') >>> pow(r1, r2) mpfr('55.901699437494742') >>> ctx.pow(r1, r2) mpfr('55.901699437494742') >>> ctx.pow(r1, r2) == r1 ** r2 True >>> pow(r1, r2, 5) Traceback (most recent call last): File "", line 1, in TypeError: pow() 3rd argument not allowed unless all arguments are integers >>> ctx.pow(r1, r2, 5) Traceback (most recent call last): File "", line 1, in TypeError: pow() requires 2 arguments. >>> pow(r1, 4) mpfr('625.0') >>> ctx.pow(r1, 4) mpfr('625.0') Test complex power ------------------ >>> ctx.pow(complex(2,5), complex(5,2)) mpc('-416.55882051164394+44.334999625388825j') >>> c1, c2 = mpc(2,5), mpc(5,2) >>> pow(c1, c2) mpc('-416.55882051164394+44.334999625388825j') >>> ctx.pow(c1, c2) mpc('-416.55882051164394+44.334999625388825j') >>> ctx.pow(c1, c2) == c1 ** c2 True >>> pow(c1, c2, 5) Traceback (most recent call last): File "", line 1, in TypeError: pow() 3rd argument not allowed unless all arguments are integers >>> pow(c1, 5) mpc('4282.0-1475.0j') >>> c1 ** mpz(5) mpc('4282.0-1475.0j') >>> c1 ** mpfr(2.5) mpc('-66.373652915897722+11.111336616269842j') Test powmod ----------- >>> powmod(z1, z2, 4) == pow(z1, z2, 4) True >>> powmod(z1) Traceback (most recent call last): File "", line 1, in TypeError: powmod() requires 3 arguments. >>> powmod(z1, q, 4) Traceback (most recent call last): File "", line 1, in TypeError: powmod() argument types not supported >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_predicate.txt0000664000175000017500000001071013452457765020525 0ustar casecase00000000000000Tests for gmpy2_predicate.c =========================== >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> import gmpy2 >>> ctx = gmpy2.get_context() >>> pynan = float('nan') >>> pyinf = float('inf') >>> rnan = mpfr('nan') >>> rinf = mpfr('inf') >>> z5 = mpz(5) Tests is_nan ------------ >>> r = mpfr(4) >>> r.is_nan() False >>> rnan.is_nan() True >>> gmpy2.is_nan(r) False >>> gmpy2.is_nan(rnan) True >>> ctx.is_nan(r) False >>> ctx.is_nan(rnan) True >>> ctx.is_nan(pynan) True >>> ctx.is_nan(pyinf) False >>> mpc(rnan).is_nan() True >>> mpc('4.0').is_nan() False >>> ctx.is_nan(complex(pynan)) True Tests is_infinite ----------------- >>> gmpy2.is_infinite(5) False >>> gmpy2.is_infinite(z5) False >>> gmpy2.is_infinite(rinf) True >>> gmpy2.is_infinite(pyinf) True >>> gmpy2.is_infinite(complex(pyinf)) True >>> ctx.is_infinite(rinf) True >>> ctx.is_infinite(pyinf) True >>> ctx.is_infinite(pynan) False >>> ctx.is_infinite(rnan) False >>> rnan.is_infinite() False >>> rinf.is_infinite() True >>> mpc(pyinf).is_infinite() True >>> mpc(3, 4).is_infinite() False Tests is_finite --------------- >>> gmpy2.is_finite(5) True >>> gmpy2.is_finite(z5) True >>> gmpy2.is_finite(rinf) False >>> gmpy2.is_finite(pyinf) False >>> gmpy2.is_finite(complex(pyinf)) False >>> ctx.is_finite(rinf) False >>> ctx.is_finite(pyinf) False >>> ctx.is_finite(pynan) False >>> ctx.is_finite(rnan) False >>> rnan.is_finite() False >>> rinf.is_finite() False >>> q = mpq(2,3) >>> ctx.is_finite(q) True >>> mpc(pyinf).is_finite() False >>> mpc(3, 4).is_finite() True Tests is_zero ------------- >>> gmpy2.is_zero(float(0)) True >>> gmpy2.is_zero(mpfr(0)) True >>> gmpy2.is_zero(pynan) False >>> gmpy2.is_zero(rinf) False >>> gmpy2.is_zero(mpfr(5)) False >>> gmpy2.is_zero(float(5)) False >>> gmpy2.is_zero(None) Traceback (most recent call last): File "", line 1, in TypeError: is_zero() argument type not supported >>> ctx.is_zero(float(0)) True >>> ctx.is_zero(mpfr(0)) True >>> ctx.is_zero(pynan) False >>> ctx.is_zero(rinf) False >>> ctx.is_zero(mpfr(5)) False >>> ctx.is_zero(float(5)) False >>> ctx.is_zero(mpc(4,4)) False >>> ctx.is_zero(mpc(0,4)) False >>> ctx.is_zero(mpc(0,0)) True >>> ctx.is_zero(complex(0,0)) True >>> ctx.is_zero(complex(0,5)) False >>> mpfr(0).is_zero() True >>> rinf.is_zero() False >>> mpfr(-5).is_zero() False >>> mpc(0, 0).is_zero() True >>> mpc(0, 4).is_zero() False Tests is_signed --------------- >>> rinf.is_signed() False >>> rnan.is_signed() False >>> mpfr(-5).is_signed() True >>> mpfr(0).is_signed() False >>> gmpy2.is_signed(5) False >>> gmpy2.is_signed(-5) True >>> gmpy2.is_signed(float(5)) False >>> gmpy2.is_signed(mpfr(5)) False Tests is_regular ---------------- >>> gmpy2.is_regular(rnan) False >>> gmpy2.is_regular(rinf) False >>> gmpy2.is_regular(mpfr(0)) False >>> gmpy2.is_regular(pyinf) False >>> gmpy2.is_regular(mpfr(5)) True >>> gmpy2.is_regular(z5) True >>> gmpy2.is_regular(-0.6) True >>> gmpy2.is_regular(pynan) False >>> ctx.is_regular(rnan) False >>> ctx.is_regular(rinf) False >>> ctx.is_regular(mpfr(0)) False >>> ctx.is_regular(pyinf) False >>> ctx.is_regular(mpfr(5)) True >>> ctx.is_regular(z5) True >>> ctx.is_regular(-0.6) True >>> ctx.is_regular(pynan) False Tests is_integer ---------------- >>> rinf.is_integer() False >>> rnan.is_integer() False >>> mpfr(0).is_integer() True >>> mpfr(-42).is_integer() True >>> mpfr(-42.65).is_integer() False >>> gmpy2.is_integer(pyinf) False >>> gmpy2.is_integer(5) True >>> gmpy2.is_integer(5.6) False >>> gmpy2.is_integer(float(5.6)) False >>> ctx.is_integer(mpfr(5)) True >>> ctx.is_integer(mpfr('5.6')) False Tests is_less_greater --------------------- >>> gmpy2.is_lessgreater(rnan, pynan) False >>> gmpy2.is_lessgreater(rnan, 5) False >>> gmpy2.is_lessgreater(5, pynan) False >>> gmpy2.is_lessgreater(5, 5) False >>> gmpy2.is_lessgreater(5, mpq(5/1)) False >>> gmpy2.is_lessgreater(-5, float(-5)) False >>> gmpy2.is_lessgreater(-5, mpfr(4)) True >>> gmpy2.is_lessgreater(mpfr(0), mpc(4,1)) Traceback (most recent call last): File "", line 1, in TypeError: is_lessgreater() argument type not supported Tests is_unordered ------------------ >>> gmpy2.is_unordered(-5, float(-5)) False >>> gmpy2.is_unordered(mpfr(0), mpc(4,1)) Traceback (most recent call last): File "", line 1, in TypeError: is_unordered() argument type not supported >>> gmpy2.is_unordered(-rinf, 0.0) False >>> gmpy2.is_unordered(rnan, pynan) True >>> gmpy2.is_unordered(rnan, 5) True >>> gmpy2.is_unordered(5, pynan) True gmpy2-2.1.0b3/test/test_gmpy2_prp.txt0000664000175000017500000000741613425750522017362 0ustar casecase00000000000000Test gmpy2 Prime Testing Functions ================================== >>> import gmpy2 >>> from gmpy2 import mpz # Test if_fermat_prp >>> gmpy2.is_fermat_prp(12345,2) False >>> gmpy2.is_fermat_prp(113,2) True >>> gmpy2.is_fermat_prp(1234,2) False >>> gmpy2.is_fermat_prp(1234,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.is_fermat_prp(1234, 2, 3) Traceback (most recent call last): ... TypeError: >>> gmpy2.is_fermat_prp(113, 1) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_fermat_prp(-113, 3) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_fermat_prp(339, 3) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_fermat_prp(mpz(12345),2) False >>> gmpy2.is_fermat_prp(113,mpz(2)) True ''' # Test is_euler_prp >>> gmpy2.is_euler_prp(12345,2) False >>> gmpy2.is_euler_prp(113,2) True >>> gmpy2.is_euler_prp(1234,2) False >>> gmpy2.is_euler_prp(1234,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.is_euler_prp(1234, 2, 3) Traceback (most recent call last): ... TypeError: >>> gmpy2.is_euler_prp(113, 1) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_euler_prp(-113, 3) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_euler_prp(339, 3) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_euler_prp(mpz(12345),2) False >>> gmpy2.is_euler_prp(113,mpz(2)) True # Test is_strong_prp >>> gmpy2.is_strong_prp(12345,2) False >>> gmpy2.is_strong_prp(113,2) True >>> gmpy2.is_strong_prp(1234,2) False >>> gmpy2.is_strong_prp(1234,'a') Traceback (most recent call last): ... TypeError: >>> gmpy2.is_strong_prp(1234, 2, 3) Traceback (most recent call last): ... TypeError: >>> gmpy2.is_strong_prp(113, 1) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_strong_prp(-113, 3) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_strong_prp(339, 3) Traceback (most recent call last): ... ValueError: >>> gmpy2.is_strong_prp(mpz(12345),2) False >>> gmpy2.is_strong_prp(113,mpz(2)) True # Test is_fibonacci_prp >>> gmpy2.is_fibonacci_prp(12345, 3, 1) False >>> gmpy2.is_fibonacci_prp(113, 3, 1) True >>> gmpy2.is_fibonacci_prp(12345, 3, -1) False >>> gmpy2.is_fibonacci_prp(113, 3, -1) True >>> gmpy2.is_fibonacci_prp(113, 3, 2) Traceback (most recent call last): File "", line 1, in ValueError: >>> gmpy2.is_fibonacci_prp('a', 3, 2) Traceback (most recent call last): File "", line 1, in TypeError: >>> gmpy2.is_fibonacci_prp(113, 2, 1) Traceback (most recent call last): File "", line 1, in ValueError: >>> gmpy2.is_fibonacci_prp(113, 2, -1) True # Test is_lucas_prp >>> gmpy2.is_lucas_prp(12345, 5, 2) False >>> gmpy2.is_lucas_prp(113, 5, 2) True >>> gmpy2.is_lucas_prp(12345, 3, 5) Traceback (most recent call last): File "", line 1, in ValueError: # Test is_stronglucas_prp >>> gmpy2.is_strong_lucas_prp(12345, 5, 2) False >>> gmpy2.is_strong_lucas_prp(113, 5, 2) True >>> gmpy2.is_strong_lucas_prp(12345, 3, 5) Traceback (most recent call last): File "", line 1, in ValueError: # Test is_extra_strong_lucas_prp >>> gmpy2.is_extra_strong_lucas_prp(12345, 9) False >>> gmpy2.is_extra_strong_lucas_prp(113, 5) True >>> gmpy2.is_extra_strong_lucas_prp(12345, 3) Traceback (most recent call last): File "", line 1, in ValueError: # Test is_selfridge_prp >>> gmpy2.is_selfridge_prp(12345) False >>> gmpy2.is_selfridge_prp(113) True # Test is_strong_selfridge_prp >>> gmpy2.is_strong_selfridge_prp(12345) False >>> gmpy2.is_strong_selfridge_prp(113) True # Test is_bpsw_prp >>> gmpy2.is_bpsw_prp(12345) False >>> gmpy2.is_bpsw_prp(113) True # Test is_strong_bpsw_prp >>> gmpy2.is_strong_bpsw_prp(12345) False >>> gmpy2.is_strong_bpsw_prp(113) True ''' gmpy2-2.1.0b3/test/test_gmpy2_root.txt0000664000175000017500000000224113452511526017532 0ustar casecase00000000000000Test gmpy2 root and rootn ========================= >>> import gmpy2 as gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc, root, rootn, zero >>> root(zero(1), 2) mpfr('0.0') >>> root(zero(-1), 2) mpfr('-0.0') >>> root(zero(-1), 3) mpfr('-0.0') >>> root(zero(-1), 4) mpfr('-0.0') >>> root(zero(-1), 5) mpfr('-0.0') >>> root(zero(-1), 6) mpfr('-0.0') >>> rootn(zero(1), 2) mpfr('0.0') >>> rootn(zero(-1), 2) mpfr('0.0') >>> rootn(zero(-1), 3) mpfr('-0.0') >>> rootn(zero(-1), 4) mpfr('0.0') >>> rootn(zero(-1), 5) mpfr('-0.0') >>> rootn(zero(-1), 6) mpfr('0.0') >>> root(2,2) mpfr('1.4142135623730951') >>> root(mpz(2),2) mpfr('1.4142135623730951') >>> root(mpq(2),2) mpfr('1.4142135623730951') >>> root(mpfr(2),2) mpfr('1.4142135623730951') >>> root(mpc(2),2) Traceback (most recent call last): File "", line 1, in TypeError: root() argument type not supported >>> root(-2,2) mpfr('nan') >>> root(2,-2) Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> root(2,0.5) Traceback (most recent call last): File "", line 1, in TypeError: root() argument type not supported >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_square.txt0000664000175000017500000000115413444070732020051 0ustar casecase00000000000000Test gmpy2 Square ================= Test code in the file gmpy2_square.c >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc, square >>> z = mpz(2) >>> square(z) mpz(4) >>> square(z) == z * z True >>> q = mpq(2,3) >>> square(q) mpq(4,9) >>> square(q) == q * q True >>> r = mpfr(5.3) >>> square(r) mpfr('28.09') >>> square(r) == r * r True >>> c = mpc(2,3) >>> square(c) mpc('-5.0+12.0j') >>> square(c) == c * c True >>> square(2) == square(z) True >>> from fractions import Fraction >>> square(Fraction(2,3)) == square(q) True >>> square(5.3) == square(r) True >>> square(complex(2,3)) == square(c) True gmpy2-2.1.0b3/test/test_gmpy2_sub.txt0000664000175000017500000000676613452546503017363 0ustar casecase00000000000000Test gmpy2 Subtraction ====================== Test all code in the file gmpy2_sub.c. >>> import gmpy2 as gmpy2 >>> from gmpy2 import mpz, xmpz, mpq, mpfr, mpc >>> from supportclasses import * >>> from decimal import Decimal as D >>> from fractions import Fraction as F >>> a = mpz(123) >>> b = mpz(456) >>> c = 12345678901234567890 Test integer operations ----------------------- >>> a-1 mpz(122) >>> a-(-1) mpz(124) >>> 1-a mpz(-122) >>> (-1)-a mpz(-124) >>> print(a-c) -12345678901234567767 >>> print(c-a) 12345678901234567767 >>> print(a-(-c)) 12345678901234568013 >>> print((-c)-a) -12345678901234568013 >>> a-b mpz(-333) >>> b-a mpz(333) >>> a-(-b) mpz(579) >>> (-b)-a mpz(-579) >>> a-z mpz(121) >>> gmpy2.sub(2,1) mpz(1) >>> ctx=gmpy2.context() >>> ctx.sub(a,b) == a-b True >>> ctx.sub(c,c) == c-c True >>> ctx.sub(1, 1) mpz(0) >>> ctx.sub(a, 1) mpz(122) >>> ctx.sub(1, a) mpz(-122) >>> ctx.sub(a, mpq(0)) mpq(123,1) >>> ctx.sub(a, mpfr(0)) mpfr('123.0') >>> ctx.sub(a, mpc(0)) mpc('123.0+0.0j') >>> ctx.sub(1) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> ctx.sub(1,2,3) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> a-'b' Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 'b'-a Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 1 1 Test rational operations ------------------------ >>> mpq(1,2) - F(3,2) mpq(-1,1) >>> F(1,2) - mpq(3,2) mpq(-1,1) >>> mpq(1,2) - mpq(3,2) mpq(-1,1) >>> mpq(1,2) - 0 mpq(1,2) >>> mpq(1,2) - mpz(1) mpq(-1,2) >>> mpq(1,2) + (-1) mpq(-1,2) >>> 1 - mpq(1,2) mpq(1,2) >>> mpz(1) - mpq(1,2) mpq(1,2) >>> mpq(1,2) - mpz(1) mpq(-1,2) >>> mpq(1,1) - mpc(0) mpc('1.0+0.0j') >>> mpc(0) - mpq(1,1) mpc('-1.0+0.0j') >>> mpq(1,2) - z mpq(-3,2) >>> mpq(1,2) - q mpq(-1,1) >>> ctx=gmpy2.context() >>> ctx.sub(mpq(1,2), mpq(3,2)) mpq(-1,1) >>> ctx.sub(mpq(1,2), F(3,2)) mpq(-1,1) >>> ctx.sub(F(1,2), mpq(3,2)) mpq(-1,1) >>> ctx.sub(F(1,2), F(3,2)) mpq(-1,1) >>> ctx.sub(1,'a') Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> mpq(1,2) - 'a' Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 'a' - mpq(1,2) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> 1 1 Test real operations -------------------- >>> mpfr(10) - 1 mpfr('9.0') >>> 10 - mpfr(1) mpfr('9.0') >>> mpfr(10) - mpz(1) mpfr('9.0') >>> mpz(10) - mpfr(1) mpfr('9.0') >>> mpfr(10) - mpfr(1) mpfr('9.0') >>> mpfr(10) - mpq(1,1) mpfr('9.0') >>> mpq(10,1) - mpfr(1) mpfr('9.0') >>> mpfr(10) - F(1,1) mpfr('9.0') >>> F(10,1) - mpfr(1) mpfr('9.0') >>> mpfr(10) - 1.0 mpfr('9.0') >>> 10.0 - mpfr(1) mpfr('9.0') >>> mpfr(0) - (1 << 100) == mpfr('-1p100', base=2) True >>> (1 << 100) - mpfr(0) == mpfr('1p100', base=2) True >>> mpfr(10) - z mpfr('8.0') >>> mpfr(10) - q mpfr('8.5') >>> mpfr(10) - r mpfr('8.5') Test complex operations ----------------------- >>> mpc(1,2) - 'a' Traceback (most recent call last): ... TypeError: >>> mpfr(1) - mpc(1,2) mpc('0.0-2.0j') >>> mpc(1,2) - mpfr(1) mpc('0.0+2.0j') >>> mpc(1,2) - 1+0j mpc('0.0+2.0j') >>> 1+0j - mpc(1,2) mpc('0.0-2.0j') >>> mpc(1,2) - z mpc('-1.0+2.0j') >>> mpc(1,2) - q mpc('-0.5+2.0j') >>> mpc(1,2) - r mpc('-0.5+2.0j') >>> mpc(1,2) - cx mpc('-41.0-65.0j') gmpy2-2.1.0b3/test/test_gmpy2_xmpz_inplace.txt0000664000175000017500000000674413452511223021246 0ustar casecase00000000000000Tests for gmpy2_xmpz_inplace functions ====================================== >>> import gmpy2 >>> from gmpy2 import mpz, xmpz, mpfr Test iadd operator ------------------ >>> x = xmpz(5) >>> x += mpz(6); x xmpz(11) >>> x += 7; x xmpz(18) >>> x += -6; x xmpz(12) >>> x += mpfr(2.5); x mpfr('14.5') Test isub operator ------------------ >>> x = xmpz(7) >>> x -= xmpz(1); x xmpz(6) >>> x -= 1; x xmpz(5) >>> x -= mpz(7); x xmpz(-2) >>> x -= -5; x xmpz(3) >>> x -= -mpfr(5); x mpfr('8.0') Test imul operator ------------------ >>> x = xmpz(2) >>> x *= xmpz(2); x xmpz(4) >>> x *= 2; x xmpz(8) >>> x *= mpz(3); x xmpz(24) >>> x *= -1; x xmpz(-24) >>> x *= mpfr(-0.5); x mpfr('12.0') Test ifloordiv operator ----------------------- >>> x = xmpz(49) >>> x //= xmpz(3); x xmpz(16) >>> x //= mpz(3); x xmpz(5) >>> x //= 2; x xmpz(2) >>> x //= 0; Traceback (most recent call last): File "", line 1, in ZeroDivisionError: xmpz division by zero >>> x xmpz(2) >>> x //= mpfr(-0.5); x mpfr('-4.0') Test imod operator ------------------ >>> x = xmpz(45) >>> x %= xmpz(18); x xmpz(9) >>> x %= mpz(2); x xmpz(1) >>> x = xmpz(40) >>> x %= 21; x xmpz(19) >>> x %= 0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: mpz modulo by zero >>> x xmpz(19) >>> x %= mpfr(10); x mpfr('9.0') Test irshift and ilshift operators ---------------------------------- >>> x = xmpz(63) >>> x >>= xmpz(63); x xmpz(0) >>> x = xmpz(63) >>> x >>= xmpz(1); x xmpz(31) >>> x >>= mpz(2); x xmpz(7) >>> x >>= 1; x xmpz(3) >>> x <<= xmpz(2); x xmpz(12) >>> x <<= mpz(1); x xmpz(24) >>> x <<= 0; x xmpz(24) >>> x >>= mpfr(2) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> x <<= mpfr(2) Traceback (most recent call last): File "", line 1, in TypeError: could not convert object to integer >>> x >>= -1 Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> x <<= -5 Traceback (most recent call last): File "", line 1, in ValueError: a non-negative value is required >>> 1 1 Test ipow operator ------------------ >>> x = xmpz(5) >>> x **= xmpz(2); x xmpz(25) >>> x **= mpz(2); x xmpz(625) >>> x **= -2 Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for ** or pow(): 'xmpz' and 'int' >>> x **= 2; x xmpz(390625) >>> x **= mpfr(2) Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for ** or pow(): 'xmpz' and 'mpfr' >>> 1 1 Test iand operator ------------------ >>> x = xmpz(7) >>> x &= xmpz(5); x xmpz(5) >>> x &= mpz(4); x xmpz(4) >>> x &= 9; x xmpz(0) >>> x = mpz(4) >>> x &= 12; x mpz(4) >>> x &= mpfr(4) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpz >>> 1 1 Test ior operator ----------------- >>> x = xmpz(0) >>> x |= xmpz(1) >>> x xmpz(1) >>> x |= xmpz(0) >>> x xmpz(1) >>> x = xmpz(0) >>> x |= xmpz(0); x xmpz(0) >>> x |= 5; x xmpz(5) >>> x |= mpfr(3) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpz >>> 1 1 Test ixor operator ------------------ >>> x = xmpz(1) >>> x ^= xmpz(0); x xmpz(1) >>> x ^= mpz(1); x xmpz(0) >>> x ^= 1; x xmpz(1) >>> x ^= mpfr(0) Traceback (most recent call last): File "", line 1, in TypeError: cannot convert object to mpz >>> 1 1 gmpy2-2.1.0b3/test/test_gmpy2_xmpz_misc.txt0000664000175000017500000000357113476477105020601 0ustar casecase00000000000000Test gmpy2_xmpz_misc.c ====================== >>> import gmpy2 >>> from gmpy2 import xmpz, mpz, mpfr >>> z = xmpz(5) >>> gmpy2.xbit_mask(7) xmpz(127) >>> gmpy2.xbit_mask(z) xmpz(31) >>> gmpy2.xbit_mask(4.5) Traceback (most recent call last): File "", line 1, in TypeError: xbit_mask() requires 'int' argumen >>> not xmpz(0) True >>> not z False >>> -z; z xmpz(-5) >>> -z; z xmpz(5) >>> +z; z xmpz(5) >>> z2 = z.copy() >>> z2 == z True >>> z2 is z False >>> z.copy().make_mpz() mpz(5) >>> xmpz(-100).make_mpz() mpz(-100) >>> z.__len__() 3 >>> xmpz(3000).__len__() 12 Test SubScript and AssignSubScript ---------------------------------- >>> x = xmpz(10) >>> x[0] == x[2] == 0 True >>> x[1] == x[3] == 1 True >>> x[0] = 1 >>> x xmpz(11) >>> x[0:2] mpz(3) >>> x[0:] mpz(11) >>> x[:4] mpz(11) >>> x[:4] = 14 >>> x xmpz(14) >>> x[0] 0 >>> x[mpfr('inf')] Traceback (most recent call last): File "", line 1, in TypeError: bit positions must be integers >>> x[3:0] mpz(0) >>> x[-1] 1 >>> x[-1] = 0; x xmpz(6) >>> x[0:4] = 15 >>> x xmpz(15) >>> x[0] = 16 Traceback (most recent call last): File "", line 1, in ValueError: bit value must be 0 or 1 >>> x[0:4] = 16; x xmpz(0) >>> x[0:4] = 15; x xmpz(15) >>> x[0:5] = 16; x xmpz(16) Test iterators -------------- >>> x = xmpz(16) >>> iter = x.iter_bits() >>> [b for b in iter] [False, False, False, False, True] >>> x = xmpz(30) >>> iter = x.iter_bits() >>> [b for b in iter] [False, True, True, True, True] >>> iter = x.iter_bits(-1, 2) >>> [b for b in iter] [] >>> iter = x.iter_bits(1, 3) >>> [b for b in iter] [True, True] >>> iter = x.iter_set() >>> [b for b in iter] [1, 2, 3, 4] >>> iter = x.iter_clear() >>> [b for b in iter] [0] >>> x = xmpz(10) >>> iter = x.iter_clear() >>> [b for b in iter] [0, 2] Test attributes --------------- >>> x.numerator xmpz(10) >>> x.denominator xmpz(1) >>> x.real xmpz(10) gmpy2-2.1.0b3/test/test_misc.txt0000664000175000017500000000353613530662600016371 0ustar casecase00000000000000Miscellaneous Functions ----------------------- >>> import gmpy2 >>> from gmpy2 import mpz >>> gmpy2.version() '2.1.0b3' >>> gmpy2.mp_limbsize() in (32,64) True >>> gmpy2.mp_version().split()[0] in ['GMP', 'MPIR'] True >>> check_gmp = gmpy2.mp_version().startswith('GMP') and '5.0.0' <= gmpy2.mp_version().split()[1] >>> check_mpir = gmpy2.mp_version().startswith('MPIR') and '3.0.0' <= gmpy2.mp_version().split()[1] >>> check_gmp or check_mpir True >>> gmpy2.mpfr_version() and gmpy2.mpfr_version().startswith('MPFR') True >>> gmpy2.mpfr_version() and '3.1.0' <= gmpy2.mpfr_version().split()[1] True >>> gmpy2.mpc_version() and gmpy2.mpc_version().startswith('MPC') True >>> gmpy2.mpc_version() and '1.0' <= gmpy2.mpc_version().split()[1] True >>> gmpy2.license() 'The GMPY2 source code is licensed under LGPL 3 or later. The supported versions of the GMP/MPIR, MPFR, and MPC libraries are also licensed under LGPL 3 or later.' >>> gmpy2.get_cache() (100, 128) >>> gmpy2.divm(5,7,13) mpz(10) >>> gmpy2.set_cache(0,16) >>> gmpy2.get_cache() (0, 16) >>> for i in range(1000): a=mpz(i) >>> del(a) >>> gmpy2.set_cache(100,128) >>> gmpy2.get_cache() (100, 128) >>> gmpy2.set_cache('a', 128) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> gmpy2.set_cache(-10, 128) Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> gmpy2.set_cache(10000, 128) Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> gmpy2.set_cache(100, -1) Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> gmpy2.set_cache(100, 100000) Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> 1 1 gmpy2-2.1.0b3/test/test_mpc.txt0000664000175000017500000001660613461370120016213 0ustar casecase00000000000000Test mpc elementary operations ------------------------------ >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from supportclasses import * >>> from fractions import Fraction as F >>> from decimal import Decimal as D >>> a = mpz(123) >>> b = mpz(456) >>> c = 12345678901234567890 >>> af = mpfr("12.34") >>> bf = mpfr("45.67") >>> aq = mpq(3,11) >>> bq = mpq(17,2) >>> aj = mpc(1+2j) >>> bj = mpc(4+5j) Test addition ------------- >>> aj + bj mpc('5.0+7.0j') >>> bj + aj mpc('5.0+7.0j') >>> aj + a mpc('124.0+2.0j') >>> a + aj mpc('124.0+2.0j') >>> aj + 1 mpc('2.0+2.0j') >>> 1 + aj mpc('2.0+2.0j') >>> aj + 0 mpc('1.0+2.0j') >>> 0 + aj mpc('1.0+2.0j') >>> -1 + aj mpc('0.0+2.0j') >>> aj - 1 mpc('0.0+2.0j') >>> aj + 1.2 == 2.2 + 2j True Test subtraction ---------------- >>> aj - bj mpc('-3.0-3.0j') >>> bj - aj mpc('3.0+3.0j') >>> aj - a mpc('-122.0+2.0j') >>> a - aj mpc('122.0-2.0j') >>> aj - 1 mpc('0.0+2.0j') >>> 1 - aj mpc('0.0-2.0j') >>> 0 - aj mpc('-1.0-2.0j') >>> aj - 0 mpc('1.0+2.0j') >>> aj - -1 mpc('2.0+2.0j') >>> -1 - aj mpc('-2.0-2.0j') >>> aj - 1.2 == (1+2j) - 1.2 True Test multiplication ------------------- >>> aj * bj mpc('-6.0+13.0j') >>> bj * aj mpc('-6.0+13.0j') >>> aj * a mpc('123.0+246.0j') >>> a * aj mpc('123.0+246.0j') >>> aj * -1 mpc('-1.0-2.0j') >>> aj * (0.0+1j) mpc('-2.0+1.0j') Test division ------------- >>> aj / bj mpc('0.34146341463414637+0.073170731707317069j') >>> gmpy2.div(aj, bj) mpc('0.34146341463414637+0.073170731707317069j') >>> aj // bj Traceback (most recent call last): File "", line 1, in TypeError: can't take floor of complex number. >>> aj / a mpc('0.008130081300813009+0.016260162601626018j') >>> a / aj mpc('24.600000000000001-49.200000000000003j') >>> aj / 0 mpc('inf+infj') >>> mpc('2.0+2.0j') / z mpc('1.0+1.0j') >>> mpc('2.0+2.0j') / q mpc('1.3333333333333333+1.3333333333333333j') >>> mpc('2.0+2.0j') / r mpc('1.3333333333333333+1.3333333333333333j') >>> mpc(15,15) / cx mpc('0.26147449224372299-0.059971213817367662j') Test modulo ----------- >>> aj % bj Traceback (most recent call last): File "", line 1, in TypeError: can't mod complex numbers >>> aj % a Traceback (most recent call last): File "", line 1, in TypeError: can't mod complex numbers >>> a % aj Traceback (most recent call last): File "", line 1, in TypeError: can't mod complex numbers >>> divmod(aj, bj) Traceback (most recent call last): File "", line 1, in TypeError: can't take floor or mod of complex number. >>> 1 1 Test operations involving NaN/Inf --------------------------------- >>> aj + float('inf') mpc('inf+2.0j') >>> aj + float('-inf') mpc('-inf+2.0j') >>> aj + float('nan') mpc('nan+2.0j') >>> float('inf') - aj mpc('inf-2.0j') >>> aj - float('inf') mpc('-inf+2.0j') >>> aj - float('-inf') mpc('inf+2.0j') >>> aj - float('nan') mpc('nan+2.0j') >>> aj * float('inf') mpc('inf+infj') >>> aj * float('-inf') mpc('-inf-infj') >>> aj * float('nan') mpc('nan+nanj') >>> mpc(0,0) * float('inf') mpc('nan+nanj') >>> mpc(0,0) * float('-inf') mpc('nan+nanj') >>> mpc(0,0) * float('nan') mpc('nan+nanj') >>> aj / float('inf') mpc('0.0+0.0j') >>> aj / float('-inf') mpc('-0.0-0.0j') >>> float('inf') / aj mpc('inf-infj') >>> float('-inf') / aj mpc('-inf+infj') Test is_XXX ----------- >>> gmpy2.is_zero(mpc("0+0j")) True >>> gmpy2.is_zero(mpc("1+0j")) False >>> gmpy2.is_zero(mpc("1+1j")) False >>> gmpy2.is_zero(mpc("0+1j")) False >>> gmpy2.is_nan(mpc("nan+1j")) True >>> gmpy2.is_nan(mpc("1+nanj")) True >>> gmpy2.is_nan(mpc("nan+nanj")) True >>> gmpy2.is_nan(mpc("1+1j")) False >>> gmpy2.is_infinite(mpc("inf+1j")) True >>> gmpy2.is_infinite(mpc("-inf+1j")) True >>> gmpy2.is_infinite(mpc("1+infj")) True >>> gmpy2.is_infinite(mpc("1-infj")) True >>> gmpy2.is_infinite(mpc("inf-infj")) True >>> gmpy2.is_infinite(mpc("1+1j")) False >>> gmpy2.is_finite(mpc("0+0j")) True >>> gmpy2.is_finite(mpc("nan+0j")) False >>> gmpy2.is_finite(mpc("0+nanj")) False >>> gmpy2.is_finite(mpc("0+infj")) False >>> gmpy2.is_finite(mpc("inf+3j")) False Test mpc misc ------------- >>> c=mpc('67+87j', precision=70) >>> c.precision (70, 70) >>> c.real.precision 70 >>> c.imag.precision 70 >>> c = mpc('42e56+42.909j', precision=(45,300)) >>> c.precision (45, 300) >>> c.real.precision 45 >>> c.imag.precision 300 >>> x = mpc("1.3142123+4.3e-1001j", precision=(70,37)) >>> mpc(x.real, x.imag, precision=(70,37)) == x True Convert from mpc ---------------- >>> complex(mpc(4,5)) (4+5j) Test phase ---------- >>> gmpy2.phase() Traceback (most recent call last): File "", line 1, in TypeError: phase() takes exactly one argument (0 given) >>> gmpy2.phase(3) Traceback (most recent call last): File "", line 1, in TypeError: phase() argument type not supported >>> gmpy2.phase(mpc(4,5)) mpfr('0.89605538457134393') >>> gmpy2.ieee(64).phase(mpc(4,5)) mpfr('0.89605538457134393') Test root_of_unity ------------------ >>> gmpy2.root_of_unity(1,1) # doctest: +SKIP_MPC_LESS_THAN_110 mpc('1.0+0.0j') >>> gmpy2.root_of_unity(1,2) # doctest: +SKIP_MPC_LESS_THAN_110 mpc('1.0+0.0j') >>> gmpy2.root_of_unity(2,1) # doctest: +SKIP_MPC_LESS_THAN_110 mpc('-1.0+0.0j') >>> gmpy2.root_of_unity(3,1) # doctest: +SKIP_MPC_LESS_THAN_110 mpc('-0.5+0.8660254037844386j') >>> gmpy2.root_of_unity(3,2) # doctest: +SKIP_MPC_LESS_THAN_110 mpc('-0.5-0.8660254037844386j') >>> gmpy2.root_of_unity(3,3) # doctest: +SKIP_MPC_LESS_THAN_110 mpc('1.0+0.0j') >>> gmpy2.ieee(128).root_of_unity(3,1) # doctest: +SKIP_MPC_LESS_THAN_110 mpc('-0.5+0.866025403784438646763723170752936161j',(113,113)) >>> gmpy2.ieee(128).root_of_unity() # doctest: +SKIP_MPC_LESS_THAN_110 Traceback (most recent call last): File "", line 1, in TypeError: root_of_unity() requires 2 arguments >>> gmpy2.ieee(128).root_of_unity('a','b') # doctest: +SKIP_MPC_LESS_THAN_110 Traceback (most recent call last): File "", line 1, in TypeError: root_of_unity() requires integer arguments >>> 1 1 Test norm --------- >>> gmpy2.norm() Traceback (most recent call last): File "", line 1, in TypeError: norm() takes exactly one argument (0 given) >>> gmpy2.norm(2) Traceback (most recent call last): File "", line 1, in TypeError: norm() argument type not supported >>> gmpy2.norm(mpc(1,2)) mpfr('5.0') >>> gmpy2.ieee(32).norm(mpc(1,2)) mpfr('5.0',24) Test polar ---------- >>> gmpy2.polar() Traceback (most recent call last): File "", line 1, in TypeError: polar() takes exactly one argument (0 given) >>> gmpy2.polar(5) Traceback (most recent call last): File "", line 1, in TypeError: polar() argument type not supported >>> gmpy2.polar(mpc(1,1)) (mpfr('1.4142135623730951'), mpfr('0.78539816339744828')) Test rect --------- >>> gmpy2.rect() Traceback (most recent call last): File "", line 1, in TypeError: rect() requires 2 arguments >>> gmpy2.rect(1) Traceback (most recent call last): File "", line 1, in TypeError: rect() requires 2 arguments >>> gmpy2.rect(1,1) mpc('0.54030230586813977+0.8414709848078965j') Test proj --------- >>> gmpy2.proj() Traceback (most recent call last): File "", line 1, in TypeError: proj() takes exactly one argument (0 given) >>> gmpy2.proj(1) Traceback (most recent call last): File "", line 1, in TypeError: proj() argument type not supported >>> gmpy2.proj(mpc(1,1)) mpc('1.0+1.0j') >>> gmpy2.proj(mpc(1,2)) mpc('1.0+2.0j') gmpy2-2.1.0b3/test/test_mpc_create.txt0000664000175000017500000000131113244654531017533 0ustar casecase00000000000000Test mpc creation ================= >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> ctx=gmpy2.get_context() >>> ctx.clear_flags() >>> a=mpc("1.2") >>> a.rc (-1, 0) >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) gmpy2-2.1.0b3/test/test_mpc_exp_log.txt0000664000175000017500000000041013105222070017705 0ustar casecase00000000000000MPFR Functionality ================== >>> import gmpy2 as G >>> from gmpy2 import mpfr >>> a = mpz(123) >>> b = mpz(456) Test special functions ====================== Test exp -------- Test log -------- Test sqrt --------- Test pow -------- gmpy2-2.1.0b3/test/test_mpc_to_from_binary.txt0000664000175000017500000000360213105222070021267 0ustar casecase00000000000000Testing of gmpy2 mpc to_binary and from_binary ---------------------------------------------- >>> import gmpy2 >>> from gmpy2 import mpc,to_binary,from_binary Test ---- >>> x=mpc("0+0j");x==from_binary(to_binary(x)) True >>> x=mpc("1+0j");x==from_binary(to_binary(x)) True >>> x=mpc("-1+0j");x==from_binary(to_binary(x)) True >>> x=mpc("0+1j");x==from_binary(to_binary(x)) True >>> x=mpc("0-1j");x==from_binary(to_binary(x)) True >>> x=mpc("inf+0j");x==from_binary(to_binary(x)) True >>> x=mpc("0+infj");x==from_binary(to_binary(x)) True >>> x=mpc("inf-infj");x==from_binary(to_binary(x)) True >>> x=mpc("inf+nanj") >>> y=from_binary(to_binary(x)) >>> x.real==y.real True >>> gmpy2.is_nan(y.imag) True >>> x=mpc("-inf+0j");x==from_binary(to_binary(x)) True >>> x=mpc("0-infj");x==from_binary(to_binary(x)) True >>> x=mpc("-inf-infj");x==from_binary(to_binary(x)) True >>> x=mpc("-inf+nanj") >>> y=from_binary(to_binary(x)) >>> x.real==y.real True >>> gmpy2.is_nan(y.imag) True >>> x=mpc("nan+0j") >>> y=from_binary(to_binary(x)) >>> x.imag==y.imag True >>> gmpy2.is_nan(y.real) True >>> x=mpc("0+nanj") >>> y=from_binary(to_binary(x)) >>> x.real==y.real True >>> gmpy2.is_nan(y.imag) True >>> x=mpc("nan-infj") >>> y=from_binary(to_binary(x)) >>> x.imag==y.imag True >>> gmpy2.is_nan(y.real) True >>> x=mpc("nan+nanj") >>> y=from_binary(to_binary(x)) >>> gmpy2.is_nan(y.real) True >>> gmpy2.is_nan(y.imag) True >>> gmpy2.get_context().real_prec=100 >>> gmpy2.get_context().imag_prec=110 >>> from_binary(to_binary(mpc("1.3-4.7j"))) mpc('1.2999999999999999999999999999994-4.7000000000000000000000000000000025j',(100,110)) >>> gmpy2.set_context(gmpy2.context()) gmpy2-2.1.0b3/test/test_mpc_trig.txt0000664000175000017500000000320613444603111017230 0ustar casecase00000000000000MPC Functionality ================= >>> import gmpy2 >>> from gmpy2 import mpz, mpc >>> a = mpz(123) >>> b = mpz(456) Test trigonometric operations ============================= Test acos --------- >>> gmpy2.acos(mpc(0.2, 0.2)) mpc('1.3735541886535356-0.20256635782456389j') >>> gmpy2.acos(mpc(0.2, 0.2)) == gmpy2.acos(complex(0.2, 0.2)) True Test asin --------- >>> gmpy2.asin(mpc(0.2,0.2)) mpc('0.1972421381413611+0.20256635782456389j') >>> gmpy2.asin(mpc(2.0,0.2)) mpc('1.4560834209500821+1.3245636864399635j') >>> gmpy2.asin(mpc(0.2,0.2)) == gmpy2.asin(complex(0.2,0.2)) True Test atan --------- >>> gmpy2.atan(mpc(2.0, 2.0)) mpc('1.311223269671635+0.23887786125685909j') >>> gmpy2.atan(mpc(2.0, 2.0)) == gmpy2.atan(complex(2.0, 2.0)) True Test cos -------- >>> c = mpc(2,3) >>> gmpy2.cos(c) mpc('-4.189625690968807-9.109227893755337j') Test sin -------- >>> gmpy2.sin(c) mpc('9.1544991469114301-4.1689069599665647j') Test sin_cos ------------ >>> gmpy2.sin_cos(c) (mpc('9.1544991469114301-4.1689069599665647j'), mpc('-4.189625690968807-9.109227893755337j')) >>> gmpy2.sin_cos(c) == gmpy2.sin_cos(complex(2,3)) True >>> gmpy2.sin_cos(c) == (gmpy2.sin(c), gmpy2.cos(c)) True Test tan -------- >>> gmpy2.tan(mpc(4,5)) mpc('8.9834776469715613e-05+1.0000132074347847j') Test acosh ---------- Test asinh ---------- Test atanh ---------- >>> gmpy2.atanh(mpc(2.0, 3.0)) mpc('0.14694666622552977+1.3389725222944935j') >>> gmpy2.atanh(mpc(2.0, 3.0)) == gmpy2.atanh(complex(2, 3)) True Test cosh --------- Test sinh --------- Test sinh_cosh -------------- Test tanh --------- >>> gmpy2.tanh(mpc(4,5)) mpc('1.0005630461157933-0.00036520305451130409j') gmpy2-2.1.0b3/test/test_mpfr.txt0000664000175000017500000002562613452562415016414 0ustar casecase00000000000000MPFR Functionality ================== Testing of mpfr functionality is split into multiple files. >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc, get_context >>> from supportclasses import * >>> a = mpfr("12.34") >>> b = mpfr("45.67") >>> c = 12345678901234567890 Test elementary operations ========================== Test addition ------------- >>> a+1 mpfr('13.34') >>> a+1.0 mpfr('13.34') >>> a+mpz(1) mpfr('13.34') >>> a+mpq(1,1) mpfr('13.34') >>> 1+a mpfr('13.34') >>> 1.0+a mpfr('13.34') >>> mpz(1)+a mpfr('13.34') >>> mpq(1,1)+a mpfr('13.34') >>> a+b mpfr('58.010000000000005') >>> a+0 mpfr('12.34') >>> 0+a mpfr('12.34') >>> b+a mpfr('58.010000000000005') >>> a+'b' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'mpfr' and 'str' >>> 'b'+a Traceback (most recent call last): File "", line 1, in TypeError: Can't convert 'mpfr' object to str implicitly >>> a == 12.34 True >>> b == 45.67 True >>> a+b == 12.34+45.67 True Test subtraction ---------------- >>> a-1 mpfr('11.34') >>> a-1.0 mpfr('11.34') >>> a-(-1) mpfr('13.34') >>> a-(-1.0) mpfr('13.34') >>> a-b mpfr('-33.329999999999998') >>> b-a mpfr('33.329999999999998') >>> a-'b' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for -: 'mpfr' and 'str' >>> 'b'-a Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for -: 'str' and 'mpfr' >>> a-b==12.34-45.67 True Test multiplication ------------------- >>> a*b mpfr('563.56780000000003') >>> a*0 mpfr('0.0') >>> a*0.0 mpfr('0.0') >>> a*1 mpfr('12.34') >>> a*1.0 mpfr('12.34') >>> a*(-1.0) mpfr('-12.34') >>> 0*a mpfr('0.0') >>> 0.0*a mpfr('0.0') >>> 1*a mpfr('12.34') >>> 1.0*a mpfr('12.34') >>> a*b mpfr('563.56780000000003') >>> a*b==12.34*45.67 True Test division ------------- >>> a//b mpfr('0.0') >>> a/b mpfr('0.27019925552879348') >>> gmpy2.div(a, b) mpfr('0.27019925552879348') >>> get_context().div(a, b) mpfr('0.27019925552879348') >>> b//a mpfr('3.0') >>> b/a mpfr('3.7009724473257699') >>> a/b==12.34/45.67 True >>> a/0 mpfr('inf') >>> a/(-0.0) mpfr('-inf') >>> a/b==12.34/45.67 True >>> mpfr(10) / z mpfr('5.0') >>> mpfr(10) / q mpfr('6.666666666666667') >>> mpfr(10) / r mpfr('6.666666666666667') >>> b / mpc(4, 4) mpc('5.7087500000000002-5.7087500000000002j') >>> get_context().div(b, mpc(4, 4)) mpc('5.7087500000000002-5.7087500000000002j') >>> b / mpc(0, 0) mpc('inf+nanj') >>> get_context().div(b, mpc(0, 0)) mpc('inf+nanj') >>> b / 'str' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for /: 'mpfr' and 'str' >>> get_context().div(b, 'str') Traceback (most recent call last): File "", line 1, in TypeError: div() argument type not supported >>> 1 1 Test modulo ----------- >>> a % 1 mpfr('0.33999999999999986') >>> 12.34 % 1 0.33999999999999986 >>> a % z mpfr('0.33999999999999986') >>> b % 0 mpfr('nan') >>> b % mpz(0) mpfr('nan') >>> get_context().mod(b, 0) mpfr('nan') >>> get_context().mod(b, mpz(0)) mpfr('nan') >>> b % mpfr(0) mpfr('nan') >>> get_context().mod(b, mpfr(0)) mpfr('nan') >>> get_context().trap_divzero = True >>> b % 0 Traceback (most recent call last): File "", line 1, in gmpy2.DivisionByZeroError: mod() modulo by zero >>> b % mpz(0) Traceback (most recent call last): File "", line 1, in gmpy2.DivisionByZeroError: mod() modulo by zero >>> get_context().mod(b, 0) Traceback (most recent call last): File "", line 1, in gmpy2.DivisionByZeroError: mod() modulo by zero >>> get_context().mod(b, mpz(0)) Traceback (most recent call last): File "", line 1, in gmpy2.DivisionByZeroError: mod() modulo by zero >>> b % mpfr(0) Traceback (most recent call last): File "", line 1, in gmpy2.DivisionByZeroError: mod() modulo by zero >>> get_context().mod(b, mpfr(0)) Traceback (most recent call last): File "", line 1, in gmpy2.DivisionByZeroError: mod() modulo by zero >>> get_context().trap_divzero = False >>> b % 'str' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for %: 'mpfr' and 'str' >>> get_context().mod(b,'str') Traceback (most recent call last): File "", line 1, in TypeError: mod() argument type not supported >>> b % mpc(3, 5) Traceback (most recent call last): File "", line 1, in TypeError: can't take mod of complex number >>> mpfr('nan') % a mpfr('nan') >>> a % mpfr('nan') mpfr('nan') >>> mpfr('inf') % a mpfr('nan') >>> a % mpfr('inf') mpfr('12.34') >>> get_context().trap_invalid = True >>> mpfr('nan') % a Traceback (most recent call last): File "", line 1, in gmpy2.InvalidOperationError: invalid operation >>> a % mpfr('nan') Traceback (most recent call last): File "", line 1, in gmpy2.InvalidOperationError: invalid operation >>> mpfr('inf') % a Traceback (most recent call last): File "", line 1, in gmpy2.InvalidOperationError: mod() invalid operation >>> a % mpfr('inf') Traceback (most recent call last): File "", line 1, in gmpy2.InvalidOperationError: mod() invalid operation >>> get_context().trap_invalid = False >>> get_context().mod(a, b, 5) Traceback (most recent call last): File "", line 1, in TypeError: mod() requires 2 arguments >>> 1 1 Test divmod ----------- >>> divmod(12.34, 45.67) (0.0, 12.34) >>> divmod(a,b) (mpfr('0.0'), mpfr('12.34')) >>> divmod(b,a) (mpfr('3.0'), mpfr('8.6500000000000021')) >>> divmod(45.67,12.34)==divmod(b,a) True Test pickle ----------- >>> import pickle >>> pickle.loads(pickle.dumps(a)) mpfr('12.34') >>> pickle.loads(pickle.dumps(mpfr("inf"))) mpfr('inf') >>> pickle.loads(pickle.dumps(mpfr("-inf"))) mpfr('-inf') >>> pickle.loads(pickle.dumps(mpfr("nan"))) mpfr('nan') >>> pickle.loads(pickle.dumps(mpfr(0))) mpfr('0.0') Test operations involving NaN/Inf --------------------------------- >>> a + float('Inf') mpfr('inf') >>> float('Inf') + a mpfr('inf') >>> a + float('-Inf') mpfr('-inf') >>> float('-Inf') + a mpfr('-inf') >>> a + float('nan') mpfr('nan') >>> float('nan') + a mpfr('nan') >>> a - float('Inf') mpfr('-inf') >>> float('Inf') - a mpfr('inf') >>> a - float('-Inf') mpfr('inf') >>> float('-Inf') - a mpfr('-inf') >>> a - float('nan') mpfr('nan') >>> float('nan') - a mpfr('nan') >>> a * float('Inf') mpfr('inf') >>> float('Inf') * a mpfr('inf') >>> a * float('-Inf') mpfr('-inf') >>> float('-Inf') * a mpfr('-inf') >>> -a * float('Inf') mpfr('-inf') >>> float('Inf') * -a mpfr('-inf') >>> -a * float('-Inf') mpfr('inf') >>> float('-Inf') * -a mpfr('inf') >>> a * float('nan') mpfr('nan') >>> float('nan') * a mpfr('nan') >>> mpfr(0) * float('Inf') mpfr('nan') >>> mpfr(0) * float('-Inf') mpfr('nan') >>> float('Inf') * mpfr(0) mpfr('nan') >>> float('-Inf') * mpfr(0) mpfr('nan') >>> a / float('Inf') mpfr('0.0') >>> -a / float('Inf') mpfr('-0.0') >>> float('Inf') / a mpfr('inf') >>> float('Inf') / -a mpfr('-inf') >>> a / float('-Inf') mpfr('-0.0') >>> -a / float('-Inf') mpfr('0.0') >>> float('-Inf') / a mpfr('-inf') >>> float('-Inf') / -a mpfr('inf') >>> a / float('nan') mpfr('nan') >>> float('nan') / a mpfr('nan') >>> float('nan') / mpfr(0) mpfr('nan') >>> float('nan') / mpfr(0) mpfr('nan') >>> a + mpfr('Inf') mpfr('inf') >>> mpfr('Inf') + a mpfr('inf') >>> a + mpfr('-Inf') mpfr('-inf') >>> mpfr('-Inf') + a mpfr('-inf') >>> a + mpfr('nan') mpfr('nan') >>> mpfr('nan') + a mpfr('nan') >>> a - mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') - a mpfr('inf') >>> a - mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') - a mpfr('-inf') >>> a - mpfr('nan') mpfr('nan') >>> mpfr('nan') - a mpfr('nan') >>> a * mpfr('Inf') mpfr('inf') >>> mpfr('Inf') * a mpfr('inf') >>> a * mpfr('-Inf') mpfr('-inf') >>> mpfr('-Inf') * a mpfr('-inf') >>> -a * mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') * -a mpfr('-inf') >>> -a * mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') * -a mpfr('inf') >>> a * mpfr('nan') mpfr('nan') >>> mpfr('nan') * a mpfr('nan') >>> mpz(0) * mpfr('Inf') mpfr('nan') >>> mpz(0) * mpfr('-Inf') mpfr('nan') >>> mpfr('Inf') * mpfr(0) mpfr('nan') >>> mpfr('-Inf') * mpfr(0) mpfr('nan') >>> a / mpfr('Inf') mpfr('0.0') >>> -a / mpfr('Inf') mpfr('-0.0') >>> mpfr('Inf') / a mpfr('inf') >>> mpfr('Inf') / -a mpfr('-inf') >>> a / mpfr('-Inf') mpfr('-0.0') >>> -a / mpfr('-Inf') mpfr('0.0') >>> mpfr('-Inf') / a mpfr('-inf') >>> mpfr('-Inf') / -a mpfr('inf') >>> a / mpfr('nan') mpfr('nan') >>> mpfr('nan') / a mpfr('nan') >>> mpfr('nan') / mpfr(0) mpfr('nan') >>> mpfr('nan') / mpfr(0) mpfr('nan') >>> divmod(a, float('Inf')) (mpfr('0.0'), mpfr('12.34')) >>> divmod(a, float('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, float('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, float('-Inf')) (mpfr('0.0'), mpfr('-12.34')) >>> divmod(a, float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr(0), float('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(mpfr(0), float('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(mpfr(0), float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), mpfr(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), mpfr(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), mpfr(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(a, mpfr('Inf')) (mpfr('0.0'), mpfr('12.34')) >>> divmod(a, mpfr('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, mpfr('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, mpfr('-Inf')) (mpfr('0.0'), mpfr('-12.34')) >>> divmod(a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr(0), mpfr('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(mpfr(0), mpfr('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(mpfr(0), mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), mpfr(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), mpfr(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), mpfr(0)) (mpfr('nan'), mpfr('nan')) Test Number Protocol -------------------- >>> a.real mpfr('12.34') >>> a.imag mpfr('0.0') >>> a.conjugate() mpfr('12.34') Test sign function ------------------ >>> gmpy2.sign(-1.5) -1 >>> gmpy2.sign(a) 1 >>> gmpy2.sign(mpfr(0)) 0 >>> gmpy2.sign(mpfr('inf')) 1 >>> gmpy2.sign(mpfr('-inf')) -1 >>> gmpy2.sign(mpfr('nan')) 0 gmpy2-2.1.0b3/test/test_mpfr4_fused.txt0000664000175000017500000000133113363134335017646 0ustar casecase00000000000000Test MPFR4 specific fused multiply/add functions ================================================ >>> import gmpy2 >>> from gmpy2 import ieee, mpz, mpq, mpfr, mpc, fmma, fmms >>> fmma(2,3,4,5) mpz(26) >>> fmma(2,3,-4,5) mpz(-14) >>> fmma(2.0,3,-4, mpq(5)) mpfr('-14.0') >>> fmma(2,3.0,-4,5) mpfr('-14.0') >>> fmma(2,3,-4.0,5) mpfr('-14.0') >>> fmma(2,mpfr(3),-4.0,5) mpfr('-14.0') >>> fmma(mpc(2),mpfr(3),-4.0,5) Traceback (most recent call last): File "", line 1, in TypeError: fmma() argument type not supported >>> fmms(2,3,4,5) mpz(-14) >>> fmms(2,3,-4,5) mpz(26) >>> ieee(128).fmma(7,1/7,-1,3/11) mpfr('0.727272727272727237401994671017746441',113) >>> ieee(128).fmma(7,mpq(1,7),-1,mpq(3,11)) mpq(8,11) gmpy2-2.1.0b3/test/test_mpfr4_random.txt0000664000175000017500000000101613356026702020020 0ustar casecase00000000000000Test gmpy2 Random mpfr and mpc based on MPFR4 ============================================= >>> import gmpy2 as gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from gmpy2 import random_state >>> gmpy2.mpfr_random(random_state(42)) mpfr('0.93002690534702315') >>> gmpy2.mpfr_grandom(random_state(42)) (mpfr('-0.32898912492644183'), mpfr('0.03656576719642516')) >>> gmpy2.mpfr_nrandom(random_state(42)) mpfr('-0.32898912492644183') >>> gmpy2.mpc_random(random_state(42)) mpc('0.86555158787663011+0.4422082613292212j') gmpy2-2.1.0b3/test/test_mpfr_create.txt0000664000175000017500000001252513244654531017731 0ustar casecase00000000000000MPFR Functionality ================== This file tests the mpfr() function that is used to create mpfr instances. >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr >>> import decimal >>> import fractions >>> from fractions import Fraction as F Test creation using default context ----------------------------------- >>> mpfr() mpfr('0.0') >>> mpfr(0) mpfr('0.0') >>> mpfr(1) mpfr('1.0') >>> mpfr(-1) mpfr('-1.0') >>> mpfr("123e17") mpfr('1.23e+19') >>> mpfr("foo") Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpfr(1,100) mpfr('1.0',100) >>> mpfr("1",100) mpfr('1.0',100) >>> mpfr("1","hi") Traceback (most recent call last): File "", line 1, in TypeError: base for mpfr() must be an integer >>> mpfr("-inf") mpfr('-inf') >>> mpfr("inf") mpfr('inf') >>> mpfr("nan") mpfr('nan') >>> mpfr(float("-inf")) mpfr('-inf') >>> mpfr(float("inf")) mpfr('inf') >>> mpfr(float("nan")) mpfr('nan') >>> mpfr(float("0")) mpfr('0.0') >>> mpfr(float("-0")) mpfr('-0.0') >>> mpfr("-0") mpfr('-0.0') >>> a = float("1.2345678901234567890") >>> b = mpfr("1.2345678901234567890") >>> a 1.2345678901234567 >>> b mpfr('1.2345678901234567') >>> a == b True >>> c = mpfr(b) >>> b is c True >>> mpfr(F(0,1)) mpfr('0.0') >>> mpfr(F(0,-1)) mpfr('0.0') >>> mpfr(F(1,2)) mpfr('0.5') >>> mpfr(-1) mpfr('-1.0') >>> mpfr(12345678901234567890) mpfr('1.2345678901234567e+19') >>> mpfr(mpz(12345678901234567890)) mpfr('1.2345678901234567e+19') >>> mpfr(mpz(-1)) mpfr('-1.0') >>> mpfr(2**15 - 1) mpfr('32767.0') >>> mpfr(2**15) mpfr('32768.0') >>> mpfr(2**15 + 1) mpfr('32769.0') >>> mpfr(2**30 - 1) mpfr('1073741823.0') >>> mpfr(2**30 ) mpfr('1073741824.0') >>> mpfr(2**30 + 1) mpfr('1073741825.0') >>> ctx=gmpy2.get_context() >>> ctx.clear_flags() >>> a=mpfr("1.2") >>> a.rc -1 >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> ctx.clear_flags() >>> a=mpfr("1.25") >>> a.rc 0 >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> ctx.clear_flags() >>> a=mpfr('nan') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=True, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> ctx.clear_flags() >>> mpfr(a) mpfr('nan') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) >>> ctx.clear_flags() >>> mpfr(float('nan')) mpfr('nan') >>> ctx context(precision=53, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=False, trap_invalid=False, invalid=True, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) Create using extended precision ------------------------------- >>> gmpy2.set_context(gmpy2.ieee(128)) >>> mpfr(1)/7 mpfr('0.14285714285714285714285714285714285',113) >>> mpfr(1.0/7) mpfr('0.142857142857142849212692681248881854',113) >>> mpfr(1.0/7).digits(2) ('10010010010010010010010010010010010010010010010010010000000000000000000000000000000000000000000000000000000000000', -2, 113) >>> gmpy2.set_context(gmpy2.ieee(32)) >>> mpfr(1)/7 mpfr('0.142857149',24) >>> (mpfr(1)/7).digits(2) ('100100100100100100100101', -2, 24) >>> mpfr(1.0/7) mpfr('0.142857149',24) >>> mpfr(1.0/7).digits(2) ('100100100100100100100101', -2, 24) >>> mpfr(1.0/7, precision=0) mpfr('0.142857149',24) >>> mpfr(1.0/7, precision=1) mpfr('0.14285714285714285') >>> gmpy2.set_context(gmpy2.context()) gmpy2-2.1.0b3/test/test_mpfr_dec.txt0000664000175000017500000000515413105222070017202 0ustar casecase00000000000000Interoperability with Decimal ============================= >>> import gmpy2 as G >>> from gmpy2 import mpz, mpq, mpfr >>> from decimal import Decimal Test comparisons ---------------- Non-trivial comparions between mpfr and Decimal instances are only equal when the fractional can be written at 1/2**n. >>> mpfr('123.456') == Decimal('123.456') False >>> mpfr('123.5') == Decimal('123.5') True >>> mpq(123456,1000) == Decimal('123.456') True >>> mpz(123) == Decimal(123) True >>> mpfr('123.456') > Decimal('123.456') True >>> mpfr('123.456') < Decimal('123.456') False >>> Decimal('123.456') > mpfr('123.456') False >>> Decimal('123.456') < mpfr('123.456') True Test elementary operations -------------------------- >>> mpz(23) == Decimal(23) True >>> mpz(Decimal('123.456')) mpz(123) >>> mpq(Decimal('123.456')) mpq(15432,125) >>> mpfr(Decimal('123.456')) mpfr('123.456') >>> f = mpfr('123.456') >>> q = mpq('789123/1000') >>> z = mpz('234') >>> dd = Decimal('12.34') >>> fd = Decimal('123.456') >>> qd = Decimal('789.123') >>> zd = Decimal('234') >>> f+dd mpfr('135.79599999999999') >>> dd+f mpfr('135.79599999999999') >>> q+dd mpfr('801.46300000000008') >>> dd+q mpfr('801.46300000000008') >>> z+dd mpfr('246.34') >>> dd+z mpfr('246.34') >>> f-dd mpfr('111.116') >>> dd-f mpfr('-111.116') >>> q-dd mpfr('776.78300000000002') >>> dd-q mpfr('-776.78300000000002') >>> z-dd mpfr('221.66') >>> dd-z mpfr('-221.66') >>> f*dd mpfr('1523.44704') >>> dd*f mpfr('1523.44704') >>> q*dd mpfr('9737.7778200000012') >>> dd*q mpfr('9737.7778200000012') >>> z*dd mpfr('2887.5599999999999') >>> dd*z mpfr('2887.5599999999999') >>> f/dd mpfr('10.00453808752026') >>> dd/f mpfr('0.099954639709694135') >>> q/dd mpfr('63.948379254457052') >>> dd/q mpfr('0.015637612894314319') >>> z/dd mpfr('18.962722852512155') >>> dd/z mpfr('0.052735042735042738') >>> G.ceil(dd) mpfr('13.0') >>> G.floor(dd) mpfr('12.0') >>> G.trunc(dd) mpfr('12.0') >>> mpfr(dd).precision 53 >>> G.sin(Decimal("123.456")) mpfr('-0.80393736857282394') >>> G.sqrt(Decimal("123.456")) mpfr('11.111075555498667') >>> G.is_nan(Decimal("123.456")) False >>> G.is_nan(Decimal("NaN")) True >>> G.is_nan(Decimal("Inf")) False >>> G.is_inf(Decimal("Inf")) True >>> G.is_inf(Decimal("-Inf")) True gmpy2-2.1.0b3/test/test_mpfr_exp_log.txt0000664000175000017500000000062613170047220020107 0ustar casecase00000000000000MPFR Functionality ================== >>> import gmpy2 as G >>> from gmpy2 import mpz,mpfr >>> a = mpz(123) >>> b = mpz(456) Test special functions ====================== Test cbrt --------- Test exp -------- Test exp10 ---------- Test exp2 --------- Test expm1 ---------- Test hypot ---------- Test log -------- Test log10 ---------- Test log1p ---------- Test log2 --------- gmpy2-2.1.0b3/test/test_mpfr_min_max.txt0000664000175000017500000000223013105222070020067 0ustar casecase00000000000000Testing of mpfr maxnum and minnum functions ------------------------------------------- >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, maxnum, minnum >>> a = mpfr("12.34") >>> b = mpfr("45.67") >>> nan = mpfr("nan") >>> inf = mpfr("inf") >>> minf = mpfr("-inf") Test maxnum ----------- >>> maxnum(a,b) mpfr('45.670000000000002') >>> maxnum(b,a) mpfr('45.670000000000002') >>> maxnum(a,-b) mpfr('12.34') >>> maxnum(a, 123456) mpfr('123456.0') >>> maxnum(12345678901234567890, a) mpfr('1.2345678901234567e+19') >>> maxnum(0, -1) mpfr('0.0') >>> maxnum(1, inf) mpfr('inf') >>> maxnum(1, -inf) mpfr('1.0') >>> maxnum(nan, a) mpfr('12.34') >>> maxnum(a, nan) mpfr('12.34') >>> maxnum(nan, inf) mpfr('inf') >>> maxnum(nan, -inf) mpfr('-inf') >>> maxnum(nan, nan) mpfr('nan') Test minnum ----------- >>> minnum(a,b) mpfr('12.34') >>> minnum(b,a) mpfr('12.34') >>> minnum(1,inf) mpfr('1.0') >>> minnum(minf, a) mpfr('-inf') >>> minnum(nan, inf) mpfr('inf') >>> minnum(nan, nan) mpfr('nan') gmpy2-2.1.0b3/test/test_mpfr_special.txt0000664000175000017500000000205213105222070020061 0ustar casecase00000000000000Test mpfr special functions --------------------------- >>> import gmpy2 >>> from gmpy2 import mpfr Test agm -------- Test ai ------- Test const_catalan ------------------ Test const_euler ---------------- Test const_log2 --------------- Test const_pi ------------- Test digamma ------------ Test eint --------- Test erf -------- Test erfc --------- Test factorial -------------- Test f2q -------- Test fma -------- Test fmod --------- Test fms -------- Test frac --------- Test frexp ---------- Test fsum --------- Test gamma ---------- Test j0 ------- Test j1 ------- Test jn ------- Test lgamma ----------- Test li2 -------- Test lngamma ------------ Test modf --------- Test mul_2exp ------------- Test next_above --------------- Test next_below --------------- Test next_toward ---------------- Test rec_sqrt ------------- Test reldiff ------------ Test remainder -------------- Test remquo ----------- Test root --------- Test sqrt --------- Test y0 ------- Test y1 ------- Test yn ------- Test zeta --------- gmpy2-2.1.0b3/test/test_mpfr_subnormalize.txt0000664000175000017500000000167613170047220021172 0ustar casecase00000000000000MPFR Subnormalize ================== >>> import gmpy2 >>> gmpy2.set_context(gmpy2.ieee(64)) >>> zeroes = '0.' + '0' * 323 >>> gmpy2.mpfr(zeroes + '2470328229206232720') mpfr('0.0') >>> gmpy2.mpfr(zeroes + '2470328229206232721') mpfr('4.9406564584124654e-324') >>> gmpy2.mpfr(zeroes + '247032822920623272088') mpfr('0.0') >>> gmpy2.mpfr(zeroes + '247032822920623272089') mpfr('4.9406564584124654e-324') >>> gmpy2.set_context(gmpy2.ieee(32)) >>> def fmt(v): ... return '{:.23b}'.format(v) ... >>> a = gmpy2.mpfr('0x1p-126') >>> fmt(a) '1.00000000000000000000000p-126' >>> fmt(gmpy2.next_below(a)) '1.11111111111111111111110p-127' >>> fmt(gmpy2.next_above(a)) '1.00000000000000000000001p-126' >>> fmt(gmpy2.next_below(0)) '-1.00000000000000000000000p-149' >>> fmt(gmpy2.next_above(0)) '1.00000000000000000000000p-149' >>> fmt(gmpy2.next_toward(a, -10)) '1.11111111111111111111110p-127' >>> fmt(gmpy2.next_toward(a, 10)) '1.00000000000000000000001p-126' gmpy2-2.1.0b3/test/test_mpfr_to_from_binary.txt0000664000175000017500000000233213105222070021453 0ustar casecase00000000000000Testing of gmpy2 mpfr to_binary and from_binary ----------------------------------------------- >>> import gmpy2 >>> from gmpy2 import mpfr,to_binary,from_binary Test ---- >>> x=mpfr("0");x==from_binary(to_binary(x)) True >>> x=mpfr("1");x==from_binary(to_binary(x)) True >>> x=mpfr("-1");x==from_binary(to_binary(x)) True >>> x=mpfr("inf");x==from_binary(to_binary(x)) True >>> x=mpfr("-inf");x==from_binary(to_binary(x)) True >>> x=mpfr("nan");gmpy2.is_nan(from_binary(to_binary(x))) True >>> x=mpfr(1.345);x==from_binary(to_binary(x)) True >>> x=mpfr("1.345e1000");x==from_binary(to_binary(x)) True >>> x=gmpy2.const_pi() >>> x.rc -1 >>> y=from_binary(to_binary(x)) >>> x==y True >>> y.rc -1 >>> gmpy2.get_context().precision=100 >>> x=gmpy2.const_pi();x==from_binary(to_binary(x)) True >>> gmpy2.get_context().precision=200 >>> x=mpfr(gmpy2.const_pi());x==from_binary(to_binary(x)) True >>> gmpy2.get_context().precision=200 >>> x=gmpy2.const_pi() >>> gmpy2.get_context().precision=300 >>> x=from_binary(to_binary(x)) >>> x.precision 200 >>> gmpy2.set_context(gmpy2.context()) gmpy2-2.1.0b3/test/test_mpfr_trig.txt0000664000175000017500000003060413444603111017417 0ustar casecase00000000000000MPFR Functionality ================== >>> import gmpy2 >>> from gmpy2 import mpfr, mpq, mpz >>> from fractions import Fraction as F >>> import sys Test trigonometric operations ============================= Note: gmpy2 returns InvalidOperationError whereas the math module returns ValueError. The test of acos verifies that InvalidOperationError is sub- classed from ValueError. Note: The math module assumes non-signaling NaNs; math.acos(float("nan")) does not raise an exception. But math.acos(float("inf")) and math.acos(float("-inf")) do raise exceptions. MPFR treats NaN as a signaling NaN and raises an exception if trap_invalid is True. Test acos --------- >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.acos(mpfr("0.2")).as_integer_ratio() (mpz(6167402294989009), mpz(4503599627370496)) >>> gmpy2.acos() Traceback (most recent call last): File "", line 1, in TypeError: acos() takes exactly one argument (0 given) >>> gmpy2.acos("a") Traceback (most recent call last): File "", line 1, in TypeError: acos() argument type not supported >>> gmpy2.acos(0,0) Traceback (most recent call last): File "", line 1, in TypeError: acos() takes exactly one argument (2 given) >>> gmpy2.acos(0) mpfr('1.5707963267948966') >>> gmpy2.acos(mpz(0)) mpfr('1.5707963267948966') >>> gmpy2.acos(mpq(1,2)) mpfr('1.0471975511965979') >>> gmpy2.acos(F(1,2)) mpfr('1.0471975511965979') >>> gmpy2.acos(mpfr("nan")) mpfr('nan') >>> gmpy2.acos(mpfr("inf")) mpfr('nan') >>> gmpy2.acos(mpfr("-inf")) mpfr('nan') >>> gmpy2.set_context(gmpy2.context(trap_invalid=True)) >>> gmpy2.acos(mpfr("nan")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.acos(mpfr("inf")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.acos(mpfr("-inf")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.set_context(gmpy2.context(precision=100)) >>> gmpy2.acos(mpfr("0.2")) mpfr('1.3694384060045658277761961394221',100) >>> gmpy2.get_context() context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) Test asin --------- >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.asin(mpfr("0.2")).as_integer_ratio() (mpz(7254683656315453), mpz(36028797018963968)) >>> gmpy2.asin() Traceback (most recent call last): File "", line 1, in TypeError: asin() takes exactly one argument (0 given) >>> gmpy2.asin("a") Traceback (most recent call last): File "", line 1, in TypeError: asin() argument type not supported >>> gmpy2.asin(0,0) Traceback (most recent call last): File "", line 1, in TypeError: asin() takes exactly one argument (2 given) >>> gmpy2.asin(0) mpfr('0.0') >>> gmpy2.asin(mpz(0)) mpfr('0.0') >>> gmpy2.asin(mpq(1,2)) mpfr('0.52359877559829893') >>> gmpy2.asin(F(1,2)) mpfr('0.52359877559829893') >>> gmpy2.asin(mpfr("nan")) mpfr('nan') >>> gmpy2.asin(mpfr("inf")) mpfr('nan') >>> gmpy2.asin(mpfr("-inf")) mpfr('nan') >>> gmpy2.set_context(gmpy2.context(trap_invalid=True)) >>> gmpy2.asin(mpfr("nan")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.asin(mpfr("inf")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.asin(mpfr("-inf")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.set_context(gmpy2.context(precision=100)) >>> gmpy2.asin(mpfr("0.2")) mpfr('0.20135792079033079145512555221757',100) >>> gmpy2.get_context() context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) Test atan --------- >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.atan(mpfr("0.2")).as_integer_ratio() (mpz(1777981139569027), mpz(9007199254740992)) >>> gmpy2.atan(mpfr("100")).as_integer_ratio() (mpz(3514601628432273), mpz(2251799813685248)) >>> gmpy2.atan() Traceback (most recent call last): File "", line 1, in TypeError: atan() takes exactly one argument (0 given) >>> gmpy2.atan("a") Traceback (most recent call last): File "", line 1, in TypeError: atan() argument type not supported >>> gmpy2.atan(0,0) Traceback (most recent call last): File "", line 1, in TypeError: atan() takes exactly one argument (2 given) >>> gmpy2.atan(0) mpfr('0.0') >>> gmpy2.atan(mpz(0)) mpfr('0.0') >>> gmpy2.atan(mpq(1,2)) mpfr('0.46364760900080609') >>> gmpy2.atan(F(1,2)) mpfr('0.46364760900080609') >>> gmpy2.atan(mpfr("nan")) mpfr('nan') >>> gmpy2.atan(mpfr("inf")) mpfr('1.5707963267948966') >>> gmpy2.atan(mpfr("-inf")) mpfr('-1.5707963267948966') >>> gmpy2.set_context(gmpy2.context(trap_invalid=True)) >>> gmpy2.atan(mpfr("nan")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.set_context(gmpy2.context(precision=100)) >>> gmpy2.atan(mpfr("0.2")) mpfr('0.19739555984988075837004976519484',100) >>> gmpy2.get_context() context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) Test atan2 ---------- >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.atan2(1,2).as_integer_ratio() (mpz(8352332796509007), mpz(18014398509481984)) >>> gmpy2.atan2(-1,2).as_integer_ratio() (mpz(-8352332796509007), mpz(18014398509481984)) >>> gmpy2.atan2(1,-2).as_integer_ratio() (mpz(3015098076232407), mpz(1125899906842624)) >>> gmpy2.atan2(-1,-2).as_integer_ratio() (mpz(-3015098076232407), mpz(1125899906842624)) >>> gmpy2.atan2(float("0"),float("0")).as_integer_ratio() (mpz(0), mpz(1)) >>> gmpy2.atan2(float("-0"),float("0")).as_integer_ratio() (mpz(0), mpz(1)) >>> gmpy2.atan2(float("0"),float("-0")).as_integer_ratio() (mpz(884279719003555), mpz(281474976710656)) >>> gmpy2.atan2(float("-0"),float("-0")).as_integer_ratio() (mpz(-884279719003555), mpz(281474976710656)) >>> gmpy2.atan2(float("inf"),float("inf")).as_integer_ratio() (mpz(884279719003555), mpz(1125899906842624)) >>> gmpy2.atan2(float("-inf"),float("inf")).as_integer_ratio() (mpz(-884279719003555), mpz(1125899906842624)) >>> gmpy2.atan2(float("inf"),float("-inf")).as_integer_ratio() (mpz(2652839157010665), mpz(1125899906842624)) >>> gmpy2.atan2(float("-inf"),float("-inf")).as_integer_ratio() (mpz(-2652839157010665), mpz(1125899906842624)) Test cos -------- >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.cos(mpfr("0.2")).as_integer_ratio() (mpz(4413827474764093), mpz(4503599627370496)) >>> gmpy2.cos(mpfr("20")).as_integer_ratio() == (mpz(7351352886077503), mpz(18014398509481984)) or (sys.platform == 'win32') True >>> gmpy2.cos(mpfr("2000")).as_integer_ratio() (mpz(-3309781376808469), mpz(9007199254740992)) >>> gmpy2.cos() Traceback (most recent call last): File "", line 1, in TypeError: cos() takes exactly one argument (0 given) >>> gmpy2.cos("a") Traceback (most recent call last): File "", line 1, in TypeError: cos() argument type not supported >>> gmpy2.cos(0,0) Traceback (most recent call last): File "", line 1, in TypeError: cos() takes exactly one argument (2 given) >>> gmpy2.cos(0) mpfr('1.0') >>> gmpy2.cos(mpz(0)) mpfr('1.0') >>> gmpy2.cos(mpq(1,2)) mpfr('0.87758256189037276') >>> gmpy2.cos(F(1,2)) mpfr('0.87758256189037276') >>> gmpy2.cos(mpfr("nan")) mpfr('nan') >>> gmpy2.cos(mpfr("inf")) mpfr('nan') >>> gmpy2.cos(mpfr("-inf")) mpfr('nan') >>> gmpy2.set_context(gmpy2.context(trap_invalid=True)) >>> gmpy2.cos(mpfr("nan")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.cos(mpfr("inf")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.cos(mpfr("-inf")) Traceback (most recent call last): File "", line 1, in InvalidOperationError: invalid operation >>> gmpy2.set_context(gmpy2.context(precision=100)) >>> gmpy2.cos(mpfr("0.2")) mpfr('0.98006657784124163112419651674809',100) >>> gmpy2.get_context() context(precision=100, real_prec=Default, imag_prec=Default, round=RoundToNearest, real_round=Default, imag_round=Default, emax=1073741823, emin=-1073741823, subnormalize=False, trap_underflow=False, underflow=False, trap_overflow=False, overflow=False, trap_inexact=False, inexact=True, trap_invalid=False, invalid=False, trap_erange=False, erange=False, trap_divzero=False, divzero=False, allow_complex=False, rational_division=False) Test cot -------- >>> gmpy2.set_context(gmpy2.context()) >>> gmpy2.cot(mpfr("0.2")).as_integer_ratio() (mpz(173569956714485), mpz(35184372088832)) >>> gmpy2.cot(gmpy2.const_pi()).as_integer_ratio() (mpz(-8165619676597685), mpz(1)) >>> gmpy2.cot(1) mpfr('0.64209261593433076') >>> gmpy2.cot(float('0')) mpfr('inf') >>> gmpy2.cot(float('-0')) mpfr('-inf') >>> gmpy2.cot(mpfr('0')) mpfr('inf') >>> gmpy2.cot(mpfr('-0')) mpfr('-inf') Test csc -------- >>> r2 = mpfr('5.6') >>> gmpy2.csc(r2) mpfr('-1.5841166632383596') Test sec -------- >>> gmpy2.sec(r2) mpfr('1.2893811186238056') Test sin -------- >>> r = mpfr(5.6) >>> gmpy2.sin(r) mpfr('-0.63126663787232162') >>> gmpy2.sin(r) == gmpy2.sin(5.6) True Test sin_cos ------------ >>> gmpy2.sin_cos(r) (mpfr('-0.63126663787232162'), mpfr('0.77556587851024961')) >>> gmpy2.sin_cos(r) == gmpy2.sin_cos(5.6) True >>> gmpy2.sin_cos(r) == (gmpy2.sin(r), gmpy2.cos(r)) True Test tan -------- >>> gmpy2.tan(r) mpfr('-0.8139432836897027') Test acosh ---------- >>> gmpy2.acosh(r) mpfr('2.4078447868719399') Test asinh ---------- >>> gmpy2.asinh(r) mpfr('2.4237920435875173') Test atanh ---------- >>> gmpy2.atanh(mpfr(0.365)) mpfr('0.38264235436318422') >>> gmpy2.atanh(mpfr(0.365)) == gmpy2.atanh(0.365) True Test cosh --------- >>> gmpy2.cosh(r) mpfr('135.2150526449345') >>> gmpy2.cosh(r) == gmpy2.cosh(5.6) True Test coth --------- >>> gmpy2.coth(r) mpfr('1.0000273487661038') Test csch --------- >>> gmpy2.csch(r) mpfr('0.0073958285649757295') >>> gmpy2.csch(r) mpfr('0.0073958285649757295') Test degrees ------------ >>> rad = mpfr(1.57) >>> ctx = gmpy2.get_context() >>> ctx.degrees(rad) mpfr('89.954373835539243') >>> gmpy2.degrees(rad) mpfr('89.954373835539243') >>> gmpy2.degrees(1) mpfr('57.295779513082323') Test radians ------------- >>> deg = mpfr(90) >>> ctx.radians(deg) mpfr('1.5707963267948966') >>> gmpy2.radians(deg) mpfr('1.5707963267948966') >>> gmpy2.radians(45) mpfr('0.78539816339744828') >>> gmpy2.radians(mpz(20)) mpfr('0.3490658503988659') >>> gmpy2.radians(mpfr('inf')) mpfr('inf') >>> gmpy2.radians(mpfr('nan')) mpfr('nan') Test sech --------- >>> gmpy2.sech(r) mpfr('0.0073956263037217584') Test sinh --------- >>> gmpy2.sinh(r) mpfr('135.21135478121803') >>> gmpy2.sinh(r) == gmpy2.sinh(5.6) True Test sinh_cosh -------------- >>> gmpy2.sinh_cosh(r) (mpfr('135.21135478121803'), mpfr('135.2150526449345')) >>> gmpy2.sinh_cosh(r) == gmpy2.sinh_cosh(5.6) True >>> gmpy2.sinh_cosh(r) == (gmpy2.sinh(r), gmpy2.cosh(r)) True Test tanh --------- >>> gmpy2.tanh(r) mpfr('0.99997265198183083') gmpy2-2.1.0b3/test/test_mpq.txt0000664000175000017500000002270713473017121016232 0ustar casecase00000000000000MPQ Functionality ================= Testing of mpq functionality is split into multiple files. >>> import gmpy2 as G >>> ctx = G.get_context() >>> from fractions import Fraction as F >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from supportclasses import * >>> a = mpq(3,11) >>> b = mpq(1,2) >>> c = F(5,7) Test elementary operations ========================== Test addition ------------- Test subtraction ---------------- >>> a-b mpq(-5,22) >>> b-a mpq(5,22) >>> a-1 mpq(-8,11) >>> 1-a mpq(8,11) >>> a-c mpq(-34,77) >>> c-a mpq(34,77) >>> a-a mpq(0,1) >>> a-mpz(123456) mpq(-1358013,11) >>> mpz(-123456)-a mpq(-1358019,11) >>> a-'b' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for -: 'mpq' and 'str' >>> 'b'-a Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for -: 'str' and 'mpq' >>> 1 1 Test multiplication ------------------- >>> a*b mpq(3,22) >>> b*a mpq(3,22) >>> a*0 mpq(0,1) >>> 0*a mpq(0,1) >>> a*-1 mpq(-3,11) >>> -1*a mpq(-3,11) >>> a*mpz(17) mpq(51,11) >>> mpz(17)*a mpq(51,11) >>> a*a mpq(9,121) >>> a*'b' Traceback (most recent call last): File "", line 1, in TypeError: can't multiply sequence by non-int of type 'mpq' >>> 'b'*a Traceback (most recent call last): File "", line 1, in TypeError: can't multiply sequence by non-int of type 'mpq' >>> 1 1 Test division ------------- >>> a//b mpz(0) >>> b//a mpz(1) >>> a/b mpq(6,11) >>> gmpy2.div(a, b) mpq(6,11) >>> ctx.div(a, b) mpq(6,11) >>> b/a mpq(11,6) >>> a/0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> a//0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> 0//a mpz(0) >>> 0/a mpq(0,1) >>> mpq(355, 113) // 2 mpz(1) >>> mpq(355, 113) // mpz(2) mpz(1) >>> a / z mpq(3,22) >>> mpq(355, 113) // z mpz(1) >>> mpq(3,11) / q mpq(2,11) >>> mpq(3,11) // q mpz(0) >>> a / mpc(5, 4) mpc('0.03325942350332594-0.02660753880266075j') >>> a / mpq(0,1) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> a / 'str' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for /: 'mpq' and 'str' >>> 1 1 Test modulo ----------- >>> a%b mpq(3,11) >>> b%a mpq(5,22) >>> a%z mpq(3,11) >>> mpq(3,1) % q mpq(0,1) >>> divmod(a,b) (mpz(0), mpq(3,11)) >>> divmod(b,a) (mpz(1), mpq(5,22)) >>> divmod(a,0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: 'mpq' division or modulo by zero >>> a % mpq(0,5) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.mod(a, mpfr(1.5)) mpfr('0.27272727272727271') >>> ctx.mod(a, mpc(0.5, 2)) Traceback (most recent call last): File "", line 1, in TypeError: can't take mod of complex number >>> ctx.mod(a, mpq(0, 2)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> divmod(17,a) (mpz(62), mpq(1,11)) >>> divmod(mpz(17),a) (mpz(62), mpq(1,11)) >>> divmod(a,c) (mpz(0), mpq(3,11)) >>> a % mpfr(1.5) mpfr('0.27272727272727271') >>> a % mpc(0.5, 2) Traceback (most recent call last): File "", line 1, in TypeError: can't take mod of complex number >>> a % 'str' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for %: 'mpq' and 'str' >>> ctx.mod(a, 'str') Traceback (most recent call last): File "", line 1, in TypeError: mod() argument type not supported >>> 1 1 Test pickle ----------- >>> import pickle >>> pickle.loads(pickle.dumps(G.mpq(1234,6789))) mpq(1234,6789) >>> pickle.loads(pickle.dumps(G.mpq(-1234,6789))) mpq(-1234,6789) >>> pickle.loads(pickle.dumps(G.mpq(0,1))) mpq(0,1) >>> 1 Test operations involving NaN/Inf --------------------------------- >>> a + float('Inf') mpfr('inf') >>> float('Inf') + a mpfr('inf') >>> a + float('-Inf') mpfr('-inf') >>> float('-Inf') + a mpfr('-inf') >>> a + float('nan') mpfr('nan') >>> float('nan') + a mpfr('nan') >>> a - float('Inf') mpfr('-inf') >>> float('Inf') - a mpfr('inf') >>> a - float('-Inf') mpfr('inf') >>> float('-Inf') - a mpfr('-inf') >>> a - float('nan') mpfr('nan') >>> float('nan') - a mpfr('nan') >>> a * float('Inf') mpfr('inf') >>> float('Inf') * a mpfr('inf') >>> a * float('-Inf') mpfr('-inf') >>> float('-Inf') * a mpfr('-inf') >>> -a * float('Inf') mpfr('-inf') >>> float('Inf') * -a mpfr('-inf') >>> -a * float('-Inf') mpfr('inf') >>> float('-Inf') * -a mpfr('inf') >>> a * float('nan') mpfr('nan') >>> float('nan') * a mpfr('nan') >>> G.mpz(0) * float('Inf') mpfr('nan') >>> G.mpz(0) * float('-Inf') mpfr('nan') >>> float('Inf') * G.mpz(0) mpfr('nan') >>> float('-Inf') * G.mpz(0) mpfr('nan') >>> a / float('Inf') mpfr('0.0') >>> -a / float('Inf') mpfr('-0.0') >>> float('Inf') / a mpfr('inf') >>> float('Inf') / -a mpfr('-inf') >>> a / float('-Inf') mpfr('-0.0') >>> -a / float('-Inf') mpfr('0.0') >>> float('-Inf') / a mpfr('-inf') >>> float('-Inf') / -a mpfr('inf') >>> a / float('nan') mpfr('nan') >>> float('nan') / a mpfr('nan') >>> float('nan') / G.mpz(0) mpfr('nan') >>> float('nan') / G.mpz(0) mpfr('nan') >>> a + mpfr('Inf') mpfr('inf') >>> mpfr('Inf') + a mpfr('inf') >>> a + mpfr('-Inf') mpfr('-inf') >>> mpfr('-Inf') + a mpfr('-inf') >>> a + mpfr('nan') mpfr('nan') >>> mpfr('nan') + a mpfr('nan') >>> a - mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') - a mpfr('inf') >>> a - mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') - a mpfr('-inf') >>> a - mpfr('nan') mpfr('nan') >>> mpfr('nan') - a mpfr('nan') >>> a * mpfr('Inf') mpfr('inf') >>> mpfr('Inf') * a mpfr('inf') >>> a * mpfr('-Inf') mpfr('-inf') >>> mpfr('-Inf') * a mpfr('-inf') >>> -a * mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') * -a mpfr('-inf') >>> -a * mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') * -a mpfr('inf') >>> a * mpfr('nan') mpfr('nan') >>> mpfr('nan') * a mpfr('nan') >>> G.mpz(0) * mpfr('Inf') mpfr('nan') >>> G.mpz(0) * mpfr('-Inf') mpfr('nan') >>> mpfr('Inf') * G.mpz(0) mpfr('nan') >>> mpfr('-Inf') * G.mpz(0) mpfr('nan') >>> a / mpfr('Inf') mpfr('0.0') >>> -a / mpfr('Inf') mpfr('-0.0') >>> mpfr('Inf') / a mpfr('inf') >>> mpfr('Inf') / -a mpfr('-inf') >>> a / mpfr('-Inf') mpfr('-0.0') >>> -a / mpfr('-Inf') mpfr('0.0') >>> mpfr('-Inf') / a mpfr('-inf') >>> mpfr('-Inf') / -a mpfr('inf') >>> a / mpfr('nan') mpfr('nan') >>> mpfr('nan') / a mpfr('nan') >>> mpfr('nan') / G.mpz(0) mpfr('nan') >>> mpfr('nan') / G.mpz(0) mpfr('nan') >>> divmod(a, float('Inf')) (mpfr('0.0'), mpfr('0.27272727272727271')) >>> divmod(a, float('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, float('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, float('-Inf')) (mpfr('0.0'), mpfr('-0.27272727272727271')) >>> divmod(a, float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(G.mpz(0), float('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(G.mpz(0), float('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(G.mpz(0), float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(a, mpfr('Inf')) (mpfr('0.0'), mpfr('0.27272727272727271')) >>> divmod(a, mpfr('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, mpfr('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, mpfr('-Inf')) (mpfr('0.0'), mpfr('-0.27272727272727271')) >>> divmod(a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(G.mpz(0), mpfr('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(G.mpz(0), mpfr('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(G.mpz(0), mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> 1 1 Test qdiv --------- >>> gmpy2.qdiv(8,1) mpz(8) >>> gmpy2.qdiv(8,2) mpz(4) >>> gmpy2.qdiv(8,3) mpq(8,3) >>> gmpy2.qdiv(8,4) mpz(2) >>> gmpy2.qdiv(gmpy2.mpq(3,4), gmpy2.mpq(1,3)) mpq(9,4) >>> gmpy2.qdiv(gmpy2.mpq(3,4), gmpy2.mpq(1,4)) mpz(3) >>> args = gmpy2.mpq(2), 1/gmpy2.mpq(2) >>> gmpy2.qdiv(*args) mpz(4) >>> args == (gmpy2.mpq(2), 1/gmpy2.mpq(2)) True Test Number Protocol -------------------- >>> a.numerator mpz(3) >>> a.denominator mpz(11) >>> a.real mpq(3,11) >>> a.imag mpz(0) >>> a.conjugate() mpq(3,11) Test sign function ------------------ >>> gmpy2.sign(a) 1 >>> gmpy2.sign(-a) -1 >>> gmpy2.sign(mpq(0,5)) 0 >>> gmpy2.sign('str') Traceback (most recent call last): File "", line 1, in TypeError: sign() argument type not supported >>> 1 1 gmpy2-2.1.0b3/test/test_mpq_to_from_binary.txt0000664000175000017500000000065613105222070021313 0ustar casecase00000000000000Testing of gmpy2 mpq to_binary and from_binary ---------------------------------------------- >>> import gmpy2 >>> from gmpy2 import mpq,to_binary,from_binary Test ---- >>> x=mpq(0,1);x==from_binary(to_binary(x)) True >>> x=mpq(1,1);x==from_binary(to_binary(x)) True >>> x=mpq(-1,2);x==from_binary(to_binary(x)) True >>> x=mpq(123456789123456789,9876);x==from_binary(to_binary(x)) True gmpy2-2.1.0b3/test/test_mpz.txt0000664000175000017500000002622313452510214016236 0ustar casecase00000000000000MPZ Functionality ================= Testing of mpz functionality is split into multiple files. test_mpz.txt Test basic functionality and stuff not covered anywhere else. test_mpz_functions.txt Test mpz functions, including error messages. test_mpz_io.txt Test input/output and formating. test_mpz_comp.txt Test comparisons. >>> import gmpy2 as G >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from supportclasses import * >>> from decimal import Decimal as D >>> from fractions import Fraction as F >>> a = mpz(123) >>> b = mpz(456) >>> c = 12345678901234567890 >>> ctx = gmpy2.get_context() Test elementary operations ========================== Test addition ------------- >>> a+1 mpz(124) >>> a+(-1) mpz(122) >>> 1+a mpz(124) >>> (-1)+a mpz(122) >>> a+b mpz(579) >>> b+a mpz(579) >>> a+'b' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'mpz' and 'str' >>> 'b'+a Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> print(a+c) 12345678901234568013 >>> print(c+a) 12345678901234568013 Test subtraction ---------------- >>> a-1 mpz(122) >>> a-(-1) mpz(124) >>> 1-a mpz(-122) >>> (-1)-a mpz(-124) >>> a-b mpz(-333) >>> b-a mpz(333) >>> a-'b' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for -: 'mpz' and 'str' >>> 'b'-a Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> print(a-c) -12345678901234567767 >>> print(c-a) 12345678901234567767 Test multiplication ------------------- >>> a*b mpz(56088) >>> b*a mpz(56088) >>> a*0 mpz(0) >>> 0*a mpz(0) >>> a*123 mpz(15129) >>> 123*a mpz(15129) >>> print(a*c) 1518518504851851850470 >>> print(c*a) 1518518504851851850470 >>> a*'b' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' >>> 'b'*a 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' Test division ------------- >>> a//b mpz(0) >>> a/b mpfr('0.26973684210526316') >>> gmpy2.div(a, b) mpfr('0.26973684210526316') >>> ctx.div(a, b) mpfr('0.26973684210526316') >>> b//a mpz(3) >>> b/a mpfr('3.7073170731707319') >>> (a*b)//b mpz(123) >>> (a*b)//a mpz(456) >>> a//0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> a/0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> a/0.0 mpfr('inf') >>> print(c//a) 100371373180768844 >>> a**10//c mpz(64) >>> a / z mpfr('61.5') >>> a // z mpz(61) >>> ctx.div(a, b, 5) Traceback (most recent call last): File "", line 1, in TypeError: div() requires 2 arguments. >>> ctx.div(a, 'str') Traceback (most recent call last): File "", line 1, in TypeError: div() argument type not supported >>> a / 'str' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for /: 'mpz' and 'str' >>> 1 1 Test modulo ----------- >>> a % b mpz(123) >>> b % a mpz(87) >>> gmpy2.mod(b, a) mpz(87) >>> ctx.mod(b, a) mpz(87) >>> a % z mpz(1) >>> divmod(a,b) (mpz(0), mpz(123)) >>> divmod(b,a) (mpz(3), mpz(87)) >>> a % mpz(0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> divmod(a,0) Traceback (most recent call last): ... ZeroDivisionError: division or modulo by zero >>> divmod(a, mpz(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> divmod(123, mpz(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> a % 0 Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> 14 % mpz(0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> gmpy2.mod(14, mpz(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> gmpy2.mod(124, 0) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> gmpy2.mod(b, mpz(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> ctx.mod(b, mpz(0)) Traceback (most recent call last): File "", line 1, in ZeroDivisionError: division or modulo by zero >>> gmpy2.mod(124, 'str') Traceback (most recent call last): File "", line 1, in TypeError: mod() argument type not supported >>> a % 'str' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for %: 'mpz' and 'str' >>> gmpy2.mod(124, mpz(5)) mpz(4) >>> divmod(b,123) (mpz(3), mpz(87)) >>> divmod(a,c) (mpz(0), mpz(123)) >>> divmod(a,int(c)) (mpz(0), mpz(123)) >>> print("%s %s" % divmod(a*(c-1),c)) 122 12345678901234567767 >>> print("%s %s" % divmod(a*(c-1),int(c))) 122 12345678901234567767 >>> divmod(a*(c-1),-c) (mpz(-123), mpz(-123)) >>> divmod(a*(c-1),-int(c)) (mpz(-123), mpz(-123)) >>> print("%s %s" % divmod(int(a*(c-1)),-int(c))) -123 -123 >>> z % mpq(1,2) mpq(0,1) >>> a % mpq(2,3) mpq(1,3) Test miscellaneous ------------------ >>> a+True mpz(124) >>> a+False mpz(123) >>> a*False mpz(0) >>> a//True mpz(123) >>> abs(-a) == a True >>> print(pow(a,10)) 792594609605189126649 >>> pow(a,7,b) mpz(99) >>> G.sign(b-a) 1 >>> G.sign(b-b) 0 >>> G.sign(a-b) -1 >>> G.sign(a) 1 >>> G.sign(-a) -1 >>> z=b-b; G.sign(z) 0 Test pickle ----------- >>> import pickle >>> pickle.loads(pickle.dumps(G.mpz(12346789))) mpz(12346789) >>> pickle.loads(pickle.dumps(G.mpz(-12346789))) mpz(-12346789) >>> pickle.loads(pickle.dumps(G.mpz(0))) mpz(0) Test mpz.__index__ ------------------ >>> range(333)[a] 123 >>> range(333)[b] Traceback (innermost last): ... IndexError: range object index out of range >>> 1 1 Test operations involving NaN/Inf --------------------------------- >>> a + float('Inf') mpfr('inf') >>> float('Inf') + a mpfr('inf') >>> a + float('-Inf') mpfr('-inf') >>> float('-Inf') + a mpfr('-inf') >>> a + float('nan') mpfr('nan') >>> float('nan') + a mpfr('nan') >>> a - float('Inf') mpfr('-inf') >>> float('Inf') - a mpfr('inf') >>> a - float('-Inf') mpfr('inf') >>> float('-Inf') - a mpfr('-inf') >>> a - float('nan') mpfr('nan') >>> float('nan') - a mpfr('nan') >>> a * float('Inf') mpfr('inf') >>> float('Inf') * a mpfr('inf') >>> a * float('-Inf') mpfr('-inf') >>> float('-Inf') * a mpfr('-inf') >>> -a * float('Inf') mpfr('-inf') >>> float('Inf') * -a mpfr('-inf') >>> -a * float('-Inf') mpfr('inf') >>> float('-Inf') * -a mpfr('inf') >>> a * float('nan') mpfr('nan') >>> float('nan') * a mpfr('nan') >>> G.mpz(0) * float('Inf') mpfr('nan') >>> G.mpz(0) * float('-Inf') mpfr('nan') >>> float('Inf') * G.mpz(0) mpfr('nan') >>> float('-Inf') * G.mpz(0) mpfr('nan') >>> a / float('Inf') mpfr('0.0') >>> -a / float('Inf') mpfr('-0.0') >>> float('Inf') / a mpfr('inf') >>> float('Inf') / -a mpfr('-inf') >>> a / float('-Inf') mpfr('-0.0') >>> -a / float('-Inf') mpfr('0.0') >>> float('-Inf') / a mpfr('-inf') >>> float('-Inf') / -a mpfr('inf') >>> a / float('nan') mpfr('nan') >>> float('nan') / a mpfr('nan') >>> float('nan') / G.mpz(0) mpfr('nan') >>> float('nan') / G.mpz(0) mpfr('nan') >>> a - mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') - a mpfr('inf') >>> a - mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') - a mpfr('-inf') >>> a - mpfr('nan') mpfr('nan') >>> mpfr('nan') - a mpfr('nan') >>> a * mpfr('Inf') mpfr('inf') >>> mpfr('Inf') * a mpfr('inf') >>> a * mpfr('-Inf') mpfr('-inf') >>> mpfr('-Inf') * a mpfr('-inf') >>> -a * mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') * -a mpfr('-inf') >>> -a * mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') * -a mpfr('inf') >>> a * mpfr('nan') mpfr('nan') >>> mpfr('nan') * a mpfr('nan') >>> G.mpz(0) * mpfr('Inf') mpfr('nan') >>> G.mpz(0) * mpfr('-Inf') mpfr('nan') >>> mpfr('Inf') * G.mpz(0) mpfr('nan') >>> mpfr('-Inf') * G.mpz(0) mpfr('nan') >>> a / mpfr('Inf') mpfr('0.0') >>> -a / mpfr('Inf') mpfr('-0.0') >>> mpfr('Inf') / a mpfr('inf') >>> mpfr('Inf') / -a mpfr('-inf') >>> a / mpfr('-Inf') mpfr('-0.0') >>> -a / mpfr('-Inf') mpfr('0.0') >>> mpfr('-Inf') / a mpfr('-inf') >>> mpfr('-Inf') / -a mpfr('inf') >>> a / mpfr('nan') mpfr('nan') >>> mpfr('nan') / a mpfr('nan') >>> mpfr('nan') / G.mpz(0) mpfr('nan') >>> mpfr('nan') / G.mpz(0) mpfr('nan') >>> divmod(a, mpfr('Inf')) (mpfr('0.0'), mpfr('123.0')) >>> divmod(a, mpfr('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, mpfr('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, mpfr('-Inf')) (mpfr('0.0'), mpfr('-123.0')) >>> divmod(a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(G.mpz(0), mpfr('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(G.mpz(0), mpfr('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(G.mpz(0), mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(a, mpfr('Inf')) (mpfr('0.0'), mpfr('123.0')) >>> divmod(a, mpfr('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, mpfr('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, mpfr('-Inf')) (mpfr('0.0'), mpfr('-123.0')) >>> divmod(a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(G.mpz(0), mpfr('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(G.mpz(0), mpfr('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(G.mpz(0), mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) Test bit operations ------------------- >>> ~a mpz(-124) >>> a&b mpz(72) >>> a|b mpz(507) >>> a^b mpz(435) >>> a<<1 mpz(246) >>> a>>1 mpz(61) >>> a<<-1 Traceback (innermost last): ... ValueError: negative shift count >>> a>>-2 Traceback (innermost last): ... ValueError: negative shift count >>> a<<0 mpz(123) >>> a>>0 mpz(123) Test conversions ---------------- >>> int(G.mpz(-3)) -3 Test Number Protocol -------------------- >>> a.numerator mpz(123) >>> a.denominator mpz(1) >>> a.real mpz(123) >>> a.imag mpz(0) >>> a.conjugate() mpz(123) gmpy2-2.1.0b3/test/test_mpz_args.py0000664000175000017500000000423113170047220017055 0ustar casecase00000000000000# Test a wide variety of input values to the commonly used mpz operations. # This test should be run whenever optimizations are made to the handling of # arguments. import sys import gmpy2 if sys.version.startswith('3'): intTypes = (int,) else: intTypes = (int, long) valueList = [0, 1, 2, 3, 4, 5] for power in (14, 15, 16, 29, 30, 31, 32, 45, 48, 60, 64, 75, 90, 96, 105, 120, 128): for i in (-2, -1, 0, 1, 2): valueList.append(2**power + i) valueList.append('123456789012345678901234567890') valueList.append('10000000000000000000000000000000000000000000000000000000000000000') testValues = [] mpzValues = [] for i in valueList: for t in intTypes: testValues.append(t(i)) testValues.append(-t(i)) mpzValues.append(gmpy2.mpz(i)) mpzValues.append(-gmpy2.mpz(i)) testValues.extend(mpzValues) def test(): for i in testValues: for z in mpzValues: # Test all permutations of addition assert int(i) + int(z) == i + z, (repr(i), repr(z)) assert int(z) + int(i) == z + i, (repr(i), repr(z)) # Test all permutations of subtraction assert int(i) - int(z) == i - z, (repr(i), repr(z)) assert int(z) - int(i) == z - i, (repr(i), repr(z)) # Test all permutations of multiplication assert int(i) * int(z) == i * z, (repr(i), repr(z)) assert int(z) * int(i) == z * i, (repr(i), repr(z)) # Test all permutations of floor division if z != 0: assert int(i) // int(z) == i // z, (repr(i), repr(z)) assert int(i) % int(z) == i % z, (repr(i), repr(z)) assert divmod(int(i), int(z)) == divmod(i, z), (repr(i), repr(z)) if i!=0: assert int(z) // int(i) == z // i, (repr(i), repr(z)) assert int(z) % int(i) == z % i, (repr(i), repr(z)) assert divmod(int(z), int(i)) == divmod(z,i), (repr(i), repr(z)) return True if __name__ == "__main__": print("Testing combinations of mpz and integer operations.") print("This test may take a few minutes.") test() print("Test successful.") gmpy2-2.1.0b3/test/test_mpz_args.pyc0000664000175000017500000000434113172273543017235 0ustar casecase00000000000000ó NàYc@slddlZddlZejjdƒr6efZn eefZddddddgZx4d"D],Zx#d#D]Z ej dee ƒqnWqaWej dƒej dƒgZ gZ xseD]kZ x5eD]-Z e j e e ƒƒe j e e ƒ ƒqËWe j eje ƒƒe j eje ƒ ƒq¾We je ƒd„ZedkrhdGHd GHeƒd!GHndS($iÿÿÿÿNt3iiiiiiiiiiiii i-i0i<i@iKiZi`iiixi€iþÿÿÿt123456789012345678901234567890tA10000000000000000000000000000000000000000000000000000000000000000cCs@x9tD]1}x(tD] }t|ƒt|ƒ||ksXtt|ƒt|ƒfƒ‚t|ƒt|ƒ||ks–tt|ƒt|ƒfƒ‚t|ƒt|ƒ||ksÔtt|ƒt|ƒfƒ‚t|ƒt|ƒ||kstt|ƒt|ƒfƒ‚t|ƒt|ƒ||ksPtt|ƒt|ƒfƒ‚t|ƒt|ƒ||ksŽtt|ƒt|ƒfƒ‚|dkrat|ƒt|ƒ||ksØtt|ƒt|ƒfƒ‚t|ƒt|ƒ||kstt|ƒt|ƒfƒ‚tt|ƒt|ƒƒt||ƒksatt|ƒt|ƒfƒ‚n|dkrt|ƒt|ƒ||ks«tt|ƒt|ƒfƒ‚t|ƒt|ƒ||ksétt|ƒt|ƒfƒ‚tt|ƒt|ƒƒt||ƒks4tt|ƒt|ƒfƒ‚qqWqWtS(Ni(t testValuest mpzValuestinttAssertionErrortreprtdivmodtTrue(titz((s,/home/case/github/gmpy/test/test_mpz_args.pyttest"s"  >>>>>> >>K >>St__main__s3Testing combinations of mpz and integer operations.s!This test may take a few minutes.sTest successful.(iiiiiii i-i0i<i@iKiZi`iiixi€(iþÿÿÿiÿÿÿÿiii(tsystgmpy2tversiont startswithRtintTypestlongt valueListtpowerR tappendRRtttmpztextendR t__name__(((s,/home/case/github/gmpy/test/test_mpz_args.pyts2             gmpy2-2.1.0b3/test/test_mpz_bit.txt0000664000175000017500000000135513105222070017066 0ustar casecase00000000000000MPZ Functionality ================= >>> import gmpy2 as G >>> from gmpy2 import mpz >>> a = mpz(123) >>> b = mpz(456) Test bit operations =================== Test bit_clear -------------- Test bit_flip ------------- Test bit_length --------------- Test bit_mask ------------- Test bit_scan0 -------------- Test bit_scan1 -------------- Test bit_set ------------ Test bit_test ------------- Test hamdist ------------ Test popcount ------------- Test __invert__ --------------- Test __lshift__ --------------- Test __or__ ----------- Test __rlshift__ ---------------- Test __ror__ ------------ Test __rrshift__ ---------------- Test __rshift__ --------------- Test __rxor__ ------------- Test __xor__ ------------ gmpy2-2.1.0b3/test/test_mpz_create.txt0000664000175000017500000000655213444070732017573 0ustar casecase00000000000000MPZ Functionality ================= Test the creation of mpz objects. >>> from gmpy2 import mpz, mpq, mpfr, mpc, xmpz >>> from decimal import Decimal as D >>> from fractions import Fraction as F >>> import gmpy2 as G >>> mpz() mpz(0) >>> mpz(0) mpz(0) >>> mpz(1) mpz(1) >>> mpz(-1) mpz(-1) >>> mpz(2**15-2) mpz(32766) >>> mpz(2**15-1) mpz(32767) >>> mpz(2**15) mpz(32768) >>> mpz(2**15+1) mpz(32769) >>> mpz(2**15+2) mpz(32770) >>> mpz(2**30-2) mpz(1073741822) >>> mpz(2**30-1) mpz(1073741823) >>> mpz(2**30) mpz(1073741824) >>> mpz(2**30+1) mpz(1073741825) >>> mpz(2**30+2) mpz(1073741826) >>> mpz(2**16-2) mpz(65534) >>> mpz(2**16-1) mpz(65535) >>> mpz(2**16) mpz(65536) >>> mpz(2**16+1) mpz(65537) >>> mpz(2**16+2) mpz(65538) >>> mpz(1000000000000) mpz(1000000000000) >>> mpz(-1000000000000) mpz(-1000000000000) >>> mpz('') Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz('a') Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz('a',16) mpz(10) >>> mpz('z',16) Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz('0b1101') mpz(13) >>> mpz('0b1101',2) mpz(13) >>> mpz('1101',2) mpz(13) >>> mpz('0b0010') mpz(2) >>> mpz('0b0010',2) mpz(2) >>> mpz('0b0b10',2) Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz('0b0b10') Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz('0b0012') Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz('0o0012') mpz(10) >>> mpz('0o0012',8) mpz(10) >>> mpz('12',8) mpz(10) >>> mpz('0x12') mpz(18) >>> mpz('0x12',16) mpz(18) >>> mpz('12',16) mpz(18) >>> mpz(float('nan')) Traceback (most recent call last): File "", line 1, in ValueError: 'mpz' does not support NaN >>> mpz(float('inf')) Traceback (most recent call last): File "", line 1, in OverflowError: 'mpz' does not support Infinity >>> mpz(float('-inf')) Traceback (most recent call last): File "", line 1, in OverflowError: 'mpz' does not support Infinity >>> mpz(12, base=16) Traceback (most recent call last): File "", line 1, in TypeError: mpz() with non-string argument needs exactly 1 argument >>> mpz('12', base=16) mpz(18) >>> mpz('\xff') Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> mpz('\x0cf') Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> mpz('\0xff') Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> mpz(b'12') mpz(12) >>> mpz(None) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> mpz(None,base=10) Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> mpz('99',base=100) Traceback (most recent call last): File "", line 1, in ValueError: ** message detail varies ** >>> mpz('99',base='a') Traceback (most recent call last): File "", line 1, in TypeError: ** message detail varies ** >>> mpz('99',base=10) mpz(99) >>> mpz(xmpz(5)) mpz(5) gmpy2-2.1.0b3/test/test_mpz_functions.txt0000664000175000017500000003055413105222070020323 0ustar casecase00000000000000MPZ Related Functions ===================== >>> import gmpy2 as G >>> from gmpy2 import mpz, mpq, mpfr >>> a = mpz(123) >>> b = mpz(456) Test gmpy2.add -------------- >>> G.add(a, b) mpz(579) >>> G.add(a, 456) mpz(579) >>> G.add(123, 456) mpz(579) >>> G.add(123, b) mpz(579) Test gmpy2.bincoef ------------------ >>> for i in range(10): ... print(G.bincoef(10,i)) ... 1 10 45 120 210 252 210 120 45 10 Test gmpy2.bit_clear -------------------- >>> a.bit_clear(0) mpz(122) Test gmpy2.bit_flip ------------------- >>> bin(a) '0b1111011' >>> bin(a.bit_flip(1)) '0b1111001' >>> bin(a.bit_flip(2)) '0b1111111' Test gmpy2.bit_length --------------------- >>> G.mpz(0).bit_length() 0 >>> G.mpz(12345).bit_length() 14 Test gmpy2.bit_mask ------------------- >>> G.bit_mask(9) mpz(511) Test gmpy2.bit_scan0 -------------------- >>> [a.bit_scan0(j) for j in range(33)] [2, 2, 2, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] >>> n=G.mpz(-(7+6*16+5*256+7*4092)) >>> [n.bit_scan0(j) for j in range(18)] [1, 1, 3, 3, 6, 6, 6, 8, 8, 10, 10, 12, 12, 13, 14, -1, None, None] >>> del n Test gmpy2.bit_scan1 -------------------- >>> [a.bit_scan1(j) for j in range(10)] [0, 1, 3, 3, 4, 5, 6, None, None, None] >>> n=G.mpz(-(7+6*16+5*256+7*4092)) >>> [n.bit_scan1(j) for j in range(33)] [0, 2, 2, 4, 4, 5, 7, 7, 9, 9, 11, 11, 15, 15, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] >>> del n Test gmpy2.bit_set ------------------ >>> a.bit_set(20) mpz(1048699) Test gmpy2.bit_test ------------------- >>> [a.bit_test(i) for i in range(8)] [True, True, False, True, True, True, True, False] >>> [b.bit_test(i) for i in range(10)] [False, False, False, True, False, False, True, True, True, False] Test gmpy2.c_div ---------------- >>> G.c_div(b,64) mpz(8) >>> G.c_div(b,-64) mpz(-7) >>> G.c_div(-b,64) mpz(-7) >>> G.c_div(-b,-64) mpz(8) Test gmpy2.c_div_2exp --------------------- >>> G.c_div_2exp(b, 6) mpz(8) >>> G.c_div_2exp(b, -6) Traceback (most recent call last): File "", line 1, in OverflowError: can't convert negative value to unsigned int >>> G.c_div_2exp(-b, 6) mpz(-7) Test gmpy2.c_divmod ------------------- >>> G.c_divmod(b,64) (mpz(8), mpz(-56)) >>> G.c_divmod(b,-64) (mpz(-7), mpz(8)) >>> G.c_divmod(-b,64) (mpz(-7), mpz(-8)) >>> G.c_divmod(-b,-64) (mpz(8), mpz(56)) >>> G.c_divmod(17,5) (mpz(4), mpz(-3)) >>> G.c_divmod(-17,5) (mpz(-3), mpz(-2)) >>> G.c_divmod(17,-5) (mpz(-3), mpz(2)) >>> G.c_divmod(-17,-5) (mpz(4), mpz(3)) >>> G.c_divmod(b, 4.0) Traceback (most recent call last): File "", line 1, in TypeError: c_divmod() requires 'mpz','mpz' arguments >>> G.c_divmod('a', b) Traceback (most recent call last): File "", line 1, in TypeError: c_divmod() requires 'mpz','mpz' arguments >>> G.c_divmod(b) Traceback (most recent call last): File "", line 1, in TypeError: c_divmod() requires 'mpz','mpz' arguments Test gmpy2.c_divmod_2exp ------------------------ >>> G.c_divmod_2exp(b, 6) (mpz(8), mpz(-56)) >>> G.c_divmod_2exp(-b, 6) (mpz(-7), mpz(-8)) Test gmpy2.c_mod ---------------- >>> G.c_mod(b,64) mpz(-56) >>> G.c_mod(b,-64) mpz(8) >>> G.c_mod(-b,64) mpz(-8) >>> G.c_mod(-b,-64) mpz(56) Test gmpy2.c_mod_2exp --------------------- >>> G.c_mod_2exp(b, 6) mpz(-56) >>> G.c_mod_2exp(-b, 6) mpz(-8) Test gmpy2.comb --------------- >>> G.comb(3,-1) Traceback (most recent call last): ... ValueError: binomial coefficient with negative k >>> G.comb(8,4) mpz(70) Test gmpy2.divexact ------------------- >>> aa=G.mpz('1234567912345678912345679') >>> bb=G.mpz('789789789789789789789789') >>> cc=aa*bb >>> print(G.divexact(cc,aa)) 789789789789789789789789 >>> del aa,bb,cc Test gmpy2.divm --------------- >>> G.divm(b,a,20) mpz(12) >>> G.divm(a,b,100) Traceback (innermost last): ... ZeroDivisionError: not invertible >>> G.divm(6,12,14) mpz(4) >>> G.divm(0,1,2) mpz(0) >>> G.divm(4,8,20) mpz(3) Test gmpy2.f_div ---------------- Test gmpy2.f_div_2exp --------------------- Test gmpy2.f_divmod ------------------- >>> G.f_divmod(17,5) (mpz(3), mpz(2)) >>> G.f_divmod(-17,5) (mpz(-4), mpz(3)) >>> G.f_divmod(17,-5) (mpz(-4), mpz(-3)) >>> G.f_divmod(-17,-5) (mpz(3), mpz(-2)) >>> G.f_divmod(b,64) (mpz(7), mpz(8)) >>> G.f_divmod(-b,64) (mpz(-8), mpz(56)) >>> G.f_divmod(b,-64) (mpz(-8), mpz(-56)) >>> G.f_divmod(-b,-64) (mpz(7), mpz(-8)) Test gmpy2.f_divmod_2exp ------------------------ >>> G.f_divmod_2exp(b,6) (mpz(7), mpz(8)) >>> G.f_divmod_2exp(-b,6) (mpz(-8), mpz(56)) Test gmpy2.f_mod ---------------- Test gmpy2.f_mod_2exp --------------------- >>> G.f_mod_2exp(a,5) mpz(27) >>> G.f_mod_2exp(b,5) mpz(8) >>> G.f_mod_2exp(b,5) == (b%32) True >>> G.f_mod_2exp(a,5) == (a%32) True Test gmpy2.fac -------------- >>> G.fac(7) mpz(5040) Test gmpy2.fib -------------- >>> G.fib(17) mpz(1597) Test gmpy2.fib2 --------------- >>> G.fib2(17) (mpz(1597), mpz(987)) Test gmpy2.gcd -------------- >>> G.gcd(a,b) mpz(3) Test gmpy2.gcdext ----------------- >>> temp=G.gcdext(a,b) >>> temp[0]==a*temp[1]+b*temp[2] True >>> temp=G.gcdext(123,456) >>> temp[0]==a*temp[1]+b*temp[2] True >>> del temp Test gmpy2.hamdist ------------------ >>> G.hamdist(a,b) 6 >>> G.hamdist(3) Traceback (innermost last): ... TypeError: hamdist() requires 'mpz','mpz' arguments >>> G.hamdist(a) Traceback (innermost last): ... TypeError: hamdist() requires 'mpz','mpz' arguments >>> G.hamdist(a, 3, 4) Traceback (innermost last): ... TypeError: hamdist() requires 'mpz','mpz' arguments Test gmpy2.invert ----------------- >>> G.invert(a,100) mpz(87) >>> G.invert(b,100) mpz(0) >>> G.invert(3) Traceback (innermost last): ... TypeError: invert() requires 'mpz','mpz' arguments >>> G.invert() Traceback (innermost last): ... TypeError: invert() requires 'mpz','mpz' arguments Test gmpy2.iroot ---------------- >>> for i in range(5): ... print(G.iroot(a,i+1),G.iroot(b,i+1)) ... (mpz(123), True) (mpz(456), True) (mpz(11), False) (mpz(21), False) (mpz(4), False) (mpz(7), False) (mpz(3), False) (mpz(4), False) (mpz(2), False) (mpz(3), False) >>> G.iroot(9,2) (mpz(3), True) Test gmpy2.iroot_rem -------------------- >>> G.iroot_rem(a,2) (mpz(11), mpz(2)) >>> G.iroot_rem(a,3) (mpz(4), mpz(59)) >>> G.iroot_rem(a*a) Traceback (most recent call last): ... TypeError: iroot_rem() requires 'mpz','int' arguments >>> G.iroot_rem(a*a,2) (mpz(123), mpz(0)) Test gmpy2.is_even ------------------ >>> G.is_even(a) False >>> G.is_even(b) True Test gmpy2.is_odd ----------------- >>> G.is_odd(a) True >>> G.is_odd(b) False Test gmpy2.is_power ------------------- >>> G.is_power() Traceback (most recent call last): File "", line 1, in TypeError: is_power() takes exactly one argument (0 given) >>> a.is_power() >>> G.is_power(99*99*99) True >>> G.is_power(99*98) False Test gmpy2.is_prime ------------------- >>> G.is_prime(3,-3) Traceback (most recent call last): ... ValueError: repetition count for is_prime must be positive >>> G.is_prime(12345) False >>> G.is_prime(80**81 + 81**80) True Test gmpy2.is_square -------------------- >>> a.is_square() False >>> G.is_square(99*99) True >>> G.is_square(99*99*99) False >>> G.is_square(0) True >>> G.is_square(-1) False Test gmpy2.isqrt ---------------- >>> print(G.isqrt(a)) 11 >>> print(G.isqrt(b)) 21 >>> G.isqrt(-1) Traceback (most recent call last): ... ValueError: isqrt() of negative number Test gmpy2.isqrt_rem -------------------- >>> print(G.isqrt_rem(a)) (mpz(11), mpz(2)) >>> print(G.isqrt_rem(b)) (mpz(21), mpz(15)) >>> G.isqrt_rem(-1) Traceback (most recent call last): ... ValueError: isqrt_rem() of negative number Test gmpy2.jacobi ----------------- >>> G.jacobi(10,3) 1 >>> G.jacobi(10,-3) Traceback (most recent call last): ... ValueError: jacobi's y must be odd prime > 0 >>> G.jacobi(3) Traceback (innermost last): ... TypeError: jacobi() requires 'mpz','mpz' arguments >>> G.jacobi() Traceback (innermost last): ... TypeError: jacobi() requires 'mpz','mpz' arguments Test gmpy2.kronecker -------------------- >>> G.kronecker(10,3) 1 >>> G.kronecker(10,-3) 1 >>> G.kronecker(3) Traceback (innermost last): ... TypeError: kronecker() requires 'mpz','mpz' arguments >>> G.kronecker() Traceback (innermost last): ... TypeError: kronecker() requires 'mpz','mpz' arguments >>> aaa = 10**20 >>> bbb = aaa+39 >>> G.jacobi(aaa,bbb) 1 >>> G.legendre(aaa,bbb) 1 >>> G.kronecker(aaa,bbb) 1 >>> del aaa,bbb Test gmpy2.lcm -------------- >>> G.lcm(a,b) mpz(18696) Test gmpy2.legendre ------------------- >>> G.legendre(10,3) 1 >>> G.legendre(10,-3) Traceback (most recent call last): ... ValueError: legendre's y must be odd and > 0 >>> G.legendre(3) Traceback (innermost last): ... TypeError: legendre() requires 'mpz','mpz' arguments >>> G.legendre() Traceback (innermost last): ... TypeError: legendre() requires 'mpz','mpz' arguments Test gmpy2.lucas ---------------- Test gmpy2.lucas2 ----------------- Test gmpy2.mul -------------- Test gmpy2.mul_2exp ------------------- Test gmpy2.next_prime --------------------- Test gmpy2.numdigits -------------------- >>> G.numdigits(23) 2 >>> G.numdigits(23,2) 5 >>> G.numdigits(23,99) Traceback (most recent call last): ... ValueError: base must be either 0 or in the interval 2 ... 62 Test gmpy2.pack --------------- Test gmpy2.popcount ------------------- >>> G.popcount(a) 6 >>> G.popcount(b) 4 >>> G.popcount(-7) -1 >>> G.popcount(0) 0 Test gmpy2.remove ----------------- gmpy2.remove factors out multiple copies of a factor from a larger integer. The factor must be greater than or equal to 2. >>> G.remove(a,2) (mpz(123), 0) >>> G.remove(a,3) (mpz(41), 1) >>> G.remove(b,2) (mpz(57), 3) >>> G.remove(b,3) (mpz(152), 1) >>> G.remove(b,1) Traceback (most recent call last): File "", line 1, in ValueError: factor must be > 1 >>> G.remove(b,0) Traceback (most recent call last): File "", line 1, in ValueError: factor must be > 1 >>> G.remove(b,789) (mpz(456), 0) >>> G.remove(b,-3) Traceback (most recent call last): File "", line 1, in ValueError: factor must be > 1 >>> G.remove(b,float('NaN')) Traceback (most recent call last): File "", line 1, in TypeError: remove() requires 'mpz','mpz' arguments >>> G.remove(3,-1) Traceback (most recent call last): ... ValueError: factor must be > 1 >>> G.remove(3) Traceback (innermost last): ... TypeError: remove() requires 'mpz','mpz' arguments >>> G.remove() Traceback (innermost last): ... TypeError: remove() requires 'mpz','mpz' arguments Test gmpy2.t_div ---------------- Test gmpy2.t_div_2exp --------------------- Test gmpy2.t_divmod ------------------- >>> G.t_divmod(17,5) (mpz(3), mpz(2)) >>> G.t_divmod(-17,5) (mpz(-3), mpz(-2)) >>> G.t_divmod(17,-5) (mpz(-3), mpz(2)) >>> G.t_divmod(-17,-5) (mpz(3), mpz(-2)) Test gmpy2.t_divmod_2exp ------------------------ Test gmpy2.t_mod ---------------- Test gmpy2.t_mod_2exp --------------------- gmpy2-2.1.0b3/test/test_mpz_io.txt0000664000175000017500000000740513170047220016725 0ustar casecase00000000000000MPZ related input/output ======================== >>> import gmpy2 as G >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from fractions import Fraction as F >>> a = mpz(123) >>> b = mpz(456) Test mpz construction --------------------- >>> mpz(3.14) mpz(3) >>> mpz(mpq(17,3)) mpz(5) >>> mpz(23) mpz(23) >>> mpz(-23) mpz(-23) >>> x=1000*1000*1000*1000*1000*1000*1000 >>> print(mpz(x)) 1000000000000000000000 >>> mpz(0.0) mpz(0) >>> mpz(0.0) mpz(0) >>> mpz(-0.0) mpz(0) >>> mpz(float("nan")) Traceback (most recent call last): File "", line 1, in ValueError: 'mpz' does not support NaN >>> mpz(float("inf")) Traceback (most recent call last): File "", line 1, in OverflowError: 'mpz' does not support Infinity >>> mpz(float("-inf")) Traceback (most recent call last): File "", line 1, in OverflowError: 'mpz' does not support Infinity >>> mpz("0") mpz(0) >>> mpz("-0") mpz(0) >>> mpz("hi") Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz("123456", 7) mpz(22875) >>> mpz("123456", base=3) Traceback (most recent call last): File "", line 1, in ValueError: invalid digits >>> mpz() mpz(0) >>> mpz(F(1,2)) mpz(0) >>> mpz(F(-3,2)) mpz(-1) >>> mpz(F(3,2)) mpz(1) >>> G.mpz('043') mpz(43) >>> G.mpz('43',0) mpz(43) >>> G.mpz('0o43') mpz(35) >>> G.mpz('0x43') mpz(67) >>> G.mpz('0x43',10) Traceback (innermost last): ... ValueError: invalid digits >>> G.mpz('43') mpz(43) Test format ----------- >>> str(a) '123' >>> repr(a) 'mpz(123)' >>> hex(a) '0x7b' >>> oct(a) == ('0o173' if sys.version_info[0] == 3 else '0173') True >>> G.mpz('123') mpz(123) >>> G.mpz('1001001011',2) mpz(587) >>> bin(G.mpz('1001001011',2)) '0b1001001011' >>> '1001001011' == G.mpz('1001001011',2).digits(2) True >>> for i in range(2,63): ... print(a.digits(i)) ... 1111011 11120 1323 443 323 234 173 146 123 102 a3 96 8b 83 7b 74 6f 69 63 5i 5d 58 53 4n 4j 4f 4b 47 43 3u 3r 3o 3l 3i 3f 3C 39 36 33 30 2d 2b 2Z 2X 2V 2T 2R 2P 2N 2L 2J 2H 2F 2D 2B 29 27 25 23 21 1z >>> print(a.digits(63)) Traceback (innermost last): ... ValueError: base must be either 0 or in the interval 2 ... 62 >>> a.__format__() Traceback (most recent call last): File "", line 1, in TypeError: function takes exactly 1 argument (0 given) >>> a.__format__('') '123' >>> a.__format__('d') '123' >>> a.__format__('b') '1111011' >>> a.__format__('o') '173' >>> a.__format__('x') '7b' >>> a.__format__('#x') '0x7b' >>> a.__format__('#X') '0X7B' >>> a.__format__('#o') '0o173' >>> a.__format__('#15o') ' 0o173' >>> a.__format__('<#15o') '0o173 ' >>> a.__format__('^#15o') ' 0o173 ' >>> a.__format__('>#15o') ' 0o173' >>> a.__format__('^ #15o') ' 0o173 ' >>> a.__format__('^#15o') ' 0o173 ' >>> a.__format__('^ #16o') ' 0o173 ' >>> a.__format__('#^16o') Traceback (most recent call last): File "", line 1, in ValueError: Invalid conversion specification >>> a.__format__('^#16o') ' 0o173 ' gmpy2-2.1.0b3/test/test_mpz_pack_unpack.txt0000664000175000017500000000151613105222070020566 0ustar casecase00000000000000Testing of gmpy2 pack and unpack -------------------------------- >>> import gmpy2 as G >>> from gmpy2 import mpz,pack,unpack Test ---- >>> x = mpz(0) >>> all((x == pack(unpack(x,i),i) for i in range(1,100))) True >>> x = mpz(1) >>> all((x == pack(unpack(x,i),i) for i in range(1,100))) True >>> x = mpz(2) >>> all((x == pack(unpack(x,i),i) for i in range(1,100))) True >>> x = mpz(3141592635) >>> all((x == pack(unpack(x,i),i) for i in range(1,100))) True >>> x = mpz(1234567891234567890000000000000000000000000000000000000123) >>> all((x == pack(unpack(x,i),i) for i in range(1,100))) True >>> x = mpz(1) << 500 >>> all((x == pack(unpack(x,i),i) for i in range(1,200))) True >>> x -= 1 >>> all((x == pack(unpack(x,i),i) for i in range(1,200))) True gmpy2-2.1.0b3/test/test_mpz_random.txt0000664000175000017500000000171013356026702017577 0ustar casecase00000000000000Test gmpy2 Random Integers ========================== >>> import gmpy2 as gmpy2 >>> from gmpy2 import mpz, mpq, mpfr, mpc >>> from gmpy2 import random_state >>> r1=random_state(42) >>> r2=random_state(42) >>> gmpy2.mpz_random(r1, 2**88) mpz(171378365038768291737094841) >>> gmpy2.mpz_random(r2, 2**88) mpz(171378365038768291737094841) >>> gmpy2.mpz_random(r1, 2**88) mpz(62749575961297098445301393) >>> gmpy2.mpz_random(r2, 2**88) mpz(62749575961297098445301393) >>> gmpy2.mpz_urandomb(random_state(42),64).digits(2) '1100100011011011101100101001100100111110010111011100101010111001' >>> gmpy2.mpz_rrandomb(random_state(42),64).digits(2) '1111111111111111111111111100000000111111111111111111000000000000' >>> gmpy2.mpfr_grandom(random_state(42)) (mpfr('-0.32898912492644183'), mpfr('0.03656576719642516')) >>> gmpy2.mpfr_nrandom(random_state(42)) mpfr('-0.32898912492644183') >>> gmpy2.mpc_random(random_state(42)) mpc('0.86555158787663011+0.4422082613292212j') gmpy2-2.1.0b3/test/test_mpz_template.txt0000664000175000017500000002257213105222070020127 0ustar casecase00000000000000MPZ Functionality ================= This file is a template for creating tests of mpz related functionality. >>> import gmpy2 as G >>> from gmpy2 import mpz, mpq, mpfr >>> a = mpz(123) >>> b = mpz(456) Test elementary operations ========================== Test addition ------------- >>> a+1 mpz(124) >>> a+(-1) mpz(122) >>> (-1)+a mpz(122) >>> 1+a mpz(124) >>> a+b mpz(579) >>> b+a mpz(579) >>> a+'b' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'mpz' and 'str' >>> 'b'+a #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): File "", line 1, in TypeError: Can't convert 'mpz' object to str implicitly Test subtraction ---------------- >>> a-1 mpz(122) >>> a-(-1) mpz(124) >>> 1-a mpz(-122) >>> (-1)-a mpz(-124) >>> a-b mpz(-333) >>> b-a mpz(333) >>> a-'b' Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for -: 'mpz' and 'str' >>> 'b'-a Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for -: 'str' and 'mpz' Test multiplication ------------------- >>> a*b mpz(56088) >>> b*a mpz(56088) >>> a*'b' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' >>> 'b'*a 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' Test division ------------- >>> a//b mpz(0) >>> a/b mpfr('0.26973684210526316') >>> b//a mpz(3) >>> b/a mpfr('3.7073170731707319') >>> a*b mpz(56088) >>> b*a mpz(56088) >>> a//b mpz(0) >>> b//a mpz(3) >>> a/b mpfr('0.26973684210526316') >>> b/a mpfr('3.7073170731707319') >>> a//0 Traceback (most recent call last): ... ZeroDivisionError: division or modulo by zero >>> a/0 Traceback (most recent call last): ... ZeroDivisionError: division or modulo by zero >>> a%b mpz(123) >>> b%a mpz(87) >>> divmod(a,b) (mpz(0), mpz(123)) >>> divmod(b,a) (mpz(3), mpz(87)) >>> divmod(a,0) Traceback (most recent call last): ... ZeroDivisionError: division or modulo by zero Test modulo ----------- >>> a+True mpz(124) >>> a+False mpz(123) >>> a*False mpz(0) >>> a//True mpz(123) >>> abs(-a)==a True >>> print(pow(a,10)) 792594609605189126649 >>> pow(a,7,b) mpz(99) >>> G.sign(b-a) 1 >>> G.sign(b-b) 0 >>> G.sign(a-b) -1 >>> G.sign(a) 1 >>> G.sign(-a) -1 >>> z=b-b; G.sign(z) 0 Test pickle ----------- >>> import pickle >>> pickle.loads(pickle.dumps(G.mpz(12346789))) mpz(12346789) >>> pickle.loads(pickle.dumps(G.mpz(-12346789))) mpz(-12346789) >>> pickle.loads(pickle.dumps(G.mpz(0))) mpz(0) Test mpz.__index__ ------------------ >>> range(333)[a] 123 >>> range(333)[b] #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (innermost last): ... IndexError: range object index out of range Test operations involving NaN/Inf --------------------------------- >>> a + float('Inf') mpfr('inf') >>> float('Inf') + a mpfr('inf') >>> a + float('-Inf') mpfr('-inf') >>> float('-Inf') + a mpfr('-inf') >>> a + float('nan') mpfr('nan') >>> float('nan') + a mpfr('nan') >>> a - float('Inf') mpfr('-inf') >>> float('Inf') - a mpfr('inf') >>> a - float('-Inf') mpfr('inf') >>> float('-Inf') - a mpfr('-inf') >>> a - float('nan') mpfr('nan') >>> float('nan') - a mpfr('nan') >>> a * float('Inf') mpfr('inf') >>> float('Inf') * a mpfr('inf') >>> a * float('-Inf') mpfr('-inf') >>> float('-Inf') * a mpfr('-inf') >>> -a * float('Inf') mpfr('-inf') >>> float('Inf') * -a mpfr('-inf') >>> -a * float('-Inf') mpfr('inf') >>> float('-Inf') * -a mpfr('inf') >>> a * float('nan') mpfr('nan') >>> float('nan') * a mpfr('nan') >>> G.mpz(0) * float('Inf') mpfr('nan') >>> G.mpz(0) * float('-Inf') mpfr('nan') >>> float('Inf') * G.mpz(0) mpfr('nan') >>> float('-Inf') * G.mpz(0) mpfr('nan') >>> a / float('Inf') mpfr('0.0') >>> -a / float('Inf') mpfr('-0.0') >>> float('Inf') / a mpfr('inf') >>> float('Inf') / -a mpfr('-inf') >>> a / float('-Inf') mpfr('-0.0') >>> -a / float('-Inf') mpfr('0.0') >>> float('-Inf') / a mpfr('-inf') >>> float('-Inf') / -a mpfr('inf') >>> a / float('nan') mpfr('nan') >>> float('nan') / a mpfr('nan') >>> float('nan') / G.mpz(0) mpfr('nan') >>> float('nan') / G.mpz(0) mpfr('nan') >>> a + mpfr('Inf') mpfr('inf') >>> mpfr('Inf') + a mpfr('inf') >>> a + mpfr('-Inf') mpfr('-inf') >>> mpfr('-Inf') + a mpfr('-inf') >>> a + mpfr('nan') mpfr('nan') >>> mpfr('nan') + a mpfr('nan') >>> a - mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') - a mpfr('inf') >>> a - mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') - a mpfr('-inf') >>> a - mpfr('nan') mpfr('nan') >>> mpfr('nan') - a mpfr('nan') >>> a * mpfr('Inf') mpfr('inf') >>> mpfr('Inf') * a mpfr('inf') >>> a * mpfr('-Inf') mpfr('-inf') >>> mpfr('-Inf') * a mpfr('-inf') >>> -a * mpfr('Inf') mpfr('-inf') >>> mpfr('Inf') * -a mpfr('-inf') >>> -a * mpfr('-Inf') mpfr('inf') >>> mpfr('-Inf') * -a mpfr('inf') >>> a * mpfr('nan') mpfr('nan') >>> mpfr('nan') * a mpfr('nan') >>> G.mpz(0) * mpfr('Inf') mpfr('nan') >>> G.mpz(0) * mpfr('-Inf') mpfr('nan') >>> mpfr('Inf') * G.mpz(0) mpfr('nan') >>> mpfr('-Inf') * G.mpz(0) mpfr('nan') >>> a / mpfr('Inf') mpfr('0.0') >>> -a / mpfr('Inf') mpfr('-0.0') >>> mpfr('Inf') / a mpfr('inf') >>> mpfr('Inf') / -a mpfr('-inf') >>> a / mpfr('-Inf') mpfr('-0.0') >>> -a / mpfr('-Inf') mpfr('0.0') >>> mpfr('-Inf') / a mpfr('-inf') >>> mpfr('-Inf') / -a mpfr('inf') >>> a / mpfr('nan') mpfr('nan') >>> mpfr('nan') / a mpfr('nan') >>> mpfr('nan') / G.mpz(0) mpfr('nan') >>> mpfr('nan') / G.mpz(0) mpfr('nan') >>> divmod(a, float('Inf')) (mpfr('0.0'), mpfr('123.0')) >>> divmod(a, float('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, float('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, float('-Inf')) (mpfr('0.0'), mpfr('-123.0')) >>> divmod(a, float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(G.mpz(0), float('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(G.mpz(0), float('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(G.mpz(0), float('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(float('Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(float('-Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(float('nan'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(a, mpfr('Inf')) (mpfr('0.0'), mpfr('123.0')) >>> divmod(a, mpfr('-Inf')) (mpfr('-1.0'), mpfr('-inf')) >>> divmod(-a, mpfr('Inf')) (mpfr('-1.0'), mpfr('inf')) >>> divmod(-a, mpfr('-Inf')) (mpfr('0.0'), mpfr('-123.0')) >>> divmod(a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(-a, mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(G.mpz(0), mpfr('Inf')) (mpfr('0.0'), mpfr('0.0')) >>> divmod(G.mpz(0), mpfr('-Inf')) (mpfr('-0.0'), mpfr('-0.0')) >>> divmod(G.mpz(0), mpfr('nan')) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), -a) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('-Inf'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) >>> divmod(mpfr('nan'), G.mpz(0)) (mpfr('nan'), mpfr('nan')) Test bit operations ------------------- >>> ~a mpz(-124) >>> a&b mpz(72) >>> a|b mpz(507) >>> a^b mpz(435) >>> a<<1 mpz(246) >>> a>>1 mpz(61) >>> a<<-1 Traceback (innermost last): ... ValueError: negative shift count >>> a>>-2 Traceback (innermost last): ... ValueError: negative shift count >>> a<<0 mpz(123) >>> a>>0 mpz(123) Test conversions ---------------- >>> int(G.mpz(-3)) -3 gmpy2-2.1.0b3/test/test_mpz_to_from_binary.txt0000664000175000017500000000064313105222070021320 0ustar casecase00000000000000Testing of gmpy2 mpz to_binary and from_binary ---------------------------------------------- >>> import gmpy2 >>> from gmpy2 import mpz,to_binary,from_binary Test ---- >>> x=mpz(1);x==from_binary(to_binary(x)) True >>> x=mpz(0);x==from_binary(to_binary(x)) True >>> x=mpz(-1);x==from_binary(to_binary(x)) True >>> x=mpz(123456789123456789);x==from_binary(to_binary(x)) True gmpy2-2.1.0b3/test/test_pack.py0000664000175000017500000000153413170047220016154 0ustar casecase00000000000000from __future__ import print_function import gmpy2 def test(repeat=1): """Test gmpy2.pack and gmpy2.unpack.""" r = gmpy2.random_state(42) try: for counter in range(repeat): for t in (10, 30, 60, 500, 1000, 2000, 10000, 100000): v = gmpy2.mpz_rrandomb(r, t) for b in range(1, max(1001,t)): temp = gmpy2.unpack(v, b) u = gmpy2.pack(temp, b) if u != v: raise ValueError return True except ValueError: return False if __name__ == "__main__": import sys try: repeat = abs(int(sys.argv[1])) except: repeat = 1 print("Testing pack/unpack for a large number of values.") print("This test may take a few minutes.") test(repeat) print("Test successful.") gmpy2-2.1.0b3/test/test_pack.pyc0000664000175000017500000000226513172273541016332 0ustar casecase00000000000000ó NàYc@sœddlmZddlZdd„Zedkr˜ddlZyeeejdƒƒZ Wn dZ nXe dƒe dƒee ƒe dƒndS( iÿÿÿÿ(tprint_functionNic CsÆtjdƒ}yžx“t|ƒD]…}x|d D]t}tj||ƒ}xYtd td |ƒƒD]?}tj||ƒ}tj||ƒ}||kr]t‚q]q]Wq,WqWtSWntk rÁt SXd S(s!Test gmpy2.pack and gmpy2.unpack.i*i ii<iôièiÐi'i †iiéN(i ii<iôièiÐi'i †( tgmpy2t random_statetranget mpz_rrandombtmaxtunpacktpackt ValueErrortTruetFalse(trepeattrtcountertttvtbttemptu((s(/home/case/github/gmpy/test/test_pack.pyttests   t__main__s1Testing pack/unpack for a large number of values.s!This test may take a few minutes.sTest successful.( t __future__RRRt__name__tsystabstinttargvR tprint(((s(/home/case/github/gmpy/test/test_pack.pyts        gmpy2-2.1.0b3/test/test_py32_hash.txt0000664000175000017500000000205013105222070017213 0ustar casecase00000000000000Test hash() behavior ==================== This test is only applicable for Python 3.2 and later. >>> import gmpy2 >>> from gmpy2 import mpz, mpq, mpfr >>> from decimal import Decimal >>> gmpy2.set_context(gmpy2.context()) >>> hash(mpfr('123.456')) == hash(float('123.456')) True >>> hash(mpfr('123.5')) == hash(float('123.5')) True >>> hash(mpfr('0')) == hash(float('0')) True >>> hash(mpfr('1')) == hash(float('1')) True >>> hash(mpfr('2')) == hash(float('2')) True >>> hash(mpfr('-1')) == hash(float('-1')) True >>> hash(mpfr('Inf')) == hash(float('Inf')) True >>> hash(mpfr('-Inf')) == hash(float('-Inf')) True >>> hash(mpfr('-0')) == hash(float('-0')) True >>> hash(mpfr('NaN')) == hash(float('NaN')) True >>> hash(mpfr('123.456')) == hash(Decimal('123.456')) False >>> hash(mpfr('123.5')) == hash(Decimal('123.5')) True >>> hash(mpq(123456,1000)) == hash(Decimal('123.456')) True >>> hash(mpz(123)) == hash(Decimal(123)) True gmpy2-2.1.0b3/windows_build.txt0000664000175000017500000001662313244654531016300 0ustar casecase00000000000000Assumptions =========== The solution files for MPIR, MPFR, and MPC support VS 2015/2017. However, if VS 2008 and/or VS 2010 is installed, the "Platform Toolset" setting can be used to select a specific compiler: - v90 = VS 2008, Python 2.6 and 2.7 - v100 = VS 2010, Python 3.3 and 3.4 - v140 = VS 2015, Python 3.5, 3.6, and 3.7 - v141 = VS 2017 Assumes MPIR is placed in c:\src\mpir. (No version number.) Assumes MPFR is placed in c:\src\mpfr. (No version number.) Assumes MPC is placed in c:\src\mpc. (No version number.) Assumes gmpy2 is placed in c:\src\gmpy2. (No version number.) Assumes vsyasm is installed. Compatibility note for vsyasm ============================= VS 2015/2017 change the platform identifier for 32-bit builds from "win32" to "Win32". To work around the issue with vsyasm v1.3.0, edit the "vsyasm.props" file. After the following line: "$(YasmPath)"vsyasm.exe -Xvc -f $(Platform) [AllOptions] [AdditionalOptions] [Inputs] add this line: "$(YasmPath)"vsyasm.exe -Xvc -f win32 [AllOptions] [AdditionalOptions] [Inputs] Compiling MPIR ============== cd c:\src\mpir\build.vc10 python mpir_config.py # enter 3 (Pentium 3) and 18 (AMD K8) Start Visual Studio 2010 and open c:\src\mpir\build.vc10\mpir.sln. Select "Release" and "Win32" Open "lib_mpir_p3" properties - Change "Platform Toolset" if needed. - Change "Character Set" to "Not Set". (Probably not needed.) - Change "Optimization" to "/O2". (Set uniformly in MPFR and MPC too.) - Change "Runtime Library" to "Multi-threaded DLL /MD". - Change "Buffer Security Check" to "No". Select "Build" - Ignore preinv* warnings (I think) - Ignore *_ux and *_sx warnings if using v90 toolset (i.e. VS2008). Select "Release" and "x64" Open "lib_mpir_k8" properties - Change "Platform Toolset" if needed. - Change "Character Set" to "Not Set". (Probably not needed.) - Change "Optimization" to "/O2". (Set uniformly in MPFR and MPC too.) - Change "Runtime Library" to "Multi-threaded DLL /MD". - Change "Buffer Security Check" to "No". Select "Build" - Ignore preinv* warnings (I think) - Ignore *_ux and *_sx warnings if using v90 toolset (i.e. VS2008). Compiling MPFR ============== Start Visual Studio 2010 and open c:\src\mpfr\build.vc10\lib_mpfr.sln. Select "Release" and "Win32" Open "lib_mpfr" properties - Change "Platform Toolset: if needed. - Change settings to match MPIR except "Enable Fiber-Safe Optimizations" should be set. Select "Build" Select "Release" and "x64" Open "lib_mpfr" properties - Change "Platform Toolset: if needed. - Change settings to match MPIR except "Enable Fiber-Safe Optimizations" should be set. Select "Build" Compiling MPC ============= Start Visual Studio 2010 and open c:\src\mpfr\build.vc10\mpc.sln. Select "Release" and "Win32" Open "mpc_lib" properties - Change "Platform Toolset: if needed. - Change remaining settings to match MPIR. Select "Build" Select "Release" and "x64" Open "lib_mpfr" properties - Change "Platform Toolset: if needed. - Change remaining settings to match MPIR. Select "Build" Copy the library files ====================== The header files will be copied c:\src\BB\vsNNNN\include and the library files will be copied to c:\src\BB\vsNNNN\lib where BB is 32 or 64, and NNNN is 2008 or 2010. 32-bit, VS 2008 cd c:\src xcopy /y c:\src\mpir\lib\Win32\Release\*.h c:\src\32\vs2008\include\ xcopy /y c:\src\mpir\lib\Win32\Release\*.lib c:\src\32\vs2008\lib\ xcopy /y c:\src\mpfr\lib\Win32\Release\*.h c:\src\32\vs2008\include\ xcopy /y c:\src\mpfr\lib\Win32\Release\*.lib c:\src\32\vs2008\lib\ xcopy /y c:\src\mpc\lib\Win32\Release\*.h c:\src\32\vs2008\include\ xcopy /y c:\src\mpc\lib\Win32\Release\*.lib c:\src\32\vs2008\lib\ 64-bit, VS 2008 cd c:\src xcopy /y c:\src\mpir\lib\x64\Release\*.h c:\src\64\vs2008\include\ xcopy /y c:\src\mpir\lib\x64\Release\*.lib c:\src\64\vs2008\lib\ xcopy /y c:\src\mpfr\lib\x64\Release\*.h c:\src\64\vs2008\include\ xcopy /y c:\src\mpfr\lib\x64\Release\*.lib c:\src\64\vs2008\lib\ xcopy /y c:\src\mpc\lib\x64\Release\*.h c:\src\64\vs2008\include\ xcopy /y c:\src\mpc\lib\x64\Release\*.lib c:\src\64\vs2008\lib\ 32-bit, VS 2010 cd c:\src xcopy /y c:\src\mpir\lib\Win32\Release\*.h c:\src\32\vs2010\include\ xcopy /y c:\src\mpir\lib\Win32\Release\*.lib c:\src\32\vs2010\lib\ xcopy /y c:\src\mpfr\lib\Win32\Release\*.h c:\src\32\vs2010\include\ xcopy /y c:\src\mpfr\lib\Win32\Release\*.lib c:\src\32\vs2010\lib\ xcopy /y c:\src\mpc\lib\Win32\Release\*.h c:\src\32\vs2010\include\ xcopy /y c:\src\mpc\lib\Win32\Release\*.lib c:\src\32\vs2010\lib\ 64-bit, VS 2010 cd c:\src xcopy /y c:\src\mpir\lib\x64\Release\*.h c:\src\64\vs2010\include\ xcopy /y c:\src\mpir\lib\x64\Release\*.lib c:\src\64\vs2010\lib\ xcopy /y c:\src\mpfr\lib\x64\Release\*.h c:\src\64\vs2010\include\ xcopy /y c:\src\mpfr\lib\x64\Release\*.lib c:\src\64\vs2010\lib\ xcopy /y c:\src\mpc\lib\x64\Release\*.h c:\src\64\vs2010\include\ xcopy /y c:\src\mpc\lib\x64\Release\*.lib c:\src\64\vs2010\lib\ 32-bit, VS 2015 cd c:\src xcopy /y c:\src\mpir\lib\Win32\Release\*.h c:\src\32\vs2015\include\ xcopy /y c:\src\mpir\lib\Win32\Release\*.lib c:\src\32\vs2015\lib\ xcopy /y c:\src\mpfr\lib\Win32\Release\*.h c:\src\32\vs2015\include\ xcopy /y c:\src\mpfr\lib\Win32\Release\*.lib c:\src\32\vs2015\lib\ xcopy /y c:\src\mpc\lib\Win32\Release\*.h c:\src\32\vs2015\include\ xcopy /y c:\src\mpc\lib\Win32\Release\*.lib c:\src\32\vs2015\lib\ 64-bit, VS 2015 cd c:\src xcopy /y c:\src\mpir\lib\x64\Release\*.h c:\src\64\vs2015\include\ xcopy /y c:\src\mpir\lib\x64\Release\*.lib c:\src\64\vs2015\lib\ xcopy /y c:\src\mpfr\lib\x64\Release\*.h c:\src\64\vs2015\include\ xcopy /y c:\src\mpfr\lib\x64\Release\*.lib c:\src\64\vs2015\lib\ xcopy /y c:\src\mpc\lib\x64\Release\*.h c:\src\64\vs2015\include\ xcopy /y c:\src\mpc\lib\x64\Release\*.lib c:\src\64\vs2015\lib\ Compile gmpy2 ============= c:\32\Python26\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2008 bdist_wininst c:\32\Python27\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2008 bdist_wininst c:\32\Python33\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2010 bdist_wininst c:\32\Python34\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2010 bdist_wininst c:\32\Python35\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2015 bdist_wininst c:\32\Python36\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2015 bdist_wininst c:\32\Python37\python.exe setup.py build_ext --force --mpir --static=c:\src\32\vs2015 bdist_wininst c:\64\Python26\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2008 bdist_wininst c:\64\Python27\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2008 bdist_wininst c:\64\Python33\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2010 bdist_wininst c:\64\Python34\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2010 bdist_wininst c:\64\Python35\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2015 bdist_wininst c:\64\Python36\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2015 bdist_wininst c:\64\Python37\python.exe setup.py build_ext --force --mpir --static=c:\src\64\vs2015 bdist_wininst