I have an input data of 4 character string (alphanumeric) or 3 character string and I need to convert these ASCII character string to unique float in 2 digits each, separated by decimal.
Ex:
Input string = 5405, output data = 54.05
Input string = 53BC, output data = 53.199 ( B ascii value is ~ 0x42 in hex and C is 0x43 )
Issue is I am seeing the same output when input strings are 560B and 5618, as both results in same output as 56.18.
Is there a way to uniquely generate a float number in these cases?
Max value of float allowed is 99.999.
CodePudding user response:
Your encoding is somewhat confusing, but here is a simple solution:
- use 2 digits for the integral part
- use 2 digits for fractional parts
00
to99
- use a combination of 1 letter and 1 letter or digit for fractional parts
100
to999
. There are 26*36 = 936 such combinations, enough to cover the 900 possibilities. - all values from
00.00
to99.999
can be encoded. - some 4 letter and digit combinations are not used.
- the encoding is not unique. eg:
53A0
is53.100
, the same number as53.10
encoded as5310
.
Here is an implementation:
#include <stdib.h>
double fdecode(const char *s) {
char a[7];
a[0] = s[0];
a[1] = s[1];
a[2] = '.';
if (s[2] >= '0' && s[2] <= '9') {
a[3] = s[3];
a[4] = s[4];
a[5] = '\0';
} else {
// assuming uppercase letters
int n = 100 (s[3] - 'A') * 36;
if (s[4] >= '0' && s[4] <= '9') {
n = s[4] - '0';
} else {
n = 10 (s[4] - 'A') % 26;
}
snprintf(&a[3], 4, "%d", n);
}
return strtod(a, NULL);
}
int fencode(char *s, double d) {
char a[7];
if (d >= 0 && snprintf(a, 7, ".3f", d) == 6) {
s[0] = a[0];
s[1] = a[1];
if (a[5] == '0') {
s[2] = a[3];
s[3] = a[4];
} else {
int n = atoi(a 3);
s[2] = 'A' (n / 36);
n %= 36;
if (n < 10) {
s[3] = '0' n;
} else {
s[3] = 'A' n - 10;
}
}
s[4] = '\0';
return 4;
} else {
s[0] = '\0';
return -1;
}
}
CodePudding user response:
Simple math tells us that this is not possible. The number of unique alphanumeric string of length 4 (case-insensitive) is 36^4 = 1,679,616 while the number of non-negative unique floating point numbers with at most 3 fractional digits and less than 100 is 10^5 = 100,000.
If the string were restricted to hexadecimal digits, there would only be 16^4 = 65,536 possibilities in which case a unique encoding would be possible.
Slightly off-topic: when a mapping is needed into a domain which is too small to accommodate the result of a unique mapping, a hash function is the "standard tool", but collisions must be handled.