5

I have the following sketch:

void setup() {}

void loop() { float af = 4294967040.0; float bf = 4294967240.0; double ad = 4294967040.0; double bd = 4294967040.00001; Serial.println(af); Serial.println(bf); Serial.println(ad); Serial.println(bd); }

The values of af, bf, ad and bd are way smaller than 3.402823466e38 which is the maximum for float values. The values can still be correctly operated with, but the result on the serial monitor however is ovf for bf and bd.

Why is that?

LukasFun
  • 295
  • 1
  • 4
  • 16

1 Answers1

10

It's not the data type, it's the printing routine that sets that limit. In Print.cpp:

227   if (isnan(number)) return print("nan");
228   if (isinf(number)) return print("inf");
229   if (number > 4294967040.0) return print ("ovf");  // constant determined empirically
230   if (number <-4294967040.0) return print ("ovf");  // constant determined empirically

Don't ask why...

Majenko
  • 105,095
  • 5
  • 79
  • 137
  • That's bizarre, it's not even the (quite) max unsigned int value. Might try a version w/o that and see what happens. – Dave Newton Jun 29 '21 at 20:36
  • @DaveNewton I know. It was a surprise to me too... – Majenko Jun 29 '21 at 20:48
  • 1
    print does not produce an exponent format, so there must be a reasonable limit somewhere. Maybe they took the mantissa size ? surprise, yes indeed. Thanks for bringing this to our attention, – DataFiddler Jun 29 '21 at 21:45
  • 2
    4294967040.0 (float) is 0x4f7fffff => (Sign) 0 (Exponent) 10011110 (Mantissa) 11111111111111111111111 – Andie2302 Jun 29 '21 at 22:06
  • 1
    Looks like it's a guard for unsigned long int_part = (unsigned long)number;. Since number can be larger than an unsigned long can hold, the explicit-cast, (unsigned long)number, probably threw an error or something, around that value. Since the value was "determined empirically", it may've been a bit stricter than necessary. Guessing it could've been as high as 2^32-1 (whereas it's actually just 2^32-256). – Nat Jun 30 '21 at 04:25