[PIC®/AVR®/dsPIC®产品] 一个OLED的显示浮点数的函数存在输出差0.01的缺陷,解决方法

[复制链接]
 楼主| 734774645 发表于 2024-1-8 22:02 | 显示全部楼层 |阅读模式
本帖最后由 734774645 于 2024-1-10 15:32 编辑

原来的函数是这样的

  1. /**
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]        Display a float
  3. * @param x  position x-axis  0 - 127
  4. * @param y  position y-axis  0
  5. * @param num  The order of the Chinese characters in the Hzb[] array
  6. * @param accuracy Preserve decimal places
  7. * @param fontsize 8/16
  8. * [url=home.php?mod=space&uid=536309]@NOTE[/url]        
  9. */
  10. void OLED_ShowFloat(uint8_t x, uint8_t y, float num, uint8_t accuracy, uint8_t fontsize)
  11. {
  12.         uint8_t i = 0;
  13.         uint8_t j = 0;
  14.         uint8_t t = 0;
  15.         uint8_t temp = 0;
  16.         uint16_t numel = 0;
  17.         uint32_t integer = 0;
  18.         float decimals = 0;

  19.         //Is a negative number?
  20.         if (num < 0)
  21.         {
  22.                 OLED_ShowChar(x, y, '-', fontsize);
  23.                 num = 0 - num;
  24.                 i++;
  25.         }

  26.         integer = (uint32_t)num;
  27.         decimals = num - integer;

  28.         //Integer part
  29.         if (integer)
  30.         {
  31.                 numel = (uint16_t)integer;

  32.                 while (numel)
  33.                 {
  34.                         numel /= 10;
  35.                         j++;
  36.                 }
  37.                 i += (j - 1);
  38.                 for (temp = 0; temp < j; temp++)
  39.                 {
  40.                         OLED_ShowChar(x + 8 * (i - temp), y, integer % 10 + '0', fontsize); // 显示整数部分
  41.                         integer /= 10;
  42.                 }
  43.         }
  44.         else
  45.         {
  46.                 OLED_ShowChar(x + 8 * i, y, temp + '0', fontsize);
  47.         }
  48.         i++;
  49.         //Decimal part
  50.         if (accuracy)
  51.         {
  52.                 OLED_ShowChar(x + 8 * i, y, '.', fontsize);

  53.                 i++;
  54.                 for (t = 0; t < accuracy; t++)
  55.                 {
  56.                         decimals *= 10;
  57.                         temp = (uint8_t)decimals;
  58.                         OLED_ShowChar(x + 8 * (i + t), y, temp + '0', fontsize);
  59.                         decimals -= temp;
  60.                 }
  61.         }
  62. }
当我要显示28.55的时候显示成了28.54,大家猜猜是哪儿的错误。

评论

[url=home.php?mod=space&uid=2502980]@mxkw0514[/url] :是的,我打错了。是0.01  发表于 2024-1-10 15:32
这个好像差0.01,跟楼主说的不一样  发表于 2024-1-10 09:37
 楼主| 734774645 发表于 2024-1-8 22:06 | 显示全部楼层
经过认真研究找到了问题,并修正了这个BUG。
  1. /**
  2. * @brief        Display a float
  3. * @param x  position x-axis  0 - 127
  4. * @param y  position y-axis  0
  5. * @param num  The order of the Chinese characters in the Hzb[] array
  6. * @param accuracy Preserve decimal places
  7. * @param fontsize 8/16
  8. * @note       
  9. */
  10. void OLED_ShowFloat(uint8_t x, uint8_t y, float num, uint8_t accuracy, uint8_t fontsize)
  11. {
  12.         uint8_t i = 0;
  13.         uint8_t j = 0;
  14.         uint8_t t = 0;
  15.         uint8_t temp = 0;
  16.         uint16_t numel = 0;
  17.         uint32_t integer = 0;
  18.         float decimals = 0;

  19.         //Is a negative number?
  20.         if (num < 0)
  21.         {
  22.                 OLED_ShowChar(x, y, '-', fontsize);
  23.                 num = 0 - num;
  24.                 i++;
  25.         }

  26.         integer = (uint32_t)num;
  27.         decimals = num - integer;

  28.         //Integer part
  29.         if (integer)
  30.         {
  31.                 numel = (uint16_t)integer;

  32.                 while (numel)
  33.                 {
  34.                         numel /= 10;
  35.                         j++;
  36.                 }
  37.                 i += (j - 1);
  38.                 for (temp = 0; temp < j; temp++)
  39.                 {
  40.                         OLED_ShowChar(x + 8 * (i - temp), y, integer % 10 + '0', fontsize); // 显示整数部分
  41.                         integer /= 10;
  42.                 }
  43.         }
  44.         else
  45.         {
  46.                 OLED_ShowChar(x + 8 * i, y, temp + '0', fontsize);
  47.         }
  48.         i++;
  49.         //Decimal part
  50.         if (accuracy)
  51.         {
  52.                 OLED_ShowChar(x + 8 * i, y, '.', fontsize);
  53.                 i++;
  54.                 for (t = 0; t < accuracy; t++)
  55.                 {
  56.                         decimals *= 10;
  57.                         temp = (uint8_t)decimals;
  58.             // 添加一个小的调整来处理精度问题
  59.             if(t==accuracy-1&&decimals-temp>=0.5) temp++;
  60.             
  61.                         OLED_ShowChar(x + 8 * (i + t), y, temp + '0', fontsize);
  62.                         decimals -= temp;
  63.                 }
  64.         }
  65. }
你看出来为何要这么做了吗?
xch 发表于 2024-1-9 18:09 | 显示全部楼层
为啥不用 printf 函数?
chenqianqian 发表于 2024-1-10 08:12 来自手机 | 显示全部楼层
直接转换成字符串显示
mxkw0514 发表于 2024-1-10 09:32 | 显示全部楼层
734774645 发表于 2024-1-8 22:06
经过认真研究找到了问题,并修正了这个BUG。
你看出来为何要这么做了吗?
...

请问这句t==accuracy-1&&decimals-temp>=0.5是如何消除差0.1精度的呢?没看懂。
 楼主| 734774645 发表于 2024-1-10 13:51 | 显示全部楼层
chenqianqian 发表于 2024-1-10 08:12
直接转换成字符串显示

意思是用重定向到OLED?
 楼主| 734774645 发表于 2024-1-10 13:51 | 显示全部楼层
mxkw0514 发表于 2024-1-10 09:32
请问这句t==accuracy-1&&decimals-temp>=0.5是如何消除差0.1精度的呢?没看懂。

你猜着是怎么个回事。
 楼主| 734774645 发表于 2024-1-10 13:52 | 显示全部楼层
mxkw0514 发表于 2024-1-10 09:32
请问这句t==accuracy-1&&decimals-temp>=0.5是如何消除差0.1精度的呢?没看懂。

说实话我也看不懂,这代码是我下载的,但是显示发现了问题。在百分位超过4的时候出现了错误。然后我把代码发给GPT帮我检查,它发现了这个问题,帮我进行了修正。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

210

主题

3585

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部

210

主题

3585

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部