【问题标题】:Why ( Math.Pow(2, x) & (2^y + 2^z + 2^i) ) is always return 0为什么( Math.Pow(2, x) & (2^y + 2^z + 2^i) )总是返回 0
【发布时间】:2014-02-21 06:44:37
【问题描述】:

就像标题一样,我不明白为什么这个表达总是正确的?

详情如下:

// x, y, z, t is always different with each other
int x = 1;
int y = 2;
int z = 3;

int total = (int)Math.Pow(2, x) + (int)Math.Pow(2, y) + (int)Math.Pow(2, z);

int t = 4; // or any number which is not x, y, z

int result = (int)Math.Pow(2, t) & total;

结果总是 = 0

谁能解释一下?

以下是一些如何将此表达式应用到我的代码中的示例:P。

我有星期几的列表。我想挑一天和我的朋友出去玩。如果今天不被选中,我哪儿也不去:D

一些预定义的值:
日期:周一-周二-周三-周四-周五-周六-周日
值:1-2-3-4-5-6-7

我会选择周一、周二和周五的储蓄值到我的数据库中。

不是保存 {1, 2, 5},而是保存 38 (2^1 + 2^2 + 2^5)。

如果今天是星期二,我会这样检查:2^2 & 38 = 4。4 是 #0,所以今天是这一天,出去吧。

如果今天是星期三,我会这样检查:2^3 & 38 = 0。所以今天不是,去睡觉

【问题讨论】:

  • 它弄错了,我编辑了它:P
  • 请注意,在031 之间使用整数a,而不是(int)Math.Pow(2, a),您可以只使用1 << a(1 << a)。也许这可以帮助您找到问题的答案?
  • 如果 a 超过 31,(int) 转换无论如何都会弄乱Math.Pow 的输出。
  • 是的,这只是一个例子,所以我输入了 (int) (打字速度比 long 快:P)

标签: c# operators


【解决方案1】:

要真正了解这里发生的事情,您必须首先了解二进制,因为您使用& 所做的是bitwise-and

因此,在我们通常的数字书写方式中,我们使用十进制系统或以 10 为底的系统。您从 0 数到 9,然后添加另一个数字来表示“溢出”:10。在二进制或 base-2 中,我们只能数 0 或 1,然后我们必须添加另一个数字。因此,例如从 0 计数到 4,我们有二进制:0 = 0, 1 = 1, 2 = 10, 3 = 11, 4 = 100。这些 0 或 1 中的每一个都是位,对于计算机进行计算,因为它可以将它们表示为打开或关闭的晶体管。

您在这里所做的是生成基本上是 1 的数字,二进制中有很多零。您会注意到,如果您执行 10^x (Math.Pow(10, x)),您会得到 10 的倍数和很多零:10、100、1000、10000 等。

2^x (Math.Pow(2, x)) 做同样的事情:它生成 二进制 数字 1、10、100、1000、10000。在我们的十进制表示法中,这些二进制数字转换为 1、2 , 4, 8, 16。

现在&(按位与)的作用是返回二进制代码,其中左边的所有代码也是右边的一个。所以,假设你有二进制:2^1 + 2^2 + 2^3 = 1 + 10 + 100 = 111。

然后你对左边的 2^4 进行按位运算,即 1000。所以你问的是 1000 和 0111(你可以在任何二进制代码的左边添加尽可能多的零,就像你可以十进制数:00100 仍然只是一百)。计算结果为 0000 = 0。

您注意到,当 t 是 x、y 或 z 时,它分别返回 x、y 或 z,实际上就像一个过滤器,因为:0010 & 0111 = 0010(第二个中都有一个位置)。更复杂的例子是 0110 1100 & 1100 0101 = 0100 0100。

那里;现在你可以计算你的电脑了:-)

【讨论】:

  • 这比 Joachim Isaksson 的更详细
【解决方案2】:

如果你把它看成二进制,并且只要 x,y,z 是不同的数字,结果是;

(int)Math.Pow(2, x) + (int)Math.Pow(2, y) + (int)Math.Pow(2, z) 

是一个整数,其中设置了位 x、y 和 z(并且只有这些位)。

(int)Math.Pow(2, t) & total

...检查是否设置了位 t。只要 t 与 x、y、z 不同,它就不会。

【讨论】:

    【解决方案3】:

    因为:

    total = 14
    Math(2,4) = 16
    
    16 and 14 = 0
    

    这是二元运算!

    16 = (10000) binary
    14 = (01110) binary
    

    它们之间没有共同位,因此and 将返回 0。如果您期望其他结果,也许您想做or

    16 or 14 = 30
    

    【讨论】:

    • 感谢您的回复,但我认为这不是答案。我知道它总是返回 0。我需要这样的东西:en.wikipedia.org/wiki/Pythagorean_theorem。它总是正确的,我们不需要再次证明它=.=
    • @Trung 你的意思是,你需要检查 a^2+b^2=c^2 吗?
    • 不,这只是关于如何管理我在数据库中的数据的问题。生病编辑我的问题。
    【解决方案4】:

    它是一个二进制比较(& 比较两个数字中的每个位置,如果两者都是 1,则返回 1):

    10000 // 16 in binary
    01110 // 14 in binary
    00000 // 14 & 16 = 0
    

    在此处使用其他值,您将获得不同的值。以 6 和 10 为例:

    00101  // 6 in binary
    01110  // 14 in binary
    00100  // 6 and 14 = 8  
    

    PS:您可以通过选择View > Programmer,并在左侧的 Bin 和 Dec 之间切换,使用 PC 上的计算器来试验这种类型的数学运算.

    【讨论】:

      【解决方案5】:

      xyzt 视为位位置 - 您正在按位执行&,这将清除所有未在 both 中设置的位 em> 个操作数,而 2t 设置tth 位。

      所以如果xyz都不同,2x + 2y + 2z设置了位 xyz,并且 2t 将设置了位 t... 所以对这两个结果执行按位与运算将始终为 0。

      现在您的原始声明(未指定 xyz 不同)不是相当正确的,因为如果 xy是相同的(例如)添加可以有效地给你一个不同的位。 (如果操作数都设置了不同的位,则每个仅设置一个位的整数值的加法仅等效于按位或。)

      例如:

      int x = 2;
      int y = 2;
      int z = 10; // Ignore this, effectively
      
      // 2^2 + 2^2 + 2^10 == 2^3 + 2^10
      int total = (int)Math.Pow(2, x) + (int)Math.Pow(2, y) + (int)Math.Pow(2, z);
      
      int t = 3;
      int result = (int)Math.Pow(2, t) & total; // result is now 8
      

      【讨论】:

      • @Trung:最好留下它,或者添加一个编辑 - 否则你实际上是在使你到目前为止得到的答案无效。
      【解决方案6】:

      & 进行二进制 AND 运算,因此 16 和 14 的二进制 ADD 为 0

         10000
       & 01110
       ------- 
         00000
      

      【讨论】:

        【解决方案7】:
        total = 14
        Math(2,4) = 16
        

        所以

        (10000) // 16
        (01110) // 14
        (00000) // 16 & 14 = 0
        

        【讨论】:

          【解决方案8】:
          (int)Math.Pow(2, t) = (2^4)base 10 = (10000)base 2
          total = (2^3 + 2^2 + 2^1)base 10 =  (01110)base 2
          

          &二进制与,可以认为是每个位之间的乘法

          因此

          1*0 = 0
          0*1 = 0
          0*1 = 0
          0*1 = 0
          0*0 = 0
          (int)Math.Pow(2, t) & total = (10000)base 2 & (01110)base 2 = (00000)base 2 = 0
          

          假设我们有

          total1 =  (10001)base 2
          

          然后

          (int)Math.Pow(2, t) & total1 = (10000)base 2 & (10001)base 2 = (10000)base 2 = (16)base 10
          

          【讨论】:

            【解决方案9】:

            在这里,您正在使用 & 进行二元运算。 这 & 等于按位与(与门)。 AND 像这样工作。

            When 1 & 1 =1
            when 1 & 0 = 0
            when 0 & 1 = 0
            when 0 & 0 = 0
            

            当匹配值满足时输出 1 ,否则输出 0.Check how and works

            1001
            1110
            ------
            1000  
            ------
            

            所以二进制1000的值为8

            【讨论】:

            • hhmm,我认为您在这里有些误会,因为有时,使用其他值,它不仅是 0 或 1。例如:t = 3,结果将是 8
            • 是的,正是我的朋友。当 t = 3 它是 9 & 14。这意味着 1001 1110 ------ 1000 所以 1000 的值是 8。请参考你修改后的答案
            猜你喜欢
            • 2018-02-05
            • 2016-05-13
            • 1970-01-01
            • 2015-07-23
            • 1970-01-01
            • 2012-12-12
            • 2021-03-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多