16bitx16bit-multiplikation mit c166(16bit-Mikrokontroller)

R

Robert Theiß

Guest
Nabend,
eigentlich sollte sich meine Frage an ein C166-Forum richten, aber ich hab
nur ein schlecht besuchtes gefunden.
Ich möchte 2 signed int's miteinander multiplizieren und das ergebnis auf
einem signed long abspeichern.
Dabei kommt immer grober Mist raus :(

C-code:
signed long a;
a = (-32666*32666);

das ergebnis ist dann -10404

Riecht ein wenig nach einem Overflow was aber eigentlich nich sein sollte,
denn ein signed int hat 15Bits für den Betrag und 1 Vorzeichen-Bit
=>
(1VZ-Bit, 15BetragBits)*(1VZ-Bit, 15BetragBits) = (1VZ-Bit, 30BetragBits)
ein signed long hat 1VZ-Bit und 31BetragBits sollte also kein Stress geben.


Hat wer ne Ahnung was ich da falsch mache? Bei manchen Sachen spinnt auch
der Keil-Compiler aber meistens mach schon ich die Fehler :)
Ich sag mal danke fürs durchlesen,

Robert

PS: Wenn jemand gute C166-Foren kennt, würde ein Link vielleicht auch
weiterhelfen.
 
"Robert Theiß" <Robert.Theiss@RWTH-Aachen.de> schrieb im Newsbeitrag
news:bukm1j$b80$1@nets3.rz.RWTH-Aachen.DE...
Hab's gefunden :)
mann muss die signed ints zuvor als long declarieren:

signed int a, b;
signed long c;
a = -30000;
b = 20000;
a = (long)a*(long)b;

dann passts :)

Hab bestimmt 3 Stunden nach gesucht!
Trotzdem Dankschön fürs Durchlesen,
Robert
 
Robert Theiß wrote:

Nabend,

8snip]
Dabei kommt immer grober Mist raus :(

C-code:
signed long a;
a = (-32666*32666);

das ergebnis ist dann -10404

Riecht ein wenig nach einem Overflow
was aber eigentlich nich sein sollte,
denn ein signed int hat 15Bits für den Betrag und 1 Vorzeichen-Bit
[snip]
Robert
Hi Robert!

Mein Wissen ist da zwar schon etwas vebrlichen, aber ich glaube mich
duester
und schmerzhaft zu erinnern, dass es auch genau so sein soll.
Heisst: zwei 16Bit-Werte Multiplizieren gibt erstmal ein 16Bit
Resultat.
'cast'e doch mal eine Konstante :'(long)-32666*32666'
oder gib sie explizit als 32-Bit an: 32666L (war doch so,oder?)
oder weise sie erst einer long int Variablen zu
und multipliziere die Variable mit der Konstanten.
Die genaue Definition, wie der Compiler (dann hoffentlich) die Typen
konvertiert findet sich (wo sonst.. ;-) ) im K&R.

Kann sich ja aber mit ANSI-C alles geaendert haben..

Der Blick in's generierte Assemblerfile klaert recht schnell was der
Compiler wohl glaubt was Du mal gemeint haben koenntest.. ;-)

Viel Spass beim Probieren wuenscht
Detlef

Hmm, hoffentliche hab' ich den Newsreader ueberhaupt konfiguriert.. :)
--
Man ersetze das _dot_ in der Email gegen einen Punkt..
 
Casten heisst das also :)
Aber was heisst K&R ??
Ich bin, was das Programmieren angeht recht mäßig beflissen, so dass mich
ein Blick in das Assemblerfile eher verwirrt :)
Wenn ich da n Furz an Durchblick hätte, könnt ich die vom Hersteller zur
Verfügung gestellte Assembler-FastFourierTransformation nutzen/anpassen
(dafür brauchts den ganzen Aufwand) und müsste die nich selber schreiben -
schneller wär die bestimmt auch.
Zum Glück gibts pfiffige Leutchen, die andren gerne helfen, sonst hätt ich
warscheinlich keine Chance.
Dank Dir,
Robert
 
In <bukp6l$cbv$1@nets3.rz.RWTH-Aachen.DE> "Robert Theiß" wrote:
"Robert Theiß" <Robert.Theiss@RWTH-Aachen.de> schrieb im Newsbeitrag
news:bukm1j$b80$1@nets3.rz.RWTH-Aachen.DE...
Hab's gefunden :)
mann muss die signed ints zuvor als long declarieren:

signed int a, b;
signed long c;
a = -30000;
b = 20000;
a = (long)a*(long)b;

dann passts :)

Hab bestimmt 3 Stunden nach gesucht!
Trotzdem Dankschön fürs Durchlesen,
Robert
Mal abgesehen davon, dass Du wahrscheinlich c = (long)a*(long)b meinst
(nicht a), ist das wohl eine Eigenart deines Compilers. Der Type-Cast
sollte vorher und immer zum grösstmöglichen Typen gemacht. In Deinem
Fall, was sich auch leicht mit z.B. einem gcc verifizieren lässt, hätte
vor der eigentlichen Operation sowohl a wie auch b, auf den Typen 'signed
long' 'gecastet' werden müssen. Dies findest Du auch in der gängigen
C-Literatur so niedergeschrieben, allerdings sucht man in dem
ANSI-Standard von 1990 vergeblich nach einer Klarstellung des
Sachverhalts. Mit Deiner Definition stehst Du jedenfalls auf der sicheren
Seite, da alles klar definiert ist.

Hätte man das Verhalten mit gängigen C-Compilern verhindern wollen, also
einen Überlauf provozieren, hätte die Zeile c = (sigend int)(a*b) lauten
müssen.

Henry


--

----------------------------------------------------------------------
snail mail : Henry Koplien \|/
From the Center of Nowhere o(O O)o
---- eMail : Henry@NiKo-Internetpraesenz.de ----ooOo---(_)---oOoo-----
 
In <rmpkub.ncf.ln@192.168.1.5> Detlef Voss wrote:
Robert Theiß wrote:

Nabend,

8snip]
Dabei kommt immer grober Mist raus :(

C-code:
signed long a;
a = (-32666*32666);

das ergebnis ist dann -10404

Riecht ein wenig nach einem Overflow
was aber eigentlich nich sein sollte,
denn ein signed int hat 15Bits für den Betrag und 1 Vorzeichen-Bit
[snip]
Robert

Hi Robert!

Mein Wissen ist da zwar schon etwas vebrlichen, aber ich glaube mich
duester
und schmerzhaft zu erinnern, dass es auch genau so sein soll.
Heisst: zwei 16Bit-Werte Multiplizieren gibt erstmal ein 16Bit
Resultat.
'cast'e doch mal eine Konstante :'(long)-32666*32666'
oder gib sie explizit als 32-Bit an: 32666L (war doch so,oder?)
oder weise sie erst einer long int Variablen zu
und multipliziere die Variable mit der Konstanten.
Die genaue Definition, wie der Compiler (dann hoffentlich) die Typen
konvertiert findet sich (wo sonst.. ;-) ) im K&R.

Kann sich ja aber mit ANSI-C alles geaendert haben..

Der Blick in's generierte Assemblerfile klaert recht schnell was der
Compiler wohl glaubt was Du mal gemeint haben koenntest.. ;-)

Viel Spass beim Probieren wuenscht
Detlef

Hmm, hoffentliche hab' ich den Newsreader ueberhaupt konfiguriert.. :)
Wann und wie automatisch konvertiert wird, ist zumindest in dem 1990er
ANSI-Standard nicht vollständig beschrieben. Genaugenommen ist der zweite
arithmetische Ausdruck cl = a * b inkonsistent zu dem ersten cs = a * b,
wenn man berücksichtigt, dass bei cf = a / b keine Konvertierung bis zu
der Zuweisung stattfindet. Wäre diese konsequent vorher, müsste das
Ergebnis 1,5 sein.

Als Beispiel:

#include <stdio.h>

void main(void) {
signed short int a,b,cs;
signed long cl;
double cf;

a = -30000;
b = 20000;
cs = a * b;
cl = a * b;
cf = a / b;
printf("-> %d %ld %f\n", cs, cl, cf);
};

liefert:
-> -17920 -600000000 -1.000000

mit einem gcc 2.7.3. Von solchen netten Begebenheiten, gibt es mit
Library-Funktion noch mehr. (Schon mal sprintf(str, " %s concat %s", str,
"C-Hell") probiert, was im Kern ja auch nur eine Zuweisung mit einem
String ist?)

Henry

--

----------------------------------------------------------------------
snail mail : Henry Koplien \|/
From the Center of Nowhere o(O O)o
---- eMail : Henry@NiKo-Internetpraesenz.de ----ooOo---(_)---oOoo-----
 
Moin,

Mal abgesehen davon, dass Du wahrscheinlich c = (long)a*(long)b meinst
(nicht a), ist das wohl eine Eigenart deines Compilers. Der Type-Cast
sollte vorher und immer zum grösstmöglichen Typen gemacht.
"Eigenart" des Compilers nur in in der Form, daß Keil den Datentyp int
als 16bit festlegt (natürliche Größe für C166). Die C-Regel sagt aus,
daß eine 'integral promotion to int' mit kleineren numerischen
Datentypen (char, enum) vorgenommen wird. Danach wird mit int gerechnet.
Also ist int * int beim Keil in 16 bit zu rechnen und wird anschließend
in einen long konvertiert. Deshalb das falsche Ergebnis.
Wenn einer der Argumente ein long ist, wird eine 'integral conversion'
des kleineren Datentypen vorgenommen. Deshalb reicht es auch, nur ein
Argument auf long zu casten, deshalb sind folgende Ausdrücke gleich
c = (long)a * b;
c = a * (long)b;
c = (long)a * (long)b;

- Heinz
 
Robert Theiß schrieb...
Casten heisst das also :)
Aber was heisst K&R ??
K&R steht für die Autoren von C, Brian Kerninghan und Dennis Ritchie.
Ist sozusagen die Bibel für C.

- Heinz
 
schrieb...
mit einem gcc 2.7.3. Von solchen netten Begebenheiten, gibt es mit
Library-Funktion noch mehr. (Schon mal sprintf(str, " %s concat %s", str,
"C-Hell") probiert, was im Kern ja auch nur eine Zuweisung mit einem
String ist?)
Es ist eben keine Zuweisung an str, sondern an den Speicherbereich, auf
den str zeigt! Die Arrays sind in C eben keine vollwertigen Datentypen
und lassen sich nicht an Funktionen übergeben. Schön ist z.B. das:

void Func(char arg[10]) {
printf("%d\n", sizeof(arg));
}

char array[10];
int main() {
printf("%d\n", sizeof(array));
Func(array);
}

Ergibt 10 und 2/4(je nach Datentypgröße für Pointer), aber nicht 10 10,
wie leicht wäre.

- Heinz
 
In <MPG.1a78588fd9e579119896e4@news.arcor.de> Heinz Saathoff wrote:
Moin,

Mal abgesehen davon, dass Du wahrscheinlich c = (long)a*(long)b
meinst
(nicht a), ist das wohl eine Eigenart deines Compilers. Der Type-Cast
sollte vorher und immer zum grösstmöglichen Typen gemacht.

"Eigenart" des Compilers nur in in der Form, daß Keil den Datentyp int
als 16bit festlegt (natürliche Größe für C166). Die C-Regel sagt aus,
daß eine 'integral promotion to int' mit kleineren numerischen
Datentypen (char, enum) vorgenommen wird. Danach wird mit int
gerechnet.
Also ist int * int beim Keil in 16 bit zu rechnen und wird anschließe
nd
in einen long konvertiert. Deshalb das falsche Ergebnis.
Das stimmt, darin ist der Standard auch defniert, aber Keil beginnt
bereits mit einem int, so dass hier die 'integral promotion to int' nicht
greift, oder habe ich was übersehen? Ich muss bei mir short int nehmen,
um sicherzugehen, dass es 16bit sind, aber egal ob short, int, oder long,
da sollte nix zu int konvertiert werden. Das Problem ist ganz einfach,
dass sich der Standard zu dem Thema überhaupt nicht auslässt, genauso
wenig, wie z.B. die Ausführungsreihenfolge definiert ist. Bei (a+b) +
(c+d) hat der Compiler freie Entscheidung ob zuerst a+b berechnet wird,
oder c+d. Früher war es sogar erlaubt, dass der Compiler die
arithmetischen Ausdrücke umstellen durfte, denn jedem ist klar das obiger
Ausdruck mathematisch gleich a + (b+c) +d ist. Dies ist inzwischen aus
gutem Grund untersagt, da durch Darstellungsungenauigkeiten bei der
Umformung völlig verschiedene Ergebnisse resultieren können.

Henry

--

----------------------------------------------------------------------
snail mail : Henry Koplien \|/
From the Center of Nowhere o(O O)o
---- eMail : Henry@NiKo-Internetpraesenz.de ----ooOo---(_)---oOoo-----
 
In <MPG.1a785bfc3e2495469896e6@news.arcor.de> Heinz Saathoff wrote:
schrieb...
mit einem gcc 2.7.3. Von solchen netten Begebenheiten, gibt es mit
Library-Funktion noch mehr. (Schon mal sprintf(str, " %s concat %s",
str,
"C-Hell") probiert, was im Kern ja auch nur eine Zuweisung mit einem
String ist?)

Es ist eben keine Zuweisung an str, sondern an den Speicherbereich, auf
den str zeigt! Die Arrays sind in C eben keine vollwertigen Datentypen
Ja, gut stimmt, aber trotzdem und? Es gibt Compiler, ich meine Borland
machte das, die sicherstellen, dass sich die Speicherbereiche nicht üb
erschreiben, wahrscheinlich vorher auf dem Stack 'realen' Platz geschaft.
Das macht die ganze Angelegenheit vielleicht langsamer, aber dafür
sicher. Da ja in C so ziemlich alles erlaubt ist, sollte ich mir meine
Variable für die Zuweisung schon genau anschauen (Die Zuweisungen gehen
ja auch innerhalb der arithmetischen Ausdrücke, z.B. e = (a + (b=c)) +
(b+d), was außerdem vom Ergebnis völlig Compiler-Abhängig ist). Es gibt
noch ohne Ende Unzulänglichkeiten in der Sprachdefinition und
Library-Funktionen, die aber nicht in dse gehören.

und lassen sich nicht an Funktionen übergeben. Schön ist z.B. das:

void Func(char arg[10]) {
printf("%d\n", sizeof(arg));
}

char array[10];
int main() {
printf("%d\n", sizeof(array));
Func(array);
}

Ergibt 10 und 2/4(je nach Datentypgröße für Pointer), aber nicht 10 10,
wie leicht wäre.

- Heinz
Wobei obiges Beispiel auch nett ist, aber sich definiert verhält :)

Henry

PS: Vielleicht noch mal als kleiner C-Wahnsinn zum Abschluss was alles
geht, -und nett anzuschauen ist es auch ;-)
Folgendes mal duch eine C-Mühle drehen und ausführen (keine Angst beisst
nicht, auch wenn es so aussieht!)

/* Should I have one? Yeah! All messed up! */ float R, y=1.5, x, r, A,
P,B;
int u, h=80, n=80,s;main(c,v)int c;char **v;
{s=(c>1?(h=atoi(v[1])):h)*h/2;
for(R=6./h;s%h||(y-=R,x=-2),s;4<(P=B*B)+(r=A*A)|++u==n&&putchar(*(((--s%
h)?
(u<n?--u%6:6):7)+"World! \n"))&&(A=B=P=u=r=0,x+=R/2))
A=B*2*A+y,B=P+x-r;}/*

Relax...
*/

--

----------------------------------------------------------------------
snail mail : Henry Koplien \|/
From the Center of Nowhere o(O O)o
---- eMail : Henry@NiKo-Internetpraesenz.de ----ooOo---(_)---oOoo-----
 
schrieb...
Das stimmt, darin ist der Standard auch defniert, aber Keil beginnt
bereits mit einem int, so dass hier die 'integral promotion to int' nicht
greift, oder habe ich was übersehen?
Nei, korrekt. Integral promotion ist nur von kleineren Datentypen zu int
vorgesehen. Da der OP gleich int's hatte, greift dies nicht.

Ich muss bei mir short int nehmen,
um sicherzugehen, dass es 16bit sind, aber egal ob short, int, oder long,
da sollte nix zu int konvertiert werden. Das Problem ist ganz einfach,
dass sich der Standard zu dem Thema überhaupt nicht auslässt
Ich habe nun leider den aktuellen C-Standard nicht greifbar, aber den
C++ Standard. Dort sind die Regeln für integral promotion und conversion
genau spezifiziert. So werden char und short in Ausdrücken zu int
promoted.
Ein long wird aber _nicht automatisch_ zu int, aber ein int _kann_
automatisch zu long konvertiert werden.

Wie Du schon anmerktest, sollten weiter Diskussionen zu C besser in
de.comp.lang.c fortgesetzt werden.


- Heinz
 
Am Wed, 21 Jan 2004 09:51:47 +0000 schrieb Henry:

/* Should I have one? Yeah! All messed up! */ float R, y=1.5, x, r, A,
P,B;
int u, h=80, n=80,s;main(c,v)int c;char **v;
{s=(c>1?(h=atoi(v[1])):h)*h/2;
for(R=6./h;s%h||(y-=R,x=-2),s;4<(P=B*B)+(r=A*A)|++u==n&&putchar(*(((--s%
h)?
(u<n?--u%6:6):7)+"World! \n"))&&(A=B=P=u=r=0,x+=R/2))
A=B*2*A+y,B=P+x-r;}/*

Relax...
*/
Das ist aber reichlich geschludert programmiert:

~# gcc -Wall -ansi -o chaos chaos.c
chaos.c:3: Warnung: return type defaults to `int'
chaos.c: In function `main':
chaos.c:4: Warnung: implicit declaration of function `atoi'
chaos.c:4: Warnung: operation on `h' may be undefined
chaos.c:5: Warnung: suggest parentheses around comparison in operand of |
chaos.c:5: Warnung: implicit declaration of function `putchar'
chaos.c:8: Warnung: control reaches end of non-void function

Probier doch mal den hier:

#include <stdio.h>

main(t,_,a)
char *a;
{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
main(-86, 0, a+1 )+a)):1,t<_?main(t+1, _, a ):3,main ( -94, -27+t, a
)&&t == 2 ?_<13 ?main ( 2, _+1, "%s %d %d\n" ):9:16:t<0?t<-72?main(_,
t,"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+\
,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/\
+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){n\
l]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#\
n'wk nw' iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;\
#'rdq#w! nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/")
:t<-50?_==*a ?putchar(a[31]):main(-65,_,a+1):main((*a == '/')+t,_,a\
+1 ):0<t?main ( 2, 2 , "%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc \
i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}

Kompiliert mit lediglich einer Warnung (gcc 3.3, -Wall -ansi)
und ist vom Ergebnis her noch deutlich beeindruckender...

MfG
Jan

--
Jan Reucker
email: jan dot reucker at web dot de
web: http://www.reucker-online.de
 
Am Wed, 21 Jan 2004 02:52:51 +0100 schrieb Robert Theiß:

Hat wer ne Ahnung was ich da falsch mache? Bei manchen Sachen spinnt auch
der Keil-Compiler aber meistens mach schon ich die Fehler :)
Ich sag mal danke fürs durchlesen,
Was falsch laufen kann wurde im Thread ja schon lang und
breit besprochen. Vielleicht noch eine Anregung: Bietet der Keil
vielleicht auch intrinsische C-Funktionen, die direkt auf
die MUL/DIV-Anweisungen des C16x umgesetzt werden? Das kenne
ich vom Tasking-Compiler. Ist zwar nicht portabel, aber man
weiss an der Stelle dann wenigestens genau, wieviel Bits mit
wieviel Bits multipliziert werden und was als Ergebnis dabei
herauskommt.

MfG
Jan

--
Jan Reucker
email: jan dot reucker at web dot de
web: http://www.reucker-online.de
 
Jan Reucker <valid.but.only.for.spam@gmx.net> schrieb:
Am Wed, 21 Jan 2004 09:51:47 +0000 schrieb Henry:

Kompiliert mit lediglich einer Warnung (gcc 3.3, -Wall -ansi)
und ist vom Ergebnis her noch deutlich beeindruckender...
Naja, Schönheitspreise gibt's für's Ergebnis nicht fürs Compilieren
und so *richtig beeindruckend* ist wohl das:

long
h[4];E[80],S;t(){signal(14,t);if(S)longjmp(E,1);}c,d,l,v[]={(int)t,0,2},
w,s,I,K=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1
,
9,-1,1,12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,1
3,
10,-12,1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16
,
-11,-12,12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=
q)-Q){Q=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28)
;
printf("\033[%dm "+(K-k?0:5),k);K=k;}alarm(1);Q[263]=c=((S=1)&&!setjmp(E))?
getchar():-1;alarm(0);}G(b){for(i=4;i--;)if(q[i?b+n:b])return 0;return
1;}
g(b){for(i=4;i--;q[i?x+n:x]=b);}main(C,V,a)char**V,*a;{for(a=C>2?V[2]:
"jkl pq";i;i--)*n++=i<25||i%12<2?7:0;srand(getpid());system("stty
raw -echo");
signal(14,t);t();puts("\033[H\033[J");for(n=f+rand() %7*4;;g(7),u(),g(0)){if
(c<0){if(G(x+12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j]
;)
if(j%12==10){for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%
7
*4;G
(x=17)||(c=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m
);if(c==a[2])G(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[
5])
{printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=0);
while(getchar()-a[4]);puts("\033[H\033[J\033[7m");}}system("stty cooked
echo");
d=popen("cat - HI|sort -rn|sed -n 1,20p>/tmp/$$;mv /tmp/$$ HI;cat HI","w");
fprintf(d ,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}

Ach so, j,k,l und space zum steuern, q to quit.

Have fun,
Gerd
 
Gerd Kluger <gerd.kluger@sap-ag.de> schrieb:

.... ein gar grauslich durch Zeilenumbruch zerstückeltes Programm ....

So ist's hoffentlich besser:

long h[4];E[80],S;t(){signal(14,t);if(S)longjmp(E,1);}c,d,l,v[]={(int)t,0,2},
w,s,I,K=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,
9,-1,1,12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,
10,-12,1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,
-11,-12,12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=
q)-Q){Q=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);
printf("\033[%dm "+(K-k?0:5),k);K=k;}alarm(1);Q[263]=c=((S=1)&&!setjmp(E))?
getchar():-1;alarm(0);}G(b){for(i=4;i--;)if(q[i?b+n:b])return 0;return 1;}
g(b){for(i=4;i--;q[i?x+n:x]=b);}main(C,V,a)char**V,*a;{for(a=C>2?V[2]:
"jkl pq";i;i--)*n++=i<25||i%12<2?7:0;srand(getpid());system("stty raw -echo");
signal(14,t);t();puts("\033[H\033[J");for(n=f+rand() %7*4;;g(7),u(),g(0)){if
(c<0){if(G(x+12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)
if(j%12==10){for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7
*4;G (x=17)||(c=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m
);if(c==a[2])G(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5])
{printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=0);
while(getchar()-a[4]);puts("\033[H\033[J\033[7m");}}system("stty cooked echo");
d=popen("cat - HI|sort -rn|sed -n 1,20p>/tmp/$$;mv /tmp/$$ HI;cat HI","w");
fprintf(d ,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}

Gruß
Gerd
 
In <pan.2004.01.23.18.22.16.596685@gmx.net> Jan Reucker wrote:
[..]
Das ist aber reichlich geschludert programmiert:

~# gcc -Wall -ansi -o chaos chaos.c
chaos.c:3: Warnung: return type defaults to `int'
chaos.c: In function `main':
chaos.c:4: Warnung: implicit declaration of function `atoi'
chaos.c:4: Warnung: operation on `h' may be undefined
chaos.c:5: Warnung: suggest parentheses around comparison in operand of
|
chaos.c:5: Warnung: implicit declaration of function `putchar'
chaos.c:8: Warnung: control reaches end of non-void function
Lief selbst mit den nicht gewollten Zeilenumbrüchen ohne eine Warnung
durch den gcc 2.7.3.
;-)


Probier doch mal den hier:
[..]

Hab ich, gefällt auch... (und wandert in meine Sammlung von abstrusen
C-Programmen)

Henry
--

----------------------------------------------------------------------
snail mail : Henry Koplien \|/
From the Center of Nowhere o(O O)o
---- eMail : Henry@NiKo-Internetpraesenz.de ----ooOo---(_)---oOoo-----
 
In <bus46u$l41$1@news1.wdf.sap-ag.de> "Gerd Kluger" wrote:
Gerd Kluger <gerd.kluger@sap-ag.de> schrieb:

... ein gar grauslich durch Zeilenumbruch zerstückeltes Programm ....

So ist's hoffentlich besser:

long
h[4];E[80],S;t(){signal(14,t);if(S)longjmp(E,1);}c,d,l,v[]={(int)t,0,2},

w,s,I,K=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-1
2,-1,
9,-1,1,12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12
,1,13,
10,-12,1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,1
2,16,
-11,-12,12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if
((k=
q)-Q){Q=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2

+28);
printf("\033[%dm
"+(K-k?0:5),k);K=k;}alarm(1);Q[263]=c=((S=1)&&!setjmp(E))?
getchar():-1;alarm(0);}G(b){for(i=4;i--;)if(q[i?b+n:b])return
0;return 1;}

g(b){for(i=4;i--;q[i?x+n:x]=b);}main(C,V,a)char**V,*a;{for(a=C>2?V[2]:
"jkl pq";i;i--)*n++=i<25||i%12<2?7:0;srand(getpid());system("stty raw
-echo");
signal(14,t);t();puts("\033[H\033[J");for(n=f+rand()
%7*4;;g(7),u(),g(0)){if

(c<0){if(G(x+12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[

++j];)
if(j%12==10){for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+ran
d()%7
*4;G
(x=17)||(c=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n
=m
);if(c==a[2])G(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c
==a[5])
{printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]
=0);
);puts("\033[H\033[J\033[7m");}}system("stty cooked
echo");
d=popen("cat - HI|sort -rn|sed -n 1,20p>/tmp/$$;mv /tmp/$$ HI;cat
HI","w");
fprintf(d ,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}

Gruß
Gerd
OK, das sieht nach dem Gewinner aus ;-). Vielleicht noch der Zusatz, dass
es sich um ein VT100-Terminal handeln sollte, oder? Bin mir allerdings da
noch nicht mal sicher bei dem Code. Der Clou ist ja sogar, dass das
spielbar ist.

Henry


--

----------------------------------------------------------------------
snail mail : Henry Koplien \|/
From the Center of Nowhere o(O O)o
---- eMail : Henry@NiKo-Internetpraesenz.de ----ooOo---(_)---oOoo-----
 
<Henry@Koplien.de> schrieb:

OK, das sieht nach dem Gewinner aus ;-). Vielleicht noch der Zusatz, dass
es sich um ein VT100-Terminal handeln sollte, oder? Bin mir allerdings da
noch nicht mal sicher bei dem Code. Der Clou ist ja sogar, dass das
spielbar ist.
Ja, VT100. Es ist übrigens nicht nur spielbar, sondern auch unterschiedlich
konfigurierbar (z.B. drop speed, Belegung der Steuerungstasten ...)
Als Krönung dann noch die Verwaltung der High-Scores :)

Gruß
Gerd
 
... ein gar grauslich durch Zeilenumbruch zerstückeltes Programm ....
Hallo,

was sagt Du dann erst zu einem 'normal' aussehendem Quelltext? Der ja
vergleichsweise strotzt vor lauter Zeilenumbrüchen?

Sich schmunzelnd fragend - und nicht widerstehen könnend - Peter

--
Für Privat-Email bitte Betreff mit "Usenet-Reh" beginnen lassen.
 

Welcome to EDABoard.com

Sponsor

Back
Top