Skip to content
Merged
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
82 changes: 4 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,8 @@

---

Decimal is an implementation of IEEE-754:2008 decimal floating point numbers.
See also [1].

The library is header-only, and requires C++14.
It is compatible through C++14, 17, 20, 23 and beyond.

# Notice

Decimal is under active development and is not an official boost library.
Boost.Decimal is an implementation of [IEEE 754](https://standards.ieee.org/ieee/754/6210/) and [ISO/IEC DTR 24733](https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf) Decimal Floating Point numbers.
The library is header-only, has no dependencies, and requires C++14.

# How To Use The Library

Expand Down Expand Up @@ -95,78 +88,11 @@ class decimal_fast128_t;
These types operate like built-in floating point types.
They have their own implementations of the Standard-Library functions
(e.g. like those found in `<cmath>`, `<charconv>`, `<cstdlib>`, etc.).

The entire library can be conveniently included with `#include <boost/decimal.hpp>`

Using the decimal types is simple.

```cpp
#include <boost/decimal.hpp>
#include <iostream>

int main()
{
using boost::decimal::decimal32_t;

constexpr decimal32_t a {2, -1}; // Constructs the number 0.2
constexpr decimal32_t b {1, -1}; // Constructs the number 0.1
auto sum {a + b};

std::cout << sum << std::endl; // prints 0.3

const auto neg_a {2, -1, true}; // Constructs the number -0.2

sum += neg_a;

std::cout << sum << std::endl; // Prints 0.1

return 0;
}
```

This intuitive straightforwardness is the same when using Standard-Library
functions (such as STL functions, `<cmath>` functions and the like).

```cpp
#include <boost/decimal.hpp>
#include <cassert>
#include <cstring>

int main()
{
using namespace boost::decimal;

decimal64_t val {-0.25}; // Construction from a double
val = abs(val); // DO NOT call std::abs

char buffer[256];
auto r_to = to_chars(buffer, buffer + sizeof(buffer) - 1, val);
assert(r_to); // checks std::errc()
*r_to.ptr = '\0';

decimal64_t return_value;
auto r_from = from_chars(buffer, buffer + std::strlen(buffer), return_value);

assert(val == return_value);

return 0;
}
```
Using the decimal types is simple and can be learned by [example](https://develop.decimal.cpp.al/decimal/examples.html).
Their usage closely resembles that of built-in binary floating point types by design.

# Full Documentation

The complete documentation can be found at: https://develop.decimal.cpp.al

## References

- Michael F. Cowlishaw [_Floating-Point: Algorism(sic) for Computers_](https://www.cs.tufts.edu/~nr/cs257/archive/mike-cowlishaw/decimal-arith.pdf_Decimal), Proceedings of the 16th IEEE Symposium on Computer Arithmetic, 2003

- Donald E. Knuth, _The Art of Computer Programming Volume 2 Seminumerical Algorithms_, 3rd edition, 1998

- Jean-Michel Muller, _Elementary Functions_, 3rd edition, 2010

- Jean-Michel Muller, et. al., _Handbook of Floating-Point Arithmetic_, 2000

- John F. Hart, et. al., _Computer Approximations_, 1968

- IEEE, _IEEE Standard for Floating-Point Arithmetic_, 2019
10 changes: 5 additions & 5 deletions doc/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
* xref:overview.adoc[]
* xref:basics.adoc[]
* xref:examples.adoc[]
** xref:examples.adoc#examples_construction[Construction]
** xref:examples.adoc#examples_promotion[Type Promotion]
** xref:examples.adoc#examples_construction[Basic Construction]
** xref:examples.adoc#examples_promotion[Promotion and Mixed Decimal Arithmetic]
** xref:examples.adoc#examples_charconv[`<charconv>`]
** xref:examples.adoc#examples_generic_programming[Generic Programming]
** xref:examples.adoc#examples_literals_constants[Literals and Constants]
** xref:examples.adoc#examples_finance[Financial Applications]
** xref:examples.adoc#examples_boost_math[Boost.Math Integration]
** xref:examples.adoc#examples_format[Formatting]
*** xref:examples.adoc#examples_fmt_format[pass:[{fmt}]]
*** xref:examples.adoc#examples_std_format[`<format>`]
** xref:examples.adoc#examples_print[`<print>`]
*** xref:examples.adoc#examples_print[`<print>`]
* xref:financial_examples.adoc[]
** xref:financial_examples.adoc#examples_boost_math[Boost.Math Integration]
* xref:api_reference.adoc[]
** xref:api_reference.adoc#api_ref_types[Types]
** xref:api_reference.adoc#api_ref_structs[Structs]
Expand Down
106 changes: 42 additions & 64 deletions doc/modules/ROOT/pages/examples.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ https://www.boost.org/LICENSE_1_0.txt
All examples can be found in the library `examples/` folder as well.

[#examples_construction]
== Basic construction

This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/basic_construction.cpp[basic_construction.cpp]

== Basic Construction
.This example demonstrates the basic use of the various constructors offered by the decimal types
====
[source, c++]
----
include::example$basic_construction.cpp[]
----

The expected output from this example is:
----
.Expected Output
....
Val_1: 100
Val_2: 100
Val_3: -100
Expand All @@ -30,58 +29,60 @@ Underflow constructs zero
NaN constructs NaN
Values constructed from const char* and std::string are the same
Can not construct from invalid string
----
....
====

[#examples_promotion]
== Promotion and Mixed Decimal Arithmetic

This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/promotion.cpp[promotion.cpp]

.This example demonstrates the behaviors of promotion between types, and mixed decimal type arithmetic
====
[source, c++]
----
include::example$promotion.cpp[]
----

Expected Output:
----
.Expected Output:
....
decimal32_t value (a): 5.2
decimal64_t value (b): 3.9
a is greater than b
5.2 is less than 1e+385
1e+385 is now less than inf
The result of a + b is a decimal64_t: 9.1
----
....
====

[#examples_charconv]
== `<charconv>`

This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/charconv.cpp[charconv.cpp]

.This example demonstrates the fundamentals of the `<charconv>` like functions provided by the library
====
[source, c++]
----
include::example$charconv.cpp[]
----

Output:
----
.Expected Output:
....
Initial decimal: -7123450
Value from string: 3.1415
Value in scientific format: -7.12345e+06
Value in scientific format with precision 20: -7.12345000000000000000e+06
----
....
====

[#examples_generic_programming]
== Generic Programming

This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/adl.cpp[adl.cpp].

.This example demonstrates how to write generic code that accepts both built-in floating point types, and decimal floating point values from this library
====
[source, c++]
----
include::example$adl.cpp[]
----

Expected Output:
----
....
Float:
sin(-0.5) = -0.479426
-sin(0.5) = -0.479426
Expand All @@ -105,49 +106,28 @@ sin(-0.5) = -0.479426
decimal128_t:
sin(-0.5) = -0.479426
-sin(0.5) = -0.479426
----
....
====

[#examples_literals_constants]
== Literals and Constants

This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/literals.cpp[literals.cpp].

.This example demonstrates how to construct values using literals, and the usage of numerical constants that are provided by the library
====
[source, c++]
----
include::example$literals.cpp[]
----

Expected Output:
----
....
32-bit Pi: 3.141593
64-bit Pi: 3.141592653589793
32-bit UDL Pi: 3.141593
Rounded UDL has the same value as the 32-bit constant
64-bit UDL Pi: 3.141592653589793
Rounded UDL has the same value as the 64-bit constant
----

[#examples_finance]
== Financial Applications

=== Simple Moving Average

In the examples folder there is a file named `moving_average.cpp`.
This example shows how to parse historical stock data from a file and use it.
This serves as a framework for other calculations for securities.

=== Currency Conversion
In the examples folder there is a file named `currency_conversion.cpp`.
This example shows how to simply convert currencies based off a given exchange rate.

[#examples_boost_math]
== Boost.Math Integration

=== Bollinger Bands

In the examples folder there is a file named `statistics.cpp`.
This example demonstrates how to parse a file, and then leverage Boost.Math to compute statistics of that data set culminating with the values of the Bollinger Bands.
This example could be extended with the simple moving average to create full bands based on the period of the moving average you would like.
....
====

[#examples_format]
== Formatting
Expand All @@ -158,8 +138,8 @@ pass:[{fmt}] support is available starting with pass:[C++14] so long as you have
[#examples_fmt_format]
=== `<fmt/format.hpp>`

This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/fmt_format.cpp[fmt_format.cpp].

.This example demonstrates the various formatting options provided by the library to support usage of pass:[{fmt}]
====
[source, c++]
----
// Copyright 2025 Matt Borland
Expand Down Expand Up @@ -205,7 +185,7 @@ int main()
----

Expected Output:
----
....
Default Format:
3.14
3.141
Expand All @@ -221,7 +201,8 @@ Scientific Format with Specified Precision:
Scientific Format with Specified Precision and Padding:
03.140e+00
03.141e+00
----
....
====

IMPORTANT: If you are using the convenience header `<boost/decimal.hpp>` the header `<boost/decimal/fmt_format.hpp>` is *NOT* automatically included since it requires an external library.
You must include it yourself.
Expand All @@ -230,15 +211,16 @@ You must include it yourself.
=== `<format>`

Taking the above example of pass:[{fmt}] and replacing all instances of `namespace fmt` with `namespace std` gives us another working example.
This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/format.cpp[format.cpp]

.This example demonstrates how to use `<format>` with the library in-place or in addition to pass:[{fmt}]
====
[source, c++]
----
include::example$format.cpp[]
----

Expected Output:
----
.Expected Output:
....
Default Format:
3.14
3.141
Expand All @@ -254,17 +236,13 @@ Scientific Format with Specified Precision:
Scientific Format with Specified Precision and Padding:
03.140e+00
03.141e+00
----
....
====


[#examples_print]
== `<print>`

We can make one final change to our `<format>` example where instead of using `std::cout`, we use pass:[C++23's] `<print>`.
This example can be found in the `examples/` folder as https://github.com/cppalliance/decimal/blob/develop/examples/print.cpp[print.cpp].


.`<print>` Example
=== `<print>`
.This example demonstrates how to use `<print>` with the library
====
[source, c++]
----
Expand Down
30 changes: 30 additions & 0 deletions doc/modules/ROOT/pages/financial_examples.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
////
Copyright 2023 Matt Borland
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////

[#examples_finance]
= Financial Examples
:idprefix: financial_examples_

== Financial Applications

=== Simple Moving Average

In the examples folder there is a file named `moving_average.cpp`.
This example shows how to parse historical stock data from a file and use it.
This serves as a framework for other calculations for securities.

=== Currency Conversion
In the examples folder there is a file named `currency_conversion.cpp`.
This example shows how to simply convert currencies based off a given exchange rate.

[#examples_boost_math]
== Boost.Math Integration

=== Bollinger Bands

In the examples folder there is a file named `statistics.cpp`.
This example demonstrates how to parse a file, and then leverage Boost.Math to compute statistics of that data set culminating with the values of the Bollinger Bands.
This example could be extended with the simple moving average to create full bands based on the period of the moving average you would like.