Skip to content

Weak precision performance for floating point values with non-negligible negative exponents #109

@steven-buytaert

Description

@steven-buytaert

Hi, I notice that the autotest floating point testing is biased towards large values. I tried the following example, against the libc printf.

#include <stdio.h>

// #define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES  0 in following file.
#include "printf_config.h"
#include "../src/printf/printf.h"

void putchar_(char character) { }

int main(int argc, char * argv[]) {

  double fp = 1.380651569e-23; // Boltzmann

  char b[128];
  
  sprintf (b, "%.16e", fp); printf("libc %s\n", b);
  sprintf_(b, "%.16e", fp); printf("this %s\n", b);

}

Output:
libc 1.3806515690000000e-23
this 1.3806515648376314e-23

As you see there's a serious precision issue due too arithmetic underflow. Depending on the application, this might be problematic or not. In any case, it's something you should check also in the test framework.

If floating point precision is/becomes an issue, I have a standalone implementation of ecvt that uses (very wide) integer multiplication/division to format floating point with the proper precision based upon GRISU; as such, the formatting code doesn't do any floating point arithmetic itself to format the floats. The total text size for ARM Thumb code with -Os is 1979 bytes, only depending on strcpy from libc. A good reference to this floating point formatting can be found here. This code produces the exact same bit representation of the boltzmann constant as GNU libc. It can also format 32 bit IEEE 754 directly, without going via a 64 bit IEEE 754 format. You can find this ecvt and the required wide integer arithmetic code here.

Kind regards,

Steven

Metadata

Metadata

Assignees

Labels

help wantedExtra attention is neededquestionFurther information is requested

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions