【问题标题】:why this code isn't converting decimals to binary from decimals 0 to 31为什么这段代码没有将小数从小数 0 到 31 转换为二进制
【发布时间】:2022-08-16 08:27:05
【问题描述】:

所以我试图使用 c 将十进制数转换为二进制数。在这段代码中,每件事似乎都运行良好。此代码也适用于 32、33 和继续的小数。但是此代码不适用于 0 到 31 的小数。这里有什么错误。

#include <stdio.h>
#include <math.h>

int main(void)
{

    int decimal;

    printf(\"Enter the decimal value: \");
    scanf(\"%i\", &decimal);
    int n, remainder;
    int i, j, k;

    for (int i = 0; i < decimal; i++)
    {
        if (pow(2, i) <= decimal)
        {
            n = i;
        }
    }

    char index[n];
    int quotient[n];

    quotient[0] = decimal;

    for (i = 0; i <= n; i++)
    {
        quotient[i + 1] = quotient[i] / 2;
        remainder = quotient[i] % 2;

        if (remainder == 1)
        {
            index[i] = \'1\';
        }
        else
        {
            index[i] = \'0\';
        }
    }

    for (int k = n; k >= 0; k--)
    {
        printf(\"%c\", index[k]);
    }

    return 0;
}
  • 除了其他事情,当\'i\' 达到\'n\' 的值时quotient[i + 1] = quotient[i] / 2; 会发生什么?
  • 在带有内存清理器/检查的调试器中运行代码可能会提供大量信息。请注意,对于 32 及以上的值,它不会“工作”。您只是认为确实如此,因为有时会调用未定义的行为似乎“工作”。 See here
  • decimal 不是十进制int 是一个int。十进制值的表示是 bt 提供的表示函数,例如printfint已经是二进制因为这就是计算机代表的方式全部对象,与类型无关。因此,您的“转换”是不必要的并且过于复杂 - 您可以简单地使用“行走 1”位掩码来检查和呈现各个位。
  • 此外,您还有一种相当复杂的方法来确定有效位数。 Fe2O3 的答案是明智的解决方案,但如果你必须用算术计算,那么int n = ceil( log( decimal ) / log( 2 ) ) ;

标签: c binary decimal


【解决方案1】:

scanf() 返回的数字是您输入的 base10 值的位模式(二进制)表示。

您的想法是正确的(尝试“分离”这些位),但使用的方法令人怀疑且令人困惑。

下面是一些熟悉的值被转换为 1 和 0 字符串的循环。

考虑它在每一步都在做什么......

int main() {
    for( int i = 253; i <= 258; i++ ) {
        printf( "Decimal %d: ", i );

        unsigned int bitmask = 0;
        bitmask = ~bitmask;
        bitmask &= ~(bitmask >> 1); // High bitmask ready

        // skip over leading 0's (optional)
        while( bitmask && (bitmask & i) == 0 ) bitmask >>= 1;

        // loop using bitmask to output 1/0, then shift mask
        do {
            putchar( (bitmask & i) ? '1' : '0' );
        } while( (bitmask >>= 1) != 0 );

        putchar( '\n' );
    }
    return 0;
}

输出:

Decimal 253: 11111101
Decimal 254: 11111110
Decimal 255: 11111111
Decimal 256: 100000000
Decimal 257: 100000001
Decimal 258: 100000010

【讨论】:

  • 感谢先生提供此代码。这段代码更加动态。但是我仍然坚持那件事。(我以前的代码)实际上我认为我的逻辑是正确的。那么真正的错误发生在哪里呢?你能帮帮我吗?
  • @Heckar 实际上,恐怕我无法帮助您实施。假设输入的数字是 5000111。您的方法将调用一个浮点函数 (pow) 半百万次,以确定设置的最左边的位......让我头疼。不过祝你好运!
  • @Heckar pow 是一个浮点函数(昂贵)。做出数百个“猜测”来试图确定哪个设置位最高是没有意义的......使用两个可变长度数组(当你知道你最多需要 32 个(或 64 个)元素时,只会增加复杂性。尝试编写清晰、简洁的代码...您的 CPU 会感谢您...
【解决方案2】:

我不喜欢这样,但您似乎想使用pow() 来查找传入整数中的最高设置位。也许这会引导您找到您正在寻找的解决方案。

int main() {

    int n = 0;

    // generate a series of numbers as input
    for( int decimal = 1; decimal < 1000*1000*1000; decimal = decimal * 2 + 1 ) {

        // Limited of 32 bit integers INCLUDING sign bit
        for (int i = 0; i < 31; i++) {

            int guess = (int)pow( 2, i ); // make a guess with this value
            printf( "Guess %d\n", guess );

            if( guess > decimal ) { // guess now encompasses set bits
                n = i; // Found what is needed.
                break;
            }
        }
        printf( "decimal input = %d: examining %d bits\n", decimal, n );
        getchar();
    }


    return 0;
}

这是上述输出的一个示例。

Guess 1
Guess 2
Guess 4
Guess 8
Guess 16
Guess 32
Guess 64
decimal input = 63: examining 6 bits

注意:这种事情只适用于正值。如果您想要负整数的位模式,它可能会爆炸。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多