Sprintf() a float number

hi there
I have a float number, say 6.38. I want to show that on a screen with one floating point.
so I used the code below

char str_tmp[5];
	sprintf(str_tmp,"%2.1f",6.38); 

I expect to get 6.3 but looks like the code line above, rounds up 6.38 to 6.4 and then shows it with one floating point...

how can I get 6.3 and not 6.4 ? I dont want the foating number to round up...

Try truncating the value

https://m.cplusplus.com/reference/cmath/trunc/

that's not really what I want... any other suggestions?

Sorry missed the point

One idea is x10, truncate and divide by 10 to get 1 decimal digit (give or take the poor precision of floats)

For many of the Arduino processors, floats are disabled in sprintf.

Another way is to convert the float number to a string with the dtostrf() function then use the %s placeholder to put it into your snprintf() function. Note that snprintf() is safer to use.

float floatNumber = 3.141592;

void setup()
{
   Serial.begin(115200);
   char buffer[30];  // final string
   char floatStr[10]; // float converted to string
   dtostrf(floatNumber, 8, 6, floatStr);  // 8 char min total width, 6 after decimal
   snprintf(buffer,  sizeof(buffer), "the float number is %s", floatStr);
   Serial.println(buffer);
}

void loop()
{
  
}

Your sketch shows:

the float number is 3.141592

OP wants: 3.1

Many arduino print functions similar to Serial.print() has the second parameter, controlling the number of floating point

float f = 6.38;
Serial.print(f,1);

output the 6.4

do before printing:

float  f = 6.38;
int i = f * 10;          // => 63
float f_1 = i/10;  //  => 6.3
1 Like

That command shows: 6.4 and not 6.3!
Output:

6.4

one approach

     123.456
#define frac(x)     (int(1000*(x - int(x))))

char s [80];

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    float x = 123.456;

    sprintf (s, "  %6d.%03d", int(x), frac(x));
    Serial.println (s);
}

// -----------------------------------------------------------------------------
void
loop ()
{
}

Your output is:

 123.456

But, OP wants:

123.4

[

quote="gcjr, post:12, topic:1013193"]
#define frac(x) (int(1000*(x - int(x))))
[/quote]

shouldn't he be able to figure out changing 1000 to 10?

Esp. With hint in post #4 :slight_smile:

===>
One idea is x10, truncate and divide by 10.0 to get 1 decimal digit (give or take the poor precision of floats)

float n = 6.38;
==> n = n*10; //n = 63.8
==> n1 = (int)n; //n = 63
==> n = n1/10.0; //n = 6.3         n = n1/10 = 6.0
void setup()
{
  Serial.begin(115200);
  float n = 6.38;
  n = n * 10; //n = 63.8
  int n1 = (int)n; //n = 63
  //Serial.println(n1); //n1 = 63
  n = n1 / 10.0; //n = 6.3
  Serial.println(n, 1);
}

void loop()
{

}

Output:

6.3

So simple and that's why it is difficult for the OP?

Another version found in net and then moderated. Good as an exercise as the solution contains so many fundamental concepts of C Programming.

float n = 6.38;
char myData[10] = {0};

void setup()
{
  Serial.begin(9600);
  //--extract integer part------------
  int iPart = (int)n;  // ipart = 6
  
  //--extract fractional part---------
  float fPart = n - (float)iPart; //0.38
  
  //-convert iPart into string and save in myData[]-------
  int index = intToStr(iPart, myData);//
  
  //-------place point at place marked by index-----------
  myData[index] = '.'; //place point
  
  //---- convert fPart to 3.8)----------
  fPart = fPart * 10.0;//fPart = 3.80; 
  
  //-----extract 3 from 3.8----------------
  int iPartF = (int)fPart; //iPrtF = 3
  
  //--cnvert iPartF into string and append at end og myData----- 
  intToStr(iPartF, myData + index + 1); //
  Serial.print(myData);
}

void loop()
{

}

int intToStr(int x, char str[])
{
  int i = 0;
  do
  {
    str[i] = (x % 10) + '0';//saving ASCII codes for digits of iPart 
    x = x / 10;
    i++;
  }
  while(x !=0);

  reverse(str, i);
  str[i] = '\0';
  return i;
}

void reverse(char *str, int len)
{
  int i = 0, j = len - 1, temp;
  while (i < j) 
  {
    temp = str[i];
    str[i] = str[j];
    str[j] = temp;
    i++;
    j--;
  }
}

Output:

6.3

i don't believe there's an issue printing an arbitrary # of decimal digits using Serial.println (). the issue is getting around the loat limitation using sprintf()

123.5
123.46
123.456
123.456
// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    float x = 123.456;

    Serial.println (x, 1);
    Serial.println (x, 2);
    Serial.println (x, 3);
    Serial.println (x, 3);
}

// -----------------------------------------------------------------------------
void
loop ()
{
}

note that it is 0.46, not 0.45

Why?

I have just implemented the algorithm of Post #4 @J-M-L.

It his liberty but ours duty as volunteers?

We help people. If they ask for help with X, and they have an XY problem, giving them X is not helping.

If they can explain the need for X, then we're helping.

1 Like

it's always a good question to ask "why" (search for "ask why seven times" or "The 7 levels of why" (some variation with "the Five Why's.") for literature on the topic) - let's you challenge what you really have in mind.