omnomnum 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/omnomnum/extconf.rb +51 -0
- data/ext/omnomnum/omnomnum/branchlut/branchlut.c +276 -0
- data/ext/omnomnum/omnomnum/branchlut/branchlut.h +14 -0
- data/ext/omnomnum/omnomnum/dtoa.c +68 -0
- data/ext/omnomnum/omnomnum/dtoa.h +39 -0
- data/ext/omnomnum/omnomnum/grisu2/diy_fp.h +61 -0
- data/ext/omnomnum/omnomnum/grisu2/double.h +121 -0
- data/ext/omnomnum/omnomnum/grisu2/fast_exponent.h +44 -0
- data/ext/omnomnum/omnomnum/grisu2/grisu2.c +120 -0
- data/ext/omnomnum/omnomnum/grisu2/grisu2.h +36 -0
- data/ext/omnomnum/omnomnum/grisu2/k_comp.h +32 -0
- data/ext/omnomnum/omnomnum/grisu2/powers.h +27 -0
- data/ext/omnomnum/omnomnum/grisu2/powers_ten_round64.h +36 -0
- data/ext/omnomnum/omnomnum/grisu2/prettify.h +76 -0
- data/ext/omnomnum/omnomnum/itoa.c +40 -0
- data/ext/omnomnum/omnomnum/itoa.h +40 -0
- data/ext/omnomnum/omnomnum/main.c +87 -0
- data/ext/omnomnum/omnomnum/omnomnum.c +208 -0
- data/ext/omnomnum/omnomnum/omnomnum.h +47 -0
- data/ext/omnomnum/omnomnum/parser.c +3445 -0
- data/ext/omnomnum/omnomnum/parser.h +130 -0
- data/ext/omnomnum/omnomnum/scan.c +55 -0
- data/ext/omnomnum/omnomnum/scan.h +68 -0
- data/ext/omnomnum/omnomnum/scanner.c +4332 -0
- data/ext/omnomnum/omnomnum/scanner.def.c +97 -0
- data/ext/omnomnum/omnomnum/scanner.def.h +105 -0
- data/ext/omnomnum/omnomnum/scanner.h +44 -0
- data/ext/omnomnum/omnomnum/sds.c +1278 -0
- data/ext/omnomnum/omnomnum/sds.h +280 -0
- data/ext/omnomnum/omnomnum/sdsalloc.h +43 -0
- data/ext/omnomnum/omnomnum/test/test_benchmark.c +107 -0
- data/ext/omnomnum/omnomnum/test/test_omnomnum.c +146 -0
- data/ext/omnomnum/omnomnum/test/test_omnomnum.h +6 -0
- data/ext/omnomnum/omnomnum/test/test_util.c +98 -0
- data/ext/omnomnum/omnomnum/util.c +84 -0
- data/ext/omnomnum/omnomnum/util.h +43 -0
- data/ext/omnomnum/ruby_omnomnum.c +96 -0
- data/ext/omnomnum/ruby_omnomnum.h +40 -0
- data/lib/omnomnum.rb +31 -0
- data/lib/omnomnum/omnomnum.so +0 -0
- data/lib/omnomnum/version.rb +32 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4fc2c84ef1dfd0a2cffeb4cbe9c91f42cc5c50e3
|
4
|
+
data.tar.gz: bae6ce36db7b94747b560fcfe6c14472274b5b93
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 085e95e2636944eef23e285907e8d48d50d72684b68349220c20a34180b47e1ca029b13b3765ff1d989df8d266b7fd21b12e0103a78dc7620efe1c37349c45a8
|
7
|
+
data.tar.gz: 3b45529b2cf25f6121d611d693e6f26a4955d0d0f86737c0bf70e11ddbae747ea760d27bb1db352e7ba53c88e3bbc208e46819d8d699a18d0b0229dedec3d217
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# OmNomNum 0.0.2 -- Gobbles up numbers in strings.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2017, Jesse Buesking <jessebuesking at gmail dot com>
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# * Redistributions of source code must retain the above copyright notice,
|
10
|
+
# this list of conditions and the following disclaimer.
|
11
|
+
# * Redistributions in binary form must reproduce the above copyright
|
12
|
+
# notice, this list of conditions and the following disclaimer in the
|
13
|
+
# documentation and/or other materials provided with the distribution.
|
14
|
+
# * Neither the name of OmNomNum nor the names of its contributors may be used
|
15
|
+
# to endorse or promote products derived from this software without
|
16
|
+
# specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
require 'mkmf'
|
31
|
+
|
32
|
+
globs = [".", "omnomnum", "omnomnum/grisu2", "omnomnum/branchlut"].map do |directory|
|
33
|
+
File.join(File.dirname(__FILE__), directory)
|
34
|
+
end.join(",")
|
35
|
+
|
36
|
+
$objs = Dir.glob("{#{globs}}/*.c").map do |file|
|
37
|
+
File.join(File.dirname(file), "#{File.basename(file, ".c")}.o")
|
38
|
+
end
|
39
|
+
|
40
|
+
HEADER_DIRS = []
|
41
|
+
LIB_DIRS = []
|
42
|
+
dir_config('omnomnum', HEADER_DIRS, LIB_DIRS)
|
43
|
+
|
44
|
+
unless find_header('omnomnum/omnomnum.h')
|
45
|
+
abort 'omnomnum is missing'
|
46
|
+
end
|
47
|
+
|
48
|
+
$CFLAGS << ' -O3 '
|
49
|
+
#$CFLAGS = ' -g '
|
50
|
+
|
51
|
+
create_makefile('omnomnum/omnomnum')
|
@@ -0,0 +1,276 @@
|
|
1
|
+
#include "branchlut.h"
|
2
|
+
|
3
|
+
// Branching for different cases (forward)
|
4
|
+
// Use lookup table of two digits
|
5
|
+
|
6
|
+
const char gDigitsLut[200] = {
|
7
|
+
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
|
8
|
+
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
|
9
|
+
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
|
10
|
+
'3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
|
11
|
+
'4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
|
12
|
+
'5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
|
13
|
+
'6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
|
14
|
+
'7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
|
15
|
+
'8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
|
16
|
+
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
|
17
|
+
};
|
18
|
+
|
19
|
+
int u32toa_branchlut(uint32_t value, char* buffer) {
|
20
|
+
char* start = buffer;
|
21
|
+
if (value < 10000) {
|
22
|
+
const uint32_t d1 = (value / 100) << 1;
|
23
|
+
const uint32_t d2 = (value % 100) << 1;
|
24
|
+
|
25
|
+
if (value >= 1000)
|
26
|
+
*buffer++ = gDigitsLut[d1];
|
27
|
+
if (value >= 100)
|
28
|
+
*buffer++ = gDigitsLut[d1 + 1];
|
29
|
+
if (value >= 10)
|
30
|
+
*buffer++ = gDigitsLut[d2];
|
31
|
+
*buffer++ = gDigitsLut[d2 + 1];
|
32
|
+
}
|
33
|
+
else if (value < 100000000) {
|
34
|
+
// value = bbbbcccc
|
35
|
+
const uint32_t b = value / 10000;
|
36
|
+
const uint32_t c = value % 10000;
|
37
|
+
|
38
|
+
const uint32_t d1 = (b / 100) << 1;
|
39
|
+
const uint32_t d2 = (b % 100) << 1;
|
40
|
+
|
41
|
+
const uint32_t d3 = (c / 100) << 1;
|
42
|
+
const uint32_t d4 = (c % 100) << 1;
|
43
|
+
|
44
|
+
if (value >= 10000000)
|
45
|
+
*buffer++ = gDigitsLut[d1];
|
46
|
+
if (value >= 1000000)
|
47
|
+
*buffer++ = gDigitsLut[d1 + 1];
|
48
|
+
if (value >= 100000)
|
49
|
+
*buffer++ = gDigitsLut[d2];
|
50
|
+
*buffer++ = gDigitsLut[d2 + 1];
|
51
|
+
|
52
|
+
*buffer++ = gDigitsLut[d3];
|
53
|
+
*buffer++ = gDigitsLut[d3 + 1];
|
54
|
+
*buffer++ = gDigitsLut[d4];
|
55
|
+
*buffer++ = gDigitsLut[d4 + 1];
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
// value = aabbbbcccc in decimal
|
59
|
+
|
60
|
+
const uint32_t a = value / 100000000; // 1 to 42
|
61
|
+
value %= 100000000;
|
62
|
+
|
63
|
+
if (a >= 10) {
|
64
|
+
const unsigned i = a << 1;
|
65
|
+
*buffer++ = gDigitsLut[i];
|
66
|
+
*buffer++ = gDigitsLut[i + 1];
|
67
|
+
}
|
68
|
+
else
|
69
|
+
*buffer++ = '0' + (char) (a);
|
70
|
+
|
71
|
+
const uint32_t b = value / 10000; // 0 to 9999
|
72
|
+
const uint32_t c = value % 10000; // 0 to 9999
|
73
|
+
|
74
|
+
const uint32_t d1 = (b / 100) << 1;
|
75
|
+
const uint32_t d2 = (b % 100) << 1;
|
76
|
+
|
77
|
+
const uint32_t d3 = (c / 100) << 1;
|
78
|
+
const uint32_t d4 = (c % 100) << 1;
|
79
|
+
|
80
|
+
*buffer++ = gDigitsLut[d1];
|
81
|
+
*buffer++ = gDigitsLut[d1 + 1];
|
82
|
+
*buffer++ = gDigitsLut[d2];
|
83
|
+
*buffer++ = gDigitsLut[d2 + 1];
|
84
|
+
*buffer++ = gDigitsLut[d3];
|
85
|
+
*buffer++ = gDigitsLut[d3 + 1];
|
86
|
+
*buffer++ = gDigitsLut[d4];
|
87
|
+
*buffer++ = gDigitsLut[d4 + 1];
|
88
|
+
}
|
89
|
+
*buffer++ = '\0';
|
90
|
+
return (int)(buffer - start);
|
91
|
+
}
|
92
|
+
|
93
|
+
int i32toa_branchlut(int32_t value, char* buffer) {
|
94
|
+
uint32_t u = (uint32_t) (value);
|
95
|
+
if (value < 0) {
|
96
|
+
*buffer++ = '-';
|
97
|
+
u = ~u + 1;
|
98
|
+
|
99
|
+
// Adding 1 to account for the negative sign.
|
100
|
+
return u32toa_branchlut(u, buffer) + 1;
|
101
|
+
}
|
102
|
+
|
103
|
+
return u32toa_branchlut(u, buffer);
|
104
|
+
}
|
105
|
+
|
106
|
+
int u64toa_branchlut(uint64_t value, char* buffer) {
|
107
|
+
char* start = buffer;
|
108
|
+
if (value < 100000000) {
|
109
|
+
uint32_t v = (uint32_t) (value);
|
110
|
+
if (v < 10000) {
|
111
|
+
const uint32_t d1 = (v / 100) << 1;
|
112
|
+
const uint32_t d2 = (v % 100) << 1;
|
113
|
+
|
114
|
+
if (v >= 1000)
|
115
|
+
*buffer++ = gDigitsLut[d1];
|
116
|
+
if (v >= 100)
|
117
|
+
*buffer++ = gDigitsLut[d1 + 1];
|
118
|
+
if (v >= 10)
|
119
|
+
*buffer++ = gDigitsLut[d2];
|
120
|
+
*buffer++ = gDigitsLut[d2 + 1];
|
121
|
+
}
|
122
|
+
else {
|
123
|
+
// value = bbbbcccc
|
124
|
+
const uint32_t b = v / 10000;
|
125
|
+
const uint32_t c = v % 10000;
|
126
|
+
|
127
|
+
const uint32_t d1 = (b / 100) << 1;
|
128
|
+
const uint32_t d2 = (b % 100) << 1;
|
129
|
+
|
130
|
+
const uint32_t d3 = (c / 100) << 1;
|
131
|
+
const uint32_t d4 = (c % 100) << 1;
|
132
|
+
|
133
|
+
if (value >= 10000000)
|
134
|
+
*buffer++ = gDigitsLut[d1];
|
135
|
+
if (value >= 1000000)
|
136
|
+
*buffer++ = gDigitsLut[d1 + 1];
|
137
|
+
if (value >= 100000)
|
138
|
+
*buffer++ = gDigitsLut[d2];
|
139
|
+
*buffer++ = gDigitsLut[d2 + 1];
|
140
|
+
|
141
|
+
*buffer++ = gDigitsLut[d3];
|
142
|
+
*buffer++ = gDigitsLut[d3 + 1];
|
143
|
+
*buffer++ = gDigitsLut[d4];
|
144
|
+
*buffer++ = gDigitsLut[d4 + 1];
|
145
|
+
}
|
146
|
+
}
|
147
|
+
else if (value < 10000000000000000) {
|
148
|
+
const uint32_t v0 = (uint32_t) (value / 100000000);
|
149
|
+
const uint32_t v1 = (uint32_t) (value % 100000000);
|
150
|
+
|
151
|
+
const uint32_t b0 = v0 / 10000;
|
152
|
+
const uint32_t c0 = v0 % 10000;
|
153
|
+
|
154
|
+
const uint32_t d1 = (b0 / 100) << 1;
|
155
|
+
const uint32_t d2 = (b0 % 100) << 1;
|
156
|
+
|
157
|
+
const uint32_t d3 = (c0 / 100) << 1;
|
158
|
+
const uint32_t d4 = (c0 % 100) << 1;
|
159
|
+
|
160
|
+
const uint32_t b1 = v1 / 10000;
|
161
|
+
const uint32_t c1 = v1 % 10000;
|
162
|
+
|
163
|
+
const uint32_t d5 = (b1 / 100) << 1;
|
164
|
+
const uint32_t d6 = (b1 % 100) << 1;
|
165
|
+
|
166
|
+
const uint32_t d7 = (c1 / 100) << 1;
|
167
|
+
const uint32_t d8 = (c1 % 100) << 1;
|
168
|
+
|
169
|
+
if (value >= 1000000000000000)
|
170
|
+
*buffer++ = gDigitsLut[d1];
|
171
|
+
if (value >= 100000000000000)
|
172
|
+
*buffer++ = gDigitsLut[d1 + 1];
|
173
|
+
if (value >= 10000000000000)
|
174
|
+
*buffer++ = gDigitsLut[d2];
|
175
|
+
if (value >= 1000000000000)
|
176
|
+
*buffer++ = gDigitsLut[d2 + 1];
|
177
|
+
if (value >= 100000000000)
|
178
|
+
*buffer++ = gDigitsLut[d3];
|
179
|
+
if (value >= 10000000000)
|
180
|
+
*buffer++ = gDigitsLut[d3 + 1];
|
181
|
+
if (value >= 1000000000)
|
182
|
+
*buffer++ = gDigitsLut[d4];
|
183
|
+
if (value >= 100000000)
|
184
|
+
*buffer++ = gDigitsLut[d4 + 1];
|
185
|
+
|
186
|
+
*buffer++ = gDigitsLut[d5];
|
187
|
+
*buffer++ = gDigitsLut[d5 + 1];
|
188
|
+
*buffer++ = gDigitsLut[d6];
|
189
|
+
*buffer++ = gDigitsLut[d6 + 1];
|
190
|
+
*buffer++ = gDigitsLut[d7];
|
191
|
+
*buffer++ = gDigitsLut[d7 + 1];
|
192
|
+
*buffer++ = gDigitsLut[d8];
|
193
|
+
*buffer++ = gDigitsLut[d8 + 1];
|
194
|
+
}
|
195
|
+
else {
|
196
|
+
const uint32_t a = (uint32_t) (value / 10000000000000000); // 1 to 1844
|
197
|
+
value %= 10000000000000000;
|
198
|
+
|
199
|
+
if (a < 10)
|
200
|
+
*buffer++ = '0' + (char) (a);
|
201
|
+
else if (a < 100) {
|
202
|
+
const uint32_t i = a << 1;
|
203
|
+
*buffer++ = gDigitsLut[i];
|
204
|
+
*buffer++ = gDigitsLut[i + 1];
|
205
|
+
}
|
206
|
+
else if (a < 1000) {
|
207
|
+
*buffer++ = '0' + (char) (a / 100);
|
208
|
+
|
209
|
+
const uint32_t i = (a % 100) << 1;
|
210
|
+
*buffer++ = gDigitsLut[i];
|
211
|
+
*buffer++ = gDigitsLut[i + 1];
|
212
|
+
}
|
213
|
+
else {
|
214
|
+
const uint32_t i = (a / 100) << 1;
|
215
|
+
const uint32_t j = (a % 100) << 1;
|
216
|
+
*buffer++ = gDigitsLut[i];
|
217
|
+
*buffer++ = gDigitsLut[i + 1];
|
218
|
+
*buffer++ = gDigitsLut[j];
|
219
|
+
*buffer++ = gDigitsLut[j + 1];
|
220
|
+
}
|
221
|
+
|
222
|
+
const uint32_t v0 = (uint32_t) (value / 100000000);
|
223
|
+
const uint32_t v1 = (uint32_t) (value % 100000000);
|
224
|
+
|
225
|
+
const uint32_t b0 = v0 / 10000;
|
226
|
+
const uint32_t c0 = v0 % 10000;
|
227
|
+
|
228
|
+
const uint32_t d1 = (b0 / 100) << 1;
|
229
|
+
const uint32_t d2 = (b0 % 100) << 1;
|
230
|
+
|
231
|
+
const uint32_t d3 = (c0 / 100) << 1;
|
232
|
+
const uint32_t d4 = (c0 % 100) << 1;
|
233
|
+
|
234
|
+
const uint32_t b1 = v1 / 10000;
|
235
|
+
const uint32_t c1 = v1 % 10000;
|
236
|
+
|
237
|
+
const uint32_t d5 = (b1 / 100) << 1;
|
238
|
+
const uint32_t d6 = (b1 % 100) << 1;
|
239
|
+
|
240
|
+
const uint32_t d7 = (c1 / 100) << 1;
|
241
|
+
const uint32_t d8 = (c1 % 100) << 1;
|
242
|
+
|
243
|
+
*buffer++ = gDigitsLut[d1];
|
244
|
+
*buffer++ = gDigitsLut[d1 + 1];
|
245
|
+
*buffer++ = gDigitsLut[d2];
|
246
|
+
*buffer++ = gDigitsLut[d2 + 1];
|
247
|
+
*buffer++ = gDigitsLut[d3];
|
248
|
+
*buffer++ = gDigitsLut[d3 + 1];
|
249
|
+
*buffer++ = gDigitsLut[d4];
|
250
|
+
*buffer++ = gDigitsLut[d4 + 1];
|
251
|
+
*buffer++ = gDigitsLut[d5];
|
252
|
+
*buffer++ = gDigitsLut[d5 + 1];
|
253
|
+
*buffer++ = gDigitsLut[d6];
|
254
|
+
*buffer++ = gDigitsLut[d6 + 1];
|
255
|
+
*buffer++ = gDigitsLut[d7];
|
256
|
+
*buffer++ = gDigitsLut[d7 + 1];
|
257
|
+
*buffer++ = gDigitsLut[d8];
|
258
|
+
*buffer++ = gDigitsLut[d8 + 1];
|
259
|
+
}
|
260
|
+
|
261
|
+
*buffer = '\0';
|
262
|
+
return (int)(buffer - start);
|
263
|
+
}
|
264
|
+
|
265
|
+
int i64toa_branchlut(int64_t value, char* buffer) {
|
266
|
+
uint64_t u = (uint64_t) (value);
|
267
|
+
if (value < 0) {
|
268
|
+
*buffer++ = '-';
|
269
|
+
u = ~u + 1;
|
270
|
+
|
271
|
+
// Adding 1 to account for the negative sign.
|
272
|
+
return u64toa_branchlut(u, buffer) + 1;
|
273
|
+
}
|
274
|
+
|
275
|
+
return u64toa_branchlut(u, buffer);
|
276
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#ifndef BRANCHLUT_H
|
2
|
+
#define BRANCHLUT_H
|
3
|
+
|
4
|
+
#include <stdint.h>
|
5
|
+
|
6
|
+
// Branching for different cases (forward)
|
7
|
+
// Use lookup table of two digits
|
8
|
+
|
9
|
+
int u32toa_branchlut(uint32_t value, char* buffer);
|
10
|
+
int i32toa_branchlut(int32_t value, char* buffer);
|
11
|
+
int u64toa_branchlut(uint64_t value, char* buffer);
|
12
|
+
int i64toa_branchlut(int64_t value, char* buffer);
|
13
|
+
|
14
|
+
#endif // BRANCHLUT_H
|
@@ -0,0 +1,68 @@
|
|
1
|
+
/* OmNomNum 0.0.2 -- Gobbles up numbers in strings.
|
2
|
+
*
|
3
|
+
* Copyright (c) 2017, Jesse Buesking <jessebuesking at gmail dot com>
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are met:
|
8
|
+
*
|
9
|
+
* * Redistributions of source code must retain the above copyright notice,
|
10
|
+
* this list of conditions and the following disclaimer.
|
11
|
+
* * Redistributions in binary form must reproduce the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
14
|
+
* * Neither the name of OmNomNum nor the names of its contributors may be used
|
15
|
+
* to endorse or promote products derived from this software without
|
16
|
+
* specific prior written permission.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
*/
|
30
|
+
|
31
|
+
#include <stdio.h>
|
32
|
+
#include <string.h>
|
33
|
+
#include "sds.h"
|
34
|
+
#include "grisu2/grisu2.h"
|
35
|
+
|
36
|
+
/*
|
37
|
+
* From http://stackoverflow.com/a/277810/435460, but converted to use sds.
|
38
|
+
*/
|
39
|
+
|
40
|
+
char DTOA_BUFFER[256];
|
41
|
+
|
42
|
+
void morphNumericString(sds *s, int n) {
|
43
|
+
char *p = strchr(*s, '.'); // Find decimal point, if any.
|
44
|
+
if (p != NULL) {
|
45
|
+
int dotPosition = (p - *s);
|
46
|
+
int endRange = dotPosition + n;
|
47
|
+
int lastPosition = (int) sdslen(*s) - 1;
|
48
|
+
|
49
|
+
endRange = endRange < lastPosition ? endRange : lastPosition;
|
50
|
+
|
51
|
+
while ((*s)[endRange] == '0') { // Remove trailing zeros.
|
52
|
+
endRange -= 1;
|
53
|
+
}
|
54
|
+
|
55
|
+
if ((*s)[endRange] == '.') { // If all decimals were zeros, remove "."
|
56
|
+
endRange -= 1;
|
57
|
+
}
|
58
|
+
|
59
|
+
sdsrange(*s, 0, endRange); // Trim the string to the range.
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
void dtoa(sds *s, double d, int precision) {
|
64
|
+
memset(DTOA_BUFFER, 0, 256);
|
65
|
+
fill_double(d, DTOA_BUFFER);
|
66
|
+
*s = sdscat(*s, DTOA_BUFFER);
|
67
|
+
morphNumericString(s, precision);
|
68
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
/* OmNomNum 0.0.2 -- Gobbles up numbers in strings.
|
2
|
+
*
|
3
|
+
* Copyright (c) 2017, Jesse Buesking <jessebuesking at gmail dot com>
|
4
|
+
* All rights reserved.
|
5
|
+
*
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
7
|
+
* modification, are permitted provided that the following conditions are met:
|
8
|
+
*
|
9
|
+
* * Redistributions of source code must retain the above copyright notice,
|
10
|
+
* this list of conditions and the following disclaimer.
|
11
|
+
* * Redistributions in binary form must reproduce the above copyright
|
12
|
+
* notice, this list of conditions and the following disclaimer in the
|
13
|
+
* documentation and/or other materials provided with the distribution.
|
14
|
+
* * Neither the name of OmNomNum nor the names of its contributors may be used
|
15
|
+
* to endorse or promote products derived from this software without
|
16
|
+
* specific prior written permission.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
21
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
22
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
23
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
24
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
25
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
26
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
27
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
28
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
*/
|
30
|
+
|
31
|
+
#ifndef DTOA_H
|
32
|
+
#define DTOA_H
|
33
|
+
|
34
|
+
#include "grisu2/grisu2.h"
|
35
|
+
|
36
|
+
void dtoa(sds *s, double d, int precision);
|
37
|
+
void morphNumericString(sds *s, int n);
|
38
|
+
|
39
|
+
#endif // DTOA_H
|