| OLD | NEW |
| (Empty) |
| 1 /* mpf_get_ui -- mpf to ulong conversion | |
| 2 | |
| 3 Copyright 2001, 2002, 2004 Free Software Foundation, Inc. | |
| 4 | |
| 5 This file is part of the GNU MP Library. | |
| 6 | |
| 7 The GNU MP Library is free software; you can redistribute it and/or modify | |
| 8 it under the terms of the GNU Lesser General Public License as published by | |
| 9 the Free Software Foundation; either version 3 of the License, or (at your | |
| 10 option) any later version. | |
| 11 | |
| 12 The GNU MP Library is distributed in the hope that it will be useful, but | |
| 13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
| 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
| 15 License for more details. | |
| 16 | |
| 17 You should have received a copy of the GNU Lesser General Public License | |
| 18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ | |
| 19 | |
| 20 #include "gmp.h" | |
| 21 #include "gmp-impl.h" | |
| 22 | |
| 23 | |
| 24 /* Any fraction bits are truncated, meaning simply discarded. | |
| 25 | |
| 26 For values bigger than a ulong, the low bits are returned (the low | |
| 27 absolute value bits actually), like mpz_get_ui, but this isn't | |
| 28 documented. | |
| 29 | |
| 30 Notice this is equivalent to mpz_set_f + mpz_get_ui. | |
| 31 | |
| 32 | |
| 33 Implementation: | |
| 34 | |
| 35 The limb just above the radix point for us to extract is ptr[size-exp]. | |
| 36 | |
| 37 We need to check that the size-exp index falls in our available data | |
| 38 range, 0 to size-1 inclusive. We test this without risk of an overflow | |
| 39 involving exp by requiring size>=exp (giving size-exp >= 0) and exp>0 | |
| 40 (giving size-exp <= size-1). | |
| 41 | |
| 42 Notice if size==0 there's no fetch, since of course size>=exp and exp>0 | |
| 43 can only be true if size>0. So there's no special handling for size==0, | |
| 44 it comes out as 0 the same as any other time we have no data at our | |
| 45 target index. | |
| 46 | |
| 47 For nails, the second limb above the radix point is also required, this | |
| 48 is ptr[size-exp+1]. | |
| 49 | |
| 50 Again we need to check that size-exp+1 falls in our data range, 0 to | |
| 51 size-1 inclusive. We test without risk of overflow by requiring | |
| 52 size+1>=exp (giving size-exp+1 >= 0) and exp>1 (giving size-exp+1 <= | |
| 53 size-1). | |
| 54 | |
| 55 And again if size==0 these second fetch conditions are not satisfied | |
| 56 either since size+1>=exp and exp>1 are only true if size>0. | |
| 57 | |
| 58 The code is arranged with exp>0 wrapping the exp>1 test since exp>1 is | |
| 59 mis-compiled by alpha gcc prior to version 3.4. It re-writes it as | |
| 60 exp-1>0, which is incorrect when exp==MP_EXP_T_MIN. By having exp>0 | |
| 61 tested first we ensure MP_EXP_T_MIN doesn't reach exp>1. */ | |
| 62 | |
| 63 unsigned long | |
| 64 mpf_get_ui (mpf_srcptr f) | |
| 65 { | |
| 66 mp_size_t size; | |
| 67 mp_exp_t exp; | |
| 68 mp_srcptr fp; | |
| 69 mp_limb_t fl; | |
| 70 | |
| 71 exp = EXP (f); | |
| 72 size = SIZ (f); | |
| 73 fp = PTR (f); | |
| 74 | |
| 75 fl = 0; | |
| 76 if (exp > 0) | |
| 77 { | |
| 78 /* there are some limbs above the radix point */ | |
| 79 | |
| 80 size = ABS (size); | |
| 81 if (size >= exp) | |
| 82 fl = fp[size-exp]; | |
| 83 | |
| 84 #if BITS_PER_ULONG > GMP_NUMB_BITS | |
| 85 if (exp > 1 && size+1 >= exp) | |
| 86 fl += (fp[size-exp+1] << GMP_NUMB_BITS); | |
| 87 #endif | |
| 88 } | |
| 89 | |
| 90 return (unsigned long) fl; | |
| 91 } | |
| OLD | NEW |