1

In computers, the math operation of floating numbers is actually processed using the base number and the exponential number separately, and then combine them together. We learn this in our computation fundamental textbooks. However, I find the limits in C program and MATLAB are quite different. Here is an example:

C program:

#include <stdio.h>

int main()
{
    float c1, c2, c3;
    
    c1 = 1.0e-20;
    c2 = 1.0e-30;
    
    c3 = c1 * c2;
    printf("%e,%e,%e\n",c1,c2,c3);

    return 0;
}

The running result is:

1.000000e-20,1.000000e-30,0.000000e+00

MATLAB program:

c1 = 1.0e-20;
c2 = 1.0e-30;
    
c3 = c1 * c2;
fprintf("%e,%e,%e\n",c1,c2,c3);

The running result is:

1.000000e-20,1.000000e-30,1.000000e-50

It is obvious that MATLAB gives the right multiplication result, whereas C gives a wrong result. Could anyone answer why this happens?

In my project, my computation involves such small number computations in C language. Since Matlab can do it correctly, can you give a suggestion how I can also do this in C?

Leo
  • 15
  • 2
  • 3
    Try using `double` instead of `float` in the C program. – user3386109 Jun 01 '23 at 21:51
  • Typically, C programs are using [32-bit `float`](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) and [64-bit `double`](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) values that are using [IEEE-754 format](https://en.wikipedia.org/wiki/IEEE_754), so you might want to read about that. – user3386109 Jun 01 '23 at 21:55
  • @user3386109 is right. Unless you have special needs and know what you are doing, never use type `float` in C; always use `double`. – Steve Summit Jun 01 '23 at 21:55
  • 1
    1e-50 is simply too small for type `float` to represent. The biggest number you can represent in a `float` is about 1e38, and the smallest is about 1e-45. – Steve Summit Jun 01 '23 at 21:59
  • Beware that C (or just about any conventional programming language) has only finite-precision floating point types that are going to have inherently more limitations (both precision and range) as opposed to programs like MATLAB or Mathematica. You said your work involves "small number computations". Type `double` will typically give you a useful range of 1e-307 to 1e307 (or down to 1e-324 if you include the subnormals), but if you need better than that, you may need to look into specialized libraries. – Steve Summit Jun 01 '23 at 22:12

1 Answers1

4

In most languages, you'll have access to at least two floating-point types: single-precision and double-precision.

In C, float is a single-precision float, double is a double-precision float.

MATLAB uses double by default, but also has single for single-precision floats.

If you use single values in your MATLAB program, you'll do the same computation that your C program does, with the same result:

c1 = single(1.0e-20);
c2 = single(1.0e-30);
c3 = c1 * c2;
fprintf("%e,%e,%e\n",c1,c2,c3);

The output is:

1.000000e-20,1.000000e-30,0.000000e+00

Likewise, you can change your C program to use double instead of float, to reproduce the MATLAB results exactly.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120