Skip to content

Commit 575d4e8

Browse files
committed
Add outline of numerical parsing example
1 parent c795e7e commit 575d4e8

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

examples/numerical_parsing.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2025 Matt Borland
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// https://www.boost.org/LICENSE_1_0.txt
4+
//
5+
// This file briefly demonstrates the difference in results when parsing monetary values between float and decimal32_t
6+
7+
#include "where_file.hpp"
8+
#include <boost/decimal/decimal32_t.hpp> // For type decimal32_t
9+
#include <boost/decimal/charconv.hpp> // For support to <charconv>
10+
#include <boost/decimal/iostream.hpp> // For decimal support to <iostream>
11+
#include <string>
12+
#include <vector>
13+
#include <fstream>
14+
#include <sstream>
15+
#include <limits>
16+
#include <numeric>
17+
#include <iostream>
18+
#include <iomanip>
19+
20+
using boost::decimal::decimal32_t;
21+
22+
template <typename T>
23+
T parse_opening_price(const std::string& line);
24+
25+
template <>
26+
float parse_opening_price<float>(const std::string& line)
27+
{
28+
const auto result {std::stof(line)};
29+
return result;
30+
}
31+
32+
template <>
33+
decimal32_t parse_opening_price<decimal32_t>(const std::string& line)
34+
{
35+
decimal32_t result;
36+
const auto r = from_chars(line, result);
37+
38+
if (!r)
39+
{
40+
// LCOV_EXCL_START
41+
result = std::numeric_limits<decimal32_t>::quiet_NaN();
42+
BOOST_DECIMAL_THROW_EXCEPTION(std::invalid_argument("Parsing has failed"));
43+
// LCOV_EXCL_STOP
44+
}
45+
46+
return result;
47+
}
48+
49+
template <typename T>
50+
auto parse_csv_line(const std::string& line) -> T
51+
{
52+
std::stringstream ss(line);
53+
std::string token;
54+
std::string date;
55+
56+
std::getline(ss, date, ',');
57+
std::getline(ss, token, ',');
58+
59+
return parse_opening_price<T>(token);
60+
}
61+
62+
int main()
63+
{
64+
// Open and read the CSV file
65+
std::ifstream file(boost::decimal::where_file("AAPL.csv"));
66+
std::string line;
67+
68+
// Skip header line
69+
std::getline(file, line);
70+
71+
std::vector<decimal32_t> decimal_opening_prices;
72+
std::vector<float> float_opening_prices;
73+
74+
while (std::getline(file, line))
75+
{
76+
decimal_opening_prices.emplace_back(parse_csv_line<decimal32_t>(line));
77+
float_opening_prices.emplace_back(parse_csv_line<float>(line));
78+
}
79+
80+
const std::string ms_result {"52151.99"};
81+
const auto decimal_sum {std::accumulate(decimal_opening_prices.begin(), decimal_opening_prices.end(), decimal32_t{0})};
82+
const auto float_sum {std::accumulate(float_opening_prices.begin(), float_opening_prices.end(), float{0})};
83+
84+
std::cout << std::setprecision(std::numeric_limits<float>::digits10 + 1)
85+
<< "Number of data points: " << decimal_opening_prices.size() << '\n'
86+
<< " Sum from MS Excel: " << ms_result << '\n'
87+
<< "Sum using decimal32_t: " << decimal_sum << '\n'
88+
<< " Sum using float: " << float_sum << std::endl;
89+
}

test/Jamfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ run ../examples/format.cpp ;
206206
run ../examples/fmt_format.cpp ;
207207
run ../examples/print.cpp ;
208208
run ../examples/promotion.cpp ;
209+
run ../examples/numerical_parsing.cpp ;
209210

210211
# Test compilation of separate headers
211212
compile compile_tests/bid_conversion.cpp ;

0 commit comments

Comments
 (0)