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?
bko
January 9, 2017, 4:29am
2
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…
bko
January 9, 2017, 2:10pm
6
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!
Ric
January 10, 2017, 12:20am
8
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
Ric
January 10, 2017, 6:24am
10
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
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);
ScruffR
January 10, 2017, 11:58am
12
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++).
I guess C style casts are OK, particularly if you know exactly what your are casting (i.e. no dynamic typing).
1 Like