# serial.print() e notazione scientifica

**URL:** <https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132>\
**Category:** Software\
**Created:** [March 3, 2020, 2:56pm UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132 "2020-03-03T14:56:05Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![dlcflv](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/dlcflv/32/1013044_2.png) [@dlcflv](https://forum.arduino.cc/u/dlcflv)\
**Post date:** [March 3, 2020, 2:56pm UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/1 "2020-03-03T14:56:05Z")

</div>

Salve a tutti.  
Mi sono imbattuto in questo problema che mi ha fatto perdere un sacco di tempo.  
Ho uno sketch che deve fare dei calcoli in floating point, il cui risultato finale è un numero "ragionevole" (tra circa 500 e 50000, a seconda del parametro d'ingresso) ma i risultati intermedi prevedevano dei numeri del tipo 1E-29 (comunque entro il range del tipo float gestibile da Arduino). Per debuggare il programma mi facevo stampare i valori intermedi con Serial.print(), ma ottenevo una sfilza di 0.00, mentre il risultato finale era corretto. Ho perso un sacco di tempo a capire dove fosse il problema ed ho scoperto che Serial.print ha dei limiti che mi sembrano assurdi.

Print.cpp alla riga 223 dice  
(Print.cpp lo si trova in C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino):

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

Ci sono quindi due problemi:

1. printFloat non supporta la notazione scientifica;
2. 4294967040.0 (~4E9) è ben inferiore al limite dei float a 32 bit supportati da Arduino (~1E38)

C'è qualcuno che ha già visto questo problema e ha trovato una soluzione?

Grazie

---

<div class="post-metadata">

**Author:** ![Datman](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/datman/32/219519_2.png) [@Datman](https://forum.arduino.cc/u/Datman)\
**Post date:** [March 3, 2020, 3:37pm UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/2 "2020-03-03T15:37:08Z")

</div>

Dovresti farti una funzioncina di stampa, qualcosa di simile:

```cpp
void ingPrint(float num)
{
float num2;
char molt;
if(num>=1000000000){num2=num/1000000000; molt='G';}
else if(num>=1000000){num2=num/0000000; molt='M';}
else if(num>=1000){num2=num/1000; molt='k';}
else if(num<0.0000001){num2=num/1000000000; molt='n';}
...
printFloat...
Serial.print(molt);

}

```

---

<div class="post-metadata">

**Author:** ![dlcflv](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/dlcflv/32/1013044_2.png) [@dlcflv](https://forum.arduino.cc/u/dlcflv)\
**Post date:** [March 3, 2020, 9:41pm UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/3 "2020-03-03T21:41:26Z")

</div>

Vorrei sperare di trovare qualcosa di meglio. Da E-38 a E38 ci sono 76 ordini di grandezza (se poi avessimo a che fare con i double…), senza contare che i prefissi del SI arrivano solo al E+/-24.  
Comunque, grazie del suggerimento.

---

<div class="post-metadata">

**Author:** ![nid69ita](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/nid69ita/32/901258_2.png) [@nid69ita](https://forum.arduino.cc/u/nid69ita)\
**Post date:** [March 4, 2020, 7:54am UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/4 "2020-03-04T07:54:26Z")

</div>

Qui un utente ha scritto una sua funzione: https://forum.arduino.cc/index.php?topic=46931.0

---

<div class="post-metadata">

**Author:** ![Datman](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/datman/32/219519_2.png) [@Datman](https://forum.arduino.cc/u/Datman)\
**Post date:** [March 4, 2020, 9:03am UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/5 "2020-03-04T09:03:38Z")

</div>

[https://forum.arduino.cc/index.php?topic=46931.0](https://forum.arduino.cc/index.php?topic=46931.0)

---

<div class="post-metadata">

**Author:** ![dlcflv](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/dlcflv/32/1013044_2.png) [@dlcflv](https://forum.arduino.cc/u/dlcflv)\
**Post date:** [March 4, 2020, 9:06am UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/6 "2020-03-04T09:06:40Z")

</div>

Comunque la risposta di Datman mi ha dato lo spunto… Basta dividere o moltiplicare ripetutamente per 10 il numero in questione, fino a portarlo nell'intervallo 1-10, e questo dà la mantissa, mentre il numero di divisioni o moltiplicazioni dà l'esponente. Una manciata di righe di codice.

Invece, per rispondere a nid69ita, il topic che lui segnala è troppo vecchio per essere la soluzione definitiva. Però l'autore del post, robtillaart, interpellato personalmente, mi segnala che ha sviluppato una libreria che risolve definitivamente e, debbo dire, elegantemente, il problema. Se vi interessa, la trovate qui [Arduino/libraries/MathHelpers at master · RobTillaart/Arduino · GitHub](https://github.com/RobTillaart/Arduino/tree/master/libraries/MathHelpers)  
Peccato solo che non sia nel formato standard delle librerie Arduino e bisogna installarla manualmente. E non ha documentazione, ma ci sono solo due esempi che hanno bisogno di qualche aggiustamento per girare su qualsiasi Arduino. Sul Micro su cui l'ho provata bisogna aggiungere il while(!Serial) per poter vedere l'output.

Comunque a questo punto direi che il problema è risolto.

---

<div class="post-metadata">

**Author:** ![Datman](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/datman/32/219519_2.png) [@Datman](https://forum.arduino.cc/u/Datman)\
**Post date:** [March 4, 2020, 9:12am UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/7 "2020-03-04T09:12:37Z")

</div>

Più semplicemente, fai il logaritmo in base 10 e prendi la parte intera: Quello è l'esponente da indicare sul display ed è la potenza di dieci per cui dividere il numero da visualizzare. Non so, però, se fare il logaritmo è più pesante che fare una fila di if/else, considerando l'ordine di grandezza medio di ciò che verrà visualizzato.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [May 7, 2021, 2:19am UTC](https://forum.arduino.cc/t/serial-print-e-notazione-scientifica/640132/8 "2021-05-07T02:19:41Z")

</div>

Closed on May 7, 2021, 2:19am UTC


