nfx-datatypes 0.2.0
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 explicit Decimal( float value ) noexcept;
224
233 explicit Decimal( double value ) noexcept;
234
239 inline explicit Decimal( std::int32_t value ) noexcept;
240
245 inline explicit Decimal( std::int64_t value ) noexcept;
246
251 inline explicit Decimal( std::uint32_t value ) noexcept;
252
257 inline explicit Decimal( std::uint64_t value ) noexcept;
258
265 inline explicit Decimal( std::string_view str );
266
273 inline explicit Decimal( const char* scStr );
274
296 explicit Decimal( const Int128& val );
297
302 Decimal( const Decimal& other ) noexcept = default;
303
308 Decimal( Decimal&& other ) noexcept = default;
309
310 //----------------------------------------------
311 // Destruction
312 //----------------------------------------------
313
315 ~Decimal() = default;
316
317 //----------------------------------------------
318 // Assignment
319 //----------------------------------------------
320
326 Decimal& operator=( const Decimal& other ) noexcept = default;
327
333 Decimal& operator=( Decimal&& other ) noexcept = default;
334
335 //----------------------------------------------
336 // Comparison operators
337 //----------------------------------------------
338
345 std::strong_ordering operator<=>( const Decimal& other ) const noexcept;
346
353 bool operator==( const Decimal& other ) const noexcept;
354
355 //----------------------------------------------
356 // Comparison with built-in floating point types
357 //----------------------------------------------
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>=( float 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
453 inline bool operator>=( double val ) const noexcept;
454
455 //----------------------------------------------
456 // Comparison with built-in integer types
457 //----------------------------------------------
458
464 inline bool operator==( std::int64_t val ) const noexcept;
465
471 inline bool operator!=( std::int64_t val ) const noexcept;
472
478 inline bool operator<( std::int64_t val ) const noexcept;
479
485 inline bool operator<=( std::int64_t val ) const noexcept;
486
492 inline bool operator>( std::int64_t val ) const noexcept;
493
499 inline bool operator>=( std::int64_t val ) const noexcept;
500
506 inline bool operator==( std::uint64_t val ) const noexcept;
507
513 inline bool operator!=( std::uint64_t val ) const noexcept;
514
520 inline bool operator<( std::uint64_t val ) const noexcept;
521
527 inline bool operator<=( std::uint64_t val ) const noexcept;
528
534 inline bool operator>( std::uint64_t val ) const noexcept;
535
541 inline bool operator>=( std::uint64_t val ) const noexcept;
542
548 inline bool operator==( std::int32_t val ) const noexcept;
549
555 inline bool operator!=( std::int32_t val ) const noexcept;
556
562 inline bool operator<( std::int32_t val ) const noexcept;
563
569 inline bool operator<=( std::int32_t val ) const noexcept;
570
576 inline bool operator>( std::int32_t val ) const noexcept;
577
583 inline bool operator>=( std::int32_t val ) const noexcept;
584
585 //----------------------------------------------
586 // Comparison with nfx::datatypes::Int128
587 //----------------------------------------------
588
595 bool operator==( const Int128& val ) const noexcept;
596
602 inline bool operator!=( const Int128& val ) const noexcept;
603
609 bool operator<( const Int128& val ) const noexcept;
610
616 inline bool operator<=( const Int128& val ) const noexcept;
617
623 inline bool operator>( const Int128& val ) const noexcept;
624
630 inline bool operator>=( const Int128& val ) const noexcept;
631
632 //----------------------------------------------
633 // Arithmetic operators
634 //----------------------------------------------
635
641 Decimal operator+( const Decimal& other );
642
648 inline Decimal operator-( const Decimal& other );
649
655 Decimal operator*( const Decimal& other ) const;
656
663 Decimal operator/( const Decimal& other ) const;
664
670 inline Decimal& operator+=( const Decimal& other );
671
677 inline Decimal& operator-=( const Decimal& other );
678
684 inline Decimal& operator*=( const Decimal& other );
685
692 inline Decimal& operator/=( const Decimal& other );
693
698 inline Decimal operator-() const noexcept;
699
700 //----------------------------------------------
701 // Property accessors
702 //----------------------------------------------
703
709 [[nodiscard]] std::uint8_t scale() const noexcept;
710
716 [[nodiscard]] inline const std::uint32_t& flags() const noexcept;
717
723 [[nodiscard]] inline std::uint32_t& flags() noexcept;
724
730 [[nodiscard]] inline const std::array<std::uint32_t, 3>& mantissa() const noexcept;
731
737 [[nodiscard]] inline std::array<std::uint32_t, 3>& mantissa() noexcept;
738
739 //----------------------------------------------
740 // Mathematical operations
741 //----------------------------------------------
742
748 [[nodiscard]] inline Decimal abs() const noexcept;
749
755 [[nodiscard]] inline Decimal ceil() const noexcept;
756
762 [[nodiscard]] inline Decimal floor() const noexcept;
763
771 [[nodiscard]] Decimal round( std::int32_t decimalsPlacesCount = 0, RoundingMode mode = RoundingMode::ToNearest ) const noexcept;
772
782 [[nodiscard]] Decimal sqrt() const;
783
789 [[nodiscard]] inline Decimal trunc() const noexcept;
790
791 //----------------------------------------------
792 // String parsing
793 //----------------------------------------------
794
812 [[nodiscard]] static bool fromString( std::string_view str, Decimal& result ) noexcept;
813
830 [[nodiscard]] static std::optional<Decimal> fromString( std::string_view str ) noexcept;
831
832 //----------------------------------------------
833 // Type conversion
834 //----------------------------------------------
835
843 [[nodiscard]] double toDouble() const noexcept;
844
850 [[nodiscard]] std::string toString() const;
851
857 [[nodiscard]] std::array<std::int32_t, 4> toBits() const noexcept;
858
859 //----------------------------------------------
860 // Utilities
861 //----------------------------------------------
862
872 [[nodiscard]] std::uint8_t decimalPlacesCount() const noexcept;
873
874 private:
875 //----------------------------------------------
876 // Internal representation
877 //----------------------------------------------
878
880 struct Layout
881 {
883 std::uint32_t flags;
884
886 std::array<std::uint32_t, 3> mantissa;
887 } m_layout;
888 };
889
890 //=====================================================================
891 // Free functions
892 //=====================================================================
893
902 [[nodiscard]] inline Decimal abs( const Decimal& value ) noexcept
903 {
904 return value.abs();
905 }
906
916 [[nodiscard]] inline Decimal sqrt( const Decimal& value )
917 {
918 return value.sqrt();
919 }
920
928 [[nodiscard]] inline Decimal ceil( const Decimal& value ) noexcept
929 {
930 return value.ceil();
931 }
932
940 [[nodiscard]] inline Decimal floor( const Decimal& value ) noexcept
941 {
942 return value.floor();
943 }
944
955 [[nodiscard]] inline Decimal round( const Decimal& value, std::int32_t decimalsPlacesCount = 0,
957 {
958 return value.round( decimalsPlacesCount, mode );
959 }
960
968 [[nodiscard]] inline Decimal trunc( const Decimal& value ) noexcept
969 {
970 return value.trunc();
971 }
972} // namespace nfx::datatypes
973
974#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:940
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:955
Decimal sqrt(const Decimal &value)
Compute square root using Newton-Raphson method (free function).
Definition Decimal.h:916
Decimal trunc(const Decimal &value) noexcept
Remove fractional part (free function).
Definition Decimal.h:968
Decimal ceil(const Decimal &value) noexcept
Round up to nearest integer (free function).
Definition Decimal.h:928
Decimal abs(const Decimal &value) noexcept
Get absolute value of decimal (free function).
Definition Decimal.h:902
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