C ++ I need to write a function that converts hexidecimal to decimal and uses recursion, and I keep getting runtime errors

This is for the class, so it must use recursion, I wrote the working code iteratively, but I cannot get it to work in recursion, and I'm really lost. I have been working on this for a week. Any recommendations or suggestions at all will be extremely helpful.

This is my function, I need to take hex as a char pointer and output it with the corresponding decimal. I constantly get either a stack overflow or a memory allocation of runtime errors, can anyone determine what is wrong and direct me in the right direction?

int hexToDecimal(const char *hex, int offset, int power){ if(offset >= 0){ hexChar = *(hex+offset); if( isalpha(hexChar) ) { hexChar = toupper(hexChar); hexNum = hexChar - asciiCharOffset; } else { hexNum = hexChar - asciiIntOffset; } return hexToDecimal(hex, offset--, power++) + hexNum * (int)pow(16,power); } else { return 0; } } 
+6
source share
5 answers

I did not compile it, but at first glance it suggests that the corresponding line should be:

 return hexToDecimal(hex, offset-1, power+1) + hexNum * (int) pow(16,power-1); 

Because in your case you call yourself ad infinitum (called using let, let say offset 6, if you pass the offset, it will go through 6 anyway, because it will decrease after it gives the value of the function).

Also, the post-increment will give you undefined behavior to call pow(16,power) later in the same expression, because (again with power = 6 as an example) it could be pow(16,6) or pow(16,7) depending on the compiler.

Everything aside also risks that pow () will give you false (rounded) when converting to int (it might turn out that pow (16,2) returns 255.9999999 and you end up with (int) 255, there is enough evidence there and solutions here in stackoverflow, just find pow).

EDIT (in response to comments):

Finally, introducing the printf magic debugger:

 int hexToDecimal(const char *hex, int offset, int power){ if(offset >= 0){ char hexChar = *(hex+offset); int hexNum, recursed; if( isalpha(hexChar) ) { hexChar = toupper(hexChar); hexNum = hexChar - asciiCharOffset; } else { hexNum = hexChar - asciiIntOffset; } recursed= hexToDecimal(hexNum, offset-1, power+1); printf("%d + %d * %d\n", recursed, hexNum, (int)pow(16,power-1)); return recursed + hexNum * (int)pow(16,power-1); } else { return 0; } } 
+7
source

You are using post-increment here:

  return hexToDecimal(hex, offset--, power++) 

A post-increment (and a post-decrement) will increase / decrease the variable (i.e., it will actually change the offset and power ), but inc / dec will happen after evaluating the variable.

i.e:.

 int i = 5; std::cout << "i = " << i; // prints 'i = 5' std::cout << "\ni = " << i++; // still prints 'i = 5' and then changes i to be 6 std::cout << "\ni = " << i; // prints 'i = 6' 

In fact, you do not want to change the offset and power - you want to pass a different value for the next hexToDecimal call.

You can catch such errors if you introduce the parameters of the const method, that is:

 int hexToDecimal(const char*hex, const int offset, const int power); 

I recommend making const parameters if you have no intention of modifying them. In this way, the compiler can help you catch many common errors.

+1
source

use predefined in function argument. Use --offset in the argument. if u uses an offset, then the intial value of the offset is passed to the function, and then the offset decreases.

+1
source

Here I wrote LONG again ... This is probably not the best or fastest approach, and I could use some error checking, but I will leave this as an exercise for the reader ...

  long GetValue(const char *pszStrVal) { long Retval = 0; try { char *p = (char*)pszStrVal; if(p == NULL) return 0; if(strstr(p, "0x")) { p++;p++; long x = strlen(p); long pval = 1 << ((x-1)*4); for(int y = 0;y < x;y++,pval = (pval >> 4)) { int digit = 0; switch(p[y]) { case 'A': case 'a': digit = 10; break; case 'B': case 'b': digit = 11; break; case 'C': case 'c': digit = 12; break; case 'D': case 'd': digit = 13; break; case 'E': case 'e': digit = 14; break; case 'F': case 'f': digit = 15; break; default: digit = p[y] - 0x30; } Retval += (pval * digit); } } else { Retval = atoi(p); } } catch(...) { Retval = 0; } return Retval; } 
0
source

Here's a simple solution that uses a call to a second recursive function. Hope this helps you debug your:

 #include <stdio.h> #include <ctype.h> int h2d_rec(const char *hex, int d); int h2d(const char *hex) { return h2d_rec(hex, 0); } int h2d_rec(const char *hex, int d) { char hexChar = *hex; if (0==hexChar) { return d; } int charNum; if (isalpha(hexChar)) { charNum = 10 + toupper(hexChar) - 'A'; } else { charNum = hexChar - '0'; } // Note d<<4 is the same as 16*d return h2d_rec(hex+1, (d<<4) + charNum); } int main(int argc, const char **argv) { const char *hex = "FF"; if (1<argc) { hex = argv[1]; } printf("%s in decimal is %d\n", hex, h2d(hex)); } 

Instead, you can use long to process large hexadecimal numbers.

0
source

Source: https://habr.com/ru/post/947254/


All Articles