I am currently writing a program in C to convert numbers between bases as an exercise. It asks the user for an input and for the base, that the number given is. It then gives the input into the following function and prints the result.
int convert_to_decimal(char* source, int base) {
int result = 0;
// Bei jeder Addition zu result wird einmal mit sign multipliziert
int sign = 1;
if (source[0] == '-') {
sign = -1;
source++; // Wir überspringen das Vorzeichen bei der Konvertierung
}
int n = strlen(source);
int i = n - 1; // Wir starten bei der letzten Ziffer
while(i >= 0) {
int c = char_to_int(source[i]);
if(c == -1) {
printf("Invalid character in input: %c\n", source[i]);
return 0;
}
if(c >= base) {
printf("Character %c out of range for base %d\n", source[i], base);
return 0;
}
printf("Current char: %c, int value: %d, position: %d\n", source[i], c, i);
printf("Rechenschritt: %d * %d * %d^%d\n", sign, c, base, n - 1 - i);
printf(" = %d * %d * %.0f\n", sign, c, pow(base, n - 1 - i));
result += c * pow(base, n - 1 - i) * sign;
printf("Current result: %d\n", result);
i--;
}
return result;
}
All my manuel tests looked correct when I tested the program, but once I returned today to write some comments for myself I stumbled upon some weird outputs for specific numbers. When entering something like 12 with base 10 or 99 with base 10 we get the correct result. But somehow when I enter:
Enter the number to convert: 100
Enter the base of the number (2 for binary, 10 for decimal, 16 for hexadecimal): 10
I don't get back the 100, but rather a 99:
Current char: 0, int value: 0, position: 2
Rechenschritt: 1 * 0 * 10^0
= 1 * 0 * 1
Current result: 0
Current char: 0, int value: 0, position: 1
Rechenschritt: 1 * 0 * 10^1
= 1 * 0 * 10
Current result: 0
Current char: 1, int value: 1, position: 0
Rechenschritt: 1 * 1 * 10^2
= 1 * 1 * 100
Current result: 99
The decimal value is: 99
So there should be something weird happening with pow(base, n - 1 - i) for 10^2, but when I enter 199 base 10 I get the CORRECT result.
[...]
Current result: 99
Current char: 1, int value: 1, position: 0
Rechenschritt: 1 * 1 * 10^2
= 1 * 1 * 100
Current result: 199
The decimal value is: 199
I suspect that there is an issue when adding up the result, since the output of pow seems to be correct (When adding printf("%.17g\n", pow(base, n - 1 - i));):
Enter the number to convert: 199
Enter the base of the number (2 for binary, 10 for decimal, 16 for hexadecimal): 10
Current char: 9, int value: 9, position: 2
Rechenschritt: 1 * 9 * 10^0
= 1 * 9 * 1
1
Current result: 9
Current char: 9, int value: 9, position: 1
Rechenschritt: 1 * 9 * 10^1
= 1 * 9 * 10
10
Current result: 99
Current char: 1, int value: 1, position: 0
Rechenschritt: 1 * 1 * 10^2
= 1 * 1 * 100
100
Current result: 199
The decimal value is: 199
I'm on Windows 11 and used gcc to compile
Why is this happening, can somebody please explain?
Edit:
I was asked for the result of different inputs:
PS C:\Users\youbo\Documents\obsidian\hda\Rechnerarchitektur\Übungen> .\convert_nums.exe
Enter the number to convert: 100
Enter the base of the number (2 for binary, 10 for decimal, 16 for hexadecimal): 10
Current char: 0, int value: 0, position: 2
Rechenschritt: 1 * 0 * 10^0
= 1 * 0 * 1
Using %.17g: 1
Using %a: 0x0.000000p+0
Current result: 0
Current char: 0, int value: 0, position: 1
Rechenschritt: 1 * 0 * 10^1
= 1 * 0 * 10
Using %.17g: 10
Using %a: 0x0.000000p+0
Current result: 0
Current char: 1, int value: 1, position: 0
Rechenschritt: 1 * 1 * 10^2
= 1 * 1 * 100
Using %.17g: 100
Using %a: 0x1.900000p+6
Current result: 100
The decimal value is: 100
PS C:\Users\youbo\Documents\obsidian\hda\Rechnerarchitektur\Übungen> .\convert_nums.exe
Enter the number to convert: 199
Enter the base of the number (2 for binary, 10 for decimal, 16 for hexadecimal): 10
Current char: 9, int value: 9, position: 2
Rechenschritt: 1 * 9 * 10^0
= 1 * 9 * 1
Using %.17g: 1
Using %a: 0x1.200000p+3
Current result: 9
Current char: 9, int value: 9, position: 1
Rechenschritt: 1 * 9 * 10^1
= 1 * 9 * 10
Using %.17g: 10
Using %a: 0x1.680000p+6
Current result: 99
Current char: 1, int value: 1, position: 0
Rechenschritt: 1 * 1 * 10^2
= 1 * 1 * 100
Using %.17g: 100
Using %a: 0x1.900000p+6
Current result: 199
The decimal value is: 199
"%a"to print to better see its exact value.printf("%.17g\n", pow(base, n - 1 - i));" --> What output do you get when trying to convert"100"?printf("%.17g\n", pow(base, n - 1 - i));yet it is the productprintf("%.17g\n", c * pow(base, n - 1 - i) * sign);that is more useful. Further, more direct use%aand to only have one computational path:double product = c * pow(base, n - 1 - i) * sign; printf("%a\n", product); result += product;