C语言钟负无穷如何表示

本文介绍了如何使用C语言表示整数和浮点数的最大及最小极限值,通过包含特定头文件并利用预定义宏实现。对于整数类型,可以通过包含limits.h来获取MIN_INT和MAX_INT,而对于浮点数,则需要包含float.h来获取DBL_MAX。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、define inf -999999
2、#include<limits.h> 直接用int的最小取值,MIN_INT
则正无穷为 MAX_INT,如果要用double 型的,需要加载头文件float.h,然后正无穷为DBL_MAX,负无穷就为-DBL_MAX;

module floatReciprocal #( parameter DATA_WIDTH = 32, // IEEE 754 单精度浮点数 parameter MAX_ITER = 3, // 最大迭代次数(FP32 通常需要 2-3 次) parameter THRESHOLD = 32'h0001 // 收敛阈值(尾数最低位变化容忍) ) ( input [DATA_WIDTH-1:0] number, // 输入浮点数 (IEEE 754 FP32) input enable, // 计算使能信号 (高电平启动) input clk, // 时信号 input rstn, // 复位信号 (低有效) output reg [DATA_WIDTH-1:0] output_rec, // 输出倒数 (1/number) output reg ack // 计算完成确认信号 ); // IEEE 754 单精度浮点数常量定义 localparam ONE = 32'h3F80_0000; // 1.0 localparam TWO = 32'h4000_0000; // 2.0 localparam INF_POS = 32'h7F80_0000; // 正无穷大 localparam INF_NEG = 32'hFF80_0000; // 负无穷大 localparam ZERO = 32'h0000_0000; // 零 localparam NAN = 32'h7FC0_0000; // NaN // 参考模块的初始值常数 (43/17 和 -32/17) localparam P1 = 32'b01000000001101001011010010110101; // ≈2.5294117647 localparam P2 = 32'b10111111111100001111000011110001; // ≈-1.8823529412 // 内部寄存器 reg [DATA_WIDTH-1:0] current_x; // 当前迭代值 reg [2:0] iter_count; // 迭代计数器 reg [DATA_WIDTH-1:0] Ddash; // 归一化后的输入值 reg input_sign; // 输入符号位 reg [7:0] input_exp; // 输入指数部分 reg [DATA_WIDTH-1:0] final_result; // 最终迭代结果 // 牛顿迭代计算单元 wire [DATA_WIDTH-1:0] prod_DX; // Ddash * current_x wire [DATA_WIDTH-1:0] two_minus; // 2 - prod_DX wire [DATA_WIDTH-1:0] x_next; // current_x * two_minus // 初始值计算单元 (参考模块的核心公式) wire [DATA_WIDTH-1:0] P2_times_Ddash; wire [DATA_WIDTH-1:0] initial_guess; // P1 + P2*Ddash // 浮点运算器实例化 floatMult mult1 ( .floatA(Ddash), .floatB(current_x), .product(prod_DX) ); floatAdd sub1 ( .floatA(TWO), .floatB({~prod_DX[31], prod_DX[30:0]}), // 取负:符号位取反 .sum(two_minus) ); floatMult mult2 ( .floatA(current_x), .floatB(two_minus), .product(x_next) ); // 初始值计算单元 (关键修改) floatMult mult_initial ( .floatA(P2), .floatB(Ddash), .product(P2_times_Ddash) ); floatAdd add_initial ( .floatA(P1), .floatB(P2_times_Ddash), .sum(initial_guess) ); // 主状态机 reg [1:0] current_state, next_state; localparam IDLE = 2'b00; localparam INIT = 2'b01; localparam ITERATE = 2'b10; localparam DONE = 2'b11; // 收敛检测:计算绝对差值 wire [22:0] abs_diff = (current_x[22:0] > x_next[22:0]) ? (current_x[22:0] - x_next[22:0]) : (x_next[22:0] - current_x[22:0]); always @(posedge clk or negedge rstn) begin if (!rstn) begin current_state <= IDLE; end else begin current_state <= next_state; end end always @(*) begin next_state = current_state; case(current_state) IDLE: begin if(enable) begin if((number[30:0] == 0) || (number[30:23] == 8'hFF)) next_state = DONE; else next_state = INIT; end end INIT: begin next_state = ITERATE; // 直接进入迭代状态 end ITERATE: begin if ((iter_count == MAX_ITER - 1) || (abs_diff < THRESHOLD)) next_state = DONE; end DONE: begin if(ack) next_state = IDLE; end default: next_state = IDLE; endcase end always @(posedge clk or negedge rstn) begin if (!rstn) begin ack <= 0; iter_count <= 0; output_rec <= 0; input_sign <= 0; input_exp <= 0; Ddash <= 0; current_x <= 0; end else begin case (current_state) IDLE: begin ack <= 0; if (enable) begin // 检查特殊情况 if (number[30:0] == 0) begin // 输入为0 output_rec <= (number[31]) ? INF_NEG : INF_POS; ack <= 1; end else if (number[30:23] == 8'hFF) begin // 无穷大或NaN output_rec <= (number[22:0] == 0) ? ZERO : // 无穷大倒数为0 NAN; // NaN输入输出NaN ack <= 1; end else begin // 正常数值 // 保存符号和指数 input_sign <= number[31]; input_exp <= number[30:23]; // 归一化输入:构造 D' = {0, 126, mantissa} Ddash <= {1'b0, 8'd126, number[22:0]}; end end end INIT: begin // 关键修改:使用参考模块的初始值公式 current_x <= initial_guess; // Xi = P1 + P2*Ddash iter_count <= 0; end ITERATE: begin // 更新迭代值 current_x <= x_next; iter_count <= iter_count + 1; // 检查终止条件 if ((iter_count == MAX_ITER - 1) || (abs_diff < THRESHOLD)) begin final_result <= x_next; end end DONE: begin // 计算结果:1/number = sign * 2^(253 - input_exp) * mantissa output_rec <= {input_sign, 8'b11111101 - input_exp, final_result[22:0]}; ack <= 1; end endcase end end endmodule 请修改代码,让算192个FP32的指数和的倒数误差小一点
最新发布
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值