DevAcademia
C++C#CPythonJava
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz

Loading C tutorial…

Loading content
C BasicsTopic 17 of 64
←PreviousPrevNextNext→

Decimal Precision in C

Why Decimal Precision Matters

When working with real numbers in C, precision determines how many digits after the decimal point can be represented and stored accurately.

Because computers store numbers in binary, not all decimal fractions can be represented exactly. This leads to rounding errors.

Precision of float vs double vs long double

• **float** → typically 4 bytes, about 6–7 digits of precision

• **double** → typically 8 bytes, about 15–16 digits of precision

• **long double** → often 8/12/16 bytes, about 18–19 digits on platforms with extended precision (implementation-dependent)

`double` is generally preferred for numeric computations when accuracy is important. For **money/finance**, prefer fixed-point or integer cents instead of binary floating-point.

TypeSize (typical)Digits of Precision (approx)
float4 bytes6–7
double8 bytes15–16
long double8/12/16 bytes (varies)18–19 (varies by platform)

Controlling Output Precision

When printing decimal values, you can control the number of digits displayed using **format specifiers** in `printf`.

• `%.2f` → prints 2 digits after the decimal

• `%.6f` → prints 6 digits after the decimal

This does not change the actual stored value, only the printed output.

Example
#include <stdio.h>

int main(void) {
    double pi = 3.141592653589;
    printf("Default: %f\n", pi);   // default precision is 6 after the decimal
    printf("2 decimals: %.2f\n", pi);
    printf("6 decimals: %.6f\n", pi);
    return 0;
}
Output
Default: 3.141593
2 decimals: 3.14
6 decimals: 3.141593
ℹ️ Note: Use %Lf for long double (e.g., printf("%.9Lf", x);) and suffix long double literals with 'L' (e.g., 1.0L).

Precision Errors

Due to binary representation, some decimal values cannot be represented exactly.

For example, `0.1 + 0.2` might not equal exactly `0.3` but something very close to it.

This is normal in floating-point arithmetic and must be handled carefully in critical applications.

Example
#include <stdio.h>

int main(void) {
    double a = 0.1, b = 0.2, c = a + b;
    printf("a+b = %.17f\n", c);
    printf("0.3 = %.17f\n", 0.3);
    printf("Equal? %s\n", (c == 0.3) ? "yes" : "no");
    return 0;
}
Output
a+b = 0.30000000000000004
0.3 = 0.29999999999999999
Equal? no
ℹ️ Note: Avoid comparing floating-point numbers directly with `==`. Instead, check if they are within a small difference (tolerance).

Comparing with a Tolerance (Epsilon)

To compare floating-point values, check whether their difference is within an absolute or relative tolerance.

Example
#include <stdio.h>
#include <float.h>
#include <math.h>

int main(void) {
    double a = 0.1, b = 0.2, c = a + b;
    double target = 0.3;
    double tol = 1e-12; // choose based on your value scales

    if (fabs(c - target) < tol) {
        printf("Close enough (abs).\n");
    } else {
        printf("Not close (abs).\n");
    }

    // Example relative tolerance
    double rel_tol = 10 * DBL_EPSILON * fmax(fabs(target), 1.0);
    if (fabs(c - target) <= rel_tol) {
        printf("Close enough (rel).\n");
    } else {
        printf("Not close (rel).\n");
    }
    return 0;
}

Using <float.h> for Limits

`` exposes compile-time constants describing your platform’s floating-point types:

• `FLT_DIG`, `DBL_DIG`, `LDBL_DIG` → number of decimal digits of precision

• `FLT_EPSILON`, `DBL_EPSILON`, `LDBL_EPSILON` → smallest `x` such that `1.0 + x != 1.0` for each type

Example
#include <stdio.h>
#include <float.h>

int main(void) {
    printf("FLT_DIG=%d, DBL_DIG=%d, LDBL_DIG=%d\n", FLT_DIG, DBL_DIG, LDBL_DIG);
    printf("FLT_EPSILON=%.20g\n", FLT_EPSILON);
    printf("DBL_EPSILON=%.20g\n", DBL_EPSILON);
    printf("LDBL_EPSILON=%.20Lg\n", LDBL_EPSILON);
    return 0;
}

Best Practices

• Use `float` when memory is limited and precision is not critical (e.g., graphics).

• Use `double` by default for most real number calculations.

• Use `long double` only if your platform provides extra precision (check `LDBL_DIG`).

• Control formatting in output using specifiers like `%.2f` and `%.*f`.

• For financial calculations, prefer fixed-point or integer cents instead of binary floating-point.

Test your knowledge: Decimal Precision in C
Quiz Configuration
4 of 8 questions
Random
Previous allowed
Review enabled
Early close allowed
Estimated time: 8 min
C BasicsTopic 17 of 64
←PreviousPrevNextNext→