Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define CHR_0 0x30
- #define CHR_9 0x39
- #define UPCASE_BIT 0x20
- #define CAP_A 0x41
- #define CAP_Z 0x5A
- /* atofhz returns a float given a buffer containing a floating point value and a multiplier
- in hz.
- ex: 18.45
- 18.45Hz
- 18.45KHz
- 18.45MHz
- This function does not require the use of the C library which should
- lead to a reduction in size.
- Note this is no longer destructive to buffer
- Compliments of Brent York, happyhax0r@gmail.com
- */
- float atofhz(char *buffer) {
- float res = 0.0f;
- char *tmp1 = buffer;
- char multiplier = '\0';
- char placement = 0;
- char tmpplacement = 0;
- char i;
- /* Loop through the buffer, looking for a character that isn't
- * a numeric or period, note it then nuke it with a null.
- */
- while (*tmp1) {
- /* This replaces isalpha and toupper... */
- if (((*tmp1 & ~UPCASE_BIT) >= CAP_A) && ((*tmp1 & ~UPCASE_BIT) <= CAP_Z)) {
- multiplier = *tmp1 & ~UPCASE_BIT;
- /* This breaks out of the loop saving cycles and further letter testing */
- break;
- }
- /* Move to the next char */
- tmp1++;
- }
- /* Now we have a string that's only the floating point number
- * first thing we need to do is count the number of characters to the left of the decimal point
- * to get our maximum placement
- */
- tmp1 = buffer;
- placement = 0;
- while (*tmp1 != '.') { placement++; tmp1++; };
- /* Now we start converting, note that for decimal values here we start multiplying by 10? We'll divide this
- back out later. This allows us to avoid a call to pow() :) */
- tmp1 = buffer;
- while (*tmp1 != '\0') {
- if ((*tmp1 >= CHR_0) && (*tmp1 <= CHR_9)) {
- if (placement < 1) {
- tmpplacement = 1;
- res *= 10.0;
- } else {
- tmpplacement = placement;
- }
- res += ((*tmp1 - CHR_0) * ipow(10, tmpplacement - 1));
- placement --;
- }
- tmp1++;
- }
- /* Finally we round up to the same number of significant digits after the decimal point that we had
- * (or as close as we can come given floating point math, note this isn't the best way to round but
- * it works and it's cheap on cycles and space)
- */
- for (i = 0; i > placement; i--) { res /= 10.0; }
- /* And finally, we need to deal with the multiplier */
- switch (multiplier) {
- case 'M':
- res *= 1000000.0;
- break;
- case 'K':
- res *= 1000.0;
- break;
- }
- /* return the value */
- return ((res/50000000)*16777216);
- }
- /* ipow - an integer power function
- *
- * Compliments of Brent York, happyhax0r@gmail.com
- */
- int ipow(int b, int x) {
- int res = 1; /* Set res to 1, assuming x of 0, because anything to the power of zero is 1 */
- /* So, if x is > 0 then we'll loop through until it's not zero, multiplying each time by base and accumulating
- * the result in res...
- *
- * The way this algorithm works is as follows:
- *
- * If the first bit of x is set we multiply the result by "base" (as the end value contains a multiple of base
- * for that bit), and shift the bits right by one. If it's a 0, it doesn't get multiplied by base. Each time
- * through the loop, we multiply base by base... The end result is an additive accumulation of the proper
- * number of multiples of base per bit, resulting in our exponentiated value.
- */
- while (x) {
- if (x & 1) res *= b;
- x >>= 1;
- b *= b;
- }
- return res;
- }
Add Comment
Please, Sign In to add comment