int charTOint(char* in)
{
int out = 0;
int i;
int z = 0;
for (i=strlen(in)-2 ; i>=0;i--,z++)
{
switch (in[i])
{
case '1':
out += 1*exponent(10, z);
break;
case '2':
out += 2*exponent(10, z);
break;
case '3':
out += 3*exponent(10, z);
break;
case '4':
out += 4*exponent(10, z);
break;
case '5':
out += 5*exponent(10, z);
break;
case '6':
out += 6*exponent(10, z);
break;
case '7':
out += 7*exponent(10, z);
break;
case '8':
out += 8*exponent(10, z);
break;
case '9':
out += 9*exponent(10, z);
break;
}
}
return out;
}
Is there an easier way of going about this?
Hopefully it is obviously easier than I think and I'm just tired, it is late...
I find it difficult to think of a more convoluted way. The entire switch statement can be replaced with a single expression and you can eliminate the variables "i" and "z". I'm not going to insult your intelligence by spoonfeeding you with a solution.
I find it difficult to think of a more convoluted way. The entire switch statement can be replaced with a single expression and you can eliminate the variables "i" and "z". I'm not going to insult your intelligence by spoonfeeding you with a solution.
What he's done is completely in line with how positional number systems are taught. The only thing he was missing was the application of Horner's rule:
His code isn't convoluted, in fact it's quite understandable but inefficient on a binary machine (exponent(10,X) would be more efficient on a decimal machine). The use of Horner's rule and knowledge about the lexicographical ordering of the ASCII alphabet makes the experienced programmer's solution difficult to understand but efficient to execute.
Every universe of discourse has its logical structure --- S. K. Langer.
unsigned int unsigned_int_of_string(const char* string)
{
unsigned int result = 0;
for ( size_t i = 0; string[i]; i++ )
result = result * 10 + string[i] - '0';
return result;
}
(without support for negative integers or error handling - that's trivial to add if desired)
There really isn't any need to mess with exponents (is that floats?) or taking the string length, when you can inductively solve the problem by reducing it to adding one more digit to a partial solution.
iansjack wrote:Better but I would replace the "for" loop with a "while" and do away with the unnecessary variable "i".
Now you are just needlessly micro-optimizing and bike-shedding. When I make your change my local gcc outputs exactly the same assembly (instructions in slightly different order) when compiling -Os (optimize for size). It doesn't really matter as the code is equivalent, the only difference is readability and the ease with which it can be statically verified as correct. To that end, I consider it superior using strings as arrays rather than pointers that are rewritten and dereferenced. Besides, if you wanted it pure, you'd do it recursively functional style.
unsigned int unsigned_int_of_string(const char* string)
{
unsigned int result = 0;
for ( size_t i = 0; string[i]; i++ )
result = result * 10 + string[i] - '0';
return result;
}
(without support for negative integers or error handling - that's trivial to add if desired)
There really isn't any need to mess with exponents (is that floats?) or taking the string length, when you can inductively solve the problem by reducing it to adding one more digit to a partial solution.
FYI 'size_t i' should be declared before the for loop, only in C99 mode can it be declared inside the loop.
BASICFreak wrote:FYI 'size_t i' should be declared before the for loop, only in C99 mode can it be declared inside the loop.
And you're deliberately lagging behind 25 years
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
BASICFreak wrote:FYI 'size_t i' should be declared before the for loop, only in C99 mode can it be declared inside the loop.
Please simply cease to use C89 and upgrade to C11, or at least C99. It's entirely silly to use obsolete versions of the C standard that has been replaced. I realized the C89 portability issue when I wrote the code and I deliberately did it anyway. :-)
BASICFreak wrote:*in++;
Why are you referencing the pointer prior to advancing it, rather than just advancing it? :-)
iansjack wrote:Better but I would replace the "for" loop with a "while" and do away with the unnecessary variable "i".
Now you are just needlessly micro-optimizing and bike-shedding. When I make your change my local gcc outputs exactly the same assembly (instructions in slightly different order) when compiling -Os (optimize for size). It doesn't really matter as the code is equivalent, the only difference is readability and the ease with which it can be statically verified as correct. To that end, I consider it superior using strings as arrays rather than pointers that are rewritten and dereferenced. Besides, if you wanted it pure, you'd do it recursively functional style.
No. I'm lazy and cutting down on the typing. Why use two words when one does the job?
unsigned int charTOint(char* in)
{
unsigned int ret = 0;
while (*in != 0)
{
if (*in < '0' || *in > '9') return -1;
ret = ret * 10 + *in - '0';
*in++;
}
return ret;
}
Tested and works fine, and returns -1 on error
I could not think of how to process in order thanks for that, makes more sense than what I was doing.
You've written a function with return type unsigned int that returns -1 on error. Interesting.......
Yea, I realized that after posting and switched to 0 on error (only issue is if 0 is the right output I'm screwed...)
bochs out (snip-it):
Testing char to int of '2048': 2048, '44578': 44578, '64728': 64728, '4d58': 0
sortie wrote:Why are you referencing the pointer prior to advancing it, rather than just advancing it?
Because that is the way I know...
C is not my native language, learning so much within 1500 lines. I'm starting to miss the OO languages though - or at the very least standard libraries.
And I'll continue to make my code C89 standard so I don't have to worry about anyone (mostly me) missing a -C99 gcc tag.
iansjack wrote:Why use two words when one does the job?
Readability is extremely important. Pointer arithmetic adds one low-level detail that can be avoided. The example sortie gave us is more elegant because it is more "portable" to more restricted languages (read: safe languages).