Конвертировать двойной формат в 6-байтный (48 бит) Паскаль

Мне нужно поработать с данными, содержащимися в старых файлах. Для этого мне нужно прочитать и писать 6-байтовые (48-битные) числа с плавающей точкой в ​​Turbo Pascal из PHP. Тип данных Turbo Pascal обычно известен как real48 (функции).

У меня есть следующий PHP-код читать Формат:

/**
* 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);
}

(адаптированы из)

Теперь мне нужно сделать обратное: записывать тип данных.

Замечания:
Я знаю о ответ на вопрос конвертировать C # double в Delphi Real48, но это кажется ужасно хакерским, и я думаю, что возможно гораздо более чистое решение. И моя машина изначально не поддерживает 64-битные.

3

Решение

На второй взгляд, метод, опубликованный в ответе на конвертацию C # double в Delphi Real48 убрано довольно красиво.

Для дальнейшего использования:

/**
* 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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]