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 |