Связь между троичной логикой и мультиплексической логикой? - PullRequest
0 голосов
/ 27 февраля 2011

Я внедряю компьютерный симулятор в C с задачей не использовать условные выражения (т. Е. Нет if / else, switch / case, while / for и т. Д.). В аппаратном обеспечении, которое я имитирую, много муксов, поэтому было бы неплохо, если бы я мог использовать условные троичные логические операторы. Итак, мой вопрос: компиляторы C создают логику MUX из троичных логических операторов или ветки?

Пример:

int a, b, q, r;
/* Ternary logic */
r = q ? a : b;
/* MUX equivalent logic */
r = ( q & a ) | ( (~q) & b )
/* Branch equivalent logic */
if (q) r = a; else r = b;

Ответы [ 3 ]

4 голосов
/ 27 февраля 2011

Тернарный оператор эквивалентен ветви: то есть не возвращенное значение не оценивается.

Я не знаю, насколько вы ограничены, поэтому обратите внимание, что логические операторы && и || не оценивают свой второй аргумент, если результат можно определить по первому.

(И обратите внимание, что строка «MUX» не сильно отличается от двух других выражений: она выбирает биты из a или b в зависимости от значения соответствующего бита в q, не выбирает a или b в зависимости если q равно нулю или нет; Изменить: это хуже: вы используете! q, а не ~ q ...).

1 голос
/ 28 февраля 2011

Часто создается логика ветвления, но очень возможно выполнить троичную операцию без какого-либо вида ветвления, если вы в порядке с обоими оцениваемыми значениями. Учтите это:

#include <stdio.h>

static inline int isel(int cond, int a, int b)
{
   int mask = cond | (-cond);
   mask >>= 31;
   return (b & mask) | (a & ~mask);
}

int main(void)
{
   printf("1 ? 3 : 4 => %d\n", isel(1, 3, 4));
   printf("0 ? 3 : 4 => %d\n", isel(0, 3, 4));
   printf("-1 ? 3 : 4 => %d\n", isel(-1, 3, 4));
   return 0;
}

В этом коде предполагается, что смещение вправо чисел со знаком будет расширяться со знаком, а размер size (int) == 4. Некоторые процессоры могут выполнять isel () как инструкцию по сборке. Тем не менее, оба значения будут оценены, что троичный?: Не делает.

В зависимости от ситуации, компилятор, как правило, пытается делать самые быстрые действия: либо ветвление, чтобы избежать избыточных вычислений, либо выполнение такой логики, если значения в троичном выражении простые.

1 голос
/ 28 февраля 2011

Компиляторы C создают ветви из троичных операторов.

Используя IDE Freescale Codewarrior, я скомпилировал следующую программу C:

int a, b, q, r;    
void main(void) {    
  a = 0;    
  b = 1;    
  q = 0;    
  r = q ? a : b;    
..
..    
}

Сборка, соответствующаятроичное утверждение выглядит следующим образом:

...
LDX    0x1104 ; load val[q] into register x    
BNE    *+4    ; branch to abs addr 0xC016 if val[q]==a    
BRA    *+5    ; branch to abs addr 0xC019 if val[q]!=a
...
...