浮动到 Real48

Float to Real48

我试图在 python 中将浮点数转换为 Real48 (Borland Pascal)。我发现这个 method 是用 C# 写的(我认为)

static byte[] DoubleToReal48(double d)
{
  byte[] r = new byte[6];

  long bits = BitConverter.DoubleToInt64Bits(d);
  bool negative = ((bits >> 63) & 1) != 0;
  long exponent = ((bits >> 52) & 0x7FF) - 1023;
  long mantissa = bits & 0xFFFFFFFFFFFFFL;

  long raw = (negative ? 1 : 0);
  raw = (raw << 39) | (mantissa >> 13);
  raw = (raw << 8) | ((exponent + 129) & 0xFF);

  for (int k = 0; k < 6; k++)
  {
    r[k] = (byte)(raw & 0xFF);
    raw >>= 8;
  }
  return r;
}

我不懂 C#,所以很难将它翻译成 python。谁能帮我?或者有更好的方法吗?

我找到了 this 但它似乎只能将 Real48 转换为 double,而不是我需要的相反方式。

让我尝试将 C# 翻译成 python

1.- 将位从双精度数转换为数字 (unsigned long long)。

long bits = BitConverter.DoubleToInt64Bits(d);

转换为

struct.unpack("Q", struct.pack("d", python_double) )[0]

它使用标准库中的 struct 模块。

2.- 从双重表示中提取每个字段

bool negative = ((bits >> 63) & 1) != 0;
long exponent = ((bits >> 52) & 0x7FF) - 1023;
long mantissa = bits & 0xFFFFFFFFFFFFFL;

可以逐字翻译 alsmot,因为 python 中存在相同的运算符。

negative = ((bits >> 63) & 1)    # Integer 1 for negative, 0 for positive
exponent = ((bits >> 52) & 0x7FF) - 1023
mantissa = bits & 0xFFFFFFFFFFFFF

3.-再次将数字打包成48位

long raw = (negative ? 1 : 0);
raw = (raw << 39) | (mantissa >> 13);
raw = (raw << 8) | ((exponent + 129) & 0xFF);

同2号,

raw = negative
raw = (raw << 39) | (mantissa >> 13)
raw = (raw << 8) | ((exponent + 129) & 0xFF)

4.- 将数字转换为 6 字节的字符串

for (int k = 0; k < 6; k++)
{
  r[k] = (byte)(raw & 0xFF);
  raw >>= 8;
}    

按照第 1 步使用敲击,

data = struck.pack('Q', raw)
data = data[:6]  # Drop the 16 MSB

注意:我删除了最后 2 个字符,因为结构默认使用处理器的字节顺序(在我的例子中是 x86),但这可以通过第一个参数来控制。

提示:如果要将数字转换为二进制表示,可以使用 '{:064b}'.format(number)。这将用零填充它以填充 64 个字符。