@@ -5,105 +5,76 @@ namespace Veldrid.Utilities
5
5
{
6
6
internal static class FastParse
7
7
{
8
- private static readonly long [ ] _powLookup = new [ ]
9
- {
10
- 1 , // 10^0
11
- 10 , // 10^1
12
- 100 , // 10^2
13
- 1000 , // 10^3
14
- 10000 , // 10^4
15
- 100000 , // 10^5
16
- 1000000 , // 10^6
17
- 10000000 , // 10^7
18
- 100000000 , // 10^8
19
- 1000000000 , // 10^9,
20
- 10000000000 , // 10^10,
21
- 100000000000 , // 10^11,
22
- 1000000000000 , // 10^12,
23
- 10000000000000 , // 10^13,
24
- 100000000000000 , // 10^14,
25
- 1000000000000000 , // 10^15,
26
- 10000000000000000 , // 10^16,
27
- 100000000000000000 , // 10^17,
28
- } ;
29
-
30
8
private static readonly double [ ] _doubleExpLookup = GetDoubleExponents ( ) ;
31
9
32
- public static bool TryParseDouble ( ReadOnlySpan < char > s , out double result , char decimalSeparator = '.' )
33
- {
34
- return TryParseDouble ( s , out result , out _ , decimalSeparator ) ;
35
- }
36
-
37
10
[ MethodImpl ( MethodImplOptions . AggressiveOptimization ) ]
38
11
public static bool TryParseInt ( ReadOnlySpan < char > s , out int result )
39
12
{
40
13
int r = 0 ;
41
14
int sign ;
42
- int start ;
15
+ int i = 0 ;
43
16
44
- char c = s [ 0 ] ;
17
+ char c = s [ i ] ;
45
18
if ( c == '-' )
46
19
{
47
20
sign = - 1 ;
48
- start = 1 ;
21
+ i = 1 ;
49
22
}
50
23
else if ( c > '9' || c < '0' )
51
24
{
52
- result = 0 ;
53
- return false ;
25
+ goto Fail ;
54
26
}
55
27
else
56
28
{
57
- start = 1 ;
29
+ i = 1 ;
58
30
r = 10 * r + ( c - '0' ) ;
59
31
sign = 1 ;
60
32
}
61
33
62
- int i = start ;
63
34
for ( ; i < s . Length ; i ++ )
64
35
{
65
36
c = s [ i ] ;
66
37
if ( c > '9' || c < '0' )
67
38
{
68
- result = 0 ;
69
- return false ;
39
+ goto Fail ;
70
40
}
71
41
72
42
r = 10 * r + ( c - '0' ) ;
73
43
}
74
44
75
45
result = r * sign ;
76
46
return true ;
47
+
48
+ Fail :
49
+ result = i ;
50
+ return false ;
77
51
}
78
52
79
- [ MethodImpl ( MethodImplOptions . AggressiveOptimization ) ]
80
53
public static bool TryParseDouble ( ReadOnlySpan < char > s , out double result , out bool hasFraction , char decimalSeparator = '.' )
81
54
{
82
55
hasFraction = false ;
83
56
84
57
double r = 0 ;
85
58
int sign ;
86
- int start ;
59
+ int i = 0 ;
87
60
88
- char c = s [ 0 ] ;
61
+ char c = s [ i ] ;
89
62
if ( c == '-' )
90
63
{
91
64
sign = - 1 ;
92
- start = 1 ;
65
+ i = 1 ;
93
66
}
94
67
else if ( c > '9' || c < '0' )
95
68
{
96
- result = 0 ;
97
- return false ;
69
+ goto Fail ;
98
70
}
99
71
else
100
72
{
101
- start = 1 ;
73
+ i = 1 ;
102
74
r = 10 * r + ( c - '0' ) ;
103
75
sign = 1 ;
104
76
}
105
77
106
- int i = start ;
107
78
for ( ; i < s . Length ; i ++ )
108
79
{
109
80
c = s [ i ] ;
@@ -120,8 +91,7 @@ public static bool TryParseDouble(ReadOnlySpan<char> s, out double result, out b
120
91
}
121
92
else
122
93
{
123
- result = 0 ;
124
- return false ;
94
+ goto Fail ;
125
95
}
126
96
}
127
97
@@ -132,7 +102,7 @@ public static bool TryParseDouble(ReadOnlySpan<char> s, out double result, out b
132
102
goto Finish ;
133
103
134
104
DecimalPoint :
135
- long tmp = 0 ;
105
+ double tmp = 0 ;
136
106
int length = i ;
137
107
double exponent = 0 ;
138
108
hasFraction = true ;
@@ -144,42 +114,42 @@ public static bool TryParseDouble(ReadOnlySpan<char> s, out double result, out b
144
114
{
145
115
if ( c == 'e' || c == 'E' )
146
116
{
147
- length = i - length ;
148
- goto ProcessExponent ;
117
+ exponent = ProcessExponent ( s , i ) ;
118
+ break ;
149
119
}
150
120
151
- result = 0 ;
152
- return false ;
121
+ goto Fail ;
153
122
}
154
123
tmp = 10 * tmp + ( c - '0' ) ;
155
124
}
156
125
length = i - length ;
157
126
158
- ProcessFraction :
159
- double fraction = tmp ;
160
-
161
- if ( length < _powLookup . Length )
162
- fraction /= _powLookup [ length ] ;
163
- else
164
- fraction /= _powLookup [ ^ 1 ] ;
165
-
127
+ double fraction = tmp * GetInversedBaseTen ( length ) ;
166
128
r += fraction ;
167
129
r *= sign ;
168
130
169
131
if ( exponent > 0 )
170
- r * = exponent ;
132
+ r / = exponent ;
171
133
else if ( exponent < 0 )
172
- r / = - exponent ;
134
+ r * = - exponent ;
173
135
174
- goto Finish ;
136
+ Finish :
137
+ result = r ;
138
+ return true ;
139
+
140
+ Fail :
141
+ result = i ;
142
+ return false ;
143
+ }
175
144
176
- ProcessExponent :
145
+ private static double ProcessExponent ( ReadOnlySpan < char > s , int i )
146
+ {
177
147
int expSign = 1 ;
178
148
int exp = 0 ;
179
149
180
150
for ( i ++ ; i < s . Length ; i ++ )
181
151
{
182
- c = s [ i ] ;
152
+ char c = s [ i ] ;
183
153
if ( c > '9' || c < '0' )
184
154
{
185
155
if ( c == '-' )
@@ -192,12 +162,17 @@ public static bool TryParseDouble(ReadOnlySpan<char> s, out double result, out b
192
162
exp = 10 * exp + ( c - '0' ) ;
193
163
}
194
164
195
- exponent = _doubleExpLookup [ exp ] * expSign ;
196
- goto ProcessFraction ;
165
+ double exponent = GetInversedBaseTen ( exp ) * expSign ;
166
+ return exponent ;
167
+ }
197
168
198
- Finish :
199
- result = r ;
200
- return true ;
169
+ private static double GetInversedBaseTen ( int index )
170
+ {
171
+ double [ ] array = _doubleExpLookup ;
172
+ if ( ( uint ) index < ( uint ) array . Length )
173
+ return array [ index ] ;
174
+ else
175
+ return Math . Pow ( 10 , - index ) ;
201
176
}
202
177
203
178
private static double [ ] GetDoubleExponents ( )
@@ -206,7 +181,7 @@ private static double[] GetDoubleExponents()
206
181
207
182
for ( int i = 0 ; i < exps . Length ; i ++ )
208
183
{
209
- exps [ i ] = Math . Pow ( 10 , i ) ;
184
+ exps [ i ] = Math . Pow ( 10 , - i ) ;
210
185
}
211
186
212
187
return exps ;
0 commit comments