rts-mach.c
1 //! @file rts-mach.c
2 //! @author J. Marcel van der Veer
3
4 //! @section Copyright
5 //!
6 //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
7 //! Copyright 2001-2024 J. Marcel van der Veer [algol68g@xs4all.nl].
8
9 //! @section License
10 //!
11 //! This program is free software; you can redistribute it and/or modify it
12 //! under the terms of the GNU General Public License as published by the
13 //! Free Software Foundation; either version 3 of the License, or
14 //! (at your option) any later version.
15 //!
16 //! This program is distributed in the hope that it will be useful, but
17 //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 //! more details. You should have received a copy of the GNU General Public
20 //! License along with this program. If not, see [http://www.gnu.org/licenses/].
21
22 //! @section Synopsis
23 //!
24 //! Machine parameters.
25
26 // These routines are variants/extensions of SLATEC routines.
27 // SLATEC Common Mathematical Library is a FORTRAN 77 library of general purpose
28 // mathematical and statistical routines, developed at US Government research
29 // laboratories and therefore public domain software.
30 // Repository: http://www.netlib.org/slatec/
31
32 #include "a68g.h"
33 #include "a68g-prelude.h"
34 #include "a68g-genie.h"
35 #include "a68g-numbers.h"
36 #include "a68g-double.h"
37
38 int a68g_i32mach (int i)
39 {
40 // Based SLATEC routine I1MACH.
41 switch (i) {
42 // i32mach(1) = the standard input unit.
43 case 1: {
44 return STDIN_FILENO;
45 }
46 // i32mach(2) = the standard output unit.
47 case 2: {
48 return STDOUT_FILENO;
49 }
50 // i32mach(3) = the standard punch unit.
51 case 3: {
52 return STDOUT_FILENO;
53 }
54 // i32mach(4) = the standard error message unit.
55 case 4: {
56 return STDERR_FILENO;
57 }
58 // i32mach(5) = the number of bits per int storage unit.
59 case 5: {
60 return CHAR_BIT * sizeof (int);
61 }
62 // i32mach(6) = the number of characters per int storage unit.
63 case 6: {
64 return sizeof (int);
65 }
66 // i32mach(7) = a, the base.
67 case 7: {
68 return 2;
69 }
70 // i32mach(8) = s, the number of base-a digits.
71 case 8: {
72 return CHAR_BIT * sizeof (int) - 1;
73 }
74 // i32mach(9) = a**s - 1, the largest magnitude.
75 case 9: {
76 return INT_MAX;
77 }
78 // i32mach(10) = b, the base.
79 case 10: {
80 return FLT_RADIX;
81 }
82 // i32mach(11) = t, the number of base-b digits.
83 case 11: {
84 return FLT_MANT_DIG;
85 }
86 // i32mach(12) = emin, the smallest exponent e.
87 case 12: {
88 return FLT_MIN_EXP;
89 }
90 // i32mach(13) = emax, the largest exponent e.
91 case 13: {
92 return FLT_MAX_EXP;
93 }
94 // i32mach(14) = t, the number of base-b digits.
95 case 14: {
96 return DBL_MANT_DIG;
97 }
98 // i32mach(15) = emin, the smallest exponent e.
99 case 15: {
100 return DBL_MIN_EXP;
101 }
102 // i32mach(16) = emax, the largest exponent e.
103 case 16: {
104 return DBL_MAX_EXP;
105 }
106 default: {
107 return 0;
108 }
109 }
110 }
111
112 //! @brief PROC i32mach (INT) INT
113
114 void genie_i32mach (NODE_T *p)
115 {
116 A68_INT i;
117 POP_OBJECT (p, &i, A68_INT);
118 PUSH_VALUE (p, a68g_i32mach (VALUE (&i)), A68_INT);
119 }
120
121 REAL_T a68g_r64mach (int i)
122 {
123 // Based SLATEC routine R1MACH.
124 switch (i) {
125 // r64mach(1) = b**(emin-1), the smallest positive magnitude.
126 case 1: {
127 return DBL_MIN;
128 }
129 // r64mach(2) = b**emax*(1 - b**(-t)), the largest magnitude.
130 case 2: {
131 return DBL_MAX;
132 }
133 // r64mach(3) = b**(-t), the smallest relative spacing.
134 case 3: {
135 return 0.5 * DBL_EPSILON;
136 }
137 // r64mach(4) = b**(1-t), the largest relative spacing.
138 case 4: {
139 return DBL_EPSILON;
140 }
141 // r64mach(5) = log10(b)
142 case 5: {
143 return CONST_M_LOG10_2;
144 }
145 // r64mach(6), the minimum exponent in base 10.
146 case 6: {
147 return DBL_MIN_10_EXP;
148 }
149 // r64mach(7), the maximum exponent in base 10.
150 case 7: {
151 return DBL_MAX_10_EXP;
152 }
153 // r64mach(8), the number of significant digits in base 10.
154 case 8: {
155 return DBL_DIG;
156 }
157 // r64mach(9), the number of mantissa bits.
158 case 9: {
159 return DBL_MANT_DIG;
160 }
161 default: {
162 return 0.0;
163 }
164 }
165 }
166
167 //! @brief PROC r64mach (INT) REAL
168
169 void genie_r64mach (NODE_T *p)
170 {
171 A68_INT i;
172 POP_OBJECT (p, &i, A68_INT);
173 PUSH_VALUE (p, a68g_r64mach (VALUE (&i)), A68_REAL);
174 }
175
176 #if (A68_LEVEL >= 3)
177
178 INT_T a68g_i64mach (int i)
179 {
180 // Based SLATEC routine I1MACH.
181 switch (i) {
182 // i64mach(6) = the number of characters per int storage unit.
183 case 6: {
184 return sizeof (INT_T);
185 }
186 // i64mach(9) = a**s - 1, the largest magnitude.
187 case 9: {
188 return LLONG_MAX;
189 }
190 default: {
191 return a68g_i32mach (i);
192 }
193 }
194 }
195
196 //! @brief PROC i64mach (INT) INT
197
198 void genie_i64mach (NODE_T *p)
199 {
200 A68_INT i;
201 POP_OBJECT (p, &i, A68_INT);
202 PUSH_VALUE (p, a68g_i64mach (VALUE (&i)), A68_INT);
203 }
204
205 DOUBLE_T a68g_r128mach (int i)
206 {
207 // Based SLATEC routine D1MACH.
208 switch (i) {
209 // r128mach(1) = b**(emin-1), the smallest positive magnitude.
210 case 1: {
211 return FLT128_MIN;
212 }
213 // r128mach(2) = b**emax*(1 - b**(-t)), the largest magnitude.
214 case 2: {
215 return FLT128_MAX;
216 }
217 // r128mach(3) = b**(-t), the smallest relative spacing.
218 case 3: {
219 return 0.5 * FLT128_EPSILON;
220 }
221 // r128mach(4) = b**(1-t), the largest relative spacing.
222 case 4: {
223 return FLT128_EPSILON;
224 }
225 // r128mach(5) = log10(b)
226 case 5: {
227 return CONST_M_LOG10_2_Q;
228 }
229 // r128mach(6), the minimum exponent in base 10.
230 case 6: {
231 return FLT128_MIN_10_EXP;
232 }
233 // r128mach(7), the maximum exponent in base 10.
234 case 7: {
235 return FLT128_MAX_10_EXP;
236 }
237 // r128mach(8), the number of significant digits in base 10.
238 case 8: {
239 return FLT128_DIG;
240 }
241 // r128mach(9), the number of mantissa bits.
242 case 9: {
243 return FLT128_MANT_DIG;
244 }
245 default: {
246 return 0.0;
247 }
248 }
249 }
250
251 //! @brief PROC r128mach (INT) REAL
252
253 void genie_r128mach (NODE_T *p)
254 {
255 A68_INT i;
256 POP_OBJECT (p, &i, A68_INT);
257 PUSH_VALUE (p, dble (a68g_r128mach (VALUE (&i))), A68_LONG_REAL);
258 }
259
260 #endif
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|