You could look in Print.cpp which on my Windows PC is in C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
n += print('.');
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)(remainder);
n += print(toPrint);
remainder -= toPrint;
}
return n;
}
because it's the standard print function in C (but not Arduino C) and can format a complete line containing multiple variables and text with as much precision as you would like. See Hello World, the first program described in The C Progamming Language
The fact that different boards support different print functions can be confusing. I have been using an ESP32 recently and find Serial.printf() with floats very useful, for instance. Then I swap to a Nano and miss it
i also assume that more than a single float needs to be printed.
Yes, but it does not have a console to output anything too so printf() alone would be of no use, hence the Serial.printf() fudge for the ESP32. Then, of course, there is the problem of most Arduinos having very little memory to work with, hence the lack of support for the %f format specifier in sprintf()
The c-string sprintf() is very fragile. You can easily overrun the buffer if you are not careful
Arduino Strings provides a constructor String(float,digs) that formats the float with that many digits.
My SafeString library (a detailed tutorial) provides Arduino print( ) support for printing directly to a SafeString, but unlike sprintf(), SafeStrings are protected against buffer overflows, will print an error msg and keep running.