Эквивалент `IF (X AND (2 ^ Y)) Тогда` в C # - PullRequest
2 голосов
/ 30 декабря 2008

У меня есть это If условие в VB6

If ( X AND ( 2 ^ Y)) Then 
  a = a + " 1" 
Else
  a = a + " 0" 

Я хочу такой же эквивалент в C #

Я пытался делать как

if ( X && ( 2 ^ Y))   // ERROR: && can not be used between int to int
  a = a + "1";
else
  a = a + "0";

но эта штука дает мне ошибку.

Вот мой полный VB-код, который я хочу преобразовать в C #

For i = 7 To 0 Step -1
        If intNumber And (2 ^ i) Then   ' Use the logical "AND" operator.
            bin = bin + "1"
        Else
            bin = bin + "0"
        End If
    Next

В приведенном выше коде intNumber может быть любое число.

Ответы [ 8 ]

15 голосов
/ 30 декабря 2008

Примечание : Этот ответ был сильно отредактирован из-за недостатка информации в исходном вопросе. Эта версия ответа теперь основана на обновленном вопросе с достаточным количеством информации. Для истории, проверьте журнал редактирования.

Две вещи:

  • && используется между логическими выражениями для определения логического значения AND
  • ^ в C # означает XOR, а не возведен в степень. Вы не задавали вопрос об этом, но было неизбежно, что вы обнаружили, что ^, кажется, не выполняет свою работу.

&& легко обрабатывается, поскольку его можно заменить одним &, который имеет двойное значение в зависимости от контекста. Либо это логический оператор AND с полной оценкой (&& является короткозамкнутым оператором), либо это побитовый оператор, который вам здесь нужен.

^ отличается, хотя. Наиболее прямым эквивалентом является Math.Pow , но в этом случае доступна лучшая альтернатива, bit-shift.

Случай 2^X можно рассматривать как смещение 1-битных позиций X влево , а смещение битов влево имеет свой собственный оператор, << оператор.

Так что 2^X можно заменить на 1 << X.

В этом контексте, вот что вы хотите для своего внутреннего оператора if:

if ((intNumber & (1 << index)) != 0)
    a = a + "1";
else
    a = a + "0";

Вставьте это в цикл, как у вас в нижнем примере, и вы получите следующее:

for (Int32 index = 7; index >= 0; index--)
    if ((intNumber & (1 << index)) != 0)
        bin = bin + "1";
    else
        bin = bin + "0";

Теперь конкатенация строк, подобных этой, создает давление GC, поэтому вам, вероятно, следует либо сохранить эти цифры в массиве Char, а затем создать строку или использовать класс StringBuilder. В противном случае вы соберете 8 (из моего примера) строк разного размера, и вы будете использовать и сохранять только последнюю. В зависимости от обстоятельств это может не вызывать проблем, но если вы будете вызывать этот код много раз, он будет складываться.

Вот лучшая версия окончательного кода:

Char[] digits = new Char[8]; // change if you want more/fewer digits
for (Int32 index = 0; index < digits.Length; index++)
    if ((intNumber & (1 << index)) != 0)
        digits[digits.Length - 1 - index] = '1';
    else
        digits[digits.Length - 1 - index] = '0';
bin = new String(digits);

Однако, а вот и кикер. В .NET уже есть способ преобразовать значение Int32 в строку, полную двоичных цифр, и это метод Convert.ToString. Разница лишь в том, что он не добавляет начальных нулей, поэтому мы должны сделать это сами.

Итак, вот последний код, который вы должны использовать:

String bin = Convert.ToString(intNumber, 2).PadLeft(8, '0');

Это заменяет весь цикл.

3 голосов
/ 30 декабря 2008

Похоже, что он использует VB для побитового И в этом случае, поэтому, возможно:

if ( (1 & ( 2 ^ 1)) != 0)

Однако это константа! Вы уверены, что где-то там нет переменной?

2 ^ 1 равно 3; 1 и 3 равно 1; так что это всегда будет правдой

(по крайней мере, в C #, где ^ - это XOR; мне говорят, что в VB ^ - это POWER, поэтому 2 ^ 1 - это 2; 1 & 2 - 0; так что это всегда будет ложным ...)

1 голос
/ 30 декабря 2008

Я не понимаю условного синтаксиса ... Вы имеете в виду 1 & (2 ^ 1))? (Используйте только один амперсанд для побитовых сравнений!) (Но это константа!)

но если a строка, тогда

 a +=  Conditional?  "1": "0";
0 голосов
/ 12 декабря 2010

Просто для справки, более краткая версия окончательного кода Лассе:

Char[] digits = new Char[8]; // change if you want more/fewer digits
int index = digits.Length;
var x = intNumber;
do {
    digits[--index] = '0' + (x & 1);
    x >>= 1;
} while (index);
bin = new String(digits);

По сути, это использует тот факт, что мы можем так же легко сместить число вправо, как сместить маску влево. Если мы поступаем таким образом, то результатом операции AND всегда будет одна цифра, то есть та же самая цифра, которую мы хотим в нашей строке, поэтому мы просто преобразуем ее в символ ASCII, добавив «0» (или 48 или 0x30) .

0 голосов
/ 30 декабря 2008

Если я правильно понимаю, что вы хотите сделать, это в цикле сделать

if i is even
a = a + "0"
else
a = a+"1"

в этом случае было бы лучше, если бы вы просто написали

for (int i=7;i>=0;i--)
{
   bin+=(i % 2).ToString();
}

также для конкатерации строк в цикле следует использовать класс StringBuilder, а не оператор +.

0 голосов
/ 30 декабря 2008

Ваш пост не имеет никакого смысла:

IF ( 1 AND ( 2 ^ 1)) Then 
 a = a + " 1" 
Else
  a = a + " 0"

2 ^ 1 = 2 = Math.Pow (2,1) 1 И 2 ​​= 1 & 2 = 0

Эта логика означает, что результат if всегда будет равен нулю.

0 голосов
/ 30 декабря 2008

Не используйте короткое замыкание и. Попробуйте это:

if (1 & (2 ^ 1) == 1)
{
    a = a + "1";
}
else
{
    a = a + "0";
}
0 голосов
/ 30 декабря 2008

Попробуйте

if ( 1 & ( 2 ^ 1))
  a = a + "1";
else
  a= a+ "0";
...