在嵌入式C中使用浮点数与sprintf() [英] Using floats with sprintf() in embedded C

查看:387
本文介绍了在嵌入式C中使用浮点数与sprintf()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道,如果 float 变量可以在 sprintf()函数中使用。



喜欢,如果我们写:

  sprintf(str,adc_read = d \\\
,adc_read);

其中 adc_read 是一个整数变量,它将存储字符串


adc_read = 1023 \\\


str (假设 adc_read = 1023



如何使用浮点变量代替整数?

解决方案

由于你是一个嵌入式平台,很可能您没有从 printf() -style的全部功能功能。



假设你有浮动(仍然不一定是嵌入的东西给定),你可以用以下方式来模拟它:

  char str [100]; 
float adc_read = 678.0123;

char * tmpSign =(adc_read< 0)? - :;
float tmpVal =(adc_read< 0)? -adc_read:adc_read;

int tmpInt1 = tmpVal; //获取整数(678)。
float tmpFrac = tmpVal - tmpInt1; //获取分数(0.0123)。
int tmpInt2 = trunc(tmpFrac * 10000); //转成整数(123)。

//打印为零件,请注意,您需要零分位数填充。

sprintf(str,adc_read =%s%d。%04d\\\
,tmpSign,tmpInt1,tmpInt2);

您需要根据整数的大小限制小数后的字符数。例如,使用16位有符号整数,您将被限制为四位数(9,999是可以表示的最大十次减号),



但是,通过进一步处理小数部分,每次将其移位四位十进制数(并使用/减去整数部分),直到有您需要的精度为止,可以解决此问题。






更新:



您提到的最后一点正在使用 avr-gcc 回应其他答案之一。我发现以下网页似乎描述了您需要在 printf()中使用%f 声明这里



正如我原来怀疑的,您需要做一些额外的工作才能获得浮点支持。这是因为嵌入式的东西很少需要浮点数(至少没有我做过的东西)。它涉及在makefile中设置额外的参数并链接额外的库。



然而,由于需要处理一般的输出格式,这可能会增加你的代码大小。如果你可以将你的浮点数限制在4位小数以内,我建议把代码转换成一个函数,只是使用这个函数 - 这可能会占用更少的空间。



如果该链接消失,则必须确保您的gcc命令具有 - Wl,-u,vfprintf -lprintf_flt -lm 。这将转换为:




  • 强制vfprintf最初未定义(以便链接器必须解决它)。

  • 指定用于搜索的浮点 printf()库。

  • 指定用于搜索的数学库。


Guys, I want to know if float variables can be used in sprintf() function.

Like, if we write:

sprintf(str,"adc_read = %d \n",adc_read);

where adc_read is an integer variable, it will store the string

"adc_read = 1023 \n"

in str (assuming that adc_read = 1023)

How can I use a float variable in place of integer?

解决方案

Since you're on an embedded platform, it's quite possible that you don't have the full range of capabilities from the printf()-style functions.

Assuming you have floats at all (still not necessarily a given for embedded stuff), you can emulate it with something like:

char str[100];
float adc_read = 678.0123;

char *tmpSign = (adc_read < 0) ? "-" : "";
float tmpVal = (adc_read < 0) ? -adc_read : adc_read;

int tmpInt1 = tmpVal;                  // Get the integer (678).
float tmpFrac = tmpVal - tmpInt1;      // Get fraction (0.0123).
int tmpInt2 = trunc(tmpFrac * 10000);  // Turn into integer (123).

// Print as parts, note that you need 0-padding for fractional bit.

sprintf (str, "adc_read = %s%d.%04d\n", tmpSign, tmpInt1, tmpInt2);

You'll need to restrict how many characters come after the decimal based on the sizes of your integers. For example, with a 16-bit signed integer, you're limited to four digits (9,999 is the largest power-of-ten-minus-one that can be represented).

However, there are ways to handle this by further processing the fractional part, shifting it by four decimal digits each time (and using/subtracting the integer part) until you have the precision you desire.


Update:

One final point you mentioned that you were using avr-gcc in a response to one of the other answers. I found the following web page that seems to describe what you need to do to use %f in your printf() statements here.

As I originally suspected, you need to do some extra legwork to get floating point support. This is because embedded stuff rarely needs floating point (at least none of the stuff I've ever done). It involves setting extra parameters in your makefile and linking with extra libraries.

However, that's likely to increase your code size quite a bit due to the need to handle general output formats. If you can restrict your float outputs to 4 decimal places or less, I'd suggest turning my code into a function and just using that - it's likely to take up far less room.

In case that link ever disappears, what you have to do is ensure that your gcc command has "-Wl,-u,vfprintf -lprintf_flt -lm". This translates to:

  • force vfprintf to be initially undefined (so that the linker has to resolve it).
  • specify the floating point printf() library for searching.
  • specify the math library for searching.

这篇关于在嵌入式C中使用浮点数与sprintf()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆