php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 18.07.2007, 13:12  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard Bitmasken

Hallo,

ich habe um den Typ einer CSV-Spalte festzustellen folgende Typ-Flags:
Code:
	const TYPE_FLAG           = 4;
	const TYPE_INTEGER        = 8;
	const TYPE_DATE           = 16;
	const TYPE_DATETIME       = 32;
	const TYPE_UNIX_TIMESTAMP = 64;
	const TYPE_DOUBLE         = 128;
	const TYPE_VARCHAR        = 256;
	const TYPE_TEXT           = 512;
Sortiert nach ihrer "Grobheit".
Gehen wir der Einfachheit halber von aus, dass der erste Flag bei 2^0 = 1 beginnt.

Ich durchlaufe nun einige hoffentlich repräsentative Zeilen eines CSV und ordne einem Array-Element (Index = Spaltennummer) nun per Bitverknüpfung | (bzw. +) den treffenden Typen zu. Wenn in einer Spalte (natürlich in verschiedenen Zeilen) ein Unix-Timestamp und ein Text mit maximaler Länge von 255 gefunden wird, bekommt dieses Element also den Wert $current = self::TYPE_UNIX_TIMESTAMP | self::TYPE_VARCHAR; /* 64 + 256 = 320 */

Nun möchte ich am Ende dieses Analyse zusammenfassen, das heißt, der gröbste Typ bekommt den Zuschlag (befinden sich in ein und der selben Spalte also TYPE_UNIX_TIMESTAMP und TYPE_VARCHAR bekommt TYPE_VARCHAR natürlich den Zuschlag).
Wie wäre der cleverste Algorithmus, das nun dynamisch zu machen?
Eine for-Schleife, deren Initiierungswert 512 wäre und dessen Wert sich dann jedesmal halbiert?

Im Moment habe ich folgenden Code:
PHP-Code:
<?php
            $type 
$current self::TYPE_TEXT
                  
self::TYPE_TEXT
                  
$current self::TYPE_VARCHAR
                    
self::TYPE_VARCHAR
                    
$current self::TYPE_DOUBLE
                    
self::TYPE_DOUBLE
                    
$current self::TYPE_UNIX_TIMESTAMP
                    
self::TYPE_UNIX_TIMESTAMP
                    
$current self::TYPE_DATETIME
                    
self::TYPE_DATETIME
                    
$current self::TYPE_DATE
                    
self::TYPE_DATE
                    
$current self  
                    
/* usw. */
?>
Wobei ich nichtmal weiß, ob dieses Konstrukt überhaupt ohne Klammerung funktioniert.

Sprich, wenn ich in $current = 1023 (was die Zuordnung aller TYPEs wäre, da 1023 = (2 * 512) - 1), soll in meiner Variable 512 stehen, da es der größte gefundene TYPE ist.
Reicht es zur nächstgrößten 2er-Potenz zu laufen und diese zu halbieren?

Habt ihr mich überhaupt verstanden? =)
Zergling-new ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 18.07.2007, 13:53  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Ich glaube nicht, dass die Trinitäten ohne Klammerung der else Zweige funktionieren.

Die rein mathematische Lösung wäre der ganzzahlige Wert eines 2er Logarithmus von 1023,
also z.B.
log2(1023) = 9,998 ; floor (9,99 = 9
1 + 4 +8 = 13 ; log2(13) = 3,700 ; floor (3,700) = 3

möglicherweise ist dieser Weg aber wesentlich rechenintensiver. Gibt es keine passende Bit-Operation?

EDIT:
Oder mal ganz blöd - wie wärs mit ner String-Variante wie einer Kombination aus
strlen() und strpos(), bzw. strrev() und strpos(), um
die am weitesten links stehende eins zu finden (und deren Offset von rechts aus gesehen).

strlen((binär) 1023) = 10 ;
strpos ((binär) 1023) , '1') = 0 ;
10-(0+1) = 9 ; (die eins resultiert aus 2^0)

strlen((binär) 13) = 4 ;
strpos ((binär) 13) , '1') = 0 ;
4-(0+1) = 3 ;

Ohne führende Nullen kann man sogar die strlen() Geschichte einsparen.
.
nikosch ist offline   Mit Zitat antworten
Alt 18.07.2007, 14:14  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Zitat:
log2(1023) = 9,998 ; floor (9,99 = 9
Na das ist doch schonmal genial, 2^9 = 512, genau was ich haben möchte. Dann muss der Algorithmus nichtmal wissen, welche Potenz maximal gesucht wird (das heißt ich kann später ohne Änderung weitere TYPEs hinzufügen.

Ich habe momentan folgende Lösung:
PHP-Code:
<?php
            
for ($i 4$i 2048$i *= 2) {
                if (
$i $current) {
                    
$type $i 2;
                    break;
                }
            }
?>
(1, 2 und 4 sind von UNSIGNED, SIGNED, NULL belegt)

Ich nehme deine Lösung, die gefällt mir. Danke!

Edit:
Zitat:
EDIT:
Oder mal ganz blöd - wie wärs mit ner Kombination aus
strlen() und strpos(), bzw. strrev() und strpos(), um die am weitesten links stehende eins zu finden (und deren Offset von rechts aus gesehen).
Wow das ist mal schnell:
Code:
echo pow(2, strlen(decbin($bitmaske)) - 1);
Danke das nehm ich jetzt schlussendlich!
Zergling-new ist offline   Mit Zitat antworten
Alt 18.07.2007, 14:29  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Vielleicht wären Bit-Operationen in Verbindung mit Konstanten mal ein gutes Kurztutorial, um die Arbeitsweise mit Flags in Funktionen zu beschreiben.
nikosch ist offline   Mit Zitat antworten
Alt 18.07.2007, 14:33  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Tu dir keinen Zwang an
Zergling-new ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php bitmaske, bitmaske php, php bitmasken, php bitmaske vergleichen, php bitmask, bitmasken php, bitmask php, bitmaske, javascript bitmaske, php bitverknüpfung, bitverknüpfung php, php bitmasks, php bitmask einführung, bit verknüpfung php, bitmasken, php bit verknüpfung, bitmasken vergleichen, mit bitmasken arbeiten, php bitmasken vergleichen, arbeiten mit bitmasken

Alle Zeitangaben in WEZ +2. Es ist jetzt 21:27 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.