Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Using double precision numbers in serial Teensy 3.2 and 4.0

  1. #1
    Junior Member
    Join Date
    Aug 2020
    Posts
    6

    Using double precision numbers in serial Teensy 3.2 and 4.0

    Hello,

    I'm trying to send some double precision values over serial to a teensy/arduino and store it in EEPROM then read it back over serial. During my testing it seems that only float precision can be displayed, does this mean that the teensy cannot store double (64 bit floats) values in its EEPROM (I am aware that the arduino can only handle 32 bit floats)? Or is this instead a flaw with the String() function?

    Code:
    void setup() {
      Serial.begin(9600);
      
    }
    
    
    void loop() {
      double number = 1.000001;
      double number2 = 1.0000005;
      
      Serial.println(String(number+ 2*number2,20));  
    }
    The output for each is as follows:

    Code:
    Arduino Uno
    16:24:23.349 -> 3.00000190000000000000
    
    Teensy 4.0
    3.00000190734863281250
    Many thanks

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,462
    Arduino String and Serial.println only support 32 bit floats.

    To print 64 bit double, use Serial.printf(). To convert to a string, use snprintf().

    Code:
    void setup() {
      Serial.begin(9600);
    }
    
    void loop() {
      double number =  1.0000010;
      double number2 = 1.0000005;
      Serial.printf("%lf\n", number+ 2*number2); 
    }

  3. #3
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,828

    Cool

    You may know this, or perhaps you don't.

    On the Teensy 3.2, 3.5, 3.6, and LC, floating point constants are single precision rather than double precision. On the Teensy 4.0 and 4.1, constants are double precision.

    If you need a double constant to full precision on the Teensy 3.x/LC, you would need to specify it as a 'long double' constant and convert that to 'double':

    Code:
      double x = (double) 3.1415926535L;
    The reason for this is the M4 chips used in the Teensy 3.x series has an optional floating point unit (Teensy 3.5 and 3.6 use the FPU, Teensy 3.2 does not have a FPU). However, the floating point unit only does single precision arithmetic. I believe Paul used the GCC option to treat constants as single precision so that having a constant in an expression would not convert the whole expression to double precision which on the 3.5/3.6 would have to be emulated, instead of being done in hardware.

    The Teensy 4.0 and 4.1 has full hardware support for both single and double precision, so constants are normally double precision (which is what the C/C++ standards specify).

  4. #4
    Junior Member
    Join Date
    Aug 2020
    Posts
    6
    Thank you both for the support, that was exactly what I was after!

  5. #5
    Junior Member
    Join Date
    Aug 2020
    Posts
    6
    As a follow up, is there a means of converting string to double other than 'string.toDouble' which gives me the error
    Code:
    'class String' has no member named 'toDouble'

  6. #6
    Member
    Join Date
    Aug 2018
    Location
    Brisbane, Australia
    Posts
    24
    Quote Originally Posted by JakeNBake View Post
    As a follow up, is there a means of converting string to double other than 'string.toDouble' which gives me the error
    Code:
    'class String' has no member named 'toDouble'
    https://en.cppreference.com/w/c/string/byte/strtof

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,462
    Quote Originally Posted by JakeNBake View Post
    is there a means of converting string to double other than 'string.toDouble'
    snprintf() works, perhaps awkwardly if you like C++, but it's highly reliable

    Code:
    void setup() {
      while (!Serial);
      double x = 1.000000123L;
      char buf[24];
      snprintf(buf, 24, "%.9lf", x);
      String s = buf;
      Serial.print(String("x is ") + s);
    }
    
    void loop() {
    }
    One minor caveat is it does not work if you set Tools > Optimize to "Smallest Code", because one of the space saving measures is a version of printf without floating point support. Only Teensy LC uses "Smallest Code" as its default.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •