Serial.print shows too few decimals or nan: format floats and check the maths

Pass the decimals as the second argument: Serial.print(value, 3). The default is two.

What the message means

Print shows two decimals unless you ask for more. A nan or inf means the calculation divided zero by zero or by zero.

Fix it in this order

  1. Use Serial.print(value, 3) for three decimals.
  2. Remember a float holds about 6 to 7 digits on an Uno, so extra digits are noise.
  3. For nan, check for a division by zero or a square root of a negative number.
  4. For inf, check the divisor before you divide.
  5. Use dtostrf or snprintf to build text with a set width.

Why it happens

Serial.print on a float shows two decimals unless you pass the number of digits as the second argument. On an Uno, a float and a double are both 32-bit, which holds about 6 to 7 significant digits, so asking for more decimals than that prints noise. The words nan and inf are what the library prints when a calculation produced not-a-number or infinity.

nan comes from operations such as 0 divided by 0 or the square root of a negative number, and it spreads: any later calculation that uses it also gives nan.

If you see this, do this

You seeDo this
Shows 0.00 for a small numberPrint more decimals.
Shows nanCheck the maths.

integer division, serial monitor shows nothing.

Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.

Why this happens

Serial.print(value) for a float shows two decimal places by default. The second argument sets how many are printed, as in Serial.print(value, 4). On AVR boards such as the Uno, float and double are both 32-bit and hold about 6 to 7 significant digits, so printing ten decimals prints digits that mean nothing.

The words nan and inf come from the arithmetic, not from the printing. nan means not-a-number and appears for 0.0 / 0.0 or the square root of a negative number. inf appears when you divide a non-zero number by zero. Once a nan enters a calculation, every result that uses it is also nan. A very large value prints ovf.

How to confirm the cause

  • Print the inputs of the calculation before the result: the numerator, the denominator and any square-root argument.
  • Print the value with six decimals. If it shows 0.000000, the true value is zero or integer division removed it.
  • Test with isnan(x) and isinf(x) and print which one is true.
  • Check the types. 1 / 3 with integer literals is 0, because integer division happens before the assignment to a float.
  • If the value comes from a sensor library, check whether the read call returned an error value.

Worked example

Integer division, float division and the limit of float precision.

float a = 1 / 3;       // integer division first: 0
float b = 1.0 / 3;     // 0.333...
Serial.println(a, 4);  // 0.0000
Serial.println(b, 4);  // 0.3333
Serial.println(b, 10); // digits after the 7th are not meaningful
float r = sqrt(-4.0);
Serial.println(r);     // nan
if (isnan(r)) Serial.println("bad input");

Common mistakes

  • Expecting the second argument of print to add precision that the float does not have.
  • Comparing with nan using ==. A nan is never equal to anything, even itself.
  • Dividing two integer variables and storing the result in a float.
  • Using String(x) and expecting more than two decimals.
  • Ignoring a sensor read that failed.

If this did not fix it

  • A library that returns nan on a failed read, as some temperature sensor libraries do. Check the wiring and the timing.
  • An uninitialised variable holding garbage.
  • A baud rate mismatch between the sketch and the serial monitor, which gives unreadable characters, not nan.