OnixS CME Drop Copy Handler C++ library 5.7.1
API documentation
Loading...
Searching...
No Matches
Numeric.h
Go to the documentation of this file.
1// Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2//
3// This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
4// and international copyright treaties.
5//
6// Access to and use of the software is governed by the terms of the applicable OnixS Software
7// Services Agreement (the Agreement) and Customer end user license agreements granting
8// a non-assignable, non-transferable and non-exclusive license to use the software
9// for it's own data processing purposes under the terms defined in the Agreement.
10//
11// Except as otherwise granted within the terms of the Agreement, copying or reproduction of any
12// part of this source code or associated reference material to any other location for further
13// reproduction or redistribution, and any amendments to this copyright notice, are expressly
14// prohibited.
15//
16// Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17// the terms of the Agreement is a violation of copyright law.
18//
19
20#pragma once
21
22#include "OnixS/CME/DropCopy/Export.h"
23
24#include <cassert>
25#include <cmath>
26#include <ostream>
27#include <stdexcept>
28#include <string>
29
30namespace OnixS { namespace CME { namespace DropCopy {
31
32typedef int Int32;
33typedef unsigned int UInt32;
34
35typedef long long Int64;
36typedef unsigned long long UInt64;
37
38typedef double Double;
39
42
44class ONIXS_CME_DROP_COPY_EXPORT Decimal
45{
46public:
49
53 Decimal(Double value, size_t precision);
54
56 Decimal(const Decimal& other);
57
60
63
66
69
71 bool operator==(const Decimal&) const;
72
74 bool operator!=(const Decimal&) const;
75
77 bool operator<(const Decimal&) const;
78
80 bool operator>(const Decimal&) const;
81
85 operator Int32() const;
86
90 operator UInt32() const;
91
95 operator Int64() const;
96
100 operator UInt64() const;
101
105 operator Double() const;
106
110 bool toNumber(Int32&) const;
111
115 bool toNumber(UInt32&) const;
116
120 bool toNumber(Int64&) const;
121
125 bool toNumber(UInt64&) const;
126
129 bool toNumber(Double&) const;
130
137
143 static Decimal fromDoubleUnchecked(Double value, size_t precision);
144
146 void toString(std::string&) const;
147
149 std::string toString() const;
150
152 Decimal& operator=(const Decimal& other);
153
157 static bool tryParse(const char* buffer, size_t bufferSize, Decimal&);
158
161 static Decimal parse(const char* buffer, size_t bufferSize);
162
163private:
165 DecimalMantissa mantissa_;
166
168 DecimalExponent exponent_;
169};
170
172 : mantissa_(mantissa)
173 , exponent_(exponent)
174{
175}
176
177inline Decimal::Decimal(const Decimal& other)
178 : mantissa_(other.mantissa_)
179 , exponent_(other.exponent_)
180{
181}
182
184{
185 return mantissa_;
186}
187
189{
190 mantissa_ = value;
191}
192
194{
195 return exponent_;
196}
197
199{
200 exponent_ = value;
201}
202
203inline Decimal& Decimal::operator=(const Decimal& other)
204{
205 mantissa_ = other.mantissa_;
206 exponent_ = other.exponent_;
207
208 return *this;
209}
210
211inline Decimal::operator Int32() const
212{
213 Int32 number;
214
215 if (toNumber(number))
216 {
217 return number;
218 }
219
220 throw std::domain_error("Cannot cast value to target type. ");
221}
222
223inline Decimal::operator UInt32() const
224{
225 UInt32 number;
226
227 if (toNumber(number))
228 {
229 return number;
230 }
231
232 throw std::domain_error("Cannot cast value to target type. ");
233}
234
235inline Decimal::operator Int64() const
236{
237 Int64 number;
238
239 if (toNumber(number))
240 {
241 return number;
242 }
243
244 throw std::domain_error("Cannot cast value to target type. ");
245}
246
247inline Decimal::operator UInt64() const
248{
249 UInt64 number;
250
251 if (toNumber(number))
252 {
253 return number;
254 }
255
256 throw std::domain_error("Cannot cast value to target type. ");
257}
258
259inline Decimal::operator Double() const
260{
261 Double number;
262
263 if (toNumber(number))
264 {
265 return number;
266 }
267
268 throw std::domain_error("Cannot cast value to target type. ");
269}
270
271inline std::string Decimal::toString() const
272{
273 std::string presentation;
274 toString(presentation);
275 return presentation;
276}
277
278namespace NumericDetails {
279static const int maxAbsPower10 = 20;
280static const int powers10Size = maxAbsPower10 * 2 + 1; // Negative, positive and zero powers
281
282static const double powers10[] = {1E-20, 1E-19, 1E-18, 1E-17, 1E-16, 1E-15, 1E-14, 1E-13, 1E-12,
283 1E-11, 1E-10, 1E-9, 1E-8, 1E-7, 1E-6, 1E-5, 1E-4, 1E-3,
284 1E-2, 1E-1, 1E0, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6,
285 1E7, 1E8, 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15,
286 1E16, 1E17, 1E18, 1E19, 1E20};
287
289{
290 const int offset = power + maxAbsPower10;
291 if (offset >= 0 && offset < powers10Size)
292 {
293 return powers10[offset];
294 }
295
296 throw std::invalid_argument("Invalid power argument, must be in range [-20, 20]");
297}
298}
299
301{
302 using namespace NumericDetails;
303 return mantissa_ * fastPower10(exponent_);
304}
305
306inline Decimal Decimal::fromDoubleUnchecked(Double value, size_t precision)
307{
308 using namespace NumericDetails;
309 DecimalExponent convertedExponent = 0;
310
311 Double dummy;
312 if (fabs(modf(value, &dummy)) != 0.0)
313 {
314 const DecimalExponent exp = static_cast<DecimalExponent>(precision);
315
316 // Apply last digit rounding
317 const Double rounding = 0.5 * fastPower10(-exp);
318 value += (value > 0) ? rounding : -rounding;
319
320 value *= fastPower10(exp);
321 convertedExponent = -exp;
322 }
323
324 return Decimal(static_cast<DecimalMantissa>(value), convertedExponent);
325}
326
328struct ONIXS_CME_DROP_COPY_EXPORT Number
329{
330 static bool tryParse(const char* buffer, size_t bufferSize, Int32& number);
331 static bool tryParse(const char* buffer, size_t bufferSize, UInt32& number);
332 static bool tryParse(const char* buffer, size_t bufferSize, Int64& number);
333 static bool tryParse(const char* buffer, size_t bufferSize, UInt64& number);
334 static bool tryParse(const char* buffer, size_t bufferSize, Double& number);
335 static bool tryParse(const char* buffer, size_t bufferSize, Decimal& number);
336};
337
342struct ONIXS_CME_DROP_COPY_EXPORT DecimalComparator
343{
345 typedef bool (*CompareFunction)(const Decimal&, const Decimal&);
346
352
355 const CompareFunction equalFunc,
356 const CompareFunction nonEqualFunc,
357 const CompareFunction lessFunc,
358 const CompareFunction greaterFunc
359 )
360 : equal(equalFunc)
361 , nonEqual(nonEqualFunc)
362 , less(lessFunc)
363 , greater(greaterFunc)
364 {
365 }
366
367 // Assignment operator: not defined.
369
371 bool fixedPoint() const;
372
374 bool genericDecimal() const;
375};
376
378namespace GenericDecimal {
379inline bool equal(const Decimal& lhs, const Decimal& rhs)
380{
381 return lhs == rhs;
382}
383
384inline bool nonEqual(const Decimal& lhs, const Decimal& rhs)
385{
386 return lhs != rhs;
387}
388
389inline bool less(const Decimal& lhs, const Decimal& rhs)
390{
391 return lhs < rhs;
392}
393
394inline bool greater(const Decimal& lhs, const Decimal& rhs)
395{
396 return lhs > rhs;
397}
398
399ONIXS_CME_DROP_COPY_EXPORT extern const DecimalComparator Comparator;
400}
401
404inline bool equal(const Decimal& lhs, const Decimal& rhs)
405{
406 assert(lhs.exponent() == rhs.exponent());
407 return lhs.mantissa() == rhs.mantissa();
408}
409
410inline bool nonEqual(const Decimal& lhs, const Decimal& rhs)
411{
412 assert(lhs.exponent() == rhs.exponent());
413 return lhs.mantissa() != rhs.mantissa();
414}
415
416inline bool less(const Decimal& lhs, const Decimal& rhs)
417{
418 assert(lhs.exponent() == rhs.exponent());
419 return lhs.mantissa() < rhs.mantissa();
420}
421
422inline bool greater(const Decimal& lhs, const Decimal& rhs)
423{
424 assert(lhs.exponent() == rhs.exponent());
425 return lhs.mantissa() > rhs.mantissa();
426}
427
428ONIXS_CME_DROP_COPY_EXPORT extern const DecimalComparator Comparator;
429}
430
432{
433 return this == &FixedPointDecimal::Comparator;
434}
435
437{
438 return this == &GenericDecimal::Comparator;
439}
440
441static const DecimalComparator& defaultDecimalComparator = GenericDecimal::Comparator;
442
443}}}
444
445namespace std {
446
447// Outputs decimal into standard stream.
448ONIXS_CME_DROP_COPY_EXPORT std::ostream&
449operator<<(std::ostream&, const OnixS::CME::DropCopy::Decimal&);
450
451}
Decimal type for better precision.
Definition Numeric.h:45
Decimal(DecimalMantissa mantissa=0, DecimalExponent exponent=0)
Initializes instance from compound components.
Definition Numeric.h:171
bool toNumber(Int32 &) const
Decimal & operator=(const Decimal &other)
Reinitializes instance from another one.
Definition Numeric.h:203
std::string toString() const
Returns text presentation of decimal.
Definition Numeric.h:271
static Decimal parse(const char *buffer, size_t bufferSize)
bool toNumber(Int64 &) const
DecimalExponent exponent() const
Returns exponent part of decimal.
Definition Numeric.h:193
static bool tryParse(const char *buffer, size_t bufferSize, Decimal &)
bool operator!=(const Decimal &) const
Compares two numbers.
bool toNumber(Double &) const
Decimal(Double value, size_t precision)
void toString(std::string &) const
Appends text presentation to given string.
bool toNumber(UInt64 &) const
bool operator==(const Decimal &) const
Compares two numbers.
bool toNumber(UInt32 &) const
DecimalMantissa mantissa() const
Returns mantissa part of decimal.
Definition Numeric.h:183
static Decimal fromDoubleUnchecked(Double value, size_t precision)
Definition Numeric.h:306
Double toDoubleUnchecked() const
Definition Numeric.h:300
bool operator<(const Decimal &) const
Establishes order between two values.
bool operator>(const Decimal &) const
Establishes order between two values.
Helper functions for CME fixed point decimal case.
Definition Numeric.h:403
const DecimalComparator Comparator
bool nonEqual(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:410
bool less(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:416
bool greater(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:422
bool equal(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:404
Helper functions for generic decimal case.
Definition Numeric.h:378
const DecimalComparator Comparator
bool nonEqual(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:384
bool less(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:389
bool greater(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:394
bool equal(const Decimal &lhs, const Decimal &rhs)
Definition Numeric.h:379
OnixS::CME::DropCopy::Double fastPower10(int power)
Definition Numeric.h:288
unsigned int UInt32
Definition Numeric.h:33
long long Int64
Definition Numeric.h:35
unsigned long long UInt64
Definition Numeric.h:36
STL namespace.
std::ostream & operator<<(std::ostream &, const OnixS::CME::DropCopy::Error &)
const CompareFunction equal
Comparing functions.
Definition Numeric.h:348
DecimalComparator & operator=(const DecimalComparator &)
bool(* CompareFunction)(const Decimal &, const Decimal &)
Comparing function signature.
Definition Numeric.h:345
bool fixedPoint() const
Returns true if this instance is fixed point decimal comparator.
Definition Numeric.h:431
DecimalComparator(const CompareFunction equalFunc, const CompareFunction nonEqualFunc, const CompareFunction lessFunc, const CompareFunction greaterFunc)
Constructor.
Definition Numeric.h:354
bool genericDecimal() const
Returns true if this instance is generic decimal comparator.
Definition Numeric.h:436
Helper class for conversion from string to number.
Definition Numeric.h:329
static bool tryParse(const char *buffer, size_t bufferSize, Int32 &number)
static bool tryParse(const char *buffer, size_t bufferSize, UInt32 &number)
static bool tryParse(const char *buffer, size_t bufferSize, UInt64 &number)
static bool tryParse(const char *buffer, size_t bufferSize, Decimal &number)
static bool tryParse(const char *buffer, size_t bufferSize, Double &number)
static bool tryParse(const char *buffer, size_t bufferSize, Int64 &number)