Home > front end >  Python to C Floating Point Imprecision
Python to C Floating Point Imprecision

Time:10-20

I'm having some problems with precision when importing floats from csv files created in Python to a program written in C. The following code is an example of what happens in my program: Python writes a float32 value to a file (in this case 9.8431373e 00), I read it into a string and use strtof to convert it back into float32, but the result is different on the last decimal place.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    
    char* a;
    char x[10] = "9.8431373";
    printf("%s\n", x);
    float f = strtof(x,&a);
    printf("%.7e\n", f);
}

Output:

9.8431373
9.8431377e 00

Now, correct me if I am wrong, but a float object in C has 32 bits which leads to 7 decimal places of precision after wherever its floating point is. So there shouldn't be any precision errors if I'm not declaring a number bigger than the float allows.

If I did indeed declare a number more precise than the float in C allows, then how has Python accepted "9.8431373e 00" as a Float32 without correcting it? Does Python and C have different standards for 32-bit floats?

CodePudding user response:

Python interprets as double by default. You would see the same issue in Python if you packed to single precision and unpacked again:

>>> import struct
>>> a = struct.pack('<f', 9.8431373)
>>> b, = struct.unpack('<f', a)
>>> b
9.843137741088867

CodePudding user response:

Fundamentally, the decimal fraction 9.8431373 does not exist in binary floating-point, either single (float) or double precision. As a 32-bit float the closest you can get is a binary number that's equivalent to about 9.84313774, and as a double the closest you can get is a number corresponding to about 9.8431373000000004.

It's up to some combination of you, and your programming language, how these numbers get displayed back to you in decimal. Sometimes they're rounded, sometimes they're truncated. I don't know that much about Python, but I know that its rules are at least a little bit different from C's, so I'm not surprised you're seeing last digits that are off by 1.

  • Related