Kannst du evt. noch ein bisschen weiter in das (<<<) eingehen.
Welche Möglichkeiten hat man damit?
Wozu benutzt man es nun eig.?
Vielen dank schonmal.
Kannst du evt. noch ein bisschen weiter in das (<<<) eingehen.
Welche Möglichkeiten hat man damit?
Wozu benutzt man es nun eig.?
Vielen dank schonmal.
Ärgerlich,da hatte ich den Post schon fast fertig und drück auf "Vorschau", da bin ich nicht mehr angemeldet ...
Bit-Shiften / Bitverschiebung benutzt man, um wie der Name schon sagt Bits zu verschieben.
Bei Wikipedia ist das ganz gut erklärt, die Bilder sind sehr deutlich wie ich finde.
http://de.wikipedia.org/wiki/B…r#Bitweise_Verschiebungen
ZitatSymbolik:
„<<“ Verschieben nach links, um den jeweils dahinter angegeben Wert
„>>“ Verschieben nach rechts, um den jeweils dahinter angegeben Wert
„>>>“ ist eine Sonderform von „>>“; linke Seite wird mit Nullen aufgefüllt.
<<< , so wie du es geschrieben hast, gibt es auch gar nicht.Kannst es mal in PAWN ausprobieren.
new a = 4 <<< 3;
Wozu man es braucht,gute Frage.Darauf hab ich leider auch keine Antwort,denn mir fällt keine "gute" Erklärung dafür ein. Es verschiebt nun mal die Bits, wofür du es am Ende konkret benutzt kann sicherlich sehr unterschiedlich sein.Ich weiss nur wofür ich es verwendet habe.
Man kann damit Daten "komprimieren". Das umfasst aber den kompletten Bit-Operationen Bereich.
Wie schon erwähnt hat eine Variable 32 Bits in PAWN.Bedeutet also,man könnten theoretisch auch 32 Unterschiedliche Sachverhalte damit darstellen, Vorrausgesetzt jeder Sachverhalt lässt sich durch wahr/falsch darstellen.Ein kleines Beispiel.
bool:bAdmin
bool:bDeveloper
bool:bFuehrerscheinA
bool:bSpawned
bool:bLogin
Wenn ich jetzt weiss,dass das 1. Bit den Sachverhalt Admin abbildet, das 2. Bit den Sachverhalt Developer usw usf, kann ich mit den Bits arbeiten.
enum e_Sachverhalte ( <<=1 ) // << Verschieb immer 1 Bit nach LINKS
bAdmin = 1 , 0b00001
bDeveloper, // 2 , 2.Bit 0b00010
bFuehrerscheinA, // 4 , 3.Bit 0b00100
bSpawned, // 8 , 4.Bit 0b01000
bLogin // 16 , 5.Bit 0b10000
}
new Sachverhalt = bAdmin | bSpawned;
// 0b01001 , für bAdmin und bSpawned
Jetzt hab zuerst einmal einiges an Platz gespart.Es ist in einigen Fällen auch leichter damit zu arbeiten.
Der Fuehrerschein lässt sich eigentlich gut damit abbilden.Anstatt extra FüherscheinA - F für jeden Spieler als anzulegen, kann ich auch lediglich einen Führerschein anlegen und über die Bits verwalten, welcher vorhanden ist oder nicht.
Das komprimieren kommt auch hier vor,hab den Code schon mal gepostet.
stock Class_CompressWeaponInfo(weaponid,ammo) {
new
info;
info = ( ammo << 7 ) | weaponid;
return info;
}
2 unabhängige Wert in einer Zelle.Natürlich kannst du damit auch einfache Rechenaufgaben machen.
Rechnungen wie * 2 , * 4 , * 8 , * 16 usw sind damit auch möglich.Sollen auch schneller sein wenn man das
direkt per Bitverschiebung macht,hab es aber nie getestet.
Die Möglichkeiten sind wohl letztendlich Umfangreich. Vielleicht hilft dir das ja wenigstens etwas.
Ok das ist soweit verständlich, nur was bringt jetzt der <<= operator den du im enum benutzt?
Es verschiebt die Bits pro Eintrag einen nach Links zum vorherigen.
Den ersten Eintrag gebe ich die 1. Würde ich dort nichts angeben,wäre es bekanntlich 0 ( Wieso ? Da fehlt wohl die Information was so ein "enum" wirklich macht ) . Würde ich 0 um 1 nach Links verschieben,wäre es immernoch 0.
Bringt also nichts.
Falls es mit der Bitverschiebung nicht ganz klar wird,hier mal etwas leichter.
enum e_Sachverhalte ( +=1 ) // Folgeeintrag ist immer +1
bAdmin = 1
bDeveloper, // 2
bFuehrerscheinA, // 3
bSpawned, // 4
bLogin // 5
}
Ok so macht es sinn
Danke
Interessant ich dachte >> und << heißen "deutlich kleiner als" bzw. "deutlich größer als"
Hab mich dann mal schlau gemacht und ist nicht so xD
Bzw @ BlackAce
<<=
Ist das selbe wie z.B.
x = x << y
Danke Ink, war mir zwar nach dem Post von Goldkiller auch klar, aber 2x hält besser^^
Okey und ich weiß immer noch nicht wozu man <<= benutzt bzw. <<
/e.
Jetzt hab ichs sagen wir ich möchte einen Führerschein Klasse M und A
if(spdaten[playerid][fSchein] <<= 1) Sagen wir das ist Führerschein M und A ist dann <<= 2 , würde das so gehen?
bzw. so
spdaten[playerid][fSchein] << 1;
Ließ dir deinen Beitrag vor dem Absenden nochmal durch,verstehe nur Bahnhof.
Damit ist gemeint ob man das so machen kann die Variablen so zu setzen, da enum ja immer +1 ist oder?
spdaten[playerid][fSchein] << 1;
Und eben für eine andere Klasse
spdaten[playerid][fSchein] << 2;
?
Hey,
Ich hab mal was kleines vorbereitet.
Es geht um mehrdimensionale Arrays.
Beispiel: 10 Variablen (in diesem Fall strings)
Das koennte so aussehen:
new var[64], var2[64], var3[64], var4[64], var5[64], var6[64], var7[64], var8[64], var9[64], var10[64];
aber ich sage euch, das geht kuerzer, und zwar so:
new Var[10][64]
Auch bei diversen dingen kann dies ganz nuetzlich:
Warum denn immer dieser stock SpielerName.
Man kann einfach die Variable Spielername mit einem 2 dimensionalen Array versehen.
So:
new SpielerName[MAX_PLAYERS][MAX_PLAYER_NAME]
dann im callback onplayerconnect den namen auslesen:
GetPlayerName(playerid,SpielerName[playerid],MAX_PLAYER_NAME);
Ein weiteres Praktisches Beispiel waere das fuer die verwendung von schleifen.
Will man z.B die vars von oben (jetzt als integer gesehen, ohne einen array) auf 0 setzen, muss man das bei jeder einzeln tuen.
So wuerde das mit dem Array gehen, hat zwar jetzt nur noch eine Dimension, aber was solls:
new i = 0
for(;i < 10; i++) var[i] = 0;
das mit den schleifen habe ich von dma, 1te seite code optimierung.
Ich garantiere nicht fuer die richtigkeit.
Goldkiller wird mich bestimmt berichtigen muessen
oha seitdem ich in meinem script MAX_PLAYERS neu definiert habe ( 32 ) ist es um 2MB geschrumpft. :o Wusste garnicht dass der Script beim compilen jeden befehl durchgeht... ich dachte das passiert erst im eigendlichen server
Ich muss den Thread mal wieder ausbuddeln.
Frage 1:
Ist es klug, eine string[128] - Variable am Anfang des Skriptes zu erstellen, mit dieser gibt man normale Texte aus, sodass man das nicht bei jedem Callback neu erstellen muss, macht das den Gamemode also schneller oder bringt das evtl. Fehler/Schwierigkeiten?
Frage 2:
Wie kann ich am besten, einen riesen Text (für ein Dialog) zusammen stellen?
Danke und freundliche Grüße
1. keine ahnung aber denke schon ;d
2. mit strcat >> weiteres info im wiki
Aber wenn ich jetzt eine string[128]-Variable hab, kann ich da ebr nicht endlos viel Text einfügen, oder?
doch du kannst es eigentlich immer neu formatieren aber da kann es zu problemen kommen also ich denke es ist besser wenn du immer neue variablen erstellst
Aber wenn ich jetzt eine string[128]-Variable hab, kann ich da ebr nicht endlos viel Text einfügen, oder?
Irgendwann wirst du dich verzählen und plötzlich steht da ein Text, den du garnicht drin haben willst.
Wenn du aber eine Variable innerhalb einer Funktion erstellst, wird diese nach dem Funktionsaufruf wieder entfernt. Von daher macht es dem Script nicht viel aus.
So, ich finde hier sollte auch wieder mal was rein und da ich mal wieder Langeweile habe, schreibe ich hier mal ein paar Sachen rein:
Booleans:
Wenn eine Variable nur 2 Werte annehmen brauch, sagen wir 0 und 1, dann sollte man anstatt so:
//Falsche Variante
new var;
//In irgendeinem Callback
var = 1;
//Unter einem anderen Callback
if(var == 1)
Sollte man es so machen:
//Richtige Variante
new bool:var;
//In irgendeinem Callback
var = true;
//Unter einem anderen Callback
if(var == true)
Das sorgt dafür, dass von Anfang an weniger Speicherplatz für diese Variable verbraucht wird.
Char Arrays
Das ist ein Thema was ich wirklich jedem ans Herz lege !
Jeder kennt folgendes:
new var[MAX_PLAYERS];
if(var[playerid] == 1)
Nun das ist aber verdammt schlecht !
Jede Zelle bzw Spalte im Array verbraucht 4 Bytes, da MAX_PLAYERS (ohne das Makro zu verändern) eine größe von 500 hat, würde diese Variable:
verbrauchen !
Aus diesem Grund sogenannte char-Arrays verwenden, dass sähe dann so aus:
new var[MAX_PLAYERS char];
if(var{playerid} == 1) //Vorsicht: Hier { } verwenden anstatt [ ] !!!
Hier würde jede Zelle bzw Spalte im Array nur 1nen Byte verbrauchen !
Sprich wir verbrauchen 500 Bytes anstatt 2000 !
Wichtig noch zu beachten, das geht nur bei 1 dimensionalen Arrays und auch nur bei Integern, wenn man das mit strings machen will muss man strpack benutzen (aber das ist eine andere Geschichte)...
Außerdem ist zu beachten, dass nur Werte von 0-255 möglich sind!
Sprich:
new test[MAX_PLAYERS char];
test{0} = 259; //Ist nicht möglich, da größer 255!
Strings-returnen
Viele von euch werden wahrscheinlich diese Funktion kennen:
stock PlayerName(playerid) {
new name[MAX_PLAYER_NAME];
GetPlayerName(playerid,name,MAX_PLAYER_NAME);
return name;
}
Nun, hier returnen wir einen string, das führt zu sog. Memory Leaks und sorgt dafür dass euer Speicher unnötig belegt wird, denn diese Variable "name" wird Lokal erzeugt, aber sie wird durch das return nicht wieder "zerstört", somit bleibt der Speicher vorhanden.
Aus diesem Grund empfehle ich diese Variante:
//Oben im Script
new pName[MAX_PLAYERS][MAX_PLAYER_NAME];
//Unter OnPlayerConnect
GetPlayerName(playerid,pName[playerid],MAX_PLAYER_NAME);
//Nutzung:
format(string,sizeof(string),"Willkommen lieber %s",pName[playerid]);
Unnötig große Arrays
Wie oben schon mal angesprochen verbrauchen große Arrays viel Speicherplatz !
Ich zeige euch mal einige Beispiele die ihr sicher kennen werdet:
new string[256], string1[300], string2[499]; /* usw... */
format(string,sizeof(string),"bla...");
Also abgesehen davon, dass man das meistens eh mit 1ner Variable lösen kann, zeige ich euch nun das:
new string[] = "Hier euren Text rein...lieber %s",name[] = "Kaliber";
format(string,sizeof(string)+sizeof(name),string,name);
print(string); //würde ausgeben: "Hier euren Text rein...lieber Kaliber"
So das wars erstmal mit dem gröbsten, werde vielleicht noch einen 2. Part dranhängen, mal sehen
mfg.
//Edited: Infos
@Schwabbel Ist es möglich einem Bool einen String zu zuweisen also zum Beispiel bei einem Integer:
new var;
var = 0;
switch (var)
{
case 0:{"an";}
case 1:{"aus";}
}
Wir würde dies bei einem Bool aussehen?
So:
new bool:var;
var = false; //eig unnötig, da der Wert eh auf false ist ^.^
switch(var) {
case false: print("false");
case true: print("true");
}
Das würde in diesem Fall natürlich false printen
mfg.