编写一个程序,读取一个整数。输出另一个整数,偶数位保留,奇数位减1,

发布于 2025-01-14 10:42:56 字数 686 浏览 3 评论 0原文

这是我的代码:

#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;
}

现在,当我在 gcc(VS Code) 中执行此操作时,对于 2 位数字,一切正常。但对于超过三位数的数字,我会收到错误。如输入=23145 输出=22043。但我期待输出=22044

另外,如果我在 DevC/C++ 中运行相同的代码,也不会出现错误。

谁能帮我解决这个问题吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橪书 2025-01-21 10:42:56

您的程序在我的系统上产生预期的输出:22044 for 23145,但这可能取决于 pow 函数的实现。

获得不同输出的原因可能是 C 库中的 pow() 函数精度问题的副作用:如果实现了 pow(x, y)exp(y * log(x))xy 的整数值的结果可能非常接近,但低于实际值整数值,导致转换为 int 以生成先前的值整数。一些 C 库作者对整数参数进行了特殊处理以避免此问题,但强烈建议避免使用浮点函数进行整数运算,以防止出现此类棘手问题。

我建议您对代码进行更多更改:

  • 测试 scanf() 的返回值。

  • 删除if (u % 2 == 0) u = u;部分,它没有任何效果。

  • 无论如何,应该有一个 else 子句,以便在测试奇数位时不使用前一种情况的结果。

  • 不要使用浮点函数pow():只需保留一个乘数变量并在循环中更新它。

  • 该程序不处理负数。

这是修改后的版本:

#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;
}

请注意,digit -= digital % 2; 将减少正奇数位,并实际增加负奇数位,这实际上总是减少奇数位的绝对值。这样,正值和负值都可以正确处理。

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.

生来就爱笑 2025-01-21 10:42:56

在我的 Visual Studio Code 实例中,对于输入 23145,我确实发现 22044 作为输出。

我猜想分歧是由 pow(10,i) 的演员阵容带来的。 C 中的 Pow 函数返回一个 double,这不是您真正想要的。我强烈建议不要使用 pow 函数进行整数运算。

解决方案可能是:

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);

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);
抽个烟儿 2025-01-21 10:42:56

问题似乎出在使用返回双精度值的函数pow

如果您正在处理整数,那么最好避免使用返回双精度数的函数,因为可能会出现截断,然后双精度数会转换为整数。

另请注意,用户可以输入负数。你的程序允许这样做。在这种情况下,您的程序也会产生不正确的结果。

我会按照以下方式编写程序

#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' );
    }
}

程序输出是

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

如果即使负数添加 -1 那么你应该用这个 if 语句替换这个

if (digit % 2 != 0)
{
    digit += ( digit < 0 ? 1 : -1 );
}

if (digit % 2 != 0)
{
    digit = ( digit -1 ) % Base;
}

这种情况下,程序输出可能看起来像

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

在这种情况下,这是新值负值-123456789将为-224466880

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文