forked from antonmks/Alenka
-
Notifications
You must be signed in to change notification settings - Fork 0
/
atof.cu
91 lines (69 loc) · 2.11 KB
/
atof.cu
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
//
// Simple and fast atof (ascii to float) function.
//
// - Executes about 5x faster than standard MSCRT library atof().
// - An attractive alternative if the number of calls is in the millions.
// - Assumes input is a proper integer, fraction, or scientific format.
// - Matches library atof() to 15 digits (except at extreme exponents).
// - Follows atof() precedent of essentially no error checking.
//
// 09-May-2009 Tom Van Baak (tvb) www.LeapSecond.com
//
#define white_space(c) ((c) == ' ' || (c) == '\t')
#define valid_digit(c) ((c) >= '0' && (c) <= '9')
double atoff (const char *p)
{
int frac;
double sign, value, scale;
// Skip leading white space, if any.
while (white_space(*p) ) {
p += 1;
}
// Get sign, if any.
sign = 1.0;
if (*p == '-') {
sign = -1.0;
p += 1;
} else if (*p == '+') {
p += 1;
}
// Get digits before decimal point or exponent, if any.
for (value = 0.0; valid_digit(*p); p += 1) {
value = value * 10.0 + (*p - '0');
}
// Get digits after decimal point, if any.
if (*p == '.') {
double pow10 = 10.0;
p += 1;
while (valid_digit(*p)) {
value += (*p - '0') / pow10;
pow10 *= 10.0;
p += 1;
}
}
// Handle exponent, if any.
frac = 0;
scale = 1.0;
if ((*p == 'e') || (*p == 'E')) {
unsigned int expon;
// Get sign of exponent, if any.
p += 1;
if (*p == '-') {
frac = 1;
p += 1;
} else if (*p == '+') {
p += 1;
}
// Get digits of exponent, if any.
for (expon = 0; valid_digit(*p); p += 1) {
expon = expon * 10 + (*p - '0');
}
if (expon > 308) expon = 308;
// Calculate scaling factor.
while (expon >= 50) { scale *= 1E50; expon -= 50; }
while (expon >= 8) { scale *= 1E8; expon -= 8; }
while (expon > 0) { scale *= 10.0; expon -= 1; }
}
// Return signed and scaled floating point result.
return sign * (frac ? (value / scale) : (value * scale));
}