stm32高精度计算器

本文记录了使用STM32平台开发电子计算器的过程,涉及浮点数运算、符号判断、函数识别及错误处理等核心功能。作者通过C语言实现了加减乘除,包括浮点数对齐、浮点补齐等算法,并逐步解决了移植到STM32时遇到的数据类型和编译问题。此外,还讨论了代码优化和内存管理策略。

寒假作业要交一个电子计算器过考核,这就很烦人。

关于计算器,怎么说我stm32平台也不能太寒酸,该有的功能都得有,借鉴CASIO fx-991es计算器(CAS功能就不考虑了),做出升级,最长显示串N百,计算结果2*N百位以上

但是小数点后的浮点计算,符号判断,各种函数识别,语法错误判断,格式转换实属不易,还有自然输入(过难,日后研究)

keil5反人类编辑器,先用gcc+codeblock在电脑上模拟,移植到stm32时再对数据类型进行替换

更加恶心的是,用厂家自带的驱动,无法使用C++编译,更改N遍后各种报错,所以只能用C语言一点一点每天打几个小模块:

设计思路:

浮点计算:加减法采用浮点对齐,乘除法采用浮点补齐

符号判断:每个数据存放的char数组的第0个下标位存放符号

函数识别:配合逆波兰表达式,扫描识别入最高优先级栈

错误判断:扫描识别,配合函数多模式

格式转换:增加科学计数函数,增加独立的分数相约模块

新建头文件(ty.h)

 头文件:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max_len 60
int accurate = 4;//小数位数
void Add(char *ch1, char *ch2, char *ch3);
void add_sign(char a[], char sign);
void cut(char *a, int mode);//去首多余0,mode=1去小数点
void Div(char *ch1, char *ch2, char *ch3);
void fun2(char *str); //翻转字符串
void Minus(char *ch1, char *ch2, char *ch3);
void add_reduce(char a[]);//给无符号数加负号
void add_plus(char a[]);//正数加正号
void cheng(char aa[], char bb[], char *result);
void cut_plus(char a[]);//去除正号
void cut_sign(char a[]);//去除任意标点
int cmp_char(char a[], char b[]);//比较大小
void chu(char aa[], char bb[], char *result);
int cmp(char *ch1, char *ch2);
int change(int a);//结果模转数
char *divide(char a[], char b[]);
int find_point(char a[], int mode);//小数点下标,找不到0,mode=1找到多个返回-1
void jia(char aa[], char bb[], char *result);
void jian(char aa[], char bb[], char *result);
int max(int a, int b);//最大值
void mid(const char a[], int start, int end, char *result);
char *substract(char a[], char b[]);    //进行减法操作



void add_sign(char a[], char sign) {
    int d = (int) strlen(a);
    for (int i = d; i >= 1; i--) {
        a[i] = a[i - 1];
    }
    a[0] = sign;
    a[d + 1] = '\0';
}


int change(int a) {
    if (a > 0)return 1;
    else if (a < 0)return -1;
    else return 0;
}

void mid(const char a[], int start, int end, char *result) {
    memset(result, 0, sizeof(*result));
    for (int i = start; i <= end; i++) {
        result[i - start] = a[i];
    }
    result[end - start + 1] = '\0';
}

int cmp_char(char a[], char b[]) {
    int a_len = (int) strlen(a), b_len = (int) strlen(b);
    char a_cmp[a_len], b_cmp[b_len];
    int a_point = find_point(a, 0), b_point = find_point(b, 0);
    if (a_point == 0)a_point = (int) strlen(a);
    if (b_point == 0)b_point = (int) strlen(b);
    if (a_point > b_point)return 1;
    else if (a_point < b_point)return -1;
    else {
        mid(a, 0, a_point - 1, a_cmp);
        mid(b, 0, b_point - 1, b_cmp);
        if (strcmp(a_cmp, b_cmp) == 0)//整数部分完全相同
        {
            if (a_point == a_len) {

                if (b_point == b_len)return 0;
                else return -1;
            } else {
                if (b_point == b_len)return 1;
                else {
                    mid(a, a_point + 1, a_len - 1,a_cmp);mid(b, b_point + 1, b_len - 1,b_cmp);
                    return change(strcmp(a_cmp,b_cmp));
                }
            }

        } else {
            mid(a, 0, a_point - 1,a_cmp);mid(b, 0, b_point - 1,b_cmp);
            return change(strcmp(a_cmp,b_cmp));
        }
    }
}

int max(int a, int b) {
    return a > b ? a : b;
}


void cut(char *a, int mode) {
    int cnt0_start = 0, cnt0_end = 0, result_sign = 1;
    if (a[1] == '0' && a[2] != '.') {
        cnt0_start++;
        for (int i = 2; a[i] == '0' && a[i + 1] != '.'; i++) {
            cnt0_start++;
        }
    }
    if (!mode) {
        for (int i = (int) strlen(a) - 1; a[i] == '0'; i--) {
            if (a[i - 1] != '.')cnt0_end++;
        }
    } else {
        if (find_point(a, 0)) {
            for (int i = (int) strlen(a) - 1; a[i] == '0' || a[i] == '.'; i--) {
                cnt0_end++;
                if (a[i] == '.')break;
            }
        }
    }
    for (int i = cnt0_start + 1; i < (int) strlen(a) - cnt0_end; i++) {
        a[result_sign++] = a[i];
    }
    a[(int) strlen(a) - cnt0_start - cnt0_end] = '\0';
}

int find_point(char a[], int mode) {
    int a_len = (int) strlen(a);

    if (!mode) {
        for (int i = 0; i < a_len; i++) {
            if (a[i] == '.')return i;
        }
    } else {
        int flag = 1;
        int local = 0;
        for (int i = 0; i < a_len; i++) {
            if (a[i] == '.' && flag) {
                local = i;
                flag = 0;
            } else if (a[i] == '.' && !flag) {
       
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoseHu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值