Verschachtelte for-Schleifen
ottogal
- javascript
Hallo in die Runde,
habe Null Erfahrung mit Javascript und probiere gerade an einer kleinen Farbtafel, die ich nur lokal verwende (also keine valide Seite, nicht schimpfen!). Folgendes funktioniert wie gewünscht, um die 216 Farben der Form #xxyyzz anzuzeigen:
<html>
<head></head>
<body style="font-family: courier, monospace;">
<script language="javascript">
t="";
c=new Array("00","33","66","99","cc","ff");
for(i=0;i<6;i++)
{
t+="<table width=100%>";
for(j=0;j<6;j++)
{
t+="<tr>";
for(k=0;k<6;k++)
{
L=c[i]+c[j]+c[k];
t+="<td bgcolor="+L+"> <span style=&qout;color:#ffffff">"+L+"</span> <span style=&qout;color:#000000">"+L+"</span></td>";
}
t+="</tr>";
}
t+="</table>";
};
with(document)
{
write(t);
void(close());
}
</script>
</body>
</html>
Nun wollte ich das Skript so modifizieren, dass auch Zwischenfarben der Form #uvwxyz zu sehen sind (also alle). Das Array bekommt also die einzelnen Hexwerte "0" bis "f", und der Farbstring besteht aus 6 Summanden, die ihre Werte in 6 verschachtelten for-Schleifen bekommen.
Dass das ein Bisschen viel ist, war mir schon klar - es geht natürlich nicht. Was mich aber nun interessiert, ist, woran es scheitert: An der Zahl der for-Ebenen? An der Größe der erzeugten Tabelle? Oder der Länge der erzeugten Tabellenzeilen? Usw.
Weiß wer was?
Es ist übrigens überhaupt nicht wichtig oder eilig - deshalb keine Großbuchstaben. Mich interessierts bloß.
Danke im Voraus
ottogal
Nun wollte ich das Skript so modifizieren, dass auch Zwischenfarben der Form #uvwxyz zu sehen sind (also alle).
ottogal,
Du hast eine ungefähre Vorstellung, wie viele das sind?
Das Array bekommt also die einzelnen Hexwerte "0" bis "f", und der Farbstring besteht aus 6 Summanden, die ihre Werte in 6 verschachtelten for-Schleifen bekommen.
Und warum so kompliziert? Warum zählst du nicht in einer Schleife von 0 bis 0xFFFFFF?
Gunnar
你好 ottogal,
ich habe nicht so recht verstanden, was du eigentlich tust, aber warum
machst du das nicht einfach so?:
function dez2hex(d) {
max = Math.pow(16,8);
var z = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
var x = "";
var i = 1, v = d, r = 0;
while(v > 15) {
v = Math.floor(v / 16); i++;
}
v = d;
for(j=i;j>=1;j--) {
x = x + z[Math.floor(v / Math.pow(16,j-1))];
v = v - (Math.floor(v / Math.pow(16,j-1)) * Math.pow(16,j-1));
}
return x;
}
for(i=0;i<256;++i) {
for(j=0;j<256;++j) {
for(k=0;k<256;++k) {
document.write("<td>#" + dez2hex(i) + dez2hex(j) + dez2hex(k) + "</td>");
}
}
}
再见,
CK
Hallo,
ich habe nicht so recht verstanden, was du eigentlich tust, aber warum
machst du das nicht einfach so?:function dez2hex(d) {
...
... oder einfach so:
function dez2hex(d) {
return d.toString(16).toUpperCase();
}
MfG, Thomas
你好 Thomas,
... oder einfach so:
function dez2hex(d) {
return d.toString(16).toUpperCase();
}
Hehe, das war mir unbekannt, danke.
再见,
CK
Hallo Christian,
function dez2hex(d) {
return d.toString(16).toUpperCase();
}
Dann könnte man ja eigentlich auch mal das kleine Helferlein vereinfachen.
Auf diese Weise habe ich jetzt auch festgestellt, jenseits welcher Zahl bei meinem Rechner die Unendlichkeit beginnt:
255 mal die Ziffer F, ab da ist Sense:
javascript:alert(0x
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFF.toString(10))
Ob das wohl bei allen Rechnern gleich ist?
Gruß Gernot
function dez2hex(d) {
return d.toString(16).toUpperCase();
}
Hi Thomas,
Hätte ja fast wieder geklappt, wenn ich nicht noch mehr geschrieben hätte. ;-)
Biste dir deines „Noes“ sicher?
Gunnar
Hallo,
Hätte ja fast wieder geklappt, wenn ich nicht noch mehr geschrieben hätte. ;-)
Dann ueberlege ich mir das naechste Posting nicht 3x, sondern (3*3*3)x ;-).
Biste dir deines „Noes“ sicher?
Noe, also !Noe ;-)
BTW:
Ich finde die 3-Schleifen-Loesung des OP auch durchaus intuitiv und habe das vor einiger Zeit aehnlich mit SVG umgesetzt und nochmal analog fuer die 4096 #RGB-Kombinationen. Die in einem davor entstandenen Beispiel verwendete Variante mit toString(16) haette es auch getan -- aber man ist ja flexibel ...
MfG, Thomas
ich habe nicht so recht verstanden, was du eigentlich tust, aber warum
machst du das nicht einfach so?:function dez2hex(d) {
max = Math.pow(16,8);
var z = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");
var x = "";
var i = 1, v = d, r = 0;
while(v > 15) {
v = Math.floor(v / 16); i++;
}
v = d;
for(j=i;j>=1;j--) {
x = x + z[Math.floor(v / Math.pow(16,j-1))];
v = v - (Math.floor(v / Math.pow(16,j-1)) * Math.pow(16,j-1));
}return x;
}
Christian,
ich habe zwar verstanden, was du eigentlich tust, aber warum machst du das nicht einfach so:
function dez2hex(d) {
return d.toString(16);
}
Du bist dir bewusst, dass bei Argumenten kleiner als 16 keine führende 0 da ist? Hm, sieht nicht so aus: ;-)
for(i=0;i<256;++i) {
for(j=0;j<256;++j) {
for(k=0;k<256;++k) {
document.write("<td>#" + dez2hex(i) + dez2hex(j) + dez2hex(k) + "</td>");
}
}
}
Und wozu die dreifache Schleife?
for (i = 0; i < 0x1000000; ++i) {
s = i.toString(16);
while (s.length < 6)
s = "0" + s;
document.write ("<td>#" + s + "</td>");
}
Gunnar
你好 Gunnar,
ich habe zwar verstanden, was du eigentlich tust, aber warum machst du
das nicht einfach so:function dez2hex(d) {
return d.toString(16);
}
Siehe meine Antwort an Thomas Meinike, mir war nicht bewusst, dass das
geht.
Du bist dir bewusst, dass bei Argumenten kleiner als 16 keine
führende 0 da ist? Hm, sieht nicht so aus: ;-)
Doch, deshalb habe ich ja extra kein bgcolor oder sowas gesetzt :)
for(i=0;i<256;++i) {
for(j=0;j<256;++j) {
for(k=0;k<256;++k) {
document.write("<td>#" + dez2hex(i) + dez2hex(j) + dez2hex(k) + "</td>");
}
}
}Und wozu die dreifache Schleife?
Damit es deutlicher und klarer wird.
再见,
CK
Und wozu die dreifache Schleife?
Damit es deutlicher und klarer wird.
??
Wir zählen bis tausend:
for(i=0; i<10; ++i)
for(j=0; j<10; ++j)
for(k=0; k<10; ++k)
document.write(100*i + 10*j + k, "<br>");
;-)
Gunnar
你好 Gunnar,
Und wozu die dreifache Schleife?
Damit es deutlicher und klarer wird.
??
Wir zählen bis tausend:
[...]
Eine Farb-Angabe im RGB-Modell von CSS besteht aus 3 * 8 Bit. Das wollte ich
klarer machen, deshalb die 3-fache Schleife. Dass man die 3*8 Bit auch
direkt hintereinander schreiben kann macht den Mechanismus nicht klarer.
再见,
CK
Hallo ottogal,
Nun wollte ich das Skript so modifizieren, dass auch Zwischenfarben der Form #uvwxyz zu sehen sind (also alle).
wenn es Dir um die Farben geht - wenig sinnvoll. Wenn es Dir um die Programmiertechnik geht, sind Farben ein dankbarer Gegenstand zum Üben.
Dass das ein Bisschen viel ist, war mir schon klar - es geht natürlich nicht. Was mich aber nun interessiert, ist, woran es scheitert: An der Zahl der for-Ebenen? An der Größe der erzeugten Tabelle? Oder der Länge der erzeugten Tabellenzeilen? Usw.
was geht denn nicht? bekommst Du eine endlose Uhr oder geht es wirklich nicht?
Es ist übrigens überhaupt nicht [...] eilig
das darf es bei diesem Ansinnen auch nicht sein ;-)
Das schreiben mit JS (document.write) ist sehr langsam - das rechnen geht eigentlich.
Ich habe Dein Script mal gemessen (nur die Ausgabe) - dauert bei mir eine gute halbe Sekunde für 216 Zellen. Was Du ausgeben willst hat über 16 Mio Zellen. Das würde umgerechnet bei mir ca. 11 Stunden dauern...
Gruß, Andreas
Hallo Andreas,
was geht denn nicht? bekommst Du eine endlose Uhr oder geht es wirklich nicht?
Es wurde keine Uhr angezeigt, schien aber stillzustehen. Abbrechen wirkte nicht, nur das Schließen des Browserfensters bzw. Tabs (Firefox 1.0).
Ich habe Dein Script mal gemessen (nur die Ausgabe) - dauert bei mir eine gute halbe Sekunde für 216 Zellen. Was Du ausgeben willst hat über 16 Mio Zellen. Das würde umgerechnet bei mir ca. 11 Stunden dauern...
Nun, dass das ein törichter Gedanke war, _alle_ 16 Mio Farben zeigen zu wollen, ist offensichtlich. Ich habe versucht, nur die Werte 0, 3, 6, 9, c und f zu nehmen, was also 6^6 = 46656 Farben ergibt:
Das ist auch noch zu viel. Schränkt man eine der Zählvariablen auf nur einen Wert ein (siehe den Code unten, Zeile for (j=0;j<1;j++) ...), klappt es noch: Es dauert bei mir gut 6 Sekunden, und die 6^5 Farben stehen da. Dann müsste es bei (j=0;j<6;j++) doch eigentlich auch nur etwa 36 Sekunden dauern. Aber es tut sich nichts.
-----------------------------
<html>
<head></head>
<body style="font-family: monospace; color: #ffffff;">
<script language="javascript">
t="";
s=new Array("0","3","6","9","c","f");
for(i=0;i<6;i++) {
t+="<table width=100%>";
for (j=0;j<1;j++) {
for (k=0;k<6;k++) {
for (l=0;l<6;l++) {
t+="<tr height=60px width=100%>";
for (m=0;m<6;m++) {
for (n=0;n<6;n++) {
C=s[i]+s[j]+s[k]+s[l]+s[m]+s[n];
t+="<td width=60px bgcolor="+C+">"+C+"<br><span style=&qout;color:#000000">"+C+"</span></td>";
}
t+="<td> </td>";
}
t+="</tr>";
}
t+="<tr><td> </td></tr>";
}
}
};
t+="</table>";
with(document)
{
write(t);
void(close());
}
</script>
</body></html>
-----------------------------
Übrigens denke ich, dass die verschachtelten For-Schleifen wirklich den Überblick erhöhen; andererseits braucht man sie auch um die Tabellen optisch zu gliedern (vgl. die leeren Zellen).
Wirklich praktisch ist ja diese Funktion toString(16), die mir auch neu war.
Dank an alle, die geantwortet haben.
ottogal
mir scheint, daß die Brauser beim Schreiben immer was zwischenspeichern und wenn das zu viel ist, läuft der Speicher über oder so. Aber zu solchen Details mußt Du mal CK oder so fragen.
Jedenfalls machen die Brauser bei mir verschieden viel: FF habe ich bis j<3 bekommen, OP bis j<4 (weiter habe ich nicht getestet). IE kackt schon bei j<1 ab. Wenn man allerdings statt t+=... in der Schleife immer direkt schon ein document.write schreibt schafft er auch ein Stückchen.
Gruß, Andreas
Hi,
Nun, dass das ein törichter Gedanke war, _alle_ 16 Mio Farben zeigen zu wollen, ist offensichtlich. Ich habe versucht, nur die Werte 0, 3, 6, 9, c und f zu nehmen, was also 6^6 = 46656 Farben ergibt:
Nicht nur, daß Du 16 Millionen Tabellenzellen erzeugen wolltest, Du hast die Zellen nicht direkt erzeugt, sondern erstmal in einen String zwischengespeichert.
Pro Zelle hast Du ca. 120 Zeichen (geschätzt, nicht gezählt) angehängt, also etwa 2 Milliarden Zeichen = 2 Giga Zeichen.
Da muß dann immer mal wieder, wenn der neue Inhalt nicht mehr in den vorhandenen Platz paßt, der ganze String noch in neuen größeren Platz umkopiert werden, bis irgendwann der Speicher ausgeht ...
cu,
Andreas
Hallo,
Da muß dann immer mal wieder, wenn der neue Inhalt nicht mehr in den vorhandenen Platz paßt, der ganze String noch in neuen größeren Platz umkopiert werden, bis irgendwann der Speicher ausgeht ...
Das leuchtet ein - danke!
Weils mir bei dem Ganzen tatsächlich nicht nur um eine Programmierübung ging, sondern um eine Nachschlagetabelle für Farben: Noch der Hinweis, dass man eine vernünftigere Auswahl bekommt, wenn man für jeden Farbkanal nur Zwillingswerte 00 bis ff zulässt, aber alle 16. Das ergibt dann 16^3=2^12=4096 einigermaßen vernünftig abgestufte Farben.
Der Code sieht dann also so aus (und dann hör ich auf):
--------------------------------
<html><head></head><body style="font-family: monospace; color: #ffffff;">
<script language="javascript">
t="";
s=new Array("00","11","22","33","44","55","66","77","88","99","aa","bb","cc","dd","ee","ff");
for(i=0;i<16;i++) {
t+="<table width=100%>";
for(j=0;j<16;j++) {
t+="<tr height=60px width=100%>";
for(k=0;k<16;k++) {
C=s[i]+s[j]+s[k];
t+="<td width=60px bgcolor="+C+">"+C+"<br><span style=&qout;color:#000000">"+C+"</span></td>";
}
t+="<td> </td>";
t+="</tr>";
}
t+="</table>";
};
with(document) {
write(t);
void(close());
}
</script>
</body></html>
--------------------------------
Ciao
ottogal