toFloat() problem? [solved]

I’m having trouble using String.toFloat() anyone seen similar problems?

This code:

newConst = s.toFloat();
Serial.print("Incoming String s="+s+" conversion s.toFloat()=");   
Serial.println(newConst);

Produces this output in Serial monitor:

Incoming String s=1294101.041 conversation s.toFloat()=1294101.00

The problem being, the fractional part of the incoming string is ignored. Is that a product of Serial.println or is toFloat() broken?

Hi @steelydev

The problem you are seeing is due to the default print method–it limits floats to two decimal places by default. Try this:

Serial.println(newConst,6);

Also, what’s the datatype of newConst?

Try this

  float newConst = s.toFloat();
  Serial.printlnf("Incoming String s=%s conversion s.toFloat()=%.5f", (const char*)s, newConst);

@bko @ScruffR Thanks for your quick responses. Had to get some sleep last night. Took your advice, but I think toString() is broken.

Changed code to:

float f = s.toFloat();
Serial.print("Incoming String s="+s+" conversion s.toFloat()=");   
Serial.println(f,6);

And since I can not copy from Particle Dev Serial Monitor, I took a screen shot of output:

did you try:

double f = atof(s.c_str());

?

I’m wondering what type ‘s’ is…

You are out of precision in single-precision floating point. 1294101.00 is the correctly rounded result.

See this page to play with various numbers:

https://www.h-schmidt.net/FloatConverter/IEEE754.html

2 Likes

@bko that must be it. Doesn’t look like that big a number to me. Cool calculator

@BulldogLowell that’s the call!

const String s1 = "1294101.041";
const String s2 = "2.161266819";
const String s3 = "0.00000008871575401";
char c[50];	

double d = atof(s1.c_str());
Serial.print("String="+s1+" d=");Serial.println(d,20);

d = atof(s2.c_str());
Serial.print("String="+s2+" d=");Serial.println(d,20);

d = atof(s3.c_str());
Serial.print("String="+s3+" d=");Serial.println(d,20);

Produces:

Thanks, guys!

Just as an aside, you can also print using a single printlnf statement to give you the same result.

Serial.printlnf("String=%s d=%.20f", (const char*)s1, d);

If you’re already using a char* or const char* instead of String objects, then you don’t need the cast.

1 Like

That part seems to have been "ignored" when given the first time already :wink:

Oops, I missed that in reading your post. The first line about the datatype was the meat of your response, so I didn’t even read the print statement - didn’t mean to copy :flushed:

1 Like

Nice tips.

I was told to always use static_cast for casting:

Serial.printf("String=%s d=%.f",static_cast<const char*>(3),d);

That cast in this situation is only there to employ the cast (const char*) overload of String to provide a C-string.

Another way without any cast would be

Serial.printf("String=%s d=%.f", s1.c_str(), d);

Which does exatly the same, but I personally prefer the cast over a function call.

You may have learned C++ from an actual learned C++ programmer (not a C programmer that later converted to C++). :wink:

I guess C style casts are OK, particularly if you know exactly what your are casting (i.e. no dynamic typing).

1 Like