Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
46572836
Kaydet (Commit)
46572836
authored
Ara 27, 2009
tarafından
Mark Dickinson
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #1811: Improve accuracy and consistency of true division for integers.
üst
13c2ef92
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
450 additions
and
37 deletions
+450
-37
test_long_future.py
Lib/test/test_long_future.py
+168
-0
NEWS
Misc/NEWS
+5
-0
intobject.c
Objects/intobject.c
+25
-6
longobject.c
Objects/longobject.c
+252
-31
No files found.
Lib/test/test_long_future.py
Dosyayı görüntüle @
46572836
...
@@ -3,9 +3,52 @@ from __future__ import division
...
@@ -3,9 +3,52 @@ from __future__ import division
# test_long.py instead. In the meantime, it's too obscure to try to
# test_long.py instead. In the meantime, it's too obscure to try to
# trick just part of test_long into using future division.
# trick just part of test_long into using future division.
import
sys
import
random
import
unittest
import
unittest
from
test.test_support
import
run_unittest
from
test.test_support
import
run_unittest
# decorator for skipping tests on non-IEEE 754 platforms
requires_IEEE_754
=
unittest
.
skipUnless
(
float
.
__getformat__
(
"double"
)
.
startswith
(
"IEEE"
),
"test requires IEEE 754 doubles"
)
DBL_MAX
=
sys
.
float_info
.
max
DBL_MAX_EXP
=
sys
.
float_info
.
max_exp
DBL_MIN_EXP
=
sys
.
float_info
.
min_exp
DBL_MANT_DIG
=
sys
.
float_info
.
mant_dig
DBL_MIN_OVERFLOW
=
2
**
DBL_MAX_EXP
-
2
**
(
DBL_MAX_EXP
-
DBL_MANT_DIG
-
1
)
# pure Python version of correctly-rounded true division
def
truediv
(
a
,
b
):
"""Correctly-rounded true division for integers."""
negative
=
a
^
b
<
0
a
,
b
=
abs
(
a
),
abs
(
b
)
# exceptions: division by zero, overflow
if
not
b
:
raise
ZeroDivisionError
(
"division by zero"
)
if
a
>=
DBL_MIN_OVERFLOW
*
b
:
raise
OverflowError
(
"int/int too large to represent as a float"
)
# find integer d satisfying 2**(d - 1) <= a/b < 2**d
d
=
a
.
bit_length
()
-
b
.
bit_length
()
if
d
>=
0
and
a
>=
2
**
d
*
b
or
d
<
0
and
a
*
2
**-
d
>=
b
:
d
+=
1
# compute 2**-exp * a / b for suitable exp
exp
=
max
(
d
,
DBL_MIN_EXP
)
-
DBL_MANT_DIG
a
,
b
=
a
<<
max
(
-
exp
,
0
),
b
<<
max
(
exp
,
0
)
q
,
r
=
divmod
(
a
,
b
)
# round-half-to-even: fractional part is r/b, which is > 0.5 iff
# 2*r > b, and == 0.5 iff 2*r == b.
if
2
*
r
>
b
or
2
*
r
==
b
and
q
%
2
==
1
:
q
+=
1
result
=
float
(
q
)
*
2.
**
exp
return
-
result
if
negative
else
result
class
TrueDivisionTests
(
unittest
.
TestCase
):
class
TrueDivisionTests
(
unittest
.
TestCase
):
def
test
(
self
):
def
test
(
self
):
huge
=
1L
<<
40000
huge
=
1L
<<
40000
...
@@ -45,6 +88,131 @@ class TrueDivisionTests(unittest.TestCase):
...
@@ -45,6 +88,131 @@ class TrueDivisionTests(unittest.TestCase):
with
self
.
assertRaises
(
ZeroDivisionError
):
with
self
.
assertRaises
(
ZeroDivisionError
):
eval
(
zero
,
namespace
)
eval
(
zero
,
namespace
)
def
check_truediv
(
self
,
a
,
b
,
skip_small
=
True
):
"""Verify that the result of a/b is correctly rounded, by
comparing it with a pure Python implementation of correctly
rounded division. b should be nonzero."""
a
,
b
=
long
(
a
),
long
(
b
)
# skip check for small a and b: in this case, the current
# implementation converts the arguments to float directly and
# then applies a float division. This can give doubly-rounded
# results on x87-using machines (particularly 32-bit Linux).
if
skip_small
and
max
(
abs
(
a
),
abs
(
b
))
<
2
**
DBL_MANT_DIG
:
return
try
:
# use repr so that we can distinguish between -0.0 and 0.0
expected
=
repr
(
truediv
(
a
,
b
))
except
OverflowError
:
expected
=
'overflow'
except
ZeroDivisionError
:
expected
=
'zerodivision'
try
:
got
=
repr
(
a
/
b
)
except
OverflowError
:
got
=
'overflow'
except
ZeroDivisionError
:
got
=
'zerodivision'
if
expected
!=
got
:
self
.
fail
(
"Incorrectly rounded division {}/{}: expected {!r}, "
"got {!r}."
.
format
(
a
,
b
,
expected
,
got
))
@requires_IEEE_754
def
test_correctly_rounded_true_division
(
self
):
# more stringent tests than those above, checking that the
# result of true division of ints is always correctly rounded.
# This test should probably be considered CPython-specific.
# Exercise all the code paths not involving Gb-sized ints.
# ... divisions involving zero
self
.
check_truediv
(
123
,
0
)
self
.
check_truediv
(
-
456
,
0
)
self
.
check_truediv
(
0
,
3
)
self
.
check_truediv
(
0
,
-
3
)
self
.
check_truediv
(
0
,
0
)
# ... overflow or underflow by large margin
self
.
check_truediv
(
671
*
12345
*
2
**
DBL_MAX_EXP
,
12345
)
self
.
check_truediv
(
12345
,
345678
*
2
**
(
DBL_MANT_DIG
-
DBL_MIN_EXP
))
# ... a much larger or smaller than b
self
.
check_truediv
(
12345
*
2
**
100
,
98765
)
self
.
check_truediv
(
12345
*
2
**
30
,
98765
*
7
**
81
)
# ... a / b near a boundary: one of 1, 2**DBL_MANT_DIG, 2**DBL_MIN_EXP,
# 2**DBL_MAX_EXP, 2**(DBL_MIN_EXP-DBL_MANT_DIG)
bases
=
(
0
,
DBL_MANT_DIG
,
DBL_MIN_EXP
,
DBL_MAX_EXP
,
DBL_MIN_EXP
-
DBL_MANT_DIG
)
for
base
in
bases
:
for
exp
in
range
(
base
-
15
,
base
+
15
):
self
.
check_truediv
(
75312
*
2
**
max
(
exp
,
0
),
69187
*
2
**
max
(
-
exp
,
0
))
self
.
check_truediv
(
69187
*
2
**
max
(
exp
,
0
),
75312
*
2
**
max
(
-
exp
,
0
))
# overflow corner case
for
m
in
[
1
,
2
,
7
,
17
,
12345
,
7
**
100
,
-
1
,
-
2
,
-
5
,
-
23
,
-
67891
,
-
41
**
50
]:
for
n
in
range
(
-
10
,
10
):
self
.
check_truediv
(
m
*
DBL_MIN_OVERFLOW
+
n
,
m
)
self
.
check_truediv
(
m
*
DBL_MIN_OVERFLOW
+
n
,
-
m
)
# check detection of inexactness in shifting stage
for
n
in
range
(
250
):
# (2**DBL_MANT_DIG+1)/(2**DBL_MANT_DIG) lies halfway
# between two representable floats, and would usually be
# rounded down under round-half-to-even. The tiniest of
# additions to the numerator should cause it to be rounded
# up instead.
self
.
check_truediv
((
2
**
DBL_MANT_DIG
+
1
)
*
12345
*
2
**
200
+
2
**
n
,
2
**
DBL_MANT_DIG
*
12345
)
# 1/2731 is one of the smallest division cases that's subject
# to double rounding on IEEE 754 machines working internally with
# 64-bit precision. On such machines, the next check would fail,
# were it not explicitly skipped in check_truediv.
self
.
check_truediv
(
1
,
2731
)
# a particularly bad case for the old algorithm: gives an
# error of close to 3.5 ulps.
self
.
check_truediv
(
295147931372582273023
,
295147932265116303360
)
for
i
in
range
(
1000
):
self
.
check_truediv
(
10
**
(
i
+
1
),
10
**
i
)
self
.
check_truediv
(
10
**
i
,
10
**
(
i
+
1
))
# test round-half-to-even behaviour, normal result
for
m
in
[
1
,
2
,
4
,
7
,
8
,
16
,
17
,
32
,
12345
,
7
**
100
,
-
1
,
-
2
,
-
5
,
-
23
,
-
67891
,
-
41
**
50
]:
for
n
in
range
(
-
10
,
10
):
self
.
check_truediv
(
2
**
DBL_MANT_DIG
*
m
+
n
,
m
)
# test round-half-to-even, subnormal result
for
n
in
range
(
-
20
,
20
):
self
.
check_truediv
(
n
,
2
**
1076
)
# largeish random divisions: a/b where |a| <= |b| <=
# 2*|a|; |ans| is between 0.5 and 1.0, so error should
# always be bounded by 2**-54 with equality possible only
# if the least significant bit of q=ans*2**53 is zero.
for
M
in
[
10
**
10
,
10
**
100
,
10
**
1000
]:
for
i
in
range
(
1000
):
a
=
random
.
randrange
(
1
,
M
)
b
=
random
.
randrange
(
a
,
2
*
a
+
1
)
self
.
check_truediv
(
a
,
b
)
self
.
check_truediv
(
-
a
,
b
)
self
.
check_truediv
(
a
,
-
b
)
self
.
check_truediv
(
-
a
,
-
b
)
# and some (genuinely) random tests
for
_
in
range
(
10000
):
a_bits
=
random
.
randrange
(
1000
)
b_bits
=
random
.
randrange
(
1
,
1000
)
x
=
random
.
randrange
(
2
**
a_bits
)
y
=
random
.
randrange
(
1
,
2
**
b_bits
)
self
.
check_truediv
(
x
,
y
)
self
.
check_truediv
(
x
,
-
y
)
self
.
check_truediv
(
-
x
,
y
)
self
.
check_truediv
(
-
x
,
-
y
)
def
test_main
():
def
test_main
():
run_unittest
(
TrueDivisionTests
)
run_unittest
(
TrueDivisionTests
)
...
...
Misc/NEWS
Dosyayı görüntüle @
46572836
...
@@ -12,6 +12,11 @@ What's New in Python 2.7 alpha 2?
...
@@ -12,6 +12,11 @@ What's New in Python 2.7 alpha 2?
Core and Builtins
Core and Builtins
-----------------
-----------------
- Issue #1811: improve accuracy and cross-platform consistency for
true division of integers: the result of a/b is now correctly
rounded for ints a and b (at least on IEEE 754 platforms), and in
particular does not depend on the internal representation of a long.
- Issue #6108: unicode(exception) and str(exception) should return the same
- Issue #6108: unicode(exception) and str(exception) should return the same
message when only __str__ (and not __unicode__) is overridden in the subclass.
message when only __str__ (and not __unicode__) is overridden in the subclass.
...
...
Objects/intobject.c
Dosyayı görüntüle @
46572836
...
@@ -645,16 +645,35 @@ int_classic_div(PyIntObject *x, PyIntObject *y)
...
@@ -645,16 +645,35 @@ int_classic_div(PyIntObject *x, PyIntObject *y)
}
}
static
PyObject
*
static
PyObject
*
int_true_divide
(
Py
Object
*
v
,
PyObject
*
w
)
int_true_divide
(
Py
IntObject
*
x
,
PyIntObject
*
y
)
{
{
long
xi
,
yi
;
/* If they aren't both ints, give someone else a chance. In
/* If they aren't both ints, give someone else a chance. In
particular, this lets int/long get handled by longs, which
particular, this lets int/long get handled by longs, which
underflows to 0 gracefully if the long is too big to convert
underflows to 0 gracefully if the long is too big to convert
to float. */
to float. */
if
(
PyInt_Check
(
v
)
&&
PyInt_Check
(
w
))
CONVERT_TO_LONG
(
x
,
xi
);
return
PyFloat_Type
.
tp_as_number
->
nb_true_divide
(
v
,
w
);
CONVERT_TO_LONG
(
y
,
yi
);
Py_INCREF
(
Py_NotImplemented
);
if
(
yi
==
0
)
{
return
Py_NotImplemented
;
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"division by zero"
);
return
NULL
;
}
if
(
xi
==
0
)
return
PyFloat_FromDouble
(
yi
<
0
?
-
0
.
0
:
0
.
0
);
#define WIDTH_OF_ULONG (CHAR_BIT*SIZEOF_LONG)
#if DBL_MANT_DIG < WIDTH_OF_ULONG
if
((
xi
>=
0
?
0UL
+
xi
:
0UL
-
xi
)
>>
DBL_MANT_DIG
||
(
yi
>=
0
?
0UL
+
yi
:
0UL
-
yi
)
>>
DBL_MANT_DIG
)
/* Large x or y. Use long integer arithmetic. */
return
PyLong_Type
.
tp_as_number
->
nb_true_divide
(
(
PyObject
*
)
x
,
(
PyObject
*
)
y
);
else
#endif
/* Both ints can be exactly represented as doubles. Do a
floating-point division. */
return
PyFloat_FromDouble
((
double
)
xi
/
(
double
)
yi
);
}
}
static
PyObject
*
static
PyObject
*
...
@@ -1355,7 +1374,7 @@ static PyNumberMethods int_as_number = {
...
@@ -1355,7 +1374,7 @@ static PyNumberMethods int_as_number = {
0
,
/*nb_inplace_xor*/
0
,
/*nb_inplace_xor*/
0
,
/*nb_inplace_or*/
0
,
/*nb_inplace_or*/
(
binaryfunc
)
int_div
,
/* nb_floor_divide */
(
binaryfunc
)
int_div
,
/* nb_floor_divide */
int_true_divide
,
/* nb_true_divide */
(
binaryfunc
)
int_true_divide
,
/* nb_true_divide */
0
,
/* nb_inplace_floor_divide */
0
,
/* nb_inplace_floor_divide */
0
,
/* nb_inplace_true_divide */
0
,
/* nb_inplace_true_divide */
(
unaryfunc
)
int_int
,
/* nb_index */
(
unaryfunc
)
int_int
,
/* nb_index */
...
...
Objects/longobject.c
Dosyayı görüntüle @
46572836
...
@@ -3037,50 +3037,271 @@ long_classic_div(PyObject *v, PyObject *w)
...
@@ -3037,50 +3037,271 @@ long_classic_div(PyObject *v, PyObject *w)
return
(
PyObject
*
)
div
;
return
(
PyObject
*
)
div
;
}
}
/* PyLong/PyLong -> float, with correctly rounded result. */
#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT)
#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT)
static
PyObject
*
static
PyObject
*
long_true_divide
(
PyObject
*
v
,
PyObject
*
w
)
long_true_divide
(
PyObject
*
v
,
PyObject
*
w
)
{
{
PyLongObject
*
a
,
*
b
;
PyLongObject
*
a
,
*
b
,
*
x
;
double
ad
,
bd
;
Py_ssize_t
a_size
,
b_size
,
shift
,
extra_bits
,
diff
,
x_size
,
x_bits
;
int
failed
,
aexp
=
-
1
,
bexp
=
-
1
;
digit
mask
,
low
;
int
inexact
,
negate
,
a_is_small
,
b_is_small
;
double
dx
,
result
;
CONVERT_BINOP
(
v
,
w
,
&
a
,
&
b
);
CONVERT_BINOP
(
v
,
w
,
&
a
,
&
b
);
ad
=
_PyLong_AsScaledDouble
((
PyObject
*
)
a
,
&
aexp
);
bd
=
_PyLong_AsScaledDouble
((
PyObject
*
)
b
,
&
bexp
);
failed
=
(
ad
==
-
1
.
0
||
bd
==
-
1
.
0
)
&&
PyErr_Occurred
();
Py_DECREF
(
a
);
Py_DECREF
(
b
);
if
(
failed
)
return
NULL
;
/* 'aexp' and 'bexp' were initialized to -1 to silence gcc-4.0.x,
but should really be set correctly after sucessful calls to
_PyLong_AsScaledDouble() */
assert
(
aexp
>=
0
&&
bexp
>=
0
);
if
(
bd
==
0
.
0
)
{
/*
Method in a nutshell:
0. reduce to case a, b > 0; filter out obvious underflow/overflow
1. choose a suitable integer 'shift'
2. use integer arithmetic to compute x = floor(2**-shift*a/b)
3. adjust x for correct rounding
4. convert x to a double dx with the same value
5. return ldexp(dx, shift).
In more detail:
0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b
returns either 0.0 or -0.0, depending on the sign of b. For a and
b both nonzero, ignore signs of a and b, and add the sign back in
at the end. Now write a_bits and b_bits for the bit lengths of a
and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise
for b). Then
2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1).
So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and
so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP -
DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of
the way, we can assume that
DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP.
1. The integer 'shift' is chosen so that x has the right number of
bits for a double, plus two or three extra bits that will be used
in the rounding decisions. Writing a_bits and b_bits for the
number of significant bits in a and b respectively, a
straightforward formula for shift is:
shift = a_bits - b_bits - DBL_MANT_DIG - 2
This is fine in the usual case, but if a/b is smaller than the
smallest normal float then it can lead to double rounding on an
IEEE 754 platform, giving incorrectly rounded results. So we
adjust the formula slightly. The actual formula used is:
shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2
2. The quantity x is computed by first shifting a (left -shift bits
if shift <= 0, right shift bits if shift > 0) and then dividing by
b. For both the shift and the division, we keep track of whether
the result is inexact, in a flag 'inexact'; this information is
needed at the rounding stage.
With the choice of shift above, together with our assumption that
a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows
that x >= 1.
3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace
this with an exactly representable float of the form
round(x/2**extra_bits) * 2**(extra_bits+shift).
For float representability, we need x/2**extra_bits <
2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP -
DBL_MANT_DIG. This translates to the condition:
extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG
To round, we just modify the bottom digit of x in-place; this can
end up giving a digit with value > PyLONG_MASK, but that's not a
problem since digits can hold values up to 2*PyLONG_MASK+1.
With the original choices for shift above, extra_bits will always
be 2 or 3. Then rounding under the round-half-to-even rule, we
round up iff the most significant of the extra bits is 1, and
either: (a) the computation of x in step 2 had an inexact result,
or (b) at least one other of the extra bits is 1, or (c) the least
significant bit of x (above those to be rounded) is 1.
4. Conversion to a double is straightforward; all floating-point
operations involved in the conversion are exact, so there's no
danger of rounding errors.
5. Use ldexp(x, shift) to compute x*2**shift, the final result.
The result will always be exactly representable as a double, except
in the case that it overflows. To avoid dependence on the exact
behaviour of ldexp on overflow, we check for overflow before
applying ldexp. The result of ldexp is adjusted for sign before
returning.
*/
/* Reduce to case where a and b are both positive. */
a_size
=
ABS
(
Py_SIZE
(
a
));
b_size
=
ABS
(
Py_SIZE
(
b
));
negate
=
(
Py_SIZE
(
a
)
<
0
)
^
(
Py_SIZE
(
b
)
<
0
);
if
(
b_size
==
0
)
{
PyErr_SetString
(
PyExc_ZeroDivisionError
,
PyErr_SetString
(
PyExc_ZeroDivisionError
,
"long division or modulo
by zero"
);
"division
by zero"
);
return
NULL
;
goto
error
;
}
}
if
(
a_size
==
0
)
/* True value is very close to ad/bd * 2**(PyLong_SHIFT*(aexp-bexp)) */
goto
underflow_or_zero
;
ad
/=
bd
;
/* overflow/underflow impossible here */
aexp
-=
bexp
;
/* Fast path for a and b small (exactly representable in a double).
if
(
aexp
>
INT_MAX
/
PyLong_SHIFT
)
Relies on floating-point division being correctly rounded; results
may be subject to double rounding on x86 machines that operate with
the x87 FPU set to 64-bit precision. */
a_is_small
=
a_size
<=
MANT_DIG_DIGITS
||
(
a_size
==
MANT_DIG_DIGITS
+
1
&&
a
->
ob_digit
[
MANT_DIG_DIGITS
]
>>
MANT_DIG_BITS
==
0
);
b_is_small
=
b_size
<=
MANT_DIG_DIGITS
||
(
b_size
==
MANT_DIG_DIGITS
+
1
&&
b
->
ob_digit
[
MANT_DIG_DIGITS
]
>>
MANT_DIG_BITS
==
0
);
if
(
a_is_small
&&
b_is_small
)
{
double
da
,
db
;
da
=
a
->
ob_digit
[
--
a_size
];
while
(
a_size
>
0
)
da
=
da
*
PyLong_BASE
+
a
->
ob_digit
[
--
a_size
];
db
=
b
->
ob_digit
[
--
b_size
];
while
(
b_size
>
0
)
db
=
db
*
PyLong_BASE
+
b
->
ob_digit
[
--
b_size
];
result
=
da
/
db
;
goto
success
;
}
/* Catch obvious cases of underflow and overflow */
diff
=
a_size
-
b_size
;
if
(
diff
>
PY_SSIZE_T_MAX
/
PyLong_SHIFT
-
1
)
/* Extreme overflow */
goto
overflow
;
goto
overflow
;
else
if
(
aexp
<
-
(
INT_MAX
/
PyLong_SHIFT
))
else
if
(
diff
<
1
-
PY_SSIZE_T_MAX
/
PyLong_SHIFT
)
return
PyFloat_FromDouble
(
0
.
0
);
/* underflow to 0 */
/* Extreme underflow */
errno
=
0
;
goto
underflow_or_zero
;
ad
=
ldexp
(
ad
,
aexp
*
PyLong_SHIFT
);
/* Next line is now safe from overflowing a Py_ssize_t */
if
(
Py_OVERFLOWED
(
ad
))
/* ignore underflow to 0.0 */
diff
=
diff
*
PyLong_SHIFT
+
bits_in_digit
(
a
->
ob_digit
[
a_size
-
1
])
-
bits_in_digit
(
b
->
ob_digit
[
b_size
-
1
]);
/* Now diff = a_bits - b_bits. */
if
(
diff
>
DBL_MAX_EXP
)
goto
overflow
;
goto
overflow
;
return
PyFloat_FromDouble
(
ad
);
else
if
(
diff
<
DBL_MIN_EXP
-
DBL_MANT_DIG
-
1
)
goto
underflow_or_zero
;
/* Choose value for shift; see comments for step 1 above. */
shift
=
MAX
(
diff
,
DBL_MIN_EXP
)
-
DBL_MANT_DIG
-
2
;
inexact
=
0
;
/* x = abs(a * 2**-shift) */
if
(
shift
<=
0
)
{
Py_ssize_t
i
,
shift_digits
=
-
shift
/
PyLong_SHIFT
;
digit
rem
;
/* x = a << -shift */
if
(
a_size
>=
PY_SSIZE_T_MAX
-
1
-
shift_digits
)
{
/* In practice, it's probably impossible to end up
here. Both a and b would have to be enormous,
using close to SIZE_T_MAX bytes of memory each. */
PyErr_SetString
(
PyExc_OverflowError
,
"intermediate overflow during division"
);
goto
error
;
}
x
=
_PyLong_New
(
a_size
+
shift_digits
+
1
);
if
(
x
==
NULL
)
goto
error
;
for
(
i
=
0
;
i
<
shift_digits
;
i
++
)
x
->
ob_digit
[
i
]
=
0
;
rem
=
v_lshift
(
x
->
ob_digit
+
shift_digits
,
a
->
ob_digit
,
a_size
,
-
shift
%
PyLong_SHIFT
);
x
->
ob_digit
[
a_size
+
shift_digits
]
=
rem
;
}
else
{
Py_ssize_t
shift_digits
=
shift
/
PyLong_SHIFT
;
digit
rem
;
/* x = a >> shift */
assert
(
a_size
>=
shift_digits
);
x
=
_PyLong_New
(
a_size
-
shift_digits
);
if
(
x
==
NULL
)
goto
error
;
rem
=
v_rshift
(
x
->
ob_digit
,
a
->
ob_digit
+
shift_digits
,
a_size
-
shift_digits
,
shift
%
PyLong_SHIFT
);
/* set inexact if any of the bits shifted out is nonzero */
if
(
rem
)
inexact
=
1
;
while
(
!
inexact
&&
shift_digits
>
0
)
if
(
a
->
ob_digit
[
--
shift_digits
])
inexact
=
1
;
}
long_normalize
(
x
);
x_size
=
Py_SIZE
(
x
);
/* x //= b. If the remainder is nonzero, set inexact. We own the only
reference to x, so it's safe to modify it in-place. */
if
(
b_size
==
1
)
{
digit
rem
=
inplace_divrem1
(
x
->
ob_digit
,
x
->
ob_digit
,
x_size
,
b
->
ob_digit
[
0
]);
long_normalize
(
x
);
if
(
rem
)
inexact
=
1
;
}
else
{
PyLongObject
*
div
,
*
rem
;
div
=
x_divrem
(
x
,
b
,
&
rem
);
Py_DECREF
(
x
);
x
=
div
;
if
(
x
==
NULL
)
goto
error
;
if
(
Py_SIZE
(
rem
))
inexact
=
1
;
Py_DECREF
(
rem
);
}
x_size
=
ABS
(
Py_SIZE
(
x
));
assert
(
x_size
>
0
);
/* result of division is never zero */
x_bits
=
(
x_size
-
1
)
*
PyLong_SHIFT
+
bits_in_digit
(
x
->
ob_digit
[
x_size
-
1
]);
/* The number of extra bits that have to be rounded away. */
extra_bits
=
MAX
(
x_bits
,
DBL_MIN_EXP
-
shift
)
-
DBL_MANT_DIG
;
assert
(
extra_bits
==
2
||
extra_bits
==
3
);
/* Round by directly modifying the low digit of x. */
mask
=
(
digit
)
1
<<
(
extra_bits
-
1
);
low
=
x
->
ob_digit
[
0
]
|
inexact
;
if
(
low
&
mask
&&
low
&
(
3
*
mask
-
1
))
low
+=
mask
;
x
->
ob_digit
[
0
]
=
low
&
~
(
mask
-
1U
);
/* Convert x to a double dx; the conversion is exact. */
dx
=
x
->
ob_digit
[
--
x_size
];
while
(
x_size
>
0
)
dx
=
dx
*
PyLong_BASE
+
x
->
ob_digit
[
--
x_size
];
Py_DECREF
(
x
);
overflow:
/* Check whether ldexp result will overflow a double. */
if
(
shift
+
x_bits
>=
DBL_MAX_EXP
&&
(
shift
+
x_bits
>
DBL_MAX_EXP
||
dx
==
ldexp
(
1
.
0
,
x_bits
)))
goto
overflow
;
result
=
ldexp
(
dx
,
shift
);
success:
Py_DECREF
(
a
);
Py_DECREF
(
b
);
return
PyFloat_FromDouble
(
negate
?
-
result
:
result
);
underflow_or_zero:
Py_DECREF
(
a
);
Py_DECREF
(
b
);
return
PyFloat_FromDouble
(
negate
?
-
0
.
0
:
0
.
0
);
overflow:
PyErr_SetString
(
PyExc_OverflowError
,
PyErr_SetString
(
PyExc_OverflowError
,
"long/long too large for a float"
);
"integer division result too large for a float"
);
error:
Py_DECREF
(
a
);
Py_DECREF
(
b
);
return
NULL
;
return
NULL
;
}
}
static
PyObject
*
static
PyObject
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment