Unexpected result when creating String from float at high precision

When initialising a String from a float using String(float f, int precision), when I set precision to 10 or above, I’m getting strange results. For 10 and 11, the number in the string is different to the number input, and for 12 and 15, it always outputs 0.000000000000. Is this a bug?

Code to reproduce:

float f = 3.14;

void setup() {
    for(int i=0; i<20; i++){
        Particle.publish("float"+String(i), String(f, i), PRIVATE);
        delay(1000);
    }
}

Output I’m getting:

float0  3
float1  3.1
float2  3.14
float3  3.140
float4  3.1400
float5  3.14000
float6  3.140000
float7  3.1400000
float8  3.14000000
float9  3.140000000
float10 3.0197409305
float11 3.00170205434
float12 0.000000000000
float13 3.0000184259026
float14 3.00000038702641
float15 0.000000000000000

I replicated your code and ran it through the debugger.

It appears that on the 10th iteration of this for loop scale becomes 1410065408, which is clearly undesired as scale is expected to be a power of 10.

On float12, scale becomes -727379968, which really screws up the rest of the function.

On float15, scale becomes -1530494976, which again messes up the function.

As you have observed, anything after float9 is erroneous due to scale overflowing.


I have rewritten your code to not use String objects and the output is much closer to what you would expect.

#include "Particle.h"

SYSTEM_MODE(MANUAL);

void setup()
{
  Serial.begin(115200);
  float f = 3.14;
  char fmtStr[10];
  char output[33];

  for (int i = 0; i < 20; i++)
  {
    snprintf(fmtStr, sizeof(fmtStr), "%%.%df", i);
    snprintf(output, sizeof(output), fmtStr, f);
    Serial.printlnf("float%d\t%s", i, output);
    delay(1000);
  }
}

void loop()
{
}

Output:

float0  3
float1	3.1
float2	3.14
float3	3.140
float4	3.1400
float5	3.14000
float6	3.140000
float7	3.1400001
float8	3.14000010
float9	3.140000105
float10	3.1400001049
float11	3.14000010490
float12	3.140000104904
float13	3.1400001049042
float14	3.14000010490417
float15	3.140000104904175
float16	3.1400001049041748
float17	3.14000010490417480
float18	3.140000104904174805
float19	3.1400001049041748047

Throughout this forum you’ve probably seen usage of String get discouraged and it’s for a good reason.

1 Like