# ctod --- convert string to double precision real longreal function ctod (str, i) character str (ARB) integer i define (MAXDIG,16) integer j, s, pe (28) integer gctoi longreal v, e, pv (28) character dig (MAXDIG) bool neg data pv / 1d 1, 1d 2, 1d 4, 1d 8, 1d 16, 1d 32, 1d 64, 1d 128, 1d 256, 1d 512, 1d 1024, 1d 2048, 1d 4096, 1d 8192, 1d -1, 1d -2, 1d -4, 1d -8, 1d -16, 1d -32, 1d -64, 1d -128, 1d -256, 1d -512, 1d-1024, 1d-2048, 1d-4096, 1d-8192 / data pe / 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, -1, -2, -4, -8, -16, -32, -64, -128, -256, -512, -1024, -2048, -4096, -8192 / SKIPBL (str, i) # ignore leading blanks neg = (str (i) == '-'c) # check for sign if (str (i) == '+'c || str (i) == '-'c) i += 1 while (str (i) == '0'c) # ignore high-order zeros i += 1 for (j = 1; j < MAXDIG && IS_DIGIT (str (i)); {j += 1; i += 1}) dig (j) = str (i) # collect significant integral digits for (s = 0; IS_DIGIT (str (i)); {s += 1; i += 1}) ; # ignore the rest, adjusting scale factor if (str (i) == '.'c) { # check for a fraction i += 1 if (j == 1) # special case to accurately handle 0.000ddd etc. while (str (i) == '0'c) { i += 1 s -= 1 } for (; j < MAXDIG && IS_DIGIT (str (i)); {j += 1; i += 1}) { dig (j) = str (i) s -= 1 # adjust scale factor } while (IS_DIGIT (str (i))) # discard insig. fractional digits i += 1 } while (j > 1 && dig (j - 1) == '0'c) { # truncate trailing zeros s += 1 # increment the scale factor (multiply by 10) j -= 1 # truncate one trailing zero (divide by 10) } dig (j) = EOS # terminate the digit string if (str (i) == 'e'c || str (i) == 'E'c) { # check for exponent i += 1 s += gctoi (str, i, 10) } v = 0.0 # now convert the mantissa bits for (j = 1; dig (j) ~= EOS; j += 1) v = v * 10.0 + (dig (j) - '0'c) e = 1.0 select when (s > 0) for (j = 14; j > 0; j -= 1) { if (s >= pe (j)) { s -= pe (j) e *= pv (j) } } when (s < 0) for (j = 28; j > 14; j -= 1) { if (s <= pe (j)) { s -= pe (j) e *= pv (j) } } ifany ctod = v * e else ctod = v if (neg) ctod = -ctod return undefine (MAXDIG) end