diff options
| author | Joseph Elliott Hand <jhand@hawaii.edu> | 2026-05-01 17:25:39 -1000 |
|---|---|---|
| committer | Joseph Elliott Hand <jhand@hawaii.edu> | 2026-05-01 17:25:39 -1000 |
| commit | 56529d472f61dba8d01af27a792b5d14df1b2c2e (patch) | |
| tree | 550a46a6aa3811030ae74ac67b2980d11cec9dc1 | |
| parent | 5de6eb0fe2c09dcc7decebf027085a2efbc92dfd (diff) | |
| download | unit.h-56529d472f61dba8d01af27a792b5d14df1b2c2e.tar.gz | |
Improve single unit identification
- Refactor into separate function
- Use array to store SI prefixes
- Add remaining SI prefixes
Signed-off-by: Joseph Elliott Hand <jhand@hawaii.edu>
| -rw-r--r-- | unit.h | 101 |
1 files changed, 49 insertions, 52 deletions
@@ -29,6 +29,7 @@ double get_unit_value(char const * string); #include <math.h> #include <regex.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -37,6 +38,32 @@ typedef struct { double value; } Unit; +double unit_prefixes[255] = { + ['Q'] = 1e30, + ['R'] = 1e27, + ['Y'] = 1e24, + ['Z'] = 1e21, + ['E'] = 1e18, + ['P'] = 1e15, + ['T'] = 1e12, + ['G'] = 1e9, + ['M'] = 1e6, + ['k'] = 1e3, + ['h'] = 1e2, + ['d'] = 1e-1, + ['c'] = 1e-2, + ['m'] = 1e-3, + ['u'] = 1e-6, + ['n'] = 1e-9, + ['p'] = 1e-12, + ['f'] = 1e-15, + ['a'] = 1e-18, + ['z'] = 1e-21, + ['y'] = 1e-24, + ['r'] = 1e-27, + ['q'] = 1e-30 +}; + Unit units[] = { {"rad", 1}, @@ -142,6 +169,25 @@ get_token(char const * str, Token * token) { } double +resolve_unit_name(char const * name) { + + double prefix_amount = unit_prefixes[name[0]]; + if(prefix_amount > 0) { + for (int j = 0; j < sizeof(units) / sizeof(units[0]); j++) { + if (strcmp(&name[1], units[j].abbr)) continue; + return prefix_amount * units[j].value; + } + } + + for (int j = 0; j < sizeof(units) / sizeof(units[0]); j++) { + if (strcmp(name, units[j].abbr)) continue; + return units[j].value; + } + + return 0.0; +} + +double get_unit_value(char const * string) { int offset = 0; @@ -190,56 +236,8 @@ get_unit_value(char const * string) { if (tokens[i].type != NAME) goto error; - double unit_value = 0.0f; - - for (int j = 0; j < sizeof(units) / sizeof(units[0]); j++) { - if (!strcmp(&tokens[i].value.str[1], units[j].abbr)) { - unit_value = units[j].value; - switch (tokens[i].value.str[0]) { - case 'k': - unit_value *= 1e3; - break; - case 'M': - unit_value *= 1e6; - break; - case 'G': - unit_value *= 1e9; - break; - case 'T': - unit_value *= 1e12; - break; - case 'c': - unit_value *= 1e-2; - break; - case 'm': - unit_value *= 1e-3; - break; - case 'u': - unit_value *= 1e-6; - break; - case 'n': - unit_value *= 1e-9; - break; - case 'p': - unit_value *= 1e-12; - break; - default: - goto error; - } - goto unit_found; - } - } - - for (int j = 0; j < sizeof(units) / sizeof(units[0]); j++) { - if (!strcmp(tokens[i].value.str, units[j].abbr)) { - unit_value = units[j].value; - goto unit_found; - } - } - - goto error; - - unit_found: + double unit_value = resolve_unit_name(tokens[i].value.str); + if(unit_value == 0.0) goto error; if (token_count <= i+1 || tokens[i + 1].type != EXP) { value *= pow(unit_value, exp_sign); @@ -256,8 +254,7 @@ get_unit_value(char const * string) { return value; error: - - fprintf(stderr, "unit.h: Invalid unit string: %s", string); + fprintf(stderr, "unit.h: Invalid unit string: %s\n", string); return 0; } |
