aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Python/pymath.c
blob: fa1384ec5b8cb55ceb5f1ca24a61946c184dec15 (plain) (blame)
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
#include "Python.h" 
 
#ifdef X87_DOUBLE_ROUNDING 
/* On x86 platforms using an x87 FPU, this function is called from the 
   Py_FORCE_DOUBLE macro (defined in pymath.h) to force a floating-point 
   number out of an 80-bit x87 FPU register and into a 64-bit memory location, 
   thus rounding from extended precision to double precision. */ 
double _Py_force_double(double x) 
{ 
    volatile double y; 
    y = x; 
    return y; 
} 
#endif 
 
#ifdef HAVE_GCC_ASM_FOR_X87 
 
/* inline assembly for getting and setting the 387 FPU control word on 
   gcc/x86 */ 
#ifdef _Py_MEMORY_SANITIZER 
__attribute__((no_sanitize_memory)) 
#endif 
unsigned short _Py_get_387controlword(void) { 
    unsigned short cw; 
    __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); 
    return cw; 
} 
 
void _Py_set_387controlword(unsigned short cw) { 
    __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); 
} 
 
#endif 
 
 
#ifndef HAVE_HYPOT 
double hypot(double x, double y) 
{ 
    double yx; 
 
    x = fabs(x); 
    y = fabs(y); 
    if (x < y) { 
        double temp = x; 
        x = y; 
        y = temp; 
    } 
    if (x == 0.) 
        return 0.; 
    else { 
        yx = y/x; 
        return x*sqrt(1.+yx*yx); 
    } 
} 
#endif /* HAVE_HYPOT */ 
 
#ifndef HAVE_COPYSIGN 
double 
copysign(double x, double y) 
{ 
    /* use atan2 to distinguish -0. from 0. */ 
    if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) { 
        return fabs(x); 
    } else { 
        return -fabs(x); 
    } 
} 
#endif /* HAVE_COPYSIGN */ 
 
#ifndef HAVE_ROUND 
double 
round(double x) 
{ 
    double absx, y; 
    absx = fabs(x); 
    y = floor(absx); 
    if (absx - y >= 0.5) 
        y += 1.0; 
    return copysign(y, x); 
} 
#endif /* HAVE_ROUND */ 

static const unsigned int BitLengthTable[32] = {
    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
};

unsigned int _Py_bit_length(unsigned long d) {
   unsigned int d_bits = 0;
   while (d >= 32) {
       d_bits += 6;
       d >>= 6;
   }
   d_bits += BitLengthTable[d];
   return d_bits;
}