aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/bc.c266
1 files changed, 133 insertions, 133 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index ca9506929..5b48f84a1 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -2196,139 +2196,6 @@ static BcStatus bc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale,
2196 return s; 2196 return s;
2197} 2197}
2198 2198
2199static bool bc_num_strValid(const char *val, size_t base)
2200{
2201 BcDig b;
2202 bool radix;
2203
2204 b = (BcDig)(base <= 10 ? base + '0' : base - 10 + 'A');
2205 radix = false;
2206 for (;;) {
2207 BcDig c = *val++;
2208 if (c == '\0')
2209 break;
2210 if (c == '.') {
2211 if (radix) return false;
2212 radix = true;
2213 continue;
2214 }
2215 if (c < '0' || c >= b || (c > '9' && c < 'A'))
2216 return false;
2217 }
2218 return true;
2219}
2220
2221// Note: n is already "bc_num_zero()"ed,
2222// leading zeroes in "val" are removed
2223static void bc_num_parseDecimal(BcNum *n, const char *val)
2224{
2225 size_t len, i;
2226 const char *ptr;
2227 bool zero;
2228
2229 len = strlen(val);
2230 if (len == 0)
2231 return;
2232
2233 zero = true;
2234 for (i = 0; val[i]; ++i) {
2235 if (val[i] != '0' && val[i] != '.') {
2236 zero = false;
2237 break;
2238 }
2239 }
2240 bc_num_expand(n, len);
2241
2242 ptr = strchr(val, '.');
2243
2244 n->rdx = 0;
2245 if (ptr != NULL)
2246 n->rdx = (size_t)((val + len) - (ptr + 1));
2247
2248 if (!zero) {
2249 i = len - 1;
2250 for (;;) {
2251 n->num[n->len] = val[i] - '0';
2252 ++n->len;
2253 skip_dot:
2254 if ((ssize_t)--i == (ssize_t)-1) break;
2255 if (val[i] == '.') goto skip_dot;
2256 }
2257 }
2258}
2259
2260// Note: n is already "bc_num_zero()"ed,
2261// leading zeroes in "val" are removed
2262static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
2263{
2264 BcStatus s;
2265 BcNum temp, mult, result;
2266 BcDig c = '\0';
2267 unsigned long v;
2268 size_t i, digits;
2269
2270 for (i = 0; ; ++i) {
2271 if (val[i] == '\0')
2272 return;
2273 if (val[i] != '.' && val[i] != '0')
2274 break;
2275 }
2276
2277 bc_num_init_DEF_SIZE(&temp);
2278 bc_num_init_DEF_SIZE(&mult);
2279
2280 for (;;) {
2281 c = *val++;
2282 if (c == '\0') goto int_err;
2283 if (c == '.') break;
2284
2285 v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
2286
2287 s = bc_num_mul(n, base, &mult, 0);
2288 if (s) goto int_err;
2289 bc_num_ulong2num(&temp, v);
2290 s = bc_num_add(&mult, &temp, n, 0);
2291 if (s) goto int_err;
2292 }
2293
2294 bc_num_init(&result, base->len);
2295 //bc_num_zero(&result); - already is
2296 bc_num_one(&mult);
2297
2298 digits = 0;
2299 for (;;) {
2300 c = *val++;
2301 if (c == '\0') break;
2302 digits++;
2303
2304 v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
2305
2306 s = bc_num_mul(&result, base, &result, 0);
2307 if (s) goto err;
2308 bc_num_ulong2num(&temp, v);
2309 s = bc_num_add(&result, &temp, &result, 0);
2310 if (s) goto err;
2311 s = bc_num_mul(&mult, base, &mult, 0);
2312 if (s) goto err;
2313 }
2314
2315 s = bc_num_div(&result, &mult, &result, digits);
2316 if (s) goto err;
2317 s = bc_num_add(n, &result, n, digits);
2318 if (s) goto err;
2319
2320 if (n->len != 0) {
2321 if (n->rdx < digits) bc_num_extend(n, digits - n->rdx);
2322 } else
2323 bc_num_zero(n);
2324
2325err:
2326 bc_num_free(&result);
2327int_err:
2328 bc_num_free(&mult);
2329 bc_num_free(&temp);
2330}
2331
2332static void bc_num_printNewline(void) 2199static void bc_num_printNewline(void)
2333{ 2200{
2334 if (G.prog.nchars == G.prog.len - 1) { 2201 if (G.prog.nchars == G.prog.len - 1) {
@@ -2492,6 +2359,139 @@ static BcStatus bc_num_stream(BcNum *n, BcNum *base)
2492} 2359}
2493#endif 2360#endif
2494 2361
2362static bool bc_num_strValid(const char *val, size_t base)
2363{
2364 BcDig b;
2365 bool radix;
2366
2367 b = (BcDig)(base <= 10 ? base + '0' : base - 10 + 'A');
2368 radix = false;
2369 for (;;) {
2370 BcDig c = *val++;
2371 if (c == '\0')
2372 break;
2373 if (c == '.') {
2374 if (radix) return false;
2375 radix = true;
2376 continue;
2377 }
2378 if (c < '0' || c >= b || (c > '9' && c < 'A'))
2379 return false;
2380 }
2381 return true;
2382}
2383
2384// Note: n is already "bc_num_zero()"ed,
2385// leading zeroes in "val" are removed
2386static void bc_num_parseDecimal(BcNum *n, const char *val)
2387{
2388 size_t len, i;
2389 const char *ptr;
2390 bool zero;
2391
2392 len = strlen(val);
2393 if (len == 0)
2394 return;
2395
2396 zero = true;
2397 for (i = 0; val[i]; ++i) {
2398 if (val[i] != '0' && val[i] != '.') {
2399 zero = false;
2400 break;
2401 }
2402 }
2403 bc_num_expand(n, len);
2404
2405 ptr = strchr(val, '.');
2406
2407 n->rdx = 0;
2408 if (ptr != NULL)
2409 n->rdx = (size_t)((val + len) - (ptr + 1));
2410
2411 if (!zero) {
2412 i = len - 1;
2413 for (;;) {
2414 n->num[n->len] = val[i] - '0';
2415 ++n->len;
2416 skip_dot:
2417 if ((ssize_t)--i == (ssize_t)-1) break;
2418 if (val[i] == '.') goto skip_dot;
2419 }
2420 }
2421}
2422
2423// Note: n is already "bc_num_zero()"ed,
2424// leading zeroes in "val" are removed
2425static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
2426{
2427 BcStatus s;
2428 BcNum temp, mult, result;
2429 BcDig c = '\0';
2430 unsigned long v;
2431 size_t i, digits;
2432
2433 for (i = 0; ; ++i) {
2434 if (val[i] == '\0')
2435 return;
2436 if (val[i] != '.' && val[i] != '0')
2437 break;
2438 }
2439
2440 bc_num_init_DEF_SIZE(&temp);
2441 bc_num_init_DEF_SIZE(&mult);
2442
2443 for (;;) {
2444 c = *val++;
2445 if (c == '\0') goto int_err;
2446 if (c == '.') break;
2447
2448 v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
2449
2450 s = bc_num_mul(n, base, &mult, 0);
2451 if (s) goto int_err;
2452 bc_num_ulong2num(&temp, v);
2453 s = bc_num_add(&mult, &temp, n, 0);
2454 if (s) goto int_err;
2455 }
2456
2457 bc_num_init(&result, base->len);
2458 //bc_num_zero(&result); - already is
2459 bc_num_one(&mult);
2460
2461 digits = 0;
2462 for (;;) {
2463 c = *val++;
2464 if (c == '\0') break;
2465 digits++;
2466
2467 v = (unsigned long) (c <= '9' ? c - '0' : c - 'A' + 10);
2468
2469 s = bc_num_mul(&result, base, &result, 0);
2470 if (s) goto err;
2471 bc_num_ulong2num(&temp, v);
2472 s = bc_num_add(&result, &temp, &result, 0);
2473 if (s) goto err;
2474 s = bc_num_mul(&mult, base, &mult, 0);
2475 if (s) goto err;
2476 }
2477
2478 s = bc_num_div(&result, &mult, &result, digits);
2479 if (s) goto err;
2480 s = bc_num_add(n, &result, n, digits);
2481 if (s) goto err;
2482
2483 if (n->len != 0) {
2484 if (n->rdx < digits) bc_num_extend(n, digits - n->rdx);
2485 } else
2486 bc_num_zero(n);
2487
2488err:
2489 bc_num_free(&result);
2490int_err:
2491 bc_num_free(&mult);
2492 bc_num_free(&temp);
2493}
2494
2495static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base, 2495static BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base,
2496 size_t base_t) 2496 size_t base_t)
2497{ 2497{