Sida 1 av 3

sanningstabell => C-kod

Postat: 22 mars 2010, 14:31:07
av jesse
jag har tre booleska variabler, A, B och C (egentligen unsigned char).

På grund om dessa är sanna eller falska (1 eller 0) så skall resultatet bli:

Kod: Markera allt

A B C     X
0 0 0     x
0 0 1     x
0 1 0     1
0 1 1     1
1 0 0     0
1 0 1     0
1 1 0     0
1 1 1     1
Egentligen ska "svaret" inte vara i form av en variabel utan skall vara del i en if-sats där en sats utförs om X = 1.

Hur formulerar jag denna funktion effektivast i C ?

(då A och B båda är noll är resultatet irrelevant eftersom denna situation ej kan uppstå, därför ett "x" i resultatet)

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 14:51:18
av sodjan
En "brute force" lösning är ju enkel att fixa, men du kanske
var mer ute efter en smart lösning (om det finns någon...) ?

Kod: Markera allt

if ( (!A and B and !C) or  (!A and B and C) or (A and B and C) )
    do-something;
else
    do-something-else;
Kan nog förenklas till :

Kod: Markera allt

if ( (!A and B and !C) or  (B and C) )
    do-something;
else
    do-something-else;
Om både B och C är "1" så ska det ju det hela vara sant...

Även detta borde fungera :

Kod: Markera allt

if ( (!A and !C) or  (B and C) )
    do-something;
else
    do-something-else;
Om både A och C = "0" så spelar inte B någon roll...

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 14:55:02
av E85
x = (a & b & c) | (~a & b);

Nånting sånt kanske. Har inte provat det och var ett tag sen jag programmerade C men principen borde vara rätt.

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:02:55
av jesse
har tänkt lite grann och tror att detta kanske är den enklaste lösningen, (om jag nu inte gjort fel):

Kod: Markera allt

if (C && B || B && !A) { sats; };
Det inte går att förenkla vidare så att B bara finns med en gång?

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:07:03
av E85
Du får nog jobba lite på prioritetsordningen där men det är sant att A inte behöver vara med i första som jag gjorde...

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:08:18
av sodjan
> Det inte går att förenkla vidare så att B bara finns med en gång?

OK, nu hänger jag inte med alls. Är det inte så i mitt sista förslag ?

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:15:30
av Icecap

Kod: Markera allt

if(!A)
  {
  return(B);
  }
else
  {
  if(B && C) return(true);
  else return(false);
  }

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:17:59
av 4kTRB
Nu var det längesedan jag skrev program i C men det här får jag som resultat
när Logic Friday genererar C-kod...

Kod: Markera allt

/*
 lookup.c
 Generated by Logic Friday on Mon Mar 22 15:15:51 2010
*/

int lu_F0( int A, int B, int C );

int lu_F0( int A, int B, int C )
{
	const unsigned int nOutAry[] =
	{0XF1000000};

	unsigned int nTerm=0, nX, nBit;

	if( A ) nTerm |= 1<<2;
	if( B ) nTerm |= 1<<1;
	if( C ) nTerm |= 1;
	nX = nTerm / 32;
	nBit = 31 - nTerm % 32;
	if( nOutAry[nX] & 1<<nBit )
		return 1;
	else
		return 0;
}
Kan det verka rimligt?


Ett annat alternativ...

Kod: Markera allt

/*
 lookup.c
 Generated by Logic Friday on Mon Mar 22 15:19:42 2010
*/

int lu_F0( unsigned int nTerm );

int lu_F0( unsigned int nTerm )
{
	const unsigned int nOutAry[] =
	{0XF1000000};

	unsigned int nX, nBit;

	nX = nTerm / 32;
	nBit = 31 - nTerm % 32;
	if( nOutAry[nX] & 1<<nBit )
		return 1;
	else
		return 0;
}

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:19:07
av E85
Nja det verkade väldigt omständigt, men icecaps förslag var nog bäst så slipper man beräkna allt varenda gång. :tumupp:

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:21:56
av sodjan
> ...så slipper man beräkna allt varenda gång.

Vad är "allt" ??

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:25:42
av E85
Nu vet jag inte exakt hur asm-koden kommer se ut men antar att den kollar minst A och C varje gång i din IF-sats men i icecaps räcker det i vissa fall att bara kolla A. Men det var bara ett antagande, sorry. edit: Nu såg jag dessutom att han returnerade B så det var ju inte riktigt som jag tänkt mig... man kan likaväl returnera true där eftersom dom två första inte spelar nån roll.

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:26:20
av 4kTRB
Vilket kommer gå snabbast?
Andra förslaget jag kom med verkar vid en snabb granskning kunna prestera bra?

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:33:33
av ahlsten
Är du helt säker på det? Modulo på en mikroprocessor i inbyggt system är nog inte jättesnabbt.
Läsbarheten var inte på top heller :(

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:36:43
av sodjan
> Nu vet jag inte exakt hur asm-koden kommer se ut...

Spelar det så väldigt stor roll igentligen ?
På dagens 3 GHz PC så blir det nog ingen större skillnad.
Eller gjorde du något annat antagande om plattform ??
Det finns inget i frågan som säger något om det...

Förslagen från 4kTRB orakar jag inte ens läsa. Andra får
ha synpunkter på dom...

> Modulo på en mikroprocessor i inbyggt system är nog inte jättesnabbt.

Tja, *om* det är ett "inbyggt system" det hela handlar om...

Re: sanningstabell => C-kod

Postat: 22 mars 2010, 15:37:54
av 4kTRB
Det kan säkert stämma då koden är för 32 bits.

Motsvarande för 8-bits kan passa bättre...

Kod: Markera allt

/*
 lookup.c
 Generated by Logic Friday on Mon Mar 22 15:36:11 2010
*/

int lu_F0( unsigned int nTerm );

int lu_F0( unsigned int nTerm )
{
	const unsigned int nOutAry[] =
	{0XF1};

	unsigned int nX, nBit;

	nX = nTerm / 8;
	nBit = 7 - nTerm % 8;
	if( nOutAry[nX] & 1<<nBit )
		return 1;
	else
		return 0;
}
Bör inte vara några problem att läsa om man dagligen mixtrar med C-kod tycker jag väl.