Révision 121
pobysoPythonSage/src/sageSLZ/sageSLZ.sage (revision 121) | ||
---|---|---|
87 | 87 |
|
88 | 88 |
# End slz_check_htr_value. |
89 | 89 |
# |
90 |
def slz_compute_binade_bounds(number, emin): |
|
90 |
def slz_compute_binade_bounds(number, emin, emax=sys.maxint):
|
|
91 | 91 |
""" |
92 | 92 |
For given "real number", compute the bounds of the binade it belongs to. |
93 |
TODO:: |
|
94 |
Deal with the emax exponent. |
|
93 |
|
|
94 |
NOTE:: |
|
95 |
When number >= 2^(emax+1), we return the "fake" binade |
|
96 |
[2^(emax+1), +infinity]. Ditto for number <= -2^(emax+1) |
|
97 |
with interval [-infinity, -2^(emax+1)]. |
|
98 |
|
|
95 | 99 |
""" |
96 |
RF = number.parent() |
|
97 |
precision = RF.precision() |
|
98 |
RRF = RealField(2 * precision) |
|
100 |
# Check the parameters. |
|
101 |
# RealNumbers only. |
|
102 |
classTree = [number.__class__] + number.mro() |
|
103 |
if not sage.rings.real_mpfr.RealNumber in classTree: |
|
104 |
return None |
|
105 |
# Non zero negative integers only for emin. |
|
106 |
if emin >= 0 or int(emin) != emin: |
|
107 |
return None |
|
108 |
# Non zero positive integers only for emax. |
|
109 |
if emax <= 0 or int(emax) != emax: |
|
110 |
return None |
|
111 |
precision = number.precision() |
|
112 |
RF = RealField(precision) |
|
113 |
# A more precise RealField is needed to avoid unwanted rounding effects |
|
114 |
# when computing number.log2(). |
|
115 |
RRF = RealField(max(2048, 2 * precision)) |
|
116 |
# number = 0 special case, the binade bounds are |
|
117 |
# [0, 2^emin - 2^(emin-precision)] |
|
99 | 118 |
if number == 0: |
100 | 119 |
return (RF(0),RF(2^(emin)) - RF(2^(emin-precision))) |
120 |
# Begin general case |
|
101 | 121 |
l2 = RRF(number).abs().log2() |
122 |
# Another special one: beyond largest representable -> "Fake" binade. |
|
123 |
if l2 >= emax + 1: |
|
124 |
if number > 0: |
|
125 |
return (RF(2^(emax+1)), RRR(+infinity) ) |
|
126 |
else: |
|
127 |
return (RF(-infinity), -RF(2^(emax+1))) |
|
102 | 128 |
offset = int(l2) |
129 |
# number.abs() >= 1. |
|
103 | 130 |
if l2 >= 0: |
104 | 131 |
if number >= 0: |
105 | 132 |
lb = RF(2^offset) |
... | ... | |
107 | 134 |
else: #number < 0 |
108 | 135 |
lb = -RF(2^(offset + 1) - 2^(-precision+offset+1)) |
109 | 136 |
ub = -RF(2^offset) |
110 |
else: # log2 < 0 |
|
137 |
else: # log2 < 0, number.abs() < 1.
|
|
111 | 138 |
if l2 < emin: # Denormal |
112 |
print "Denormal:", l2 |
|
139 |
# print "Denormal:", l2
|
|
113 | 140 |
if number >= 0: |
114 | 141 |
lb = RF(0) |
115 | 142 |
ub = RF(2^(emin)) - RF(2^(emin-precision)) |
... | ... | |
118 | 145 |
ub = RF(0) |
119 | 146 |
elif l2 > emin: # Normal number other than +/-2^emin. |
120 | 147 |
if number >= 0: |
121 |
lb = RF(2^(offset-1)) |
|
122 |
ub = RF(2^(offset)) - RF(2^(-precision+offset)) |
|
148 |
if int(l2) == l2: |
|
149 |
lb = RF(2^(offset)) |
|
150 |
ub = RF(2^(offset+1)) - RF(2^(-precision+offset+1)) |
|
151 |
else: |
|
152 |
lb = RF(2^(offset-1)) |
|
153 |
ub = RF(2^(offset)) - RF(2^(-precision+offset)) |
|
123 | 154 |
else: # number < 0 |
124 |
lb = -RF(2^(offset) - 2^(-precision+offset)) |
|
125 |
ub = -RF(2^(offset-1)) |
|
126 |
else: # +/-2^emin |
|
155 |
if int(l2) == l2: # Binade limit. |
|
156 |
lb = -RF(2^(offset+1) - 2^(-precision+offset+1)) |
|
157 |
ub = -RF(2^(offset)) |
|
158 |
else: |
|
159 |
lb = -RF(2^(offset) - 2^(-precision+offset)) |
|
160 |
ub = -RF(2^(offset-1)) |
|
161 |
else: # l2== emin, number == +/-2^emin |
|
127 | 162 |
if number >= 0: |
128 | 163 |
lb = RF(2^(offset)) |
129 | 164 |
ub = RF(2^(offset+1)) - RF(2^(-precision+offset+1)) |
Formats disponibles : Unified diff