Here is my code:
#include <stdio.h>
#include <math.h>
int main() {
int num, i = 0, new_num = 0, u;
printf("Enter a number: ");
scanf("%d", &num);
while (num > 0) {
u = num % 10;
if (u % 2 == 0)
u = u;
if (u % 2 == 1)
u = u - 1;
new_num = new_num + u * pow(10, i);
num = num / 10;
i++;
}
printf("The new number is: %d", new_num);
return 0;
}
Now, when I am doing this in gcc(VS Code), for 2-digit number everything is ok. But for digits more than three I am getting a error. Like Input=23145 Output=22043. But I was expecting output=22044.
Also, if I run the same code in DevC/C++, there is no error.
Can anyone help me out in this?
Your program produces the expected output on my system: 22044 for 23145, but this might depend on the implementation of the pow function.
The reason you get a different output is probably a side effect of a precision issue with the pow() function in your C library: if pow(x, y) is implemented as exp(y * log(x)), the result for integral values of x and y could be very close but inferior to the actual integral value, causing the conversion to int to produce the previous integer. Some C library authors make a special case of integral arguments to avoid this problem, but it is highly recommended to avoid floating point functions for integer arithmetics to prevent such tricky issues.
I would advise some more changes in your code:
test the return value of scanf().
remove the if (u % 2 == 0) u = u; part, it has no effect.
in any case, there should be an else clause to not use the result of the previous case when testing for odd digits.
do not use the floating point function pow(): just keep a multiplier variable and update it in the loop.
the program does not handle negative numbers.
Here is a modified version:
#include <stdio.h>
int main() {
int num, new_num = 0, pow10 = 1;
printf("Enter a number: ");
if (scanf("%d", &num) != 1)
return 1;
while (num != 0) {
int digit = num % 10;
/* decrement odd digits absolute value */
digit -= digit % 2;
new_num = new_num + digit * pow10;
pow10 = pow10 * 10;
num = num / 10;
}
printf("The new number is: %d\n", new_num);
return 0;
}
Note that digit -= digit % 2; will decrement positive odd digits and actually increment negative odd digits, which effectively always decrements the absolute value of odd digits. This way both positive values and negative values are handled correctly.
It seems that the problem is using the function pow that returns a double value.
If you are dealing with integers then it is better to avoid using functions that return doubles due to a possible truncation then a double is converted to an integer.
Also pay attention to that the user can enter a negative number. Your program allows to do that. In this case your program also will produce an incorrect result.
I would write the program the following way
#include <stdio.h>
int main( void )
{
while (1)
{
const int Base = 10;
int num;
printf( "Enter a number (0 - exit): " );
if (scanf( "%d", &num ) != 1 || num == 0) break;
int new_num = 0;
for (int tmp = num, multiplier = 1; tmp != 0; tmp /= Base)
{
int digit = tmp % Base;
if (digit % 2 != 0)
{
digit += ( digit < 0 ? 1 : -1 );
}
new_num = new_num + multiplier * digit;
multiplier *= Base;
}
printf( "The original number is %d and the new number is: %d\n",
num, new_num );
putchar( '\n' );
}
}
The program output is
Enter a number (0 - exit): -123456789
The original number is -123456789 and the new number is: -22446688
Enter a number (0 - exit): 123456789
The original number is 123456789 and the new number is: 22446688
Enter a number (0 - exit): 0
If even for negative digits to add -1 then you should substitute this if statement
if (digit % 2 != 0)
{
digit += ( digit < 0 ? 1 : -1 );
}
for this one
if (digit % 2 != 0)
{
digit = ( digit -1 ) % Base;
}
In this case the program output might look like
Enter a number (0 - exit): -123456789
The original number is -123456789 and the new number is: -224466880
Enter a number (0 - exit): 123456789
The original number is 123456789 and the new number is: 22446688
Enter a number (0 - exit): 0
That is in this case the new value for the negative value -123456789 will be -224466880.
In my instance of Visual Studio Code, for an input 23145, I indeed find 22044 as an output.
I guess the divergence comes with the cast of pow(10,i). Pow function in C returns a double which is not what you really want here. I strongly advice to not use the pow function for integer arithmetic.
A solution could be :
uint16_t i = 0u;
uint16_t current_digit = 0u, decimal_digit = 1u;
uint16_t new_number = 0u;
uint16_t number = 23145u;
while(number > 0u) {
current_digit = number % 10;
if (current_digit % 2) {
current_digit = current_digit - 1;
}
new_number = new_number + current_digit * decimal_digit;
decimal_digit *= 10u;
number /= 10;
i++;
}
printf("The new number is: %d", new_number);