Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions content/languages/c.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
title: Floating-point cheat sheet for C
description: tips for using floating-point, arbitrary-precision, and fixed-point numbers in C
---

Floating-Point Types
---
C has [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) single and double precision types supported by keywords:

float f = 0.1f;
double d = 0.1;
long double ld = 0.1L;


Because of binary floating-point representation, some decimal fractions cannot be represented exactly (e.g., 1/10 → 0.1 or π), so small rounding errors can occur. In fact, in this naive example we have:

#include <stdio.h>

int main() {
double pi = 3.1415926535897932384626433832795028841971;
double y = 0.1;
printf("%.30f\n", pi + y);
// may show small error
// input: 3.1415926535897932384626433832795028841971
// output: 3.241592653589793204815805438557
}

So we perform rounding.

Decimal Types
-------------
C does not have a built-in decimal type, but exact decimal arithmetic can be done using libraries like [GMP/MPFR](https://gmplib.org/).

#include <gmp.h>

int main(void) {
mpf_set_default_prec(256);
mpf_t pi;
mpf_init_set_str(pi, "3.1415926535897932384626433832795028841971", 10);
// output: 3.14159265358979323846264338327950288419710000000000
gmp_printf("%.50Ff\n", pi);
mpf_clear(pi);
return 0;
}

Otherwise, arbitrary-precision libraries allow you exact storage up to the specified precision but rounding is done manually when needed.

Fixed-Point Types
-----------------
C does not have built-in fixed-point types, but you can implement them using integers with a fixed scaling factor.

#include <stdio.h>

#define SCALE 65536 // 2^16 scaling factor

int main() {
double pi = 3.1415926535897932384626433832795028841971;
// output: 3.1415863037109375 (limited by 16-bit fractional precision

int pi_fixed = (int)(pi * SCALE);
double pi_value = (double)pi_fixed / SCALE;
printf("%.16f\n", pi_value);

return 0;
}


Resources
---------
* [C Standard Library Reference](https://en.cppreference.com/w/c)
* [IEEE 754 Standard](https://en.wikipedia.org/wiki/IEEE_754)
* [float type](https://en.cppreference.com/w/c/language/arithmetic_types#Real_floating_types)
* [double type](https://en.cppreference.com/w/c/language/arithmetic_types#Real_floating_types)
* [long double type](https://en.cppreference.com/w/c/language/arithmetic_types#Real_floating_types)
* [GMP library (GNU Multiple Precision)](https://gmplib.org/)
* [MPFR library (Multiple Precision Floating-Point)](https://www.mpfr.org/)
* [Fixed-point arithmetic](https://en.wikipedia.org/wiki/Fixed-point_arithmetic)
* [Math functions (math.h)](https://en.cppreference.com/w/c/numeric/math)

17 changes: 9 additions & 8 deletions layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
<link rel="stylesheet" type="text/css" href="/style.css?v1" media="screen">
<link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon">
</head>
<body>
<body>
<div id="main">
<h1><%= @item[:title] %></h1>
<%= yield %>

<div id="license">
<p>&copy; Published at <a href="https://floating-point-gui.de/">floating-point-gui.de</a> under the
<p>&copy; Published at <a href="https://floating-point-gui.de/">floating-point-gui.de</a> under the
<a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution License (BY)</a></p>
</div>
</div>
Expand All @@ -33,22 +33,22 @@ <h2>The Floating-Point Guide</h2>
<li><a href="/references/">References</a></li>
<li><a href="/xkcd/">xkcd</a></li>
</ul>
<h2>Number Formats</h2>

<h2>Number Formats</h2>
<ul>
<li><a href="/formats/binary/">Binary Fractions</a></li>
<li><a href="/formats/fp/">Floating-Point</a></li>
<li><a href="/formats/exact/">Exact Types</a></li>
<li><a href="/formats/integer/">On Using Integers</a></li>
</ul>
<h2>Errors</h2>

<h2>Errors</h2>
<ul>
<li><a href="/errors/rounding/">Rounding</a></li>
<li><a href="/errors/comparison/">Comparison</a></li>
<li><a href="/errors/propagation/">Propagation</a></li>
</ul>

<h2>Language<br>cheat sheets</h2>
<ul>
<li><a href="/languages/csharp/">C#</a></li>
Expand All @@ -60,6 +60,7 @@ <h2>Language<br>cheat sheets</h2>
<li><a href="/languages/ruby/">Ruby</a></li>
<li><a href="/languages/rust/">Rust</a></li>
<li><a href="/languages/sql/">SQL</a></li>
<li><a href="/languages/c/">C</a></li>
</ul>
</div>
<a href="http://github.com/brazzy/floating-point-gui.de"><img style="position: absolute; top: 0; right: 0; border: 0;" src="/forkme_right_white_ffffff.png" alt="Fork me on GitHub" /></a>
Expand Down