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