Math 在switch case语句中检测2个变量值的4个排列

Math 在switch case语句中检测2个变量值的4个排列,math,coding-style,geometry,Math,Coding Style,Geometry,我有两个变量,width和height作为整数。其中任何一个都可以是正的或负的(不是零)。自然有4例 width>0和&height>0 width>0和&height0和高度0 打破 } 如果您选择的语言没有二进制数字文本,那么它就不那么可读,但是您可以通过注释来解决这个问题 还请注意,支持将true解释为1和false解释为0的语言将有助于缩短int v=…行。您可以这样做 var bits=0; if(width > 0) { bits+=1; } if(height &

我有两个变量,
width
height
作为整数。其中任何一个都可以是正的或负的(不是零)。自然有4例

  • width>0和&height>0
  • width>0和&height<0
  • width<0&&height>0
  • 宽度<0和高度<0
  • 现在,我想在不使用4个if语句的情况下对这4个案例中的每一个采取不同的操作

    是否有一种方法可以汇总这些案例,以便将其作为一个简单的
    开关案例

    switch( aggregate ){
      case 1:
      case 2:
      case 3:
      case 4:
    }
    
    如果没有比使用
    If
    更好的方法,那么在三维空间中,您有3个长度
    (x,y,z)
    ,并且将有27个
    If


    如果有必要的话,我正在使用javascript

    javascript中,这很简单,只需将条件颠倒过来:

    switch(true)
    {
        case (width > 0 && height > 0):
            break;
        case (width > 0 && height < 0):
            break;
        case (width < 0 && height > 0):
            break;
        case (width < 0 && height < 0):
            break;
    
        default:
    
    }
    
    开关(真)
    {
    大小写(宽度>0和高度>0):
    打破
    外壳(宽度>0和高度<0):
    打破
    外壳(宽度<0和高度>0):
    打破
    外壳(宽度<0和高度<0):
    打破
    违约:
    }
    

    这也适用于VB6/VBA,但在许多C++语言和C语言中都没有。


    这里有一个简单的证明:

    您可以将每个条件(宽度为正、高度为正)视为一个布尔属性,将它们组合成二进制数并切换

    伪代码:

    int v = (width > 0 ? 0 : 1) << 1 | (height > 0 ? 0 : 1) << 0;
    switch (v) {
      case 0b00:
        // width < 0 && height < 0;
        break;
      case 0b01:
        // width < 0 && height > 0;
        break;
      case 0b10:
        // width > 0 && height < 0
        break;
      case 0b11:
        // width > 0 && height > 0
        break;
    }
    
    intv=(宽度>0?0:1)0?0 : 1)  0;
    打破
    案例0b10:
    //宽度>0和高度<0(&H)
    打破
    案例0b11:
    //宽度>0&&高度>0
    打破
    }
    
    如果您选择的语言没有二进制数字文本,那么它就不那么可读,但是您可以通过注释来解决这个问题

    还请注意,支持将
    true
    解释为
    1
    false
    解释为
    0
    的语言将有助于缩短
    int v=…
    行。

    您可以这样做

    var bits=0;
    if(width > 0) {
         bits+=1;
    }
    if(height > 0) {
         bits+=2;
    }
    
    switch{bits} {
        case 0: //both negative
            //something
            break;
        case 1: //width positive, height negative
            //something
            break;
        case 2: //width negative, height positive
            //something
            break;
        case 3: //both positive
            //something
            break;
    }
    
    虽然这有点让人困惑。(特别是当您有3个值时)。您可以使用变量使代码更加清晰

    var WIDTH_POSITIVE_BIT=1;
    var HEIGHT_POSITIVE_BIT=2;
    
    var bits=0;
    if(width > 0) {
         bits+=WIDTH_POSITIVE_BIT;
    }
    if(height > 0) {
         bits+=HEIGHT_POSITIVE_BIT;
    }
    
    switch{bits} {
        case 0: //both negative
            //something
            break;
        case WIDTH_POSITIVE_BIT: //width positive, height negative
            //something
            break;
        case HEIGHT_POSITIVE_BIT: //width negative, height positive
            //something
            break;
        case WIDTH_POSITIVE_BIT+HEIGHT_POSITIVE_BIT: //both positive
            //something
            break;
    }
    

    我想说,这无助于使代码更加清晰。

    如果不增加一点开销,就无法做到这一点

    s = ( width < 0 ) ? 0 : 1;
    s += ( height < 0 ) ? 0 : 2;
    
    switch(s) {
        case  0: // 00 => both < 0
        case  1: // 01 => width > 0, height < 0
        case  2: // 10 => width < 0, height > 0
        case  3: // 11 => both > 0
    }
    
    s=(宽度<0)?0 : 1;
    s+=(高度<0)?0 : 2;
    开关{
    案例0://00=>两者均<0
    案例1://01=>宽度>0,高度<0
    案例2://10=>宽度<0,高度>0
    案例3://11=>两者均>0
    }
    
    这可能适用于3D案例:

    s = ( width < 0 ) ? 0 : 1;   //First bit for width
    s += ( height < 0 ) ? 0 : 2; //Second bit for height
    s += ( depth < 0 ) ? 0 : 4;  //Third bit for depth
    
    switch(s) {
        case  0: // 0 0 0
        case  1: // 0 0 1
        case  2: // 0 1 0
        case  3: // 0 1 1
        case  4: // 1 0 0
        case  5: // 1 0 1
        case  6: // 1 1 0
        case  7: // 1 1 1
    }
    
    s=(宽度<0)?0 : 1;   //宽度的第一位
    s+=(高度<0)?0 : 2; //高度的第二位
    s+=(深度<0)?0 : 4;  //深度第三位
    开关{
    案例0://0
    案例1://01
    案例2://0 1 0
    案例3://0 1
    案例4://10
    案例5://10 1
    案例6://1 0
    案例7://1
    }
    

    当然,假设你不能有一个0维。

    有几个答案在逻辑上是正确的。如果您在C中执行此操作,它将是:

    s = ((width<0)<<1) | (height<0);
    switch(s) {
    ....
    }
    

    s=((宽度一个4路
    开关
    和四个相互排斥的
    if
    块基本上是一样的。如果在3d的情况下,你确实需要根据事实做27个完全不同的事情中的一个,那么你将得到27个代码块,不管它们是如何组织的……加上,我猜这4个(或27个)块实际上不会做完全不同的事情-事实上,我敢打赌它们可以做相同的事情,有两个或三个参数取值
    +1
    -1
    。如果块是27,为什么?每个维度有两个选择,2^3=8。假设在这种情况下也不能有0。
    if (witdh<0) {
        if (height<0) {
            // both negative
        }
        else {
            // only width negative
        }
     }
     else {
        if (height<0) {
            // only height negative
        }
        else {
            // both positive
        }
     }