原创 浮点数转换成整数

2014-7-18 15:36 1319 13 13 分类: FPGA/CPLD

考虑几个方面:

1:可能是非规格化格式   形式是:8位阶码位=0,而且尾数位!=0,,,这样的数太小,必将导致精度损失。

2:因为32位补码整数能表示的范围只能是-231<=d<=231,而单精度浮点数能表示的数的范围比整数大的多,所以很多浮点数不能转换成整数,不能太小,也不能太大。

转换的方法:

   先根据阶数计算出右移位数n,和根据尾数组成frac0,然后将frac0右移n位形成f_abs,截取f_abs[23:0],如果全是0 则精度没有损失,如果有则精度损失。

最后根据符号位,将f_abs[55:24]就是结果,如果是负的,将f_abs[55:24]转换成负数。

  wire [8:0] shift_right_bits=9'b010011110-{1'b0,a[30:23]};/////需要右移的位数

  wire [55:0] frac0={hidden_bit,a[22:0],32'h0};///////////为能检测出精度是否损失,使用了56位的数据格式,左32位为结果,右24位是被移除的位。
  wire [55:0] f_abs=($signed(shift_right_bits)>9'h20)?frac0>>6'h20:frac0>>shift_right_bits;/////frac0右移后的数据
wire lost_bits=|f_abs[23:0];//判别是否精度损失
wire [31:0] int32 = (sign)? -f_abs[55:24]:f_abs[55:24];//根据符号,转换,并取出结果。
 
代码:
module f2i(a,d,precision_lost,denormlized,invalid,state);
input [31:0] a;
output reg  [31:0] d;
output reg precision_lost;
output denormlized;
output reg  invalid;
output reg [2:0] state;
wire hidden_bit=|a[30:23];
wire frac_is_not_0=|a[22:0];
assign denormlized=~hidden_bit&frac_is_not_0;
wire is_zero=~hidden_bit&~frac_is_not_0;
wire sign =a[31];
wire [8:0] shift_right_bits=9'b010011110-{1'b0,a[30:23]};
wire [55:0] frac0={hidden_bit,a[22:0],32'h0};
wire [55:0] f_abs=($signed(shift_right_bits)>9'h20)?frac0>>6'h20:frac0>>shift_right_bits;
wire lost_bits=|f_abs[23:0];
wire [31:0] int32 = (sign)? -f_abs[55:24]:f_abs[55:24];
always @* begin 
     if(denormlized) begin 
            precision_lost=1;
            invalid=0;
            d=32'h00000000;
            state=3'b000;
       end
    else 
        begin 
          if(shift_right_bits[8]) begin 
              precision_lost=0;
             invalid=1;
             d=32'h80000000;
             state=3'b001;
           end 
         else 
            begin 
             if(shift_right_bits[7:0]>8'h1f) begin 
                 if(is_zero)  precision_lost=0;
                 else  precision_lost=1;
                 invalid=0;
                 d=32'h00000000;
                 state=3'b010;
                 end
             else begin 
                  if(sign!=int32[31]) begin 
                        precision_lost=0;
                        invalid=1;
                        d=32'h80000000;
                         state=3'b011;
                        end 
                  else 
                     begin 
                         if(lost_bits)  precision_lost=1;
                         else  precision_lost=0;
                         invalid=0;
                         d=int32;
                         state=3'b100;
                     end
                 end 
            end 
       end 
end 
 
endmodule 
 
 
 
 
 
 
 
   
 
 
 
 
 
 
 

文章评论0条评论)

登录后参与讨论
我要评论
0
13
关闭 站长推荐上一条 /2 下一条