Последовательный монитор не может отображать плавающие и двойные значения с абсолютным значением больше 4294967040=2^32-2^8

У меня есть следующий скетч:

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);
}

Значения af, bf, ad и bd намного меньше, чем 3.402823466e38, что является максимальным значением для значений с плавающей точкой. Со значениями все еще можно корректно работать, но результат на последовательном мониторе, однако, является ovf для bf и bd.

Это почему?

, 👍5

Обсуждение

Также обратите внимание, что в Unos и т. Д. Нет разницы между двойными и плавающими: https://www.arduino.cc/reference/en/language/variables/data-types/double/, @Dave Newton

По теме: [Ответ на StackOverflow.](https://stackoverflow.com/questions/42034906/too-large-const-on-arduino-uno/42040706#42040706), @Nat


1 ответ


Лучший ответ:

10

Это не тип данных, а процедура печати, которая устанавливает это ограничение. В 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

Не спрашивай, почему...

,

Это странно, это даже не (совсем) максимальное значение int без знака. Можно попробовать версию без этого и посмотреть, что произойдет., @Dave Newton

@DaveNewton я знаю. Для меня это тоже было неожиданностью..., @Majenko

печать не создает формат экспоненты, поэтому где-то должен быть разумный предел. Может быть, они взяли размер мантиссы ? удивление, да, действительно. **Спасибо, что обратили на это наше внимание,**, @DataFiddler

4294967040.0 (с плавающей точкой) равно 0x4f7fffff => (Знак) 0 (Показатель степени) 10011110 (Мантисса) 1111111111111111111111111, @Andie2302

Похоже, это защита для [unsigned long int_part = (без знака long)number;](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/samd/cores/LilyMini/Print.cpp). Поскольку "число" может быть больше, чем может содержать "длинное число без знака", явное приведение " (длинное число без знака)", вероятно, вызвало ошибку или что-то в этом роде вокруг этого значения. Поскольку значение было **" _ определено эмпирически"**, оно могло быть немного строже, чем необходимо. Предполагаю, что это могло быть до 2^32-1 (в то время как на самом деле это всего лишь 2^32-256)., @Nat