【问题标题】:Perform XNOR on 2 integers对 2 个整数执行 XNOR
【发布时间】:2018-03-13 11:20:22
【问题描述】:

应该对两个整数值 (1101011 XNOR 1010101) 执行 XNOR 运算并返回 1000001。

int a = 1101011;
int b = 1010101;

int res = 0;
res = ~(a ^ b);

cout << res;

这输出:-2073959。

我对编程很陌生,如果我在哪里出错,我们将不胜感激。

【问题讨论】:

  • 不就是按位与运算符吗?
  • 你知道怎么读十六进制吗?如果您将#include &lt;iomanip&gt; 放在文件顶部,则可以使用std::cout &lt;&lt; std::hex &lt;&lt; res; 显示它。每个十六进制数字编码 4 个二进制数字,因此更容易看出结果与输入的关系。您现在所做的是将十进制数 11010111010101 放入 ab - 不是您想要的二进制数。 abints,所以有 32 位 - 比您希望参与 XNOR 操作的多:高位最终被 XNOR 设置为 1,高位打开意味着结果是否定的。
  • 您应该始终对无符号整数进行按位运算。而且您不应该将仅使用零和二进制数的十进制数字混淆。 (十进制的‘11’是十一,二进制的‘11’是三——二进制的‘1101011’是一百零七。)

标签: c++ visual-c++ int


【解决方案1】:

您似乎认为变量ab 是由二进制值初始化的。然而这些

1101011
1010101

是十进制整数文字。

如果您想使用二进制文字并且您的编译器支持它们,那么您应该编写

int a = 0b1101011;
int b = 0b1010101;

否则,您可以使用十进制整数文字,但您必须对它们应用适合十进制值的操作,以获得看起来像二进制值的新十进制值。

另外,XNOR 操作看起来像二进制按位与运算符。

下面有一个演示程序,展示了如何获得所需的结果。

#include <iostream>

std::ostream & binary( int x, std::ostream &os = std::cout )
{
    if ( x ) binary( ( unsigned int )x >> 1 );
    os << ( x & 1 );

    return os;
}

int main() 
{
    int a = 0b1101011;
    int b = 0b1010101;

    int res = a & b;

    binary( a ) << std::endl;
    std::cout << "XNOR" << std::endl;
    binary( b ) << std::endl;
    std::cout << "========" << std::endl;
    binary( res ) << std::endl;

    return 0;
}

程序输出是

01101011
XNOR
01010101
========
01000001

如果你想处理二进制值的十进制表示,那么你可以为 XNOR 操作编写一个单独的函数,例如

#include <iostream>

int xnor( unsigned int a, unsigned int b )
{
    const unsigned int Base = 10;
    unsigned int n = 1;
    unsigned int res = 0;

    while ( a and b )
    {
        res = res + n * ( a % Base and b % Base );
        n *= Base;
        a /= Base;
        b /= Base;
    }

    return res;
}

int main() 
{
    unsigned int a = 1101011;
    unsigned int b = 1010101;

    int res = xnor( a, b );

    std::cout << a << std::endl;
    std::cout << "XNOR" << std::endl;
    std::cout << b << std::endl;
    std::cout << "========" << std::endl;
    std::cout << res << std::endl;

    return 0;
}

程序输出是

1101011
XNOR
1010101
========
1000001

考虑到你的方法在任何情况下都是错误的。

这个表达式

res = ~(a ^ b);

如果两个变量ab 的最高有效位等于0,则将其设置为1。所以对于正数,你总是会得到一个负数,因为符号位将被设置为1

【讨论】:

    【解决方案2】:

    我认为你的问题是你想这样做:

      1101011 ^
      1010101
      -------
    = 0111110
    
      0111110 ~
      -------
    = 1000001
    

    而你实际上是这样做的:

      00000000000100001100110011010011 ^  // int  1101011
      00000000000011110110100110110101    // int  1010101
      --------------------------------
    = 00000000000111111010010101100110    // int  2073958
    
      00000000000111111010010101100110 ~  // int  2073958
      --------------------------------
    = 11111111111000000101101010011001    // int -2073959
    

    所以而不是:

    #include <iostream>
    
    int main()
    {
        int a = 1101011;
        int b = 1010101;
    
        int res = 0;
        int ans = 0;
        ans = (a ^ b);
        res = ~ans;
    
        std::cout << a << '\n';
        std::cout << b << '\n';
        std::cout << ans << '\n';
        std::cout << res << '\n';
    }
    

    使用#include &lt;bitset&gt;

    #include <iostream>
    #include <bitset>
    
    int main()
    {
        int a = 107;
        int b = 85;
    
        int res = 0;
        int ans = 0;
        ans = (a ^ b);
        res = ~ans;
    
        std::cout << std::bitset<7>(a) << '\n';
        std::cout << std::bitset<7>(b) << '\n';
        std::cout << std::bitset<7>(res) << '\n';
        std::cout << std::bitset<7>(res) << '\n';
    }
    

    【讨论】:

      【解决方案3】:

      您错误地假设 110101110101010 是十进制值。事实上,它们是二进制的。

      AFAIK,C++ 不支持二进制赋值;如果是这样,您通常会使用0110101101101011b 来表明这一点。既然没有,您需要将它们视为 Hex 以最轻松地处理它们。

      01101011 = 0x6b
      10101010 = 0xaa
      

      如果您在代码中使用这些值(换句话说,int a = 0x6b 等)然后重复您的操作,您将正确执行操作。您当前打印结果的方式将以十进制打印,然后必须将其转换为二进制(如果需要),尽管有人提供了评论以帮助您将输出转换为十六进制。

      【讨论】:

        【解决方案4】:

        有关 ISO 标准 c++ 二进制、八进制、十进制和十六进制的输入,请参阅https://en.cppreference.com/w/cpp/language/integer_literal

        将输出显示为十六进制、十进制、二进制,然后再次显示十进制:

        unsigned int y = 17 ;
        std::cout << std::hex << y << '\n' ;
        std::cout << std::dec << y << '\n' ;
        std::bitset<32>x(y) ; 
        std::cout << x << '\n' ; 
        std::cout << y << endl ;
        

        “32”设置二进制输出的长度,将其设置得太低,包含的值将显示最低有效位,bitset&lt;8&gt;M(515); cout &lt;&lt; M &lt;&lt; endl ; 将显示 00000011。将长度设置为大于输入类型将填充最高有效位带有 '0' 的数字。默认情况下,std::cout 不将 char 类型处理为数字,并将显示相应的字符,要将 char 显示为其数字代码,您必须将其转换为 [unsigned] shortint 或 @ 987654328@。但是std::bitset 会将char 视为原始位,与其他整数类型相同。

        使用unsigned 整数类型,可以是charshortintlonglong long。每个的确切字节长度可能因 cpu 和操作系统而异,使用sizeof(x)char 为单位打印项目 x 的长度。 [char == 8 位在 99% 的现代实现中] (最常见的现代 x86_64 将分别具有 1、2、4、8、8 或 1、2、4、4、8 字节的整数类型长度。128 位/ 16 字节 c++ 整数类型在 x86_64 上尚未标准化,有一个非标准的 128 位整数类型但使用起来很麻烦,还有一些库允许使用任意长度的数字。)

        如果比较两个大小,例如shortlongshort 可能会隐式转换为long 并用零填充以进行比较;我会在依赖它之前测试这个案例。

        逻辑门情况:XNOR[NXOR] 不等于 AND。您真正想要的选择取决于您。

        假和假==假;真 AND 真 == 真;假 AND 真 == 假

        假 XNOR 假 == 真 ;真 XNOR 真 == 真;假异或真 == 假

        signed 类型可以进行比较,因为它们也是二进制字符串,但是对于所有可能的输入,输出不会是直观的,你应该有一个非常充分的理由这样做,比如尝试关于二进制恭维的数学猜想数字。

        【讨论】:

          猜你喜欢
          • 2013-08-14
          • 1970-01-01
          • 2022-01-14
          • 2021-06-12
          • 1970-01-01
          • 2017-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多