Ik heb een file met gegevens in binair formaat waar little endian en big endian door elkaar worden gebruikt.
Er worden integers en doubles gebruikt, die als volgt zijn gedefinieerd:
Integer: Signed 32-bit integer (4 bytes)
Double: Signed 64-bit IEEE double precision integer (8 bytes)
Nou wil ik die gegevens in kunnen lezen in normale menselijk leesbare getallen en heb ik tot nu toe het volgende stukje code in elkaar geflanst:
De output van dit progje, bij de file die ik aan het bewerken ben, is nu:
De eerste 3 results kloppen, maar over de volgende 4 heb ik zo m'n twijfels. De waardes zijn veel te groot. PHP heeft, zover ik kan nagaan, niet echt support voor dit soort dingen dus ik kan me voorstellen dat de Signed 64-bit IEEE double precision integer compleet verkeerd wordt behandeld.
Kan iemand me hier mee helpen?
Er worden integers en doubles gebruikt, die als volgt zijn gedefinieerd:
Integer: Signed 32-bit integer (4 bytes)
Double: Signed 64-bit IEEE double precision integer (8 bytes)
Nou wil ik die gegevens in kunnen lezen in normale menselijk leesbare getallen en heb ik tot nu toe het volgende stukje code in elkaar geflanst:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| // define types define('_INT', 4); define('_DOUBLE', 8); // define byte orders (litte/big endian) define('_BIG', 1); define('_LITTLE', 2); // reads a piece of binary data from a file and returns a value function read_data($fh, $type, $order) { $c = fread($fh, $type); $a = unpack('C*', $c); $n = 0; if ($order == _BIG) { // MSB left, LSB right $p = $type-1; foreach ($a as $v) { $n += $v*pow(2, 8*$p--); } } else if ($order == _LITTLE) { // MSB right, LSB left $p = 0; foreach ($a as $v) { $n += $v*pow(2, 8*$p++); } } // DEBUG!!! echo "<p>".bin2hex($c)." ($type/$order)<br>"; var_dump($a); echo "<br>"; echo "result: $n<br>"; return $n; } |
De output van dit progje, bij de file die ik aan het bewerken ben, is nu:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| 0000270a (4/1) array(4) { [1]=> int(0) [2]=> int(0) [3]=> int(39) [4]=> int(10) } result: 9994 002fa4ee (4/1) array(4) { [1]=> int(0) [2]=> int(47) [3]=> int(164) [4]=> int(238) } result: 3122414 03000000 (4/2) array(4) { [1]=> int(3) [2]=> int(0) [3]=> int(0) [4]=> int(0) } result: 3 00000000005efa40 (8/2) array(8) { [1]=> int(0) [2]=> int(0) [3]=> int(0) [4]=> int(0) [5]=> int(0) [6]=> int(94) [7]=> int(250) [8]=> int(64) } result: 4.6821581166981E+18 0000000000cf1c41 (8/2) array(8) { [1]=> int(0) [2]=> int(0) [3]=> int(0) [4]=> int(0) [5]=> int(0) [6]=> int(207) [7]=> int(28) [8]=> int(65) } result: 4.6918525107202E+18 0000000000940141 (8/2) array(8) { [1]=> int(0) [2]=> int(0) [3]=> int(0) [4]=> int(0) [5]=> int(0) [6]=> int(148) [7]=> int(1) [8]=> int(65) } result: 4.6841878151629E+18 0000000000461e41 (8/2) array(8) { [1]=> int(0) [2]=> int(0) [3]=> int(0) [4]=> int(0) [5]=> int(0) [6]=> int(70) [7]=> int(30) [8]=> int(65) } result: 4.6922648275806E+18 |
De eerste 3 results kloppen, maar over de volgende 4 heb ik zo m'n twijfels. De waardes zijn veel te groot. PHP heeft, zover ik kan nagaan, niet echt support voor dit soort dingen dus ik kan me voorstellen dat de Signed 64-bit IEEE double precision integer compleet verkeerd wordt behandeld.
Kan iemand me hier mee helpen?
[ specs ] [ Tweaker gallery ]