MCU如何处理带小数点的数字?


8

请告诉我MCU如何处理十进制数字(例如“ 23.3”,“ 3.24”等)?它如何存储在存储器寄存器中?我知道在编程时处理这些数字时必须使用浮点数据类型。但是实际上在处理这些类型时,MCU内部正在发生什么。还告诉我没有FPU单元的MCU如何处理Float数据类型。

Answers:


13

典型的微控制器内部的数字根本没有小数点。它们是二进制整数。机器内部没有小数。编译器或汇编器可以让您以这种方式指定常量,但是在机器看到常量之前,它们会被转换为二进制。

但是,您可以决定整数值的单位。例如,假设您想在微积分中表示美元。它本身无法做到3.21美元,但可以做到321美分。微型仅在值321上运行,但是您知道它代表1/100美元的单位。

这只是说明任意单位概念的一个示例。通常,数字用几个二进制小数位表示。这与说每个计数代表2 -N的值相同,其中N是小数位数。这种表示称为“固定点”。您预先确定所需的分辨率,然后假想的二进制点右边有足够的位来支持该分辨率。例如,假设您需要以至少1/100的分辨率表示某物。在这种情况下,由于2 7 = 128 ,因此至少要使用7个小数位。实际上,您的分辨率为1/128。

机器不知道这是怎么回事。它将这些数字加减为普通整数,但一切仍然可行。当您将定点值相乘和相除时,它会变得有些棘手。两个定点值与N个小数位的乘积将具有2N个小数位。有时您只是跟踪新数字具有2N个小数位的事实,或者有时您可能会将其右移N位以返回到与以前相同的表示形式。

浮点是一回事,但是小数位数与整数部分一起存储,因此可以在运行时进行调整。对浮点数执行数学运算可能会花费很多周期。浮点硬件会为您完成所有这些操作,以便快速完成操作。但是,也可以在软件中执行相同的操作。没有理由不能编写一个子程序来添加两个浮点数,只是这样做比专用硬件做同样的事情要花费更多的时间。

我为8位PIC定义了一个3字节的浮点格式,并编写了一堆例程来处理它们。微控制器通常处理的实际值最多为10或12位精度。我的浮点格式使用16位精度,足以进行几次中间计算。

对于16位PIC,我也有32位格式。尾数使用一个16位字,这可以加快计算速度,因为这些PIC一次可以操作16位。

这些例程包含在我的PIC开发工具版本中。安装后,在SOURCE> PIC目录中查看名称中带有“ fp24”的文件,在SOURCE> DSPIC目录中查看名称中具有“ fp32f”的文件。


浮点标准还有一个IBM标准只是与偏差混为一谈。
NickHalden

4

定点算法通常用于在MCU中执行分数计算。

诀窍是说(例如)a的高16位uint32_t在小数点之前,而低16 位在小数点之后。存储的整数为1/2 ^ 16th。有一些小的警告,常规的算术“有效”。

这是概述


我对该“概述”链接投了赞成票。
0xakhil 2011年

3

除非您的MCU是带有浮点乘法器的DSP,否则所有内容都将存储为16位(或8或32,具体取决于您的平台)数字。这就是实际MCU所知道的全部。

在此上方,您具有“ C”代码和C编译器。编译器“知道”各种数据类型,例如char,int,uint,floats,doubles等。

浮点数在硬件上最常见的表示形式是IEEE格式。这会将尾数与指数分开,并使用两个16位字来存储信息。查看有关IEEE数字格式的Wiki文章。

因此,是编译器知道尾数和指数在哪里,并对其应用数学运算。记得学习对数吗?当您想倍数运算时,它们如何通过增加功能来简化数学?C编译器可以对指数进行类似的处理,然后将尾数相乘以计算出答案。因此,对于浮点乘法,编译器将创建汇编代码,以添加指数并执行尾数乘法。

MCU不知道数字!!!就像被告知要执行的操作一样,将内存加载到寄存器中,将内存添加到寄存器中,并根据需要设置进位标志,依此类推,直到乘法完成。

是C编译器和您的代码从MCU中“抽象”了数字,小数点等的概念。

附带一提的是,某些语言还支持“十进制”数据类型,该类型对金融系统很有用-在嵌入式平台上并不常见,因为浮点数使用较少的内存并有效执行。


1

没有fpu(例如大多数ARM)的完整处理器处理浮点的方式相同。带有软件fpu。有一个执行数学/按位运算的库。如果您还记得在小学时用铅笔和纸进行加法,乘法等操作,那么您从整数到带小数点的数字的变化就不会太大。进行数学运算时,只需调整数字,就可以在开始之前(加减)或完成之后(乘法或除法)排列小数点。硬性和软性fpu都没有区别,它们在操作之前和之后都会调整位,但是该操作基本上是整数操作。

我不记得现在在哪里找到它,但是得克萨斯仪器有一个很好的文档,涉及其DSP产品。它解释了它们的浮点格式,甚至解释了这些操作是如何工作的。它们的格式不具有舍入和非正规,无穷大,安静和信号传递之类的特性,如IEEE,因此比IEEE格式更容易理解,并且速度更快。看到该格式的实际效果后,您便迈出了迈向IEEE格式的第一步。四舍五入需要一些解释和思考,但其余部分,符号,指数和尾数的基本知识是相同的。

使用软浮点库在资源方面(内存,闪存,cpu周期)非常昂贵,我不建议在嵌入式系统或微控制器中使用它。例如,只要记住或可能确保所有关联的数学都理解数字都乘以10,并且如果/当显示为a时,则12.3和24.5就像整数123和245一样易于管理。用户在该转换上添加小数点。节省大量代码和性能。当然,整数除法对于微控制器和嵌入式系统是一件坏事,而且大多数处理器都没有除法指令,其中包括除以10以转换为十进制以显示给用户。同样的答案,使用库完成从C代码获得的除法。


0

浮点数以32位二进制格式存储,第一位指示浮点数是否为pos / neg数,接下来的8位为指数-127,然后有23位为整数,包括小数位,即:
1 00010001 00010001000000000000000
所以1是负数,在这种情况下,接下来的8位用来表示指数:
0001 0001 = 17 (17-127 = -110)
然后将尾数除以:
(1+1/4+1/128)2^5

2^5是将浮点数移动到二进制数时小数位的移动。结果转换时确实丢失了一些数字,但它们接近。1.5ex10-110
我可能在跟随其他人时犯了错误,但这是如何将浮点数保存在内存中的一般思路。


2
这篇文章可能包含信息的痕迹,但隐藏在一些未格式化的聊天消息文本墙中。Stack Exchange并非Facebook,因此请尝试使用更专业的语言,并使用从段落开始的可用格式工具,使信息清晰易读。
管道
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.