(noinst_HEADERS): Added conv-integer.i.c and conv-uinteger.i.c.
[bpt/guile.git] / libguile / conv-integer.i.c
CommitLineData
bfd7932e
MV
1TYPE
2SCM_TO_TYPE_PROTO (SCM val)
3{
4 if (SCM_I_INUMP (val))
5 {
6 scm_t_signed_bits n = SCM_I_INUM (val);
7#if SIZEOF_TYPE != 0 && SIZEOF_TYPE > SIZEOF_SCM_T_BITS
8 return n;
9#else
10 if (n >= TYPE_MIN && n <= TYPE_MAX)
11 return n;
12 else
13 {
14 goto out_of_range;
15 }
16#endif
17 }
18 else if (SCM_BIGP (val))
19 {
20 if (TYPE_MIN >= SCM_MOST_NEGATIVE_FIXNUM
21 && TYPE_MAX <= SCM_MOST_POSITIVE_FIXNUM)
22 goto out_of_range;
23 else if (TYPE_MIN >= LONG_MIN && TYPE_MAX <= LONG_MAX)
24 {
25 if (mpz_fits_slong_p (SCM_I_BIG_MPZ (val)))
26 {
27 long n = mpz_get_si (SCM_I_BIG_MPZ (val));
28#if SIZEOF_TYPE != 0 && SIZEOF_TYPE > SCM_SIZEOF_LONG
29 return n;
30#else
31 if (n >= TYPE_MIN && n <= TYPE_MAX)
32 return n;
33 else
34 goto out_of_range;
35#endif
36 }
37 else
38 goto out_of_range;
39 }
40 else
41 {
42 scm_t_intmax n;
43 size_t count;
44
45 if (mpz_sizeinbase (SCM_I_BIG_MPZ (val), 2)
46 > CHAR_BIT*sizeof (scm_t_uintmax))
47 goto out_of_range;
48
49 mpz_export (&n, &count, 1, sizeof (scm_t_uintmax), 0, 0,
50 SCM_I_BIG_MPZ (val));
51
52 if (mpz_sgn (SCM_I_BIG_MPZ (val)) >= 0)
53 {
54 if (n < 0)
55 goto out_of_range;
56 }
57 else
58 {
59 n = -n;
60 if (n >= 0)
61 goto out_of_range;
62 }
63
64 if (n >= TYPE_MIN && n <= TYPE_MAX)
65 return n;
66 else
67 {
68 out_of_range:
69 scm_out_of_range (NULL, val);
70 return 0;
71 }
72 }
73 }
74 else
75 {
76 scm_wrong_type_arg_msg (NULL, 0, val, "exact integer");
77 return 0;
78 }
79}
80
81SCM
82SCM_FROM_TYPE_PROTO (TYPE val)
83{
84#if SIZEOF_TYPE != 0 && SIZEOF_TYPE < SIZEOF_SCM_T_BITS
85 return SCM_I_MAKINUM (val);
86#else
87 if (SCM_FIXABLE (val))
88 return SCM_I_MAKINUM (val);
89 else if (val >= LONG_MIN && val <= LONG_MAX)
90 {
91 SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0);
92 mpz_init_set_si (SCM_I_BIG_MPZ (z), val);
93 return z;
94 }
95 else
96 {
97 SCM z = scm_double_cell (scm_tc16_big, 0, 0, 0);
98 mpz_init (SCM_I_BIG_MPZ (z));
99 if (val < 0)
100 {
101 val = -val;
102 mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (TYPE), 0, 0,
103 &val);
104 mpz_neg (SCM_I_BIG_MPZ (z), SCM_I_BIG_MPZ (z));
105 }
106 else
107 mpz_import (SCM_I_BIG_MPZ (z), 1, 1, sizeof (TYPE), 0, 0,
108 &val);
109 return z;
110 }
111#endif
112}
113
114/* clean up */
115#undef TYPE
116#undef TYPE_MIN
117#undef TYPE_MAX
118#undef SIZEOF_TYPE
119#undef SCM_TO_TYPE_PROTO
120#undef SCM_FROM_TYPE_PROTO
121
122/*
123 Local Variables:
124 c-file-style: "gnu"
125 End:
126*/