Convert two-phase 6-byte (48 bit) to Pascal real format

I need to do some work on the data contained in old files. To do this, I need to read and write Turbo Pascal 6-byte (48 bit) floating-point numbers with PHP. The Turbo Pascal data type is commonly known as real48 ( specifications ).

I have the following php code for read format:

/** * Convert Turbo Pascal 48-bit (6 byte) real to a PHP float * @param binary 48-bit real (in binary) to convert * @return float number */ function real48ToDouble($real48) { $byteArray = array_values( unpack('C*', $real48) ); if ($byteArray[0] == 0) { return 0; // Zero exponent = 0 } $exponent = $byteArray[0] - 129; $mantissa = 0; for ($b = 1; $b <= 4; $b++) { $mantissa += $byteArray[$b]; $mantissa /= 256; } $mantissa += ($byteArray[5] & 127); $mantissa /= 128; $mantissa += 1; if ($byteArray[5] & 128) { // Sign bit check $mantissa = -$mantissa; } return $mantissa * pow(2, $exponent); } 

( adapted from )

Now I need to do the opposite: write the data type.


Note: I know the answer to the question "Convert C # double to Delphi Real48", but it seems terribly hacked, and I think a much cleaner solution is possible. And my machine does not support 64-bit version.

+3
source share
1 answer

In a second glance, the method sent in response to converting C # double to Delphi Real48 clears very well.

For future reference:

 /** * Convert a PHP number [Int|Float] to a Turbo Pascal 48-bit (6 byte) real byte representation * @param float number to convert * @return binary 48-bit real */ function doubleToReal48($double) { $byteArray = array_values( unpack('C*', pack('d', $double)) ); // 64 bit double as array of integers $real48 = array(0, 0, 0, 0, 0, 0); // Copy the negative flag $real48[5] |= ($byteArray[7] & 128); // Get the exponent $n = ($byteArray[7] & 127) << 4; $n |= ($byteArray[6] & 240) >> 4; if ($n == 0) { // Zero exponent = 0 return pack('c6', $real48[0], $real48[1], $real48[2], $real48[3], $real48[4], $real48[5]); } $real48[0] = $n - 1023 + 129; // Copy the Mantissa $real48[5] |= (($byteArray[6] & 15) << 3); // Get the last 4 bits $real48[5] |= (($byteArray[5] & 224) >> 5); // Get the first 3 bits for ($b = 4; $b >= 1; $b--) { $real48[$b] = (($byteArray[$b+1] & 31) << 3); // Get the last 5 bits $real48[$b] |= (($byteArray[$b] & 224) >> 5); // Get the first 3 bits } return pack('c6', $real48[0], $real48[1], $real48[2], $real48[3], $real48[4], $real48[5]); } 
+1
source

All Articles