Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
26.01.2002, 10:10
CabaL



ich hoffe ich nerve euch nicht,indem ich hier ständig so scheiss fragen stelle. ich verstehe den unteren code nicht so ganz. ich weiss was er macht(dezimal in dualzahlen umwandeln),aber ich weiss nicht wieso. mir ist unverständlich was die schleife macht. was ich noch nicht verstehe ist, was das dez&(1<<i) macht. das & und das << sind mir völlig fremd.
bitte nicht hauen.
Quellcode:#include <stdio.h>
void main (void)
{
       int dez;
       int i;
       printf("\nBitte Geben sie eine Zahl zwischen 0-255 ein:");
       scanf("\n%d",&dez);
       printf("\n%d ist im Dualsystem:",dez);
       for (i=7;i>=0;i--)
       {
                if (dez&(1<<i)) printf("1");
                else
                printf("0");
       }

}

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.

zum Seitenanfang zum Seitenende Profil || Suche
001
26.01.2002, 11:52
Tron



wenn du die operatoren & und << nicht kennst, solltest du dir unbedingt ein gutes c(++) buch oder tutorial (z.b. www.cplusplus.com) besorgen.

& ist bitweises UND
<< ist bitweises shiften nach links

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
002
26.01.2002, 12:06
CabaL



was ist shiften?
um eine stelle nach links gehen (bits) ?

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.

zum Seitenanfang zum Seitenende Profil || Suche
003
26.01.2002, 12:07
CabaL



lol jo klar thx
ich hab ein tut und da wurden diese beiden operatoren nicht erklärt und deshalb fragte ich hier nach, ansonsten ist das tut aber ganz gut

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.

zum Seitenanfang zum Seitenende Profil || Suche
004
26.01.2002, 12:28
Tron



wenn ein tut so elementare operatoren nicht erklaert, dann kann es nicht gut sein...

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
005
26.01.2002, 12:30
CabaL



ne wahrscheinlich setzt es halt diese grundlegenden operatoren schon voraus...
[e]hmm bitweises und das hört sich strange an, was hat das für ne funktion?[/e]

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.


Dieser Beitrag wurde am 26.01.2002 um 13:03 von CabaL- bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
006
26.01.2002, 13:11
jannisch



hm..kleines beispiel:
Quellcode:
#include <iostream.h>
int x,y;

//cin für eingabe     ">>" bedeutet das die eingabe in x "reingeschoben" wird
cin >> x;
cin >> y;

//  && = logisches UND   also wenn x<=0 UND y<=0
if (x<=0 && y<=0)
// cout für ausgabe <<  bedeutet das das nachfolgende in die eingabe (cout) "reingeschoebn" wird
cout << "blablabal";
.
.
.

edit: super tuts auf www.thewall.de/coding !!!!

--

hm..d0n´t u know?
jannisch


Dieser Beitrag wurde am 26.01.2002 um 13:12 von jannisch bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
007
26.01.2002, 13:14
CabaL



ja schön das wusste ich vorher auch schon alles, das ist halt c++
cin und cout sind eh schwul, printf und scanf sind viel edler ;D

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.

zum Seitenanfang zum Seitenende Profil || Suche
008
26.01.2002, 13:50
dp
Administrator


wie wäre es mal mit einem topic welches das problem beschreibt? es heisst nicht umsonst topic/thema/subject . . .

--

zum Seitenanfang zum Seitenende Profil || Suche
009
26.01.2002, 13:52
CabaL



bin aber völlig unkreativ,sry ich wüsste nicht wie ich das topic formulieren sollt,aber immerhin kann man vom topic aus schliessen dass es um c geht *aufjannischschiel
@jannisch die tuts von thewall.de sind alle c++

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.


Dieser Beitrag wurde am 26.01.2002 um 13:54 von CabaL- bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
010
26.01.2002, 14:12
jannisch



jo des fällt mir jetzt erst auf @topic :D

--

hm..d0n´t u know?
jannisch

zum Seitenanfang zum Seitenende Profil || Suche
011
26.01.2002, 14:15
CabaL



:D lol

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.

zum Seitenanfang zum Seitenende Profil || Suche
012
27.01.2002, 00:01
thinktank



ALSO :

shiften heißt ja soetwas wie verschieben.

1 << i

00000001 wird um i (am Anfang = 1) nach links geshiftet

also ist das dann :

00000010

im dezimalsystem ist das dann : 2

wenn wir z.B. 6 eingegeben haben macht das wiederum :

00000110 & 0000010 = 00000010 , was wiederum als Ausdruck = true ist.

( zur Einfachheit habe ich jetzt ein int als 1 Byte geschrieben )
Alles klar ?

--

zum Seitenanfang zum Seitenende Profil || Suche
013
27.01.2002, 00:07
Archangel



Zitat:
jannisch postete
hm..kleines beispiel:
Quellcode:
#include <iostream.h>
int x,y;

//cin für eingabe     ">>" bedeutet das die eingabe in x "reingeschoben" wird
cin >> x;
cin >> y;

//  && = logisches UND   also wenn x<=0 UND y<=0
if (x<=0 && y<=0)
// cout für ausgabe <<  bedeutet das das nachfolgende in die eingabe (cout) "reingeschoebn" wird
cout << "blablabal";
.
.
.

edit: super tuts auf www.thewall.de/coding !!!!

da sieht man mal, welchen unsinn c++ verbreiten kann..
die operatoren << und >> sind bei den classes für cin/cout überladen, und haben NICHTS mehr mit ihrer ursprünglichen funktion zu tun!
<< verschiebt bits nach links, >> nach rechts
also:
int i = 5; // 5 binär: 00000101
(i << 1) ist also binär 00001010 // 10 dezimal
und
(i >> 1) ist binär 00000010 // 2 dezimal

(n << x) entspricht also n * x^2, (n >> x) also n / x^2

edit: ack thinktank hat ja das gleiche geschrieben.. naja den letzten teil hat er nich

--

Mar 01 01:10:13 <voice> jo
Mar 01 01:10:40 <voice> bis dann ^^
Mar 01 01:11:20 <Archangel> jo
**** ENDING LOGGING AT Tue Mar 1 01:58:13 2005


Dieser Beitrag wurde am 27.01.2002 um 00:08 von Archangel bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
014
27.01.2002, 09:37
Tron



Zitat:
Archangel postete
da sieht man mal, welchen unsinn c++ verbreiten kann..
die operatoren << und >> sind bei den classes für cin/cout überladen, und haben NICHTS mehr mit ihrer ursprünglichen funktion zu tun!

wieso unsinn? das ist ein sehr schoener syntax, besser als zig normale funktionsaufrufe hintereinander (jaja, ich weis... operatoren sind auch funtkionen)
und printf ist das allemal ueberlegen, da die c++-variante typensicherheit bietet

Zitat:

(n << x) entspricht also n * x^2, (n >> x) also n / x^2

shiften bildet eine expotientalfunktion, keine quadratische!
richtig waere:
n << x == n * (2 ^ x) und n >> x == n / (2 ^ x)
btw: du hast hier den ^ operator auch voellig anders 'ueberladen', ^ ist xor und nicht x hoch y (;

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
015
27.01.2002, 11:00
Archangel



hrm, ich meinte ja 2^x (5 * 1^2 ist ja nun nicht 10..)
ja, ^ ist XOR, aber wie würdest du das schreiben ? 2 hoch x sieht doch assig aus..

und:
//cin für eingabe ">>" bedeutet das die eingabe in x "reingeschoben" wird
// cout für ausgabe << bedeutet das das nachfolgende in die eingabe (cout)

is doch wirklich unsinn, das hilft CabaL- kein bisschen weiter...

--

Mar 01 01:10:13 <voice> jo
Mar 01 01:10:40 <voice> bis dann ^^
Mar 01 01:11:20 <Archangel> jo
**** ENDING LOGGING AT Tue Mar 1 01:58:13 2005

zum Seitenanfang zum Seitenende Profil || Suche
016
27.01.2002, 16:09
thinktank



Hmmm das versteh ich nicht ganz :

Zitat:

n << x == n * (2 ^ x) und n >> x == n / (2 ^ x)

Wie kann man sich das Multiplizieren auf Bit-Ebene vorstellen ?

--

zum Seitenanfang zum Seitenende Profil || Suche
017
28.01.2002, 01:12
Kriz



Ganz einfach:

nibble x = 1;

Ein Nibble ist ein halbes Byte, also 4 Bit =) Den Datentyp gibbet zwar in C/C++ nicht, aber egal. 1 ist binär = 0001.

x << 1;

Nun wird der binäre Inhalt um 1 Stelle nach links verschoben und defaultmäßig eine 0 rechts angehängt: 0010

So, jetzt ins Eingemachte =)

In der Informatik rechnet man Binärzahlen immer von RECHTS nach LINKS:

0 0 1 0 <-- Erstes Bit (0) an Position 0 (Position = Bitnummer-1)
0 0 1 <-- Zweites Bit (1) an Pos 1
0 0 <-- Drittes Bit (0) an Pos 2
0 <-- Letztes Bit (0) an Pos 3

Das Binärsystem baut auf Potenzen mit der Basis 2 auf:

2^x

Um den dezimalen Wert einer Binärzahl zu erfahren, ersetzt man das x mit der Position des Bits. Dann multipliziert man das Ergebnis mit 0 oder 1, je nachdem ob das Bit "gesetzt" (1) ist oder nicht (0). Anschließend bildet man die Summe aller Werte und man hat die Dezimalzahl:

erg = (0*2^3) + (0*2^2) + (1*2^1) + (0*2^0)
erg= (0*8) + (0*4) + (1*2) + (0*1)
erg = 0 + 0 + 2 + 0
erg = 2

Voilá =)

So wird also aus 0001 der Dezimalwert 1 und beim Linksschieben mit 1 eben der Wert 2. Und genau das ist eine Multiplikation mit 2:

Multiplikationswert = 2^Zahl

Wenn da stände x << 3, dann gäbe das eine Multiplikation mit 2^3 = 8. Und 1 * 8 ergibt 8, klar =)

Beweis:

0001 << 3 = 1000

erg = 1*2^3 + 0*2^2 + 0*2^1 + 0*2^0
erg = 8 + 0 + 0 + 0
erg = 8

Und genauso verhält es sich mit dem Rechtsschieben. Hier wird einfach der Binärwert um "Zahl" Stellen nach rechts verschoben. Alle Bits, die über die Position 0 gedrückt werden, gehen verloren. Allerdings liegt es im Ermessen des Compilers, ob er links eine 1 oder eine 0 reindrückt. Das ergibt 2 Fälle:

a)

x = 0001
x >> 1;
x = 0000 (die 1 wird nach rechts weggeschoben)

b)

x = 0001
x >> 1;
x = 1000 (die 1 wird nach rechts weggeschoben)

Der Haken ist der, daß nach dem Zweierkomplement (die Methode, mit der man negative und positive Ganzzahlen im Rechner darstellt) das letzte Bit einer Binärzahl (also das ganz linke Bit, denn wir zählen ja von rechts nach links durch) bei signed Datentypen als Kennzeichen für eine negative Zahl arbeitet.

signed Datentypen (negativ/positiv):

1111 = -8
1110 = -7
1101 = -6
1100 = -5
1011 = -4
1010 = -3
1001 = -2
1000 = -1
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7

PS: Das erklärt auch, warum positive Zahlen bei signed Datentypen immer um 1 Wert kleiner sind als ihre negative Pedanten =)

unsigned Datentypen (nur positiv):

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = 10
1011 = 11
1100 = 12
1101 = 13
1110 = 14
1111 = 15

So, wenn nun beim einfachen Rechtschieben (x >> 1) einer SIGNED Zahl der Compiler eine 0 anhängt, dann wird aus 0001 (1) eben 0000 (0). Hängt er aber eine 1 links an, dann wird aus 0001 (1) eben 1000 (-1).

Bei UNSIGNED Zahlen ist es einfacher:

0001 (1) -> 0000 (0)
oder
0001(1) -> 1000 (8)

Da können schon wilde Sachen passieren =)

Cu

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
018
28.01.2002, 07:44
Tron



eine kleine ergaenzung zu Kriz:
ob beim rechtsschieben eine 1 oder eine 0 angefuegt wird ist NICHT compilerabhaengig, sondern:
wenn es ein unsigned datentyp ist wird immer eine 0 angefuegt (wie Kriz gesagt hat)
wenn es ein signed datentyp ist wird wenn die zahl vorher positiv war (hoechtes bit 0) wird auch eine 0 angefuegt
war sie negativ (hoechstes bit 1) wird eine 1 agefuegt

damit kann man generell sagen x >> y dividiert x durch (2 ^ y) und dabei wird gegen minus undendlich gerundet
3 >> 1 == 1
1 >> 1 == 0
aber
-3 >> 1 == -2
-1 >> 1 == -1

--

'KEINE PANIK' - aus der Triologie in fuenf Baenden von Douglas Adams

'FÜR DEINN FERD' - aus 'Gevatter Tod' von Terry Pratchett

zum Seitenanfang zum Seitenende Profil || Suche
019
28.01.2002, 13:37
Kriz



Nee nee, Tron, so einfach ist das nicht mit dem "ist festgelegt, ob 1 oder 0"... Schön wäre es, aber dieses Verhalten ist wirklich Compilerabhängig, auch wenn nicht gerne darüber geschrieben oder gesprochen wird.

Wenn es nach den Datentypen geht, dann ist das im Prinzip ein "nettes Geschenk" des Compilerentwicklers. Es gibt tatsächlich keine Vorschrift die besagt, ob beim Rechtsschieben 0 oder 1 kommt. Das finde ich zwar auch unverschämt, aber es ist nunmal so. Allerdings ist dieses Verhalten aus alten Compilertagen und moderne Compiler werden sicherlich den verwendeten Datentyp als Referenz heranziehen.

Folgender Code in VC++ 6.0:
Quellcode:typedef unsigned char UBYTE;
typedef signed char BYTE;

// Unsigned Rechtsschieben

UBYTE x = 255; // Maximalwert für UBYTE
UBYTE y = x >> 1; // 1 Stelle nach rechts schieben

cout << "UNSIGNED: x = " << (int)x << " und y = " << (int)y << endl;

// Signed Rechtsschieben, positiv

BYTE a = 127; // Maximal pos
BYTE b = a >> 1;

cout << "SIGNED POS: a = " << (int)a << " und b = " << (int)b << endl;

// Signed Rechtsschieben, negativ

a = -128; // Maximal neg
b = a >> 1;

cout << "SIGNED NEG: a = " << (int)a << " und b = " << (int)b << endl;

Ergebnis:

UNSIGNED: x = 255 und y = 127
SIGNED POS: a = 127 und b = 63
SIGNED NEG: a = -128 und b = -64

Hm, komisch wah? Wieso? Also:

UNSIGNED: x = 255 und y = 127

Das ist soweit alles richtig. 255 ist binär 11111111, einen nach rechts und wir haben 01111111 = 127. Bei unsigned fügt der Compiler von VC++ eine 0 vorne dran.

SIGNED POS: a = 127 und b = 63

127 ist binär 01111111 nach dem Zweierkomplement. Einen nach rechts: 00111111 = 63. Bei signed fügt der Compiler eine 0 vorne dran. Jetzt könnte man meinen, da das Vorzeichenbit eine 0 war, ist auch das angefügte Bit eine 0, oder? Abwarten:

SIGNED NEG: a = -128 und b = -64

-128 ist binär 11111111 nach dem Zweierkomplement. Einen nach rechts: 10111111 = -64. Hmmmmmm... Komisch..... hrhrhrhr. Ginge man nach deiner Theorie, dann war das Vorzeichenbit eine 1 und der Compiler müßte auch eine 1 dranhängen. Hat er aber nicht, denn dann würde nur Scheiße rauskommen:

11111111 = -128
>> 1
11111111 = -128

Das wäre fatal, oder?

Der Compiler weiß zwar, daß es sich um eine negative Zahl handelt infolge des Vorzeichenbits, aber er muß nun schlau rechnen. Da bei einer negativen Zahl das Vorzeichenbit FIX ist und sich solange nicht ändert wie die Zahl im allgemeinen einen negativen Wert besitzt, ist das letzte Bit für den Compiler völlig schnurze. Er beschäftigt sich daher mit dem vorletzten Bit und dort hat er auf Teufel komm raus auch eine 0 angefügt und keine 1 !!!

1|1111111 = -128
1|0111111 = -64

Du siehst, Tron, der Compiler fügt auch hier eine 0 ein anstatt eine 1 von vorne. Nur ist dieses Verhalten eben nicht grundlegend vorgeschrieben. Das der VC++ sich so korrekt verhält, ist eine Beigabe der Entwickler. Das muß nicht heißen, daß alle Compiler so reagieren. Aber so wie in diesem Beispiel ist es mathematisch und informatisch korrekt.

Trotzdem danke für den Hinweis =)

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
020
28.01.2002, 14:29
Prefect



Ich fürchte, zu viel C++, RAD, und so bekommen einem Programmierer ganz und gar nicht gut.

Du hast leider bei der Darstellung von negativen Zahlen total daneben gelangt. Wenn wir von einem char ausgehen (also vorzeichenbehafteter Bytewert), dann gilt:

00000000 == 0
00000001 == 1

10000000 == -128
10000001 == -127
11000000 == -64
11111111 == -1

Damit ist auch erklärt, warum (unsigned)-1 == 0xffffffff (eine absolute Notwendigkeit, was Bitoperationen angeht). Zudem werden gerade dadurch simple mathematische Vorgänge einfach gemacht, genauso wie Timewindows (nur so ist es möglich, daß auch ein 32Bit-Millisekundentimer überläuft, öhne das man Schaden davonträgt).

Und das mit dem Shifting ist durchaus so, wie Tron es gesagt hat - zumindest auf i386-Architekturen - man lese dazu auch die Beschreibung von SHL/SHR vs. SAL/SAR.

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
021
28.01.2002, 15:37
Kriz



Fuck, das ist mir jetzt echt peinlich (habe hier zwei Zettel, eines mit den korrekten Bitsets und eines, wo uns damals der Prof gefaked hatte). Prefect hat gottseidank recht. Na, wenigstens gebe ich meinen Fehler zu und hier seht ihr auch warum:Quellcode:
NIBBLE x = 4;

x := 0100

~x; // Einerkomplement bilden, negieren

x := 1011 (-5)

++x; // 1 addieren

x :=  1100; (-4)

Durch das Zweierkomplement bekommt man das negative Bitset einer Zahl. Man muß natürlich wissen, ob man mit signed oder unsigned Datentypen rechnet, sonst wird die Sache witzlos.

Quellcode:BYTE x = 127;

x := 01111111

~x;

x := 10000000 (-128)

++x;

x := 10000001 (-127)

Tja, ich glaube, diesen Fakezettel lasse ich gleich mal in der Tonne verschwinden...

Cu

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)

zum Seitenanfang zum Seitenende Profil || Suche
022
28.01.2002, 16:09
CabaL



omg?!
mal so ne frage: wie lange programmiert ihr schon kriz und prefect? und wie alt seid ihr?

--

..::I've carved my soul to shreds in service of the Cabal. What little humanity I retain is corrupted by the Beast, which has grown stronger with every life I've taken::.

zum Seitenanfang zum Seitenende Profil || Suche
023
28.01.2002, 17:42
thinktank



Also so genau wollte ichs gar nicht wissen :D. Ne wirklich : Was ihr euch Mühe macht, uns hier so was zu erklären *klatsch*.

Naja Cabal , da Kriz von einem Prof spricht, Profs normalerweise in Unis sind und Studenten normalerweise über 18 sind .........

Von Prefect habe ich keine Ahung ausser, dass er mehr Code als Text schreibt :). Hab ich jetzt nicht gut genug mitgelesen ? Warum ist das denn so :

BYTE x = 127;
x == 01111111; // Ich dachte 2 hoch 7 sei = 128

Was ist jetzt richtig ?

Das erste Bit gibt das Vorzeichen an oder nicht ?

--


Dieser Beitrag wurde am 28.01.2002 um 17:48 von thinktank bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche
024
28.01.2002, 19:14
Kriz



BYTE ist signed, also negative und positive Werte. Wenn ein Datentyp signed ist, dann ist das linke Bit das Vorzeichenbit. 0 = positiv, 1 = negativ. Daher ist 01111111 der maximale positive Wert = (2^7)-1, also 127. Der maximale negative Wert ist dann -(2^7), also -128.

PS: Das "erste" Bit ist immer das rechte Bit, da man die Bits von rechts nach links durchnummeriert.

--

K:R-I)Z++
"CSS ist cascading style sheets. Und nicht so'n Ranzspiel." - dp
In memory of Voice († 2005/03/30)


Dieser Beitrag wurde am 28.01.2002 um 19:15 von Kriz bearbeitet.
zum Seitenanfang zum Seitenende Profil || Suche