存储小数的时候尽量用定点数来表示

定点数: decimal 或 numeric




单精度浮点数的有效数字二进制是24位,按十进制来说,是8位;双精度浮点数的有效数字二进制是53位,按十进制来说,是16 位 一个实数的有效数字超过8位,用单精度浮点数来表示的话,就会产生误差!同样,如果一个实数的有效数字超过16位,用双精度浮点数来表示,也会产生误差

b) IEEE754标准的计算机浮点数,在内部是用二进制表示的,但在将一个十进制数转换为二进制浮点数时,也会造成误差,原因是不是所有的数都能转换成有限长度的二进制数。

即一个二进制可以准确转换成十进制,但一个带小数的十进制不一定能够准确地用二进制来表示。

实例:
drop table if exists t;
 
create table t(value float(10,2));
 
insert into t values(131072.67),(131072.68);
 
select value from t;
 
+-----------+
 
| value |
 
+-----------+
 
| 131072.67 |
 
| 131072.69 |
 
+-----------+

<think>嗯,用户想用51单片机做一个计算器,支持四则运算小数显示,用码管。我得先理清楚整个系统的组成部分。首先,硬件方面,51单片机是核心,需要键盘输入、码管显示,可能还需要其他外设比如锁存器来驱动码管。软件部分的话,得处理按键扫描、运算逻辑、显示驱动这些模块。 键盘输入部分,用户可能需要矩阵键盘,4x4的布局比较常见,16个键,字0-9,加减乘除,等于,小数点,还有清除键。矩阵键盘的扫描需要用到IO口,行列轮流检测,确定哪个按键被按下。要注意消抖,硬件或者软件消抖,软件的话可以延时检测。 码管显示的话,因为是多个码管,可能需要动态扫描,比如4位或者8位的。要显示小数的话,得考虑小数点的位置,比如在某个码管的dp段控制。码管驱动可能需要锁存器,比如74HC573来扩展IO,因为51的IO口可能不够用。动态扫描需要定时器中断,定时刷新每个码管,保持显示稳定。 运算逻辑部分,处理四则运算,需要考虑运算优先级吗?比如先乘除后加减。或者采用后缀表达式,比如逆波兰,但实现起来可能复杂。或者按顺序计算,不考虑优先级,但用户可能希望符合常规的运算顺序。这需要权衡。另外,处理小数的话,存储用浮点还是定点数?51的浮点运算能力有限,定点数可能更高效,比如用整表示小数点后固定位,但编程会复杂一些。用户需要显示小数,所以运算过程中要保留小数位,可能涉及到精度问题。 存储方面,需要存储当前输入的字,运算符,中间结果等。可能需要一个缓冲区来保存输入的运算符,比如用组或者结构体。比如,当用户按字键时,将字累加到当前操作,按运算符时,存储当前操作运算符,然后准备接收下一个操作。等于键按下时,执行运算并显示结果。 程序结构的话,主循环负责扫描键盘,处理输入,更新显示。中断服务程序处理码管的动态扫描。运算函处理具体的加减乘除,注意错误处理,比如除零的情况,溢出等。显示函需要将值转换为码管的段码,包括小数点的处理。 可能的难点是按键消抖码管显示的稳定性,动态扫描的频率要合适,不然会有闪烁。另外运算中的精度错误处理需要仔细考虑,比如除以零时要提示错误。小数点的处理,比如输入字时,用户按小数点后,后面的字作为小数部分,需要记录小数点的位置,并在显示时正确点亮dp段。 需要规划变量,比如当前输入的值,前一个操作,当前运算符,是否已经按下小数点,小数点的位等。例如,当用户输入字时,如果有小数点按下,则后续字作为小数部分,乘以相应的0.1、0.01等,或者用整保存,记录小数。 可能还需要考虑最大输入位,防止溢出。比如,码管显示4位,那么输入的字不能超过4位,或者根据据类型来决定。比如使用long类型保存整部分,或者用定点数,比如32位整,其中后两位是小数部分。 步骤分解的话,大概分硬件设计、键盘驱动、显示驱动、运算逻辑、主程序逻辑这几个部分。硬件连接要确认好引脚分配,比如P0口接码管的段选,P2口接位选,矩阵键盘的行列接P1口或者其他可用端口。 测试时,先单独调试各个模块,比如先确保码管能正确显示字,再测试键盘输入是否准确,最后整合运算逻辑。调试过程中可能需要用Proteus仿真或者实际硬件测试,逐步排查问题。 总之,整个项目需要模块化设计,逐步实现每个部分,然后整合测试。考虑到51的资源有限,代码要尽量优化,避免内存溢出或者运行缓慢。特别是浮点运算可能会比较慢,如果采用定点数的话,可以提高效率,但需要处理小数点位置。</think>好的!基于51单片机的计算器设计可以分为硬件设计软件设计两部分。以下是具体的实现思路步骤: --- ### **一、硬件设计思路** 1. **核心控制器** - 使用STC89C52或其他51系列单片机作为主控芯片。 2. **输入模块** - **4×4矩阵键盘**:布局如下: ``` 1 2 3 + 4 5 6 - 7 8 9 × C 0 = ÷ ``` - 功能键:`C`(清除)、`=`(计算结果)、`+/-`(符号切换,可选)。 3. **显示模块** - **4位或8位共阴码管**:用于显示输入结果。 - **驱动芯片**:74HC573锁存器扩展IO口,控制段选位选。 - **小数点处理**:通过控制码管的`dp`段(第8位)实现。 4. **电路连接** - 键盘行线接P1口高4位,列线接P1口低4位。 - 码管段选接P0口,位选接P2口。 --- ### **二、软件设计思路** #### **1. 主程序流程图** ``` 初始化 → 键盘扫描 → 处理输入 → 更新显示 → 循环 ``` #### **2. 关键代码模块** - **键盘扫描** - 使用行列扫描法检测按键,配合软件消抖(延时10ms)。 - 示例代码片段: ```c char KeyScan() { char key = 'N'; // 默认无按键 P1 = 0xF0; // 高4位输出0,低4位输入 if (P1 != 0xF0) { DelayMs(10); // 消抖 // 扫描具体按键... } return key; } ``` - **显示驱动** - 动态扫描码管,通过定时器中断刷新显示。 - 示例代码片段: ```c void Timer0_ISR() interrupt 1 { static uint8_t pos = 0; // 当前显示位 P2 = ~(0x01 << pos); // 位选 P0 = seg_code[display_buffer[pos]]; // 段选 pos = (pos + 1) % 4; // 循环显示4位 } ``` - **运算逻辑** - **存储**:用`float`类型保存操作结果(注意51的浮点运算速度较慢)。 - **运算优先级**:暂时按顺序执行(如不支持括号,需用户手动分步计算)。 - **错误处理**:检测除零错误并显示`Err`。 - **小数处理** - 输入时记录小数点位置,转换为浮点存储。 - 显示时分离整小数部分,控制`dp`段点亮。 --- ### **三、核心难点与解决方案** 1. **浮点运算速度慢** - 改用定点数(如放大1000倍用`long`存储),但需自行处理小数位。 2. **码管显示闪烁** - 提高定时器中断频率(如1ms刷新一次)。 3. **按键冲突** - 增加长按检测或队列缓冲机制。 --- ### **四、示例代码框架** ```c #include <reg52.h> #include <math.h> // 码管段码表(0-9小数点) code unsigned char seg_code[] = {0x3F, 0x06, 0x5B, ..., 0x80}; // 最后一位为dp float num1 = 0, num2 = 0, result = 0; char op = '\0'; // 当前运算符 bit has_decimal = 0; // 是否输入了小数点 void main() { Init_Timer0(); // 初始化定时器 while(1) { char key = KeyScan(); if (key != 'N') ProcessKey(key); // 处理按键 } } void ProcessKey(char key) { if (key >= '0' && key <= '9') { // 处理字输入 } else if (key == '.') { has_decimal = 1; // 标记小数点 } else if (key == 'C') { // 清除据 } else if (key == '=') { // 执行计算 } else { // 保存运算符 } } ``` --- ### **五、调试建议** 1. **分模块调试** - 先单独测试键盘输入码管显示是否正常。 2. **仿真工具** - 使用Proteus仿真验证硬件逻辑。 3. **边界测试** - 测试最大值、除零、负等特殊情况。 --- 通过以上步骤,您可以逐步实现一个支持四则运算小数显示的51单片机计算器。如果需要更详细的代码或电路图,可以进一步沟通!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值