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
30970e9e
Kaydet (Commit)
30970e9e
authored
Eki 23, 2011
tarafından
Mark Dickinson
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #10925: Add equivalent pure Python code for the builtin int-to-float conversion to test_long.
üst
36645681
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
80 additions
and
0 deletions
+80
-0
test_long.py
Lib/test/test_long.py
+80
-0
No files found.
Lib/test/test_long.py
Dosyayı görüntüle @
30970e9e
...
...
@@ -43,6 +43,53 @@ 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 integer-to-float conversion.
def
int_to_float
(
n
):
"""
Correctly-rounded integer-to-float conversion.
"""
# Constants, depending only on the floating-point format in use.
# We use an extra 2 bits of precision for rounding purposes.
PRECISION
=
sys
.
float_info
.
mant_dig
+
2
SHIFT_MAX
=
sys
.
float_info
.
max_exp
-
PRECISION
Q_MAX
=
1
<<
PRECISION
ROUND_HALF_TO_EVEN_CORRECTION
=
[
0
,
-
1
,
-
2
,
1
,
0
,
-
1
,
2
,
1
]
# Reduce to the case where n is positive.
if
n
==
0
:
return
0.0
elif
n
<
0
:
return
-
int_to_float
(
-
n
)
# Convert n to a 'floating-point' number q * 2**shift, where q is an
# integer with 'PRECISION' significant bits. When shifting n to create q,
# the least significant bit of q is treated as 'sticky'. That is, the
# least significant bit of q is set if either the corresponding bit of n
# was already set, or any one of the bits of n lost in the shift was set.
shift
=
n
.
bit_length
()
-
PRECISION
q
=
n
<<
-
shift
if
shift
<
0
else
(
n
>>
shift
)
|
bool
(
n
&
~
(
-
1
<<
shift
))
# Round half to even (actually rounds to the nearest multiple of 4,
# rounding ties to a multiple of 8).
q
+=
ROUND_HALF_TO_EVEN_CORRECTION
[
q
&
7
]
# Detect overflow.
if
shift
+
(
q
==
Q_MAX
)
>
SHIFT_MAX
:
raise
OverflowError
(
"integer too large to convert to float"
)
# Checks: q is exactly representable, and q**2**shift doesn't overflow.
assert
q
%
4
==
0
and
q
//
4
<=
2
**
(
sys
.
float_info
.
mant_dig
)
assert
q
*
2
**
shift
<=
sys
.
float_info
.
max
# Some circularity here, since float(q) is doing an int-to-float
# conversion. But here q is of bounded size, and is exactly representable
# as a float. In a low-level C-like language, this operation would be a
# simple cast (e.g., from unsigned long long to double).
return
math
.
ldexp
(
float
(
q
),
shift
)
# pure Python version of correctly-rounded true division
def
truediv
(
a
,
b
):
"""Correctly-rounded true division for integers."""
...
...
@@ -367,6 +414,23 @@ class LongTest(unittest.TestCase):
return
1729
self
.
assertEqual
(
int
(
LongTrunc
()),
1729
)
def
check_float_conversion
(
self
,
n
):
# Check that int -> float conversion behaviour matches
# that of the pure Python version above.
try
:
actual
=
float
(
n
)
except
OverflowError
:
actual
=
'overflow'
try
:
expected
=
int_to_float
(
n
)
except
OverflowError
:
expected
=
'overflow'
msg
=
(
"Error in conversion of integer {} to float. "
"Got {}, expected {}."
.
format
(
n
,
actual
,
expected
))
self
.
assertEqual
(
actual
,
expected
,
msg
)
@support.requires_IEEE_754
def
test_float_conversion
(
self
):
...
...
@@ -421,6 +485,22 @@ class LongTest(unittest.TestCase):
y
=
2
**
p
*
2
**
53
self
.
assertEqual
(
int
(
float
(
x
)),
y
)
# Compare builtin float conversion with pure Python int_to_float
# function above.
test_values
=
[
int_dbl_max
-
1
,
int_dbl_max
,
int_dbl_max
+
1
,
halfway
-
1
,
halfway
,
halfway
+
1
,
top_power
-
1
,
top_power
,
top_power
+
1
,
2
*
top_power
-
1
,
2
*
top_power
,
top_power
*
top_power
,
]
test_values
.
extend
(
exact_values
)
for
p
in
range
(
-
4
,
8
):
for
x
in
range
(
-
128
,
128
):
test_values
.
append
(
2
**
(
p
+
53
)
+
x
)
for
value
in
test_values
:
self
.
check_float_conversion
(
value
)
self
.
check_float_conversion
(
-
value
)
def
test_float_overflow
(
self
):
for
x
in
-
2.0
,
-
1.0
,
0.0
,
1.0
,
2.0
:
self
.
assertEqual
(
float
(
int
(
x
)),
x
)
...
...
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