Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting digits in a float

I am following some beginner tutorials for OpenGL in c++ but as I started off as a c# programmer it has made me take a lot of things for granted. So my problem occurred when I was debug printing my FPS reading to the output. I think the method was something like DebugPrintString off the top of my head which took a char* and basically i was printing "FPS: x". I was using scanf_s to place the fps value into the character array but this is where my problem lies. How big does the character array have to be?

Let me elaborate a bit more: my FPS reading is stored as a float as the frames/seconds usually ends up not being a nice number. So my number could be 60, or it could be 59.12345. 60 would only need 2 bytes and 59.12345 would need 8 (1 for the period). So I thought "Oh ok i need to count the amount of digits it has, no problem!" Boy was I in for a shock.

I made a method to count the digits, counting the left hand side of the decimal place was easy, just first of all cast it as a int to remove the decimal points and divide by 10 (actually I think I had some bitshifting there) and count the amount of times i can do that until i reach 0. And now to count the digits on the right hand side, well i'll just multiply by 10, subtract the digit, and do this until it reaches zero. The method would usually return 32 i think it was. So i WTF'd and had a look at it in debug, turns out when you multiply the float effectively moving the digit columns up because of the well known precision issue it just appended another digit!

I did some major googling, but couldn't really find anything above char str[128] and scanf if in then do strlen(str) minus 1 (null terminator). But i was hoping for a more elegant solution. In the end i just casted it as an int and allowed enough for 9999 fps, also added a check to see if the fps > 9999 but I don't think thats ever going to happen. Better safe than SEG FAULT :(

TLDR: Is there a way to get the amount of digits in a float? How does scanf do it?!

Sorry for long post, just wanted to share my frustation >:D

Edit: spelling errors

like image 559
daniel Avatar asked Dec 10 '22 17:12

daniel


2 Answers

Considering it's C++ we're talking about, why not go the STL way?

Precision 5 places after decimal dot, may be variable amount of characters:

std::stringstream ss;
ss << std::setprecision (5) << std::fixed << f; 
std::string fps = ss.str();

Precision maximum 5 significant digits:

std::stringstream ss;
ss << std::setprecision (5) << f; 
std::string fps = ss.str();
like image 84
Kornel Kisielewicz Avatar answered Dec 17 '22 20:12

Kornel Kisielewicz


You can truncate/force the floating-point number to whatever precision you want using sprintf. Then the problem goes away.

like image 34
John Avatar answered Dec 17 '22 22:12

John