[php]Bitwise operators in PHP?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • PanMan
  • Registratie: November 1999
  • Laatst online: 18-09 22:50
Hoi!
Ik had het laatst al over een manier om getallen in minder bytes te encoden. na een discussie, Cijfers encoden in minder bytes?, had ik eigenlijk besloten om er vanaf te zien. Maar het blijkt dat de source die ik gebruik voor het oversturen van de gegevens ze al encode. Dus dan vind ik het zonde om het eruit te slopen. Het decoden lukt me echter niet: Ik heb een stuk java source dat de getallen zou moeten decoden, maar het lukt me niet om dat naar PHP om te zetten: ik heb te weinig ervaring met bitwise operators in PHP. Iemand tips hoe ik hier verder mee kan komen? De java source voor het decoden is:
code:
1
2
3
4
5
int latitude = 0x00ff0000 & (bytes[0] << 16);
latitude |= 0x0000ff00 & (bytes[1] << 8);
latitude |= 0x000000ff & bytes[2];
latitude |= (latitude & 0x00800000) != 0 ? 0xff000000 : 0;
out.write(new Float(latitude).Div(DEGREESTOINT).toString().getBytes());


In PHP heb ik daar (optimist als ik ben :)) dit van gemaakt, maar dat doet niets:
PHP:
1
2
3
4
$latitude = 0x00ff0000 & ($first[0] << 16);
$latitude |= 0x0000ff00 & ($first[1] << 8);
$latitude |= 0x000000ff & $first[2];
$latitude |= ($latitude & 0x00800000) != 0 ? 0xff000000 : 0;


Iemand tips?

Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949


Acties:
  • 0 Henk 'm!

  • DizzyWeb
  • Registratie: Februari 2001
  • Laatst online: 05-09 14:30

DizzyWeb

Ondertiteld


Acties:
  • 0 Henk 'm!

  • PanMan
  • Registratie: November 1999
  • Laatst online: 18-09 22:50
Daar staar ik me al een halve dag blind op :). Ik snap het idee wel, en ook nog wel enigsinds wat dit stukje code doet, maar kom er niet uit...

Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Die |= operator is niet geldig in PHP. Moet je die misschien vervangen door .= ?
=

[ Voor 5% gewijzigd door Grijze Vos op 22-11-2006 16:07 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • B-Man
  • Registratie: Februari 2000
  • Niet online
Grijze Vos schreef op dinsdag 21 november 2006 @ 16:10:
Die |= operator is niet geldig in PHP. Moet je die misschien vervangen door .= ?
|= is gewoon een geldige operator in PHP hoor, gebruik ik al jaren.

Wat zit er precies in $first? Als daar een getal in zit, dan werken $first[0], $first[1] etc niet.
Zo aan je java code te zien krijg je daar een array van bytes door, en bitshift je die, zodat je een getal van 4 bytes samenstelt.

Acties:
  • 0 Henk 'm!

  • PanMan
  • Registratie: November 1999
  • Laatst online: 18-09 22:50
Inderdaad. $first lees ik uit uit een file:
PHP:
1
2
$all=file_get_contents($filenaam);
$first=substr($all,0,3);

Volgens mij staat die file gewoon vol met steeds 3 bytes achter elkaar.
http://panman.nl/test.tr is een voorbeeldfile (en, als je er goed over nadenkt, privacy gevoelig :)).

Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Vandaar, weaktyping probleempje. $first is gewoon een string en wordt niet geinterpreteerd als een byte array. Je zult ze zelf nog handmatig om moeten zetten naar een getal.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

En houdt er daarbij rekening mee dat Java big-endian is, terwijl PHP de endianness van z'n host aanneemt (en dat is waarschijnlijk little-endian als je op een doodgewone PC werkt)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 16:28
Mja, die Java code klinkt heel ingewikkeld, maar wat er eigenlijk gebeurt is dat er een big-endian 24-bits signed integer ingelezen wordt. Al die bitmasks zijn nodig omdat Java signed bytes gebruikt (stompzinnig idee, en dat blijkt bij dit soort dingen). In PHP maak ik er zoiets van:
PHP:
1
2
3
4
5
6
7
8
$bytes=file_get_contents('test.tr');
for($n = 0; $n + 3 <= strlen($bytes); $n += 3)
{
        $x = (ord($bytes{$n})<<8) | (ord($bytes{$n + 1})<<16) | (ord($bytes{$n + 2})<<24);
        if($x&0x800000)
                $x = -(($x&0x7fffff) + 1);
        echo "$x\n";
}

De sign extentie heb ik wat anders gedaan dan in Java, omdat ik geen idee heb hoe PHP omgaat met signed/unsigned integers en of integers misschien 64 bits zijn op andere platforms. Geen idee of het klopt, want er staan geen negatieve getallen in je invoer voor zover ik kan zien.

Dit levert op:
2440253
226323
2440255
226319
2440256
226313
2440256
226308

Kan dat een beetje kloppen?
.oisyn schreef op dinsdag 21 november 2006 @ 16:38:
En houdt er daarbij rekening mee dat Java big-endian is, terwijl PHP de endianness van z'n host aanneemt (en dat is waarschijnlijk little-endian als je op een doodgewone PC werkt)
Wat heeft dat er mee te maken? De getallen staan big endian in het bestand, en voor de bit-operaties maakt de endianness van de machine niets uit.

[ Voor 23% gewijzigd door Soultaker op 21-11-2006 16:45 ]


Acties:
  • 0 Henk 'm!

  • PanMan
  • Registratie: November 1999
  • Laatst online: 18-09 22:50
Ik ben er uit! Thanks voor de hulp!
had het ook naar iemand gemaild, en die kwam met deze functie:
PHP:
1
2
3
4
5
6
7
function shizzle($bytes) {
    $test  = 0x00ff0000 & ($bytes[0] << 16);
    $test |= 0x0000ff00 & ($bytes[1] << 8);
    $test |= 0x000000ff &  $bytes[2];
    $test |= ($test & 0x00800000) != 0 ? 0xff000000 : 0;
    return $test;
}

Echt een dag tegenaan zitten klooien...

Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
peoh wat een moeite! PHP zou PHP niet zijn als daar geen handige builtin crap voor was ;)
PHP:
1
2
3
4
5
6
$f  = file_get_contents("test.tr");
$chunks = str_split($f, 3);
foreach($chunks as $c) {
    list(,$value) = unpack("N", chr(0).$c);
    echo $value."\n";
}

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 16:28
Op zich een goede suggestie, maar dat doet nog geen sign extension. Dan moet het zoiets worden:
PHP:
1
unpack("N", chr((ord($c{0})&0x80) ? 0xff : 0).$c);

[ Voor 44% gewijzigd door Soultaker op 21-11-2006 17:33 ]


Acties:
  • 0 Henk 'm!

  • PanMan
  • Registratie: November 1999
  • Laatst online: 18-09 22:50
Ik had ook al andere code gezien, maar deze is wel heel compact.... :).

Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons, computers in the future may have only 1,000 vacuum tubes and weigh only 1.5 tons.
– Popular Mechanics, March 1949


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Soultaker schreef op dinsdag 21 november 2006 @ 17:31:
Op zich een goede suggestie, maar dat doet nog geen sign extension. Dan moet het zoiets worden:
PHP:
1
unpack("N", chr((ord($c{0})&0x80) ? 0xff : 0).$c);
Ja da's waar, zo ist nog beter. Is er trouwens een reden waarom je {} gebruikt voor een index in een byte-array (lees:string)?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op dinsdag 21 november 2006 @ 16:42:
Wat heeft dat er mee te maken? De getallen staan big endian in het bestand
Het heeft uiteraard alles te maken met hoe je die data uitleest. Byte-voor-byte uitlezen en zelf in de goede volgorde te zetten hoeft niet hetzelfde te zijn als in een keer 4 bytes naar het geheugen van een int kopiëren.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 16:28
.oisyn schreef op dinsdag 21 november 2006 @ 18:04:
Het heeft uiteraard alles te maken met hoe je die data uitleest. Byte-voor-byte uitlezen en zelf in de goede volgorde te zetten hoeft niet hetzelfde te zijn als in een keer 4 bytes naar het geheugen van een int kopiëren.
Accoord, maar dat kan nu precies niet (noch in Java, noch in PHP). Als je het geheugen waarin getallen opgeslagen worden niet anders dan als geheel getal kunt benaderen, maakt het voor de programmeur niet uit hoe die getallen opgeslagen worden. Op zo'n platform is endianness dus geen issue, en een uitspraak als 'Java is big-endian' is i.m.o. onzin, of het betekent slechts dat een aantal serialization functies toevallig big-endian data lezen/schrijven.
Genoil schreef op dinsdag 21 november 2006 @ 18:04:
Ja da's waar, zo ist nog beter. Is er trouwens een reden waarom je {} gebruikt voor een index in een byte-array (lees:string)?
Ik vind het zelf iets duidelijker, omdat dan uit de context blijkt dat ik een element uit een string en niet uit een array haal. Je noemt het een byte-array, maar in PHP zijn strings en arrays toch hele verschillende dingen; geen van de array-functies werkt op strings (terwijl een heleboel wel zouden kunnen werken) bijvoorbeeld.

Inhoudelijk is het alleen een keuze in programmeerstijl; blokhaken doen precies hetzelfde.

Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Soultaker schreef op dinsdag 21 november 2006 @ 18:49:

[...]

Ik vind het zelf iets duidelijker, omdat dan uit de context blijkt dat ik een element uit een string en niet uit een array haal. Je noemt het een byte-array, maar in PHP zijn strings en arrays toch hele verschillende dingen; geen van de array-functies werkt op strings (terwijl een heleboel wel zouden kunnen werken) bijvoorbeeld.

Inhoudelijk is het alleen een keuze in programmeerstijl; blokhaken doen precies hetzelfde.
Ok, helder. Ik vind het idd wel duidelijker :). Ik heb gemerkt dat het gebruiken van strings op plaatsen waar normaalgesproken (in PHP) een array voor de hand ligt, een stuk sneller is. Ben nu bezig met een 8-bit realtime raycaster in PHP (CLI met php_sdl voor de video en i/o), en daar gebruik ik een string als framebuffer. Vroeg me af of {} nog sneller was maar dat leek me al een beetje onwaarschijnlijk...

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44

MBV

dan ben ik toch ineens heel benieuwd waarom je een CLI-programma voor een rekenintensief iets in PHP doet. Waarom niet in willekeurig welke andere taal? PHP is zo ongeveer de langzaamste van allemaal, vziw...

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Soultaker schreef op dinsdag 21 november 2006 @ 18:49:

Accoord, maar dat kan nu precies niet (noch in Java, noch in PHP).
DataInputStream.readInt()
En gezien de substr(getfilecontents(), 0, 3) in PHP vermoedde ik al een soortgelijke implementatie.

.edit: maar ik had niet goed gelezen, omdat ze overduidelijk gewoon met bytes werken die ze bij elkaar shiften en orren 8)7

[ Voor 17% gewijzigd door .oisyn op 21-11-2006 22:17 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
MBV schreef op dinsdag 21 november 2006 @ 21:20:
dan ben ik toch ineens heel benieuwd waarom je een CLI-programma voor een rekenintensief iets in PHP doet. Waarom niet in willekeurig welke andere taal? PHP is zo ongeveer de langzaamste van allemaal, vziw...
Nou eigenlijk gewoon om te kijken of het kan. Ik moet toegeven dat ik niet onder de indruk ben van de performance van PHP als het op dit soort dingen aankomt. Ik heb nu een Wolfenstein3D (die uit de jaren negentig)-stijl raycaster die in 320*240*8 zo'n 10 fps haalt op een voxel-resolutie van 160*120 op een Core Duo 1.66Ghz...dus dat houdt niet bepaald over ;). Maar het is wel erg leuk om dan te kijken waar je nog een extra 0.1 fps weg kunt slepen in een taal die je goed kent en waar snelheid doorgaans niet zo'n punt is :)

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44

MBV

@Genoil: http://shootout.alioth.de...all&lang=php&lang2=python
Diverse 'web'-talen met elkaar vergeleken :)
Verrassende winnaar: Java :)
Oh ja, als je eens echt iets anders wilt: ga dan functioneel proggen met Haskell, meeste operaties beter dan PHP, en een heel ander concept :)

[ Voor 30% gewijzigd door MBV op 22-11-2006 15:31 ]


Acties:
  • 0 Henk 'm!

  • djc
  • Registratie: December 2001
  • Laatst online: 08-09 23:18

djc

MBV: hij zegt "in een taal die je goed kent en waar snelheid doorgaans niet zo'n punt is"...

Rustacean


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Genoil schreef op woensdag 22 november 2006 @ 08:42:

Nou eigenlijk gewoon om te kijken of het kan. Ik moet toegeven dat ik niet onder de indruk ben van de performance van PHP als het op dit soort dingen aankomt. Ik heb nu een Wolfenstein3D (die uit de jaren negentig)-stijl raycaster die in 320*240*8 zo'n 10 fps haalt op een voxel-resolutie van 160*120 op een Core Duo 1.66Ghz...dus dat houdt niet bepaald over ;). Maar het is wel erg leuk om dan te kijken waar je nog een extra 0.1 fps weg kunt slepen in een taal die je goed kent en waar snelheid doorgaans niet zo'n punt is :)
Cast je je gewoon een weg door de voxels heen zonder enige datastructuur? Want dat is natuurlijk ook niet zo handig :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
.oisyn schreef op woensdag 22 november 2006 @ 16:13:
[...]

Cast je je gewoon een weg door de voxels heen zonder enige datastructuur? Want dat is natuurlijk ook niet zo handig :)
Hangt er vanaf wat je onder datastructuur verstaat ;). Het is zeg maar Wolf3D-stijl, met een grid. Deuren en area's ben ik nog niet aan toe ;). Ik ben nu toevallig bezig de tracer om te bouwen van Euclidiaans naar DDA (Digital Differential Analysis). Non-textured geeft dat al weer een meer dan dubbel zo hoge fps. Textured ongeveer 1.5 keer sneller...

[edit] ik bedacht me later dat je door mijn waarschijnlijk foute gebruik van het woord 'voxelresolutie' die vraag stelt. ik bedoelde dat de framebuffer 160*120 karakters is, die ik opschaal naar 320*240. het level-grid is vooralsnog maar 16 * 16, maar het zou denk ik niet veel schelen als die veel groter is...

[ Voor 24% gewijzigd door Genoil op 23-11-2006 09:37 ]

Pagina: 1