Feature request - DrawFloat and DrawNumber with thousands separator #353
Replies: 3 comments
-
Thanks for the suggestion, I will think about this and perhaps overload the existing functions with an extra optional parameter. The other option is to add the function to the TFT_eFEX library. |
Beta Was this translation helpful? Give feedback.
-
Thanks, but do not use my code example as it doesn't work properly if any of the numbers between commas do not have three digits! Should have tested properly before posting. |
Beta Was this translation helpful? Give feedback.
-
Here's one way to do this using locales (in C++). This is not a lightweight solution, but it's flexible and simple - easy to change the digit patterns etc. Found the idea on stackoverflow and adapted. Tested this and it works on esp32. I'm not suggesting that this approach be included in the library, but it's a work-around for people who need it.
Use it like this:
|
Beta Was this translation helpful? Give feedback.
-
Hi, many thanks for a superb library. It would be useful to be able to print numbers with separator for thousands, eg 1,000,000.000.
I am aware that some countries use different separators for thounds and decimals, so most use , and . while some use . for thousands and , for decimal. Confusing!
As a novice programmer I added it as below, based on your drawFloat but I am sure you can find a better method:
/***************************************************************************************
** Function name: drawSepFloat
** Descriptions: drawSepFloat, prints 7 non zero digits maximum, with thousands separator
***************************************************************************************/
int16_t TFT_eSPI::drawSepFloat(float floatNumber, uint8_t dp, int32_t poX, int32_t poY)
{
return drawSepFloat(floatNumber, dp, poX, poY, textfont);
}
int16_t TFT_eSPI::drawSepFloat(float floatNumber, uint8_t dp, int32_t poX, int32_t poY, uint8_t font)
{
isDigits = true;
char str[16]; // Array to contain decimal string
uint8_t ptr = 0; // Initialise pointer for array
int8_t digits = 1; // Count the digits to avoid array overflow
float rounding = 0.5; // Round up down delta
if (dp > 7) dp = 7; // Limit the size of decimal portion
// Adjust the rounding value
for (uint8_t i = 0; i < dp; ++i) rounding /= 10.0;
if (floatNumber < -rounding) // add sign, avoid adding - sign to 0.0!
{
str[ptr++] = '-'; // Negative number
str[ptr] = 0; // Put a null in the array as a precaution
digits = 0; // Set digits to 0 to compensate so pointer value can be used later
floatNumber = -floatNumber; // Make positive
}
floatNumber += rounding; // Round up or down
// For error put ... in string and return (all TFT_eSPI library fonts contain . character)
if (floatNumber >= 2147483647) {
strcpy(str, "...");
return drawString(str, poX, poY);
}
// No chance of overflow from here on
// Get integer parts, ignore the possibility of billions for now!
uint32_t temp = (uint32_t)floatNumber;
uint32_t thousands = temp/1000;
uint32_t millions = thousands/1000;
uint32_t units = temp % 1000; // % is modulo operator
if (millions !=0) {
ltoa(millions, str+ptr, 10);
while ((uint8_t)str[ptr] != 0) ptr++; // Move the pointer along
digits += ptr; // Count the digits
str[ptr++] = ','; // Add comma
//str[ptr + 1] = 0; // Add a null but don't increment pointer so it can be overwritten
}
if (thousands !=0) {
ltoa(thousands, str+ptr, 10);
while ((uint8_t)str[ptr] != 0) ptr++; // Move the pointer along
digits += ptr; // Count the digits
str[ptr++] = ','; // Add comma
//str[ptr + 1] = 0; // Add a null but don't increment pointer so it can be overwritten
}
// Put integer part into array
ltoa(units, str + ptr, 10);
// Find out where the null is to get the digit count loaded
while ((uint8_t)str[ptr] != 0) ptr++; // Move the pointer along
digits += ptr; // Count the digits
str[ptr++] = '.'; // Add decimal point
str[ptr] = '0'; // Add a dummy zero
str[ptr + 1] = 0; // Add a null but don't increment pointer so it can be overwritten
// Get the decimal portion
floatNumber = floatNumber - temp;
// Get decimal digits one by one and put in array
// Limit digit count so we don't get a false sense of resolution
uint8_t i = 0;
while ((i < dp) && (digits < 9)) // while (i < dp) for no limit but array size must be increased
{
i++;
floatNumber *= 10; // for the next decimal
temp = floatNumber; // get the decimal
ltoa(temp, str + ptr, 10);
ptr++; digits++; // Increment pointer and digits count
floatNumber -= temp; // Remove that digit
}
// Finally we can plot the string and return pixel length
return drawString(str, poX, poY);
}
Beta Was this translation helpful? Give feedback.
All reactions