nfx-datatypes 0.1.1
Cross-platform C++ library with high-precision Int128 and Decimal datatypes
Loading...
Searching...
No Matches
Decimal.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 nfx
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
119
120#pragma once
121
122#include <array>
123#include <compare>
124#include <cstdint>
125#include <limits>
126#include <optional>
127#include <string>
128#include <string_view>
129
130#include "Int128.h"
131
132namespace nfx::datatypes
133{
134 //=====================================================================
135 // Decimal class
136 //=====================================================================
137
166 class Decimal final
167 {
168 friend struct std::numeric_limits<Decimal>;
169
170 public:
171 //----------------------------------------------
172 // Rounding modes
173 //----------------------------------------------
174
203
204 //----------------------------------------------
205 // Construction
206 //----------------------------------------------
207
211 inline constexpr Decimal() noexcept;
212
223 inline explicit Decimal( float value ) noexcept;
224
233 explicit Decimal( double value ) noexcept;
234
239 explicit inline Decimal( std::int32_t value ) noexcept;
240
245 explicit inline Decimal( std::int64_t value ) noexcept;
246
251 explicit inline Decimal( std::uint32_t value ) noexcept;
252
257 explicit inline Decimal( std::uint64_t value ) noexcept;
258
265 explicit inline Decimal( std::string_view str );
266
288 explicit Decimal( const Int128& val );
289
294 Decimal( const Decimal& other ) noexcept = default;
295
300 Decimal( Decimal&& other ) noexcept = default;
301
302 //----------------------------------------------
303 // Destruction
304 //----------------------------------------------
305
307 ~Decimal() = default;
308
309 //----------------------------------------------
310 // Assignment
311 //----------------------------------------------
312
318 Decimal& operator=( const Decimal& other ) noexcept = default;
319
325 Decimal& operator=( Decimal&& other ) noexcept = default;
326
327 //----------------------------------------------
328 // Comparison operators
329 //----------------------------------------------
330
337 std::strong_ordering operator<=>( const Decimal& other ) const noexcept;
338
345 bool operator==( const Decimal& other ) const noexcept;
346
347 //----------------------------------------------
348 // Comparison with built-in floating point types
349 //----------------------------------------------
350
357 inline bool operator==( float val ) const noexcept;
358
365 inline bool operator!=( float val ) const noexcept;
366
373 inline bool operator<( float val ) const noexcept;
374
381 inline bool operator<=( float val ) const noexcept;
382
389 inline bool operator>( float val ) const noexcept;
390
397 inline bool operator>=( float val ) const noexcept;
398
405 inline bool operator==( double val ) const noexcept;
406
413 inline bool operator!=( double val ) const noexcept;
414
421 inline bool operator<( double val ) const noexcept;
422
429 inline bool operator<=( double val ) const noexcept;
430
437 inline bool operator>( double val ) const noexcept;
438
445 inline bool operator>=( double val ) const noexcept;
446
447 //----------------------------------------------
448 // Comparison with built-in integer types
449 //----------------------------------------------
450
456 inline bool operator==( std::int64_t val ) const noexcept;
457
463 inline bool operator!=( std::int64_t val ) const noexcept;
464
470 inline bool operator<( std::int64_t val ) const noexcept;
471
477 inline bool operator<=( std::int64_t val ) const noexcept;
478
484 inline bool operator>( std::int64_t val ) const noexcept;
485
491 inline bool operator>=( std::int64_t val ) const noexcept;
492
498 inline bool operator==( std::uint64_t val ) const noexcept;
499
505 inline bool operator!=( std::uint64_t val ) const noexcept;
506
512 inline bool operator<( std::uint64_t val ) const noexcept;
513
519 inline bool operator<=( std::uint64_t val ) const noexcept;
520
526 inline bool operator>( std::uint64_t val ) const noexcept;
527
533 inline bool operator>=( std::uint64_t val ) const noexcept;
534
540 inline bool operator==( std::int32_t val ) const noexcept;
541
547 inline bool operator!=( std::int32_t val ) const noexcept;
548
554 inline bool operator<( std::int32_t val ) const noexcept;
555
561 inline bool operator<=( std::int32_t val ) const noexcept;
562
568 inline bool operator>( std::int32_t val ) const noexcept;
569
575 inline bool operator>=( std::int32_t val ) const noexcept;
576
577 //----------------------------------------------
578 // Comparison with nfx::datatypes::Int128
579 //----------------------------------------------
580
587 bool operator==( const Int128& val ) const noexcept;
588
594 inline bool operator!=( const Int128& val ) const noexcept;
595
601 bool operator<( const Int128& val ) const noexcept;
602
608 inline bool operator<=( const Int128& val ) const noexcept;
609
615 inline bool operator>( const Int128& val ) const noexcept;
616
622 inline bool operator>=( const Int128& val ) const noexcept;
623
624 //----------------------------------------------
625 // Arithmetic operators
626 //----------------------------------------------
627
633 Decimal operator+( const Decimal& other );
634
640 inline Decimal operator-( const Decimal& other );
641
647 Decimal operator*( const Decimal& other ) const;
648
655 Decimal operator/( const Decimal& other ) const;
656
662 inline Decimal& operator+=( const Decimal& other );
663
669 inline Decimal& operator-=( const Decimal& other );
670
676 inline Decimal& operator*=( const Decimal& other );
677
684 inline Decimal& operator/=( const Decimal& other );
685
690 inline Decimal operator-() const noexcept;
691
692 //----------------------------------------------
693 // Property accessors
694 //----------------------------------------------
695
701 [[nodiscard]] std::uint8_t scale() const noexcept;
702
708 [[nodiscard]] inline const std::uint32_t& flags() const noexcept;
709
715 [[nodiscard]] inline std::uint32_t& flags() noexcept;
716
722 [[nodiscard]] inline const std::array<std::uint32_t, 3>& mantissa() const noexcept;
723
729 [[nodiscard]] inline std::array<std::uint32_t, 3>& mantissa() noexcept;
730
731 //----------------------------------------------
732 // Mathematical operations
733 //----------------------------------------------
734
740 [[nodiscard]] inline Decimal abs() const noexcept;
741
747 [[nodiscard]] inline Decimal ceil() const noexcept;
748
754 [[nodiscard]] inline Decimal floor() const noexcept;
755
763 [[nodiscard]] Decimal round( std::int32_t decimalsPlacesCount = 0, RoundingMode mode = RoundingMode::ToNearest ) const noexcept;
764
774 [[nodiscard]] Decimal sqrt() const;
775
781 [[nodiscard]] inline Decimal trunc() const noexcept;
782
783 //----------------------------------------------
784 // String parsing
785 //----------------------------------------------
786
804 [[nodiscard]] static bool fromString( std::string_view str, Decimal& result ) noexcept;
805
822 [[nodiscard]] static std::optional<Decimal> fromString( std::string_view str ) noexcept;
823
824 //----------------------------------------------
825 // Type conversion
826 //----------------------------------------------
827
835 [[nodiscard]] double toDouble() const noexcept;
836
842 [[nodiscard]] std::string toString() const;
843
849 [[nodiscard]] std::array<std::int32_t, 4> toBits() const noexcept;
850
851 //----------------------------------------------
852 // Utilities
853 //----------------------------------------------
854
864 [[nodiscard]] std::uint8_t decimalPlacesCount() const noexcept;
865
866 private:
867 //----------------------------------------------
868 // Internal representation
869 //----------------------------------------------
870
872 struct Layout
873 {
875 std::uint32_t flags;
876
878 std::array<std::uint32_t, 3> mantissa;
879 } m_layout;
880 };
881
882 //=====================================================================
883 // Free functions
884 //=====================================================================
885
894 [[nodiscard]] inline Decimal abs( const Decimal& value ) noexcept
895 {
896 return value.abs();
897 }
898
908 [[nodiscard]] inline Decimal sqrt( const Decimal& value )
909 {
910 return value.sqrt();
911 }
912
920 [[nodiscard]] inline Decimal ceil( const Decimal& value ) noexcept
921 {
922 return value.ceil();
923 }
924
932 [[nodiscard]] inline Decimal floor( const Decimal& value ) noexcept
933 {
934 return value.floor();
935 }
936
947 [[nodiscard]] inline Decimal round( const Decimal& value, std::int32_t decimalsPlacesCount = 0,
949 {
950 return value.round( decimalsPlacesCount, mode );
951 }
952
960 [[nodiscard]] inline Decimal trunc( const Decimal& value ) noexcept
961 {
962 return value.trunc();
963 }
964} // namespace nfx::datatypes
965
966#include "nfx/detail/datatypes/Decimal.inl"
Cross-platform 128-bit integer arithmetic type.
Decimal floor(const Decimal &value) noexcept
Round down to nearest integer (free function).
Definition Decimal.h:932
Decimal round(const Decimal &value, std::int32_t decimalsPlacesCount=0, Decimal::RoundingMode mode=Decimal::RoundingMode::ToNearest) noexcept
Round decimal to specified precision (free function).
Definition Decimal.h:947
Decimal sqrt(const Decimal &value)
Compute square root using Newton-Raphson method (free function).
Definition Decimal.h:908
Decimal trunc(const Decimal &value) noexcept
Remove fractional part (free function).
Definition Decimal.h:960
Decimal ceil(const Decimal &value) noexcept
Round up to nearest integer (free function).
Definition Decimal.h:920
Decimal abs(const Decimal &value) noexcept
Get absolute value of decimal (free function).
Definition Decimal.h:894
Cross-platform high-precision decimal type.
Definition Decimal.h:167
Decimal ceil() const noexcept
Round up to nearest integer.
std::uint8_t scale() const noexcept
Get decimal scale (number of decimal places).
const std::array< std::uint32_t, 3 > & mantissa() const noexcept
Get mantissa array.
std::uint8_t decimalPlacesCount() const noexcept
Count actual decimal places (excluding trailing zeros).
const std::uint32_t & flags() const noexcept
Get flags value.
Decimal round(std::int32_t decimalsPlacesCount=0, RoundingMode mode=RoundingMode::ToNearest) const noexcept
Round decimal to specified precision using configurable rounding mode.
Decimal trunc() const noexcept
Remove fractional part.
Decimal abs() const noexcept
Get absolute value.
double toDouble() const noexcept
Convert to double (may lose precision).
static bool fromString(std::string_view str, Decimal &result) noexcept
Parse string to decimal with error handling.
std::string toString() const
Convert to string with exact precision.
constexpr Decimal() noexcept
Default constructor (zero value).
RoundingMode
Rounding modes for decimal arithmetic operations.
Definition Decimal.h:196
@ ToNearestTiesAway
Round to nearest, ties away from zero (standard rounding).
Definition Decimal.h:198
@ ToPositiveInfinity
Round towards +∞ (ceiling).
Definition Decimal.h:200
@ ToNearest
Round to nearest, ties to even (banker's rounding).
Definition Decimal.h:197
@ ToNegativeInfinity
Round towards -∞ (floor).
Definition Decimal.h:201
@ ToZero
Round towards zero (truncate).
Definition Decimal.h:199
Decimal sqrt() const
Compute square root using Newton-Raphson method.
Decimal floor() const noexcept
Round down to nearest integer.
std::array< std::int32_t, 4 > toBits() const noexcept
Get internal 32-bit representation.
Cross-platform 128-bit signed integer type.
Definition Int128.h:146