File: test_longlong2float.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (131 lines) | stat: -rw-r--r-- 4,083 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import math
from rpython.translator.c.test.test_genc import compile
from rpython.rlib.longlong2float import longlong2float, float2longlong, r_rettype
from rpython.rlib.longlong2float import uint2singlefloat, singlefloat2uint
from rpython.rlib.rarithmetic import r_singlefloat, r_longlong
from rpython.rtyper.test.test_llinterp import interpret

from rpython.rtyper.lltypesystem import lltype, rffi

DOUBLE_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.DOUBLE))
LONGLONG_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.LONGLONG))
UINT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.UINT))
FLOAT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.FLOAT))


from hypothesis import given, strategies


def fn(f1):
    ll = float2longlong(f1)
    f2 = longlong2float(ll)
    return f2

def enum_floats():
    inf = 1e200 * 1e200
    yield 0.0
    yield -0.0
    yield 1.0
    yield -2.34567
    yield 2.134891117e22
    yield inf
    yield -inf
    yield inf / inf     # nan

def test_float2longlong():
    assert float2longlong(0.0) == r_longlong(0)

def test_longlong_as_float():
    for x in enum_floats():
        res = fn(x)
        assert repr(res) == repr(x)

@given(strategies.floats())
def test_longlong_as_float_hypothesis_roundtrip(x):
    assert repr(x) == repr(fn(x))

@given(strategies.integers(-2**63, 2**63-1))
def test_consistency_longlong2float_ll2ctypes(llval):
# these definitions are used only in tests, when not translated
    #return struct.unpack('@d', struct.pack('@q', llval))[0]
    with lltype.scoped_alloc(DOUBLE_ARRAY_PTR.TO, 1) as d_array:
        ll_array = rffi.cast(LONGLONG_ARRAY_PTR, d_array)
        ll_array[0] = r_rettype(llval)
        floatval = d_array[0]
    assert repr(floatval) == repr(longlong2float(llval))

@given(strategies.floats())
def test_consistency_float2longlong_ll2ctypes(floatval):
    #return struct.unpack('@q', struct.pack('@d', floatval))[0]
    with lltype.scoped_alloc(DOUBLE_ARRAY_PTR.TO, 1) as d_array:
        ll_array = rffi.cast(LONGLONG_ARRAY_PTR, d_array)
        d_array[0] = floatval
        llval = ll_array[0]
    assert llval == float2longlong(floatval)


def test_compiled():
    fn2 = compile(fn, [float])
    for x in enum_floats():
        res = fn2(x)
        assert repr(res) == repr(x)

def test_interpreted():
    def f(f1):
        try:
            ll = float2longlong(f1)
            return longlong2float(ll)
        except Exception:
            return 500

    for x in enum_floats():
        res = interpret(f, [x])
        assert repr(res) == repr(x)

# ____________________________________________________________

def fnsingle(f1):
    sf1 = r_singlefloat(f1)
    ii = singlefloat2uint(sf1)
    sf2 = uint2singlefloat(ii)
    f2 = float(sf2)
    return f2

def test_int_as_singlefloat():
    for x in enum_floats():
        res = fnsingle(x)
        assert repr(res) == repr(float(r_singlefloat(x)))

def test_compiled_single():
    fn2 = compile(fnsingle, [float])
    for x in enum_floats():
        res = fn2(x)
        assert repr(res) == repr(float(r_singlefloat(x)))

# ____________________________________________________________

def fn_encode_nan(f1, i2):
    from rpython.rlib.longlong2float import can_encode_float, can_encode_int32
    from rpython.rlib.longlong2float import encode_int32_into_longlong_nan
    from rpython.rlib.longlong2float import decode_int32_from_longlong_nan
    from rpython.rlib.longlong2float import is_int32_from_longlong_nan
    assert can_encode_float(f1)
    assert can_encode_int32(i2)
    l1 = float2longlong(f1)
    l2 = encode_int32_into_longlong_nan(i2)
    assert not is_int32_from_longlong_nan(l1)
    assert is_int32_from_longlong_nan(l2)
    f1b = longlong2float(l1)
    assert f1b == f1 or (math.isnan(f1b) and math.isnan(f1))
    assert decode_int32_from_longlong_nan(l2) == i2
    return 42

def test_compiled_encode_nan():
    fn2 = compile(fn_encode_nan, [float, int])
    ints = [int(-2**31), int(2**31-1), 42]
    for x in enum_floats():
        y = ints.pop()
        ints.insert(0, y)
        fn_encode_nan(x, y)
        res = fn2(x, y)
        assert res == 42