Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]1568[/thread]

$a >> $b: in perl und php = verschieden?

Leser: 1


<< |< 1 2 >| >> 16 Einträge, 2 Seiten
jan
 2004-07-07 01:26
#15308 #15308
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
ich bin ja generell kein tiefgreifender entwickler, ich verstehe mich eher auf die logik im programmablauf, auf die idee hinter einem script als auf die algo-entwicklung und logik/funktion/wasauchimmer in der ausführung.
hier nun ein problem, auf das ich traf, als ich einen php-schnippsel in perl übersetzen wollte:

perl:
Quote
This is perl, v5.8.0 built for i686-linux

Code: (dl )
1
2
3
4
use strict;
my $a = 4653896912;
my $b = 13;
print ($a >> $b); # 524287


php:
Quote
PHP 4.3.3 (cli) (built: Oct 25 2003 15:06:16)
Copyright &copy; 1997-2003 The PHP Group
Zend Engine v1.3.0, Copyright &copy; 1998-2003 Zend Technologies

Code: (dl )
1
2
3
4
5
<?
$a = 4653896912;
$b = 13;
print ($a >> $b); #43814
?>


woran liegt es, dass die ergebnisse unterschiedlich sind? was müsste ich tun, damit die ergebnisse gleich sind? beides auf dem selben rechner, Redhat 7.2
jan
 2004-07-07 01:33
#15309 #15309
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
so, bash meldet auch das php-ergebnis:
Code: (dl )
echo $((4653896912 >> 13))

ergbit 43814
spielt das OS hier eigentlich eine rolle? oder nur die prozessor-architektur? und könnte mir unwissendem jemand dann gleich noch mal little und big endian mit verständlichen worten erklären? hat das eigentlich was damit zu tun? die begriffe fielen mir nur im zusammenhang mit meiner eigenen recherche auf.
lichtkind
 2004-07-07 02:20
#15310 #15310
User since
2004-03-22
5697 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
os is egal

perl 5.6.2 macht unter win auch 524287

print ((4653896912 >> 13));
auch
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
Crian
 2004-07-07 04:03
#15311 #15311
User since
2003-08-04
5871 Artikel
ModeratorIn
[Homepage]
user image
[quote=jan,06.07.2004, 23:33]könnte mir unwissendem jemand dann gleich noch mal little und big endian mit verständlichen worten erklären?[/quote]
ja


.


.


.


.


.


na gut: ;-)

Bei Zahlen, die größer als 255 sind, und also nicht mehr durch ein Byte (oder besser Oktett) repräsentiert werden können, gibt es Unterschiede zwischen verschiedenen Prozessorarchitekturen: Bei manchen ist das hochwertigste Byte vorne und bei manchen hinten (= big-endian).

Beispiel: 256 = 1*256 + 0 = 100000000

Mögliche Repräsentationen (byteweise) im Speicher:

1, 0 (little-endian)
0, 1 (big-endian)\n\n

<!--EDIT|Crian|1089158655-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
esskar
 2004-07-07 05:19
#15312 #15312
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
das Problem ist ganz simpel:
Perl unstützt als scalar standardmäßig 32-bit Zahlen.
Die größte Zahl, die Perl damit verarbeiten kann ist also
2^32 = 4_294_967_296
Man sieht nun, dass 4_653_896_912 > 2^32 ist;
dadurch kommt es zu einem Überlauf; dadurch wird die Zahl dann als (4_653_896_912 - 4_294_967_296) = 358_929_616 von Perl verwaltet; und (358_929_616 >> 13) ist eben mal 43_814
esskar
 2004-07-07 05:28
#15313 #15313
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
Quote
Auf Computern gibt es mehrere Möglichkeiten, wie Zahlenwerte, die aus mehreren Bytes bestehen, im Speicher abgelegt sind. Die beiden wichtigsten sind big endian und little endian.

Nehmen wir im Folgenden als Beispiel den 32-Bit Integer-Wert mit der hexadezimalen Darstellung 0xA1B2C3D4.

Wenn wir die 4 Bytes in der Reihenfolge D4 C3 B2 A1, also das niederwertigste Byte an der niedrigsten Speicheradresse ablegen, spricht man von little endian. Eingeführt wurde diese Byte-Reihenfolge beispielsweise mit dem 6502 oder den Intel x86 Prozessoren.

Die Speicherung in der Reihenfolge A1 B2 C3 D4, also das höchstwertige Byte an der niedrigsten Speicheradresse wird als big endian bezeichnet. Verwendet wird diese Byte-Reihenfolge beispielsweise bei der Motorola 68000er Familie, dem PowerPC oder den Prozessoren der z/Series. Auch die gewöhnliche Darstellung von Zahlen ist damit - im Sinne der Leserichtung von links nach rechts - big endian, wenn man so will.

Einige - meist ältere - Systeme speicherten die Daten in der Reihenfolge C3 D4 A1 B2 oder B2 A1 D4 C3, dies wird jeweils als middle endian bezeichnet.

Um einen fehlerfreien Datenaustausch im Internet zu ermöglichen, ist bei Netzwerkprotokollen normalerweise immer die Byte-Reihenfolge festgeschrieben als network byte order, die im Falle von TCP/IP im big endian Format definiert ist. Arbeitet das System nicht mit dieser Byte-Reihenfolge, muss dies im Netzwerktreiber entsprechend umgesetzt werden.

Die kuriose Bezeichnung lehnt an den satirischen Roman "Gullivers Reisen" von Jonathan Swift an, in dem der Streit darüber, ob ein Ei am spitzen oder am dicken Ende aufzuschlagen sei, die Bewohner von Liliput in zwei verfeindete Lager spaltet - die "Little-Endians" und die "Big-Endians", in der deutschen Übersetzung des Buches "Dickender" und "Spitzender".


Quelle: Byte-Reihenfolge
lichtkind
 2004-07-07 10:31
#15314 #15314
User since
2004-03-22
5697 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
stimmt, für grosse zahlen gab es doch extra module,

bei perl6 denk ich müsste man nur beim definieren es angeben das man grosse ahl haben will
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
jan
 2004-07-07 10:33
#15315 #15315
User since
2003-08-04
2536 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=esskar,07.07.2004, 03:19]das Problem ist ganz simpel:
Perl unstützt als scalar standardmäßig 32-bit Zahlen.
Die größte Zahl, die Perl damit verarbeiten kann ist also
2^32 = 4_294_967_296
Man sieht nun, dass 4_653_896_912 > 2^32 ist;
dadurch kommt es zu einem Überlauf; dadurch wird die Zahl dann als (4_653_896_912 - 4_294_967_296) = 358_929_616 von Perl verwaltet; und (358_929_616 >> 13) ist eben mal 43_814[/quote]
ok, das klingt soweit logisch. wie setzt man das nun in code um, sodass ich das verhalten von php und bash auch in perl bekomme?
Taulmarill
 2004-07-07 12:07
#15316 #15316
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
die erklärung von esskar ist leider nicht ganz richtig.
bei bash und php findet ein überlauf statt wie von ihm beschrieben, bei perl ist das ein bischen anders!
perl läuft anscheinend nicht über sondern voll. so kommt 524287 zustande.

zur verdeutlichung:
4294967294 ist 11111111111111111111111111111110
4294967295 ist 11111111111111111111111111111111
9999999999 ist 11111111111111111111111111111111 (!!!)

die 524287 die bei perl rauskommen sind nun binär 00000000000001111111111111111111.
wir erkennen hier, dass anscheinend der mit 32 bit gefüllte integer um die 13 bits geshiftet wurde.

lösung:

benutze das modul Math::BigInt
Code: (dl )
perl -MMath::BigInt -e'$x = Math::BigInt->new("4653896912");$x->brsft("13");print $x->bstr;'
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
esskar
 2004-07-07 19:42
#15317 #15317
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
okay... perl macht eben das selbe, was an der stelle ein c programm machen würde! :)
<< |< 1 2 >| >> 16 Einträge, 2 Seiten



View all threads created 2004-07-07 01:26.