将8个内存字节转为浮点数(Double)

{
函数功能:将8个内存字节(低位在前,高位在后)转为浮点数 Double
创建人:skyjacker
网址:Http://blog.csdn.net/skyjacker
Email:hemiaoyu At gmail.com
创建日期:2007-01-12
函数根据:IEEE标准754(4个内存字节转为Single同理)
双精度:N共32位,其中S占1位,E占11位,M占52位。
公式:n=(-1)^s * 2^e * m
}
function ByteToFloat(const Bytes: TByte8): Double;
const
  k = 11; //幂位数 Double=11
var
  TmpByte: Byte; //临时字节

  //公式相关
  n: Double; //结果
  s: Integer; //符号位数字表示 +1 -1
  e: Integer; //幂值
  m: Double; //位数值

  //规格化
  bias: Integer; //偏置
  En: Integer; //幂的值

  I: Integer; //位数 m 23位
  A: Integer; //3~8个字节
  B: Integer; //TBits偏移 从5开始
  Bits: TBits; //存放二进制位 E=11 M=52

  //判断是否规格化
  function NormalizedStatus(const Bits: TBits): Byte;
  var
    I: Integer;
    a, b: Integer;
  begin
    a := 0;
    b := 0;
    for I := 11 downto 1 do //Error:for I:=Bits.size(=12) downto 1 do
    begin
      if Bits.Bits[I] then
        Inc(b)
      else
        Inc(a);
    end;
    if (Bits.Size - 1) = a then //Bits.Size大小变为12
      Result := $00
    else if (Bits.Size - 1) = b then
      Result := $FF
    else Result := $01; //规格化
  end;
begin

  //符号相关
  if (Bytes[1] and $80) = $00 then
    s := 1
  else
    s := -1;

  bias := pow(2, (k - 1)) - 1;

  //整理11位二进制幂值 E
  Bits := TBits.Create;
  Bits.Size := 11;
  TmpByte := Bytes[1];
  TmpByte := TmpByte shl 1; //移去符号位
  for I := 1 to 7 do
  begin
    Bits[I] := ((TmpByte and $80) = $80);
    TmpByte := TmpByte shl 1;
  end;

  TmpByte := Bytes[2];
  for I := 1 to 4 do
  begin
    Bits[I + 7] := ((TmpByte and $80) = $80);
    TmpByte := TmpByte shl 1;
  end;
  //求幂值
  En := 0;
  for I := 11 downto 1 do
  begin
    if Bits.Bits[12 - I] then
      En := En + pow(2, (I - 1));
  end;

  TmpByte := NormalizedStatus(Bits);
  //是否规格化判断
  if TmpByte = $00 then
  begin
    e := 1 - bias;
    m := 0; //m的初始值 非规格化
  end
  else if TmpByte = $FF then
  begin
    //特殊数值: 当E的二进制位全为1时为特殊数值。
    Result := 0; //防止溢出或未初始化
    Exit;
  end
  else
  begin //规格化计算方法
    e := En - bias;
    m := 1; //m的初始值 规格化
  end;

  //整理52位尾数二进制M
  Bits.Size := 52; //Size自动复值了以前11个值,由于重新赋值,因为不会影响结果。
  TmpByte := Bytes[2]; //5~8 bit
  TmpByte := TmpByte shl 4;
  for I := 1 to 4 do
  begin
    Bits[I] := ((TmpByte and $80) = $80);
    TmpByte := TmpByte shl 1;
  end;

  //3到8个字节位存入Bits
  B := 5;
  for A := 3 to 8 do
  begin
    TmpByte := Bytes[A];
    for I := 1 to 8 do
    begin
      Bits[B] := ((TmpByte and $80) = $80);
      TmpByte := TmpByte shl 1;
      Inc(B);
    end;
  end;

  //求m值
  for I := 1 to 52 do
  begin
    if Bits.Bits[I] then
      m := m + 1 / power(2, I);
  end;

  n := s * Power(2, e) * m;

  Bits.Free;

  Result := n;
end;

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值