1
1
2
- from std/ parseutils import skipWhile, parseInt
2
+ import std/ parseutils # skipWhile, parseInt, parseBiggestInt
3
3
from std/ strutils import find, initSkipTable, isSpaceAscii, toLowerAscii,
4
4
HexDigits
5
5
import std/ fenv
@@ -99,9 +99,6 @@ func hexImpl*(x: float): string =
99
99
template IS_SPACE(c): bool = isSpaceAscii(c)
100
100
101
101
func floatFromhexImpl* (s: string ): float =
102
- const
103
- LONG_MAXd2 = high(int ) div 2
104
- LONG_MINd2 = low(int ) div 2
105
102
#[ For the sake of simplicity and correctness, we impose an artificial
106
103
limit on ndigits, the total number of hex digits in the coefficient
107
104
The limit is chosen to ensure that, writing exp for the exponent,
@@ -148,9 +145,18 @@ func floatFromhexImpl*(s: string): float =
148
145
let
149
146
s_hi = s.high
150
147
s_end = s.len
151
- var
152
- exp: int
153
- negate = false
148
+ when sizeof(int ) >= 8 :
149
+ var exp: int
150
+ const intExp = true
151
+ else :
152
+ var exp: BiggestInt
153
+ const intExp = false
154
+ type TExp = typeof(exp)
155
+ const
156
+ LONG_MAXd2 = high(TExp) div 2
157
+ LONG_MINd2 = low(TExp) div 2
158
+ var negate = false
159
+
154
160
155
161
template raiseValueError(msg) =
156
162
raise newException(ValueError, msg)
@@ -227,14 +233,16 @@ func floatFromhexImpl*(s: string): float =
227
233
parse_error
228
234
step
229
235
while inBound and cur in '0' .. '9' :
230
- step
231
- let n = parseInt(s, exp, exp_start)
236
+ step
237
+ let n =
238
+ when intExp: parseInt(s, exp, exp_start)
239
+ else : parseBiggestInt(s, exp, exp_start)
232
240
assert n != 0
233
241
else :
234
242
exp = 0
235
243
236
244
# for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit
237
- template HEX_DIGIT(j): int =
245
+ template HEX_DIGIT(j: int ): int =
238
246
hex_from_char(s[
239
247
if j < fdigits: coeff_end- j
240
248
else : coeff_end- 1 - j
@@ -261,10 +269,10 @@ func floatFromhexImpl*(s: string): float =
261
269
overflow_error
262
270
263
271
# Adjust exponent for fractional part.
264
- exp -= 4 * fdigits
272
+ exp -= TExp 4 * fdigits
265
273
266
274
# top_exp = 1 more than exponent of most sig. bit of coefficient
267
- var top_exp = exp + 4 * (ndigits - 1 )
275
+ var top_exp = exp + 4 * (ndigits.TExp - 1 )
268
276
var digits = HEX_DIGIT(ndigits- 1 )
269
277
while digits != 0 :
270
278
top_exp.inc
@@ -279,7 +287,7 @@ func floatFromhexImpl*(s: string): float =
279
287
280
288
# lsb = exponent of least significant bit of the *rounded* value
281
289
# This is top_exp - DBL_MANT_DIG unless result is subnormal.
282
- let lsb = max(top_exp, int ( DBL_MIN_EXP)) - DBL_MANT_DIG
290
+ let lsb = max(top_exp, DBL_MIN_EXP.TExp) - TExp DBL_MANT_DIG
283
291
284
292
result = 0.0
285
293
template handleInTill(till) =
@@ -288,16 +296,16 @@ func floatFromhexImpl*(s: string): float =
288
296
if exp >= lsb:
289
297
# no rounding required
290
298
handleInTill 0
291
- result = ldexp(result , exp)
299
+ result = ldexp(result , exp. int )
292
300
finished
293
301
# rounding required. key_digit is the index of the hex digit
294
302
# containing the first bit to be rounded away.
295
303
let
296
- half_eps = 1 shl ((lsb - exp - 1 ) mod 4 )
297
- key_digit = (lsb - exp - 1 ) div 4
304
+ half_eps = 1 shl (cast [ int ] (lsb - exp - 1 ) mod 4 )
305
+ key_digit = int (lsb - exp - 1 ) div 4
298
306
handleInTill key_digit+ 1
299
307
let digit = HEX_DIGIT(key_digit)
300
- result = 16.0 * result + float (digit and (16 - 2 * half_eps))
308
+ result = 16.0 * result + float (digit.TExp and (16 - 2 * half_eps))
301
309
302
310
# round-half-even: round up if bit lsb-1 is 1 and at least one of
303
311
# bits lsb, lsb-2, lsb-3, lsb-4, ... is 1.
@@ -320,5 +328,5 @@ func floatFromhexImpl*(s: string): float =
320
328
# overflow corner case:
321
329
# pre-rounded value < 2**DBL_MAX_EXP; rounded=2**DBL_MAX_EXP.
322
330
overflow_error
323
- result = ldexp(result , exp+ 4 * key_digit)
331
+ result = ldexp(result , int exp+ 4 * key_digit)
324
332
finished
0 commit comments