BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdldfp_decimal.h
Go to the documentation of this file.
1/// @file bdldfp_decimal.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdldfp_decimal.h -*-C++-*-
8#ifndef INCLUDED_BDLDFP_DECIMAL
9#define INCLUDED_BDLDFP_DECIMAL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$")
13
14/// @defgroup bdldfp_decimal bdldfp_decimal
15/// @brief Provide IEEE-754 decimal floating-point types.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdldfp
19/// @{
20/// @addtogroup bdldfp_decimal
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdldfp_decimal-purpose"> Purpose</a>
25/// * <a href="#bdldfp_decimal-classes"> Classes </a>
26/// * <a href="#bdldfp_decimal-macros"> Macros </a>
27/// * <a href="#bdldfp_decimal-description"> Description </a>
28/// * <a href="#bdldfp_decimal-floating-point-primer"> Floating-Point Primer </a>
29/// * <a href="#bdldfp_decimal-floating-point-peculiarities"> Floating-Point Peculiarities </a>
30/// * <a href="#bdldfp_decimal-floating-point-environment"> Floating-Point Environment </a>
31/// * <a href="#bdldfp_decimal-rounding-direction-in-the-environment"> Rounding Direction in The Environment </a>
32/// * <a href="#bdldfp_decimal-status-flags"> Status Flags </a>
33/// * <a href="#bdldfp_decimal-floating-point-traps"> Floating-Point Traps </a>
34/// * <a href="#bdldfp_decimal-error-reporting"> Error Reporting </a>
35/// * <a href="#bdldfp_decimal-floating-point-terminology"> Floating-Point Terminology </a>
36/// * <a href="#bdldfp_decimal-decimal-floating-point"> Decimal Floating-Point </a>
37/// * <a href="#bdldfp_decimal-warning-conversions-from-float-and-double"> WARNING: Conversions from float and double </a>
38/// * <a href="#bdldfp_decimal-cohorts"> Cohorts </a>
39/// * <a href="#bdldfp_decimal-standards-conformance"> Standards Conformance </a>
40/// * <a href="#bdldfp_decimal-no-namespace-level-named-functions"> No Namespace Level Named Functions </a>
41/// * <a href="#bdldfp_decimal-all-converting-constructors-from-integer-types-are-explicit"> All Converting Constructors from Integer Types are Explicit </a>
42/// * <a href="#bdldfp_decimal-no-heterogeneous-comparisons-without-casting"> No Heterogeneous Comparisons Without Casting </a>
43/// * <a href="#bdldfp_decimal-arithmetic-and-computing-support-for-decimal32"> Arithmetic And Computing Support For Decimal32 </a>
44/// * <a href="#bdldfp_decimal-non-standard-member-functions"> Non-Standard Member Functions </a>
45/// * <a href="#bdldfp_decimal-decimal32-type"> Decimal32 Type </a>
46/// * <a href="#bdldfp_decimal-decimal64-type"> Decimal64 Type </a>
47/// * <a href="#bdldfp_decimal-decimal128-type"> Decimal128 Type </a>
48/// * <a href="#bdldfp_decimal-decimal-number-stream-based-formatting"> Decimal Number Stream-based Formatting </a>
49/// * <a href="#bdldfp_decimal-bsl-format-format-strings"> bsl::format Format Strings </a>
50/// * <a href="#bdldfp_decimal-user-defined-literals"> User-defined literals </a>
51/// * <a href="#bdldfp_decimal-usage"> Usage </a>
52/// * <a href="#bdldfp_decimal-example-1-portable-initialization-of-non-integer-constant-values"> Example 1: Portable Initialization of Non-Integer, Constant Values </a>
53/// * <a href="#bdldfp_decimal-example-2-precise-calculations-with-decimal-values"> Example 2: Precise Calculations with Decimal Values </a>
54///
55/// # Purpose {#bdldfp_decimal-purpose}
56/// Provide IEEE-754 decimal floating-point types.
57///
58/// # Classes {#bdldfp_decimal-classes}
59///
60/// - bdldfp::Decimal32: 32bit IEEE-754 decimal floating-point type
61/// - bdldfp::Decimal64: 64bit IEEE-754 decimal floating-point type
62/// - bdldfp::Decimal128: 128bit IEEE-754 decimal floating-point type
63/// - bdldfp::DecimalNumGet: Stream Input Facet
64/// - bdldfp::DecimalNumPut: Stream Output Facet
65/// - template bsl::formatter<bdldfp::Decimal32, t_CHAR>: formatter impl
66/// - template bsl::formatter<bdldfp::Decimal64, t_CHAR>: formatter impl
67/// - template bsl::formatter<bdldfp::Decimal128, t_CHAR>: formatter impl
68///
69/// # Macros {#bdldfp_decimal-macros}
70///
71/// - BDLDFP_DECIMAL_DF: Portable Decimal32 literal macro
72/// - BDLDFP_DECIMAL_DD: Portable Decimal64 literal macro
73/// - BDLDFP_DECIMAL_DL: Portable Decimal128 literal macro
74///
75/// @see bdldfp_decimalutil, bdldfp_decimalconvertutil,
76/// bdldfp_decimalplatform
77///
78/// # Description {#bdldfp_decimal-description}
79/// This component provides classes that implement decimal
80/// floating-point types that conform in layout, encoding and operations to the
81/// IEEE-754 2008 standard. This component also provides two facets to support
82/// standard C++ streaming operators as specified by ISO/IEC TR-24733:2009.
83/// These classes are `bdldfp::Decimal32` for 32-bit Decimal floating point
84/// numbers, `bdldfp::Decimal64` for 64-bit Decimal floating point numbers, and
85/// `bdldfp::Decimal128` for 128-bit decimal floating point numbers.
86///
87/// Decimal encoded floating-point numbers are important where exact
88/// representation of decimal fractions is required, such as in financial
89/// transactions. Binary encoded floating-point numbers are generally optimal
90/// for complex computation but cannot exactly represent commonly encountered
91/// numbers such as 0.1, 0.2, and 0.99.
92///
93/// NOTE: Interconversion between binary and decimal floating-point values is
94/// fraught with misunderstanding and must be done carefully and with intent,
95/// taking into account the provenance of the data. See the discussion on
96/// conversion below and in the @ref bdldfp_decimalconvertutil component.
97///
98/// The BDE decimal floating-point system has been designed from the ground up
99/// to be portable and support writing portable decimal floating-point user
100/// code, even for systems that do not have compiler or native library support
101/// for it; while taking advantage of native support (such as ISO/IEC TR
102/// 24732 - C99 decimal TR) when available.
103///
104/// `bdldfp::DecimalNumGet` and `bdldfp::DecimalNumPut` are IO stream facets.
105///
106/// This component also provides support for `bsl::format` formatting as
107/// described in {`bsl::format` Format Strings}
108///
109/// ## Floating-Point Primer {#bdldfp_decimal-floating-point-primer}
110///
111///
112/// There are several ways of represent numbers when using digital computers.
113/// The simplest would be an integer format, however such a format severely
114/// limits the range of numbers that can be represented; and it cannot represent
115/// real (non-integer) numbers directly at all. Integers might be used to
116/// represent real numbers of limited precision by treating them as a multiple
117/// of the real value being represented; these are often known as fixed-point
118/// numbers. However general computations require higher precision and a larger
119/// range than integer and fixed point types are able to efficiently provide.
120/// Floating-point numbers provide what integers cannot. They are able to
121/// represent a large range of real values (although not precisely) while using
122/// a fixed (and reasonable) amount of storage.
123///
124/// Floating-point numbers are constructed from a set of significant digits of a
125/// radix on a sliding scale, where their position is determined by an exponent
126/// over the same radix. For example let's see some 32bit decimal (radix 10)
127/// floating-point numbers that have maximum 7 significant digits (significand):
128/// @code
129/// Significand | Exponent | Value |
130/// -------------+----------+--------------+ In the Value column you may
131/// 1234567 | 0 | 1234567.0 | observer how the decimal point
132/// 1234567 | 1 | 12345670.0 | is "floating" about the digits
133/// 1234567 | 2 | 123456700.0 | of the significand.
134/// 1234567 | -1 | 123456.7 |
135/// 1234567 | -2 | 12345.67 |
136/// @endcode
137/// Floating-point numbers are standardized by IEEE-754 2008, in two major
138/// flavors: binary and decimal. Binary floating-point numbers are supported by
139/// most computer systems in the forms of the `float`, `double` and
140/// `long double` fundamental data types. While they are not required to be
141/// binary that is almost always the choice on modern binary computer
142/// architectures.
143///
144/// ### Floating-Point Peculiarities {#bdldfp_decimal-floating-point-peculiarities}
145///
146///
147/// Floating-point approximation of real numbers creates a deliberate illusion.
148/// While it looks like we are working with real numbers, floating-point
149/// encodings are not able to represent real numbers precisely since they have a
150/// restricted number of digits in the significand. In fact, a 64 bit
151/// floating-point type can represent fewer distinct values than a 64 bit binary
152/// integer. Yet, because floating-point encodings can represent numbers over a
153/// much larger range, including extremely small (fractional) numbers, they are
154/// useful in practice.
155///
156/// Floating-point peculiarities may be split into three categories: those that
157/// are due to the (binary) radix/base, those that are inherent properties of
158/// any floating-point representation and finally those that are introduced by
159/// the IEEE-754 2008 standard. Decimal floating-point addresses the first set
160/// of surprises only; so users still need to be aware of the rest.
161///
162/// 1. Floating-point types cannot exactly represent every number in their
163/// range. The consequences are surprising and unexpected for the newcomer.
164/// For example: when using binary floating-point numbers, the following
165/// expression is typically *false*: `0.1 + 0.2 == 0.3`. The problem is not
166/// limited to binary floating-point. Decimal floating-point cannot
167/// represent the value of one third exactly.
168/// 2. Unlike with real numbers, the order of operations on floating-point
169/// numbers is significant, due to accumulation of round off errors.
170/// Therefore floating-point arithmetic is neither commutative nor
171/// transitive. E.g., 2e-30 + 1e30 - 1e-30 - 1e30 will typically produce 0
172/// (unless your significand can hold 60 decimal digits). Alternatively,
173/// 1e30 - 1e30 + 2e-30 - 1e-30 will typically produce 1e-30.
174///
175/// 3. IEEE floating-point types can have special values: negative zero,
176/// negative and positive infinity; and they can be NaN (Not a Number, in two
177/// variants: quiet or signaling). A NaN (any variant) is never equal to
178/// anything else - including NaN or itself!
179/// 4. In IEEE floating-point there are at least two representations of 0, the
180/// positive zero and negative zero. Consequently unary - operators change
181/// the sign of the value 0; therefore leading to surprising results: if
182/// `f == 0.0` then `0 - f` and `-f` will not result in the same value,
183/// because `0 - f` will be +0.0' while `-f` will be -0.0.
184/// 5. Most IEEE floating-point operations (like arithmetic) have implicit input
185/// parameters and output parameters (that do not show up in function
186/// signatures. The implicit input parameters are called *attributes* by
187/// IEEE while the outputs are called status flags. The C/C++ programming
188/// language defines a so-called floating-point environment that contains
189/// those attributes and flags (`<fenv.h>` C and `<cfenv>` C++ headers). To
190/// learn more about the floating point environment read the subsection of
191/// the same title, but first make sure you read the next point as well.
192/// 6. IEEE floating-points overloads some very common programming language
193/// terms: *exception*, *signal* and *handler* with IEEE floating-point
194/// specific meanings that are not to be confused with C or C++ or Posix
195/// terms of the same spelling. Floating-point exceptions are events that
196/// occur when a floating-point operations on the specified operands is
197/// unable to produce a perfect outcome; such as when the result of an
198/// operation is inexact. When a floating point exception occurs the
199/// (floating-point) - and reporting it is requested by a so-called trap
200/// attribute - the implementation signals the user(*) by invoking a default
201/// or a user-defined handler. None of the words *exception*, *signal*, and
202/// *handler* used above have nothing to do with C++ exceptions, Posix
203/// signals and the handlers of those. (To complicate matters more, C and
204/// Posix has decided to implement IEEE floating-point exception reporting as
205/// C/Posix signals - and therefore rendered them mostly useless.)
206/// 7. While a 32bit integer is a quite useful type for (integer) calculations,
207/// a 32bit floating-point type has such low accuracy (its significand is so
208/// short) that it is all but useless for calculation. Such types are called
209/// "interchange formats" by the IEEE standard and should not be used for
210/// calculations. (Except in special circumstances and by floating-point
211/// experts. Even a 16 bit binary floating-point type can be useful for an
212/// expert in special circumstances, for example in graphics acceleration
213/// hardware.)
214///
215/// Notes:
216/// (*) IEEE Floating-point user is any person, hardware or software that uses
217/// the IEEE floating-point implementation.
218///
219/// ### Floating-Point Environment {#bdldfp_decimal-floating-point-environment}
220///
221///
222/// NOTE: We currently do not give access to the user to the floating-point
223/// environment used by our decimal system, so description of it here is
224/// preliminary and generic. Note that since compilers and the C library
225/// already provides a (possibly binary floating-point only) environment and we
226/// cannot change that, our decimal floating-point environment implementation
227/// cannot conform to the C and C++ TRs (because those require extending the
228/// existing standard C library functions).
229///
230/// The floating-point environment provides implicit input and output parameters
231/// to floating-point operations (that are defined to use them). IEEE defined
232/// those parameters in principle, but how they are provided is left up to be
233/// designed/defined by the implementors of the programming languages.
234///
235/// C (and consequently C++) decided to provide a so-called floating-point
236/// environment that has "thread storage duration", meaning that each thread of
237/// a multi-threaded program will have its own distinct floating-point
238/// environment.
239///
240/// The C/C++ floating-point environment consists of 3 major parts: the rounding
241/// mode, the traps and the status flags.
242///
243/// #### Rounding Direction in The Environment {#bdldfp_decimal-rounding-direction-in-the-environment}
244///
245///
246/// A floating-point *rounding direction* determines how is the significand of a
247/// higher (or infinite) precision number get rounded to fit into the limited
248/// number of significant digits (significand) of the floating-point
249/// representation that needs to store it as a result of an operation. Note
250/// that the rounding is done in the radix of the representation, so binary
251/// floating-point will do binary rounding while decimal floating-point will do
252/// decimal rounding - and not all rounding modes are useful with all radixes.
253/// An example of a generally applicable rounding mode would be `FE_TOWARDZERO`
254/// (round towards zero).
255///
256/// Most floating point operations in C and C++ do not take a rounding direction
257/// parameter (and the ones that are implemented as operators simply could not).
258/// When such operations (that do not have an explicit rounding direction
259/// parameter) need to do rounding, they use the rounding direction set in the
260/// floating-point environment (of their thread of execution).
261///
262/// #### Status Flags {#bdldfp_decimal-status-flags}
263///
264///
265/// Floating point operations in C and C++ do not take a status flag output
266/// parameter. They report an important events (such as underflow, overflow or
267/// in inexact (rounded) result) by setting the appropriate status flag in the
268/// floating-point environment (of their thread of execution). (Note that this
269/// is very similar to how flags work in CPUs, and that is not a coincidence.)
270/// The flags work much like individual, boolean `errno` values. Operations may
271/// set them to true. Users may examine them (when interested) and also reset
272/// them (set them to 0) before an operation.
273///
274/// #### Floating-Point Traps {#bdldfp_decimal-floating-point-traps}
275///
276///
277/// IEEE says that certain floating-point events are floating-point exceptions
278/// and they result in invoking a handler. It may be a default handler (set a
279/// status flag and continue) or a user defined handler. Floating point traps
280/// are a C invention to enable "sort-of handlers" for floating point
281/// exceptions, but unfortunately they all go to the same handler: the `SIGFPE`
282/// handler. To add insult to injury, setting what traps are active (what will)
283/// cause a `SIGFPE`) is not standardized. So floating-point exceptions and
284/// handlers are considered pretty much useless in C. (All is not lost, since
285/// we do have the status flags. An application that wants to know about
286/// floating-point events can clear the flags prior to an operation and check
287/// their values afterwards.)
288///
289/// #### Error Reporting {#bdldfp_decimal-error-reporting}
290///
291///
292/// The @ref bdldfp_decimalutil utility component provides a set of decimal math
293/// functions that parallel those provided for binary floating point in the C++
294/// standard math library. Errors during computation of these functions (e.g.,
295/// domain errors) will be reported through the setting of `errno` as described
296/// in the "Status Flags" section above. (Note that this method of reporting
297/// errors is atypical for BDE-provided interfaces, but matches the style used
298/// by the standard functions.)
299///
300/// ### Floating-Point Terminology {#bdldfp_decimal-floating-point-terminology}
301///
302///
303/// A floating-point representation of a number is defined as follows:
304/// `sign * significand * BASE^exponent`, where sign is -1 or +1, significand is
305/// an integer, BASE is a positive integer (but usually 2 or 10) and exponent is
306/// a negative or positive integer. Concrete examples of (decimal) numbers in
307/// the so-called scientific notation are: 123.4567 is 1.234567e2, while
308/// -0.000000000000000000000000000000000000001234567 would be -1.234567e-41.
309///
310/// "base":
311/// the number base of the scaling used by the exponent; and by the
312/// significand
313///
314/// "bias":
315/// the number added to the exponent before it is stored in memory; 101, 398
316/// and 6176 for the 32, 64 and 128 bit types respectively.
317///
318/// "exponent":
319/// the scaling applied to the significand is calculated by raising the base
320/// to the exponent (which may be also negative)
321///
322/// "quantum":
323/// (IEEE-754) the value of one unit at the last significant digit
324/// position; in other words the smallest difference that can be
325/// represented by a floating-point number without changing its exponent.
326///
327/// "mantissa":
328/// the old name for the significand
329///
330/// "radix":
331/// another name for base
332///
333/// "sign":
334/// +1 or -1, determines if the number is positive or negative. It is
335/// normally represented by a single sign bit.
336///
337/// "significand":
338/// the significant digits of the floating-point number; the value of the
339/// number is: `sign * significand * base^exponent`
340///
341/// "precision":
342/// the significant digits of the floating-point type in its base
343///
344/// "decimal precision":
345/// the maximum significant decimal digits of the floating-point type
346///
347/// "range":
348/// the smallest and largest number the type can represent. Note that for
349/// floating-point types there are at least *two* interpretations of
350/// minimum. It may be the largest negative number *or* the smallest number
351/// in absolute value) that can be represented.
352///
353/// "normalized number":
354/// `1 <= significand <= base`
355///
356/// "normalization":
357/// finding the exponent such as `1 <= significand <= base`
358///
359/// "denormal number":
360/// `significand < 1`
361///
362/// "densely packed decimal":
363/// one of the two IEEE significand encoding schemes
364///
365/// "binary integer significand":
366/// one of the two IEEE significand encoding schemes
367///
368/// "cohorts":
369/// equal numbers encoded using different exponents (to signify accuracy)
370///
371/// ## Decimal Floating-Point {#bdldfp_decimal-decimal-floating-point}
372///
373///
374/// Binary floating-point formats give best accuracy, they are the fastest (on
375/// binary computers), and were carefully designed by IEEE to minimize rounding
376/// errors (errors due to the inherent imprecision of floating-point types)
377/// during a lengthy calculation. This makes them the best solution for and
378/// serious scientific computation. However, they have a fatal flow when it
379/// comes to numbers and calculations that involve humans. Humans think in base
380/// 10 - decimal. And as the example has shown earlier, binary floating-point
381/// formats are unable to precisely represent very common decimal real numbers;
382/// with binary floating-point `0.1 + 0.2 != 0.3`. (Why? Because none of the
383/// three numbers in that expression have an exact binary floating-point
384/// representation.)
385///
386/// Financial calculations are governed by laws and expectations that are based
387/// on decimal (10 based) thinking. Due to the inherent limitations of the
388/// binary floating-point format, doing such decimal based calculations and
389/// algorithms using binary floating-point numbers is so involved and hard that
390/// that it is considered not feasible. The IEEE-754 committee have recognized
391/// the issue and added specifications for 3 decimal floating-point types into
392/// their 2008 standard: the 32, 64 and 128 bits decimal floating-point formats.
393///
394/// Floating-point types are carefully designed trade-offs between saving space
395/// (in memory), CPU cycles (for calculations) and still provide useful accuracy
396/// for computations. Decimal floating-point types represent further
397/// compromises (compared to binary floating-points) in being able to represent
398/// less numbers (than their binary counterparts) and being slower, but
399/// providing exact representations for the numbers humans care about.
400///
401/// In decimal floating-point world `0.1 + 0.2 == 0.3`, as humans expect;
402/// because each of those 3 numbers can be represented *exactly* in a decimal
403/// floating-point format.
404///
405/// ### WARNING: Conversions from float and double {#bdldfp_decimal-warning-conversions-from-float-and-double}
406///
407///
408/// Clients should *be* *careful* when using the conversions from `float` and
409/// `double` provided by this component. In situations where a `float` or
410/// `double` was originally obtained from a decimal floating point
411/// representation (e.g., a `bdldfp::Decimal`, or a string, like "4.1"), the
412/// conversions in @ref bdldfp_decimalconvertutil will provide the correct
413/// conversion back to a decimal floating point value. The conversions in this
414/// component provide the closest decimal floating point value to the supplied
415/// binary floating point representation, which may replicate imprecisions
416/// required to initially approximate the value in a binary representation.
417/// The conversions in this component are typically useful when converting
418/// binary floating point values that have undergone mathematical operations
419/// that require rounding (so they are already in-exact approximations).
420///
421/// ### Cohorts {#bdldfp_decimal-cohorts}
422///
423///
424/// In the binary floating-point world the formats are optimized for the highest
425/// precision, range and speed. They are stored normalized and therefore store
426/// no information about their accuracy. In finances, the area that decimal
427/// floating-point types target, accuracy of a number is usually very important.
428/// We may have a number that is 1, but we know it may be 1.001 or 1.002 etc.
429/// And we may have another number 1, which we know to be accurate to 6
430/// significant digits. We would display the former number as `1.00` and the
431/// latter number as `1.00000`. The decimal floating-point types are able to
432/// store both numbers *and* their precision using so called cohorts. The
433/// `1.00` will be stored as `100e-2` while `1.00000` will be stored as
434/// `100000e-5`.
435///
436/// Cohorts compare equal, and mostly behave the same way in calculation except
437/// when it comes to the accuracy of the result. If I have a number that is
438/// accurate to 5 digits only, it would be a mistake to try to expect more than
439/// 5 digits accuracy from a calculation involving it. The IEEE-754 rules of
440/// cohorts (in calculations) ensures that results will be a cohort that
441/// indicates the proper expected accuracy.
442///
443/// ## Standards Conformance {#bdldfp_decimal-standards-conformance}
444///
445///
446/// The component has also been designed to resemble the C++ Decimal
447/// Floating-Point Technical Report ISO/IEC TR-24733 of 2009 and its C++11
448/// updates of ISO/IEC JTC1 SC22 WG21 N3407=12-0097 of 2012 as much as it is
449/// possible with C++03 compilers and environments that do not provide decimal
450/// floating-point support in any form.
451///
452/// At the time of writing there is just one standard about decimal-floating
453/// point, the IEEE-754 2008 standard and the content of this component conforms
454/// to it. The component does not fully implement all required IEEE-754
455/// functionality because due to our architectural design guidelines some of
456/// these must go into a separate so-called utility component.)
457///
458/// The component uses the ISO/IEC TR 24732 - the C Decimal Floating-Point
459/// TR - in its implementation where it is available.
460///
461/// The component closely resembles ISO/IEC TR 24733 - the C++ Decimal
462/// Floating-Point TR - but does not fully conform to it for several reasons.
463/// The major reasons are: it is well known that TR 24733 has to change before
464/// it is included into the C++ standard; the TR would require us to change
465/// system header files we do not have access to.
466///
467/// In the following subsections the differences to the C++ technical report are
468/// explained in detail, including a short rationale.
469///
470/// ### No Namespace Level Named Functions {#bdldfp_decimal-no-namespace-level-named-functions}
471///
472///
473/// BDE design guidelines do not allow namespace level functions other than
474/// operators and aspects. According to BDE design principles all such
475/// functions are placed into a utility component.
476///
477/// ### All Converting Constructors from Integer Types are Explicit {#bdldfp_decimal-all-converting-constructors-from-integer-types-are-explicit}
478///
479///
480/// This change is necessary to disable the use of comparison operators without
481/// explicit casting. See No Heterogeneous Comparisons Without Casting.
482///
483/// ### No Heterogeneous Comparisons Without Casting {#bdldfp_decimal-no-heterogeneous-comparisons-without-casting}
484///
485///
486/// The C and C++ Decimal TRs refer to IEEE-754 for specifications of the
487/// heterogeneous comparison operators (comparing decimal floating-point types
488/// to binary floating-point types and integer types); however IEEE-754 does
489/// *not* specify such operations - leaving them unspecified. To make matters
490/// worse, there are two possible ways to implement those operators (convert the
491/// decimal to the other type, or convert the other type to decimal first) and
492/// depending on which one is chosen, the result of the operator will be
493/// different. Also, the C committee is considering the removal of those
494/// operators. We have removed them until we know how to implement them.
495/// Comparing decimal types to those other types is still possible, it just
496/// requires explicit casting/conversion from the user code.
497///
498/// ### Arithmetic And Computing Support For Decimal32 {#bdldfp_decimal-arithmetic-and-computing-support-for-decimal32}
499///
500///
501/// IEEE-754 designates the 32 bit floating-point types "interchange formats"
502/// and does not require or recommend arithmetic or computing support of any
503/// kind for them. The C (and consequently the C++) TR goes against the IEEE
504/// design and requires `_Decimal32` (and `std::decimal32`) to provide computing
505/// support, however, in a twist, allows it to be performed using one of the
506/// larger types (64 or 128 bits). The rationale from the C committee is that
507/// small embedded systems may need to do their calculations using the small
508/// type (so they have made it mandatory for everyone). To conform the
509/// requirement we provide arithmetic and computing support for Decimal32 type
510/// but users need to be aware of the drawbacks of calculations using the small
511/// type. Industry experience with the `float` C type (32bit floating-point
512/// type, usually binary) has shown that enabling computing using small
513/// floating-point types are a mistake that causes novice programmers to write
514/// calculations that are very slow and inaccurate.
515///
516/// We recommend what IEEE recommends: convert your 32 bit types on receipt to a
517/// type with higher precision (usually 64 bit will suffice), so you
518/// calculations using that larger type, and convert it back to 32 bit type only
519/// if your output interchange format requires it.
520///
521/// ### Non-Standard Member Functions {#bdldfp_decimal-non-standard-member-functions}
522///
523///
524/// Due to BDE rules of design and some implementation needs we have extended
525/// the C++ TR mandated interface of the decimal floating-point types to include
526/// support for accessing the underlying data (type), to parse literals for the
527/// portable literal support.
528///
529/// Note that using any of these public member functions will render your code
530/// non-portable to non-BDE (but standards conforming) implementations.
531///
532/// ## Decimal32 Type {#bdldfp_decimal-decimal32-type}
533///
534///
535/// A basic format type that supports input, output, relational operators
536/// construction from the TR mandates data types and arithmetic or operations.
537/// The type has the size of exactly 32 bits. It supports 7 significant decimal
538/// digits and an exponent range of -95 to 96. The smallest non-zero value that
539/// can be represented is 1e-101.
540///
541/// Portable `Decimal32` literals are created using the `BDLDFP_DECIMAL_DF`
542/// macro.
543///
544/// ## Decimal64 Type {#bdldfp_decimal-decimal64-type}
545///
546///
547/// A basic format type that supports input, output, relational operators
548/// construction from the TR mandates data types and arithmetic or operations.
549/// The type has the size of exactly 64 bits. It supports 16 significant
550/// decimal digits and an exponent range of -383 to 384. The smallest non-zero
551/// value that can be represented is 1e-398.
552///
553/// Portable `Decimal64` literals are created using the `BDLDFP_DECIMAL_DD`
554/// macro.
555///
556/// ## Decimal128 Type {#bdldfp_decimal-decimal128-type}
557///
558///
559/// A basic format type that supports input, output, relational operators
560/// construction from the TR mandates data types and arithmetic or operations.
561/// The type has the size of exactly 128 bits. It supports 34 significant
562/// decimal digits and an exponent range of -6143 to 6144. The smallest
563/// non-zero value that can be represented is 1e-6176.
564///
565/// Portable `Decimal128` literals are created using the `BDLDFP_DECIMAL_DL`
566/// macro.
567///
568/// ## Decimal Number Stream-based Formatting {#bdldfp_decimal-decimal-number-stream-based-formatting}
569///
570///
571/// Streaming decimal floating point numbers to an output stream supports
572/// formatting flags for width, capitalization and justification and flags used
573/// to output numbers in natural, scientific and fixed notations. When
574/// scientific or fixed flags are set then the precision manipulator specifies
575/// how many digits of the decimal number are to be printed, otherwise all
576/// significant digits of the decimal number are output using native notation.
577///
578/// ## bsl::format Format Strings {#bdldfp_decimal-bsl-format-format-strings}
579///
580///
581/// `bsl::format` formatting is supported with format strings very similar to
582/// binary floating point formats strings, with two major exceptions: there is
583/// no support for hexadecimal format, and the default precision is the
584/// precision stored within the decimal floating point number (see {Cohorts}),
585/// unlike binary floating point where it is always 6.
586///
587/// The formats supported are the so-called General, Fixed, Scientific, and
588/// their uppercase equivalents.
589///
590/// The sign support is the usual: Negative-only, Always, and
591/// Positive-as-space.
592///
593/// The alternative format flag ('#') causes the decimal point to be always
594/// written (but does not remove trailing zeros).
595///
596/// Alignment, fill, and leading zeros are supported as usual.
597///
598/// ## User-defined literals {#bdldfp_decimal-user-defined-literals}
599///
600///
601/// The user-defined literal `operator""_d32`, `operator""_d64`, and
602/// `operator""_d128` are declared for the `bdldfp::Decimal32`,
603/// `bdldfp::Decimal64`, and `bdldfp::Decimal128` types respectively . These
604/// user-defined literal suffixes can be applied to both numeric and string
605/// literals, (i.e., 1.2_d128, "1.2"_d128 or "inf"_d128) to produce a decimal
606/// floating-point value of the indicated type by parsing the argument string
607/// or numeric value:
608/// @code
609/// using namespace bdldfp::DecimalLiterals;
610///
611/// bdldfp::Decimal32 d0 = "1.2"_d32;
612/// bdldfp::Decimal32 d1 = 1.2_d32;
613/// assert(d0 == d1);
614///
615/// bdldfp::Decimal64 d2 = "3.45678901234"_d64;
616/// bdldfp::Decimal64 d3 = 3.45678901234_d64;
617/// assert(d2 == d3);
618///
619/// bdldfp::Decimal128 inf = "inf"_d128;
620/// bdldfp::Decimal128 nan = "nan"_d128;
621/// @endcode
622/// The operators providing literals are available in the
623/// `BloombergLP::bdldfp::literals::DecimalLiterals` namespace (where `literals`
624/// and `DecimalLiterals` are both inline namespaces). Because of inline
625/// namespaces, there are several viable options for a using declaration, but
626/// *we* *recommend* `using namespace bdldfp::DecimalLiterals`, which minimizes
627/// the scope of the using declaration.
628///
629/// Note that the parsing follows the rules as specified for the `strtod32`,
630/// `strtod64` and `strtod128` functions in section 9.6 of the ISO/EIC TR 247128
631/// C Decimal Floating-Point Technical Report.
632///
633/// Also note that these operators can be used only if the compiler supports
634/// C++11 standard.
635///
636/// ## Usage {#bdldfp_decimal-usage}
637///
638///
639/// In this section, we show the intended usage of this component.
640///
641/// ### Example 1: Portable Initialization of Non-Integer, Constant Values {#bdldfp_decimal-example-1-portable-initialization-of-non-integer-constant-values}
642///
643///
644/// If your compiler does not support the C Decimal TR, it does not support
645/// decimal floating-point literals, only binary floating-point literals. The
646/// problem with binary floating-point literals is the same as with binary
647/// floating-point numbers in general: they cannot represent the decimal numbers
648/// we care about. To solve this problem there are 3 macros provided by this
649/// component that can be used to initialize decimal floating-point types with
650/// non-integer values, precisely. These macros will evaluate to real, C
651/// language literals where those are supported and to a runtime-parsed solution
652/// otherwise. The following code demonstrates the use of these macros as well
653/// as mixed-type arithmetics and comparisons:
654/// @code
655/// bdldfp::Decimal32 d32( BDLDFP_DECIMAL_DF(0.1));
656/// bdldfp::Decimal64 d64( BDLDFP_DECIMAL_DD(0.2));
657/// bdldfp::Decimal128 d128(BDLDFP_DECIMAL_DL(0.3));
658///
659/// assert(d32 + d64 == d128);
660/// assert(bdldfp::Decimal64(d32) * 10 == bdldfp::Decimal64(1));
661/// assert(d64 * 10 == bdldfp::Decimal64(2));
662/// assert(d128 * 10 == bdldfp::Decimal128(3));
663/// @endcode
664///
665/// ### Example 2: Precise Calculations with Decimal Values {#bdldfp_decimal-example-2-precise-calculations-with-decimal-values}
666///
667///
668/// Suppose we need to add two (decimal) numbers and then tell if the result is
669/// a particular decimal number or not. That can get difficult with binary
670/// floating-point, but easy with decimal:
671/// @code
672/// if (std::numeric_limits<double>::radix == 2) {
673/// assert(.1 + .2 != .3);
674/// }
675/// assert(BDLDFP_DECIMAL_DD(0.1) + BDLDFP_DECIMAL_DD(0.2)
676/// == BDLDFP_DECIMAL_DD(0.3));
677/// @endcode
678/// @}
679/** @} */
680/** @} */
681
682/** @addtogroup bdl
683 * @{
684 */
685/** @addtogroup bdldfp
686 * @{
687 */
688/** @addtogroup bdldfp_decimal
689 * @{
690 */
691
692#include <bdldfp_decimal.fwd.h>
693
694#include <bdlscm_version.h>
695
698
699#include <bsla_fallthrough.h>
700
701#include <bslh_hash.h>
702
703#include <bslfmt_formaterror.h>
705#include <bslfmt_formatterbase.h>
707#include <bslfmt_padutil.h>
708
710#include <bslma_default.h>
712
715
716#include <bsls_annotation.h>
717#include <bsls_assert.h>
719#include <bsls_keyword.h>
720#include <bsls_libraryfeatures.h>
721#include <bsls_platform.h>
722
723#include <bsl_cstddef.h>
724#include <bsl_cstring.h>
725#include <bsl_ios.h>
726#include <bsl_iosfwd.h>
727#include <bsl_iterator.h>
728#include <bsl_limits.h>
729#include <bsl_locale.h>
730
731#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
732 #include <bslalg_typetraits.h>
733#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
734
735 // Portable decimal floating-point literal support
736
737#define BDLDFP_DECIMAL_DF(lit) \
738 BloombergLP::bdldfp::Decimal32(BDLDFP_DECIMALIMPUTIL_DF(lit))
739
740#define BDLDFP_DECIMAL_DD(lit) \
741 BloombergLP::bdldfp::Decimal64(BDLDFP_DECIMALIMPUTIL_DD(lit))
742
743#define BDLDFP_DECIMAL_DL(lit) \
744 BloombergLP::bdldfp::Decimal128(BDLDFP_DECIMALIMPUTIL_DL(lit))
745
746
747namespace bdldfp {
748
751
752/// The decimal floating-point types are typedefs to the unspecified
753/// implementation types.
755
756 // ====================
757 // class Decimal_Type32
758 // ====================
759
760/// This value-semantic class implements the IEEE-754 32 bit decimal
761/// floating-point interchange format type. This class is a standard layout
762/// type that is `const` thread-safe and exception-neutral.
763///
764/// See @ref bdldfp_decimal
766
767 private:
768 // DATA
769 DecimalImpUtil::ValueType32 d_value; // The underlying IEEE representation
770
771 public:
772 // CLASS METHODS
773
774 // Aspects
775
776 /// Return the maximum valid BDEX format version, as indicated by the
777 /// specified `versionSelector`, to be passed to the `bdexStreamOut` method.
778 ///
779 /// \note Note that it is highly recommended that `versionSelector`
780 /// be formatted as "YYYYMMDD", a date representation. Also note that
781 /// `versionSelector` should be a *compile*-time-chosen value that
782 /// selects a format version supported by both externalizer and
783 /// unexternalizer. See the `bslx` package-level documentation for more
784 /// information on BDEX streaming of value-semantic types and
785 /// containers.
786 static int maxSupportedBdexVersion();
787 static int maxSupportedBdexVersion(int versionSelector);
788
789 // TRAITS
792
793 // CREATORS
794
795 /// Create a `Decimal32_Type` object having the value positive zero and
796 /// the smallest exponent value.
798
799 /// Create a `Decimal32_Type` object having the specified `value`.
801
802 /// Create a `Decimal32_Type` object having the value closest to the
803 /// value of the specified `other` following the conversion rules as
804 /// defined by IEEE-754:
805 ///
806 /// * If `other` is NaN, initialize this object to a NaN.
807 /// * Otherwise if `other` is infinity (positive or negative), then
808 /// initialize this object to infinity with the same sign.
809 /// * Otherwise if `other` has a zero value, then initialize this
810 /// object to zero with the same sign.
811 /// * Otherwise if `other` has an absolute value that is larger than
812 /// `std::numeric_limits<Decimal32>::max()` then store the value of
813 /// the macro `ERANGE` into `errno` and initialize this object to
814 /// infinity with the same sign as `other`.
815 /// * Otherwise if `other` has an absolute value that is smaller than
816 /// `std::numeric_limits<Decimal32>::min()` then store the value of
817 /// the macro `ERANGE` into `errno` and initialize this object to
818 /// zero with the same sign as `other`.
819 /// * Otherwise if `other` has a value that has more significant digits
820 /// than `std::numeric_limits<Decimal32>::max_digit` then initialize
821 /// this object to the value of `other` rounded according to the
822 /// rounding direction.
823 /// * Otherwise initialize this object to the value of the `other`.
824 explicit Decimal_Type32(Decimal_Type64 other);
825 explicit Decimal_Type32(Decimal_Type128 other);
826
827 /// Create a `Decimal32_Type` object having the value closest to the
828 /// value of the specified `other` value. *Warning:* clients requiring
829 /// a conversion for an exact decimal value should use
830 /// @ref bdldfp_decimalconvertutil (see *WARNING*: Conversions from
831 /// `float` and `double`}. This conversion follows the conversion
832 /// rules as defined by IEEE-754:
833 ///
834 /// * If `other` is NaN, initialize this object to a NaN.
835 /// * Otherwise if `other` is infinity (positive or negative), then
836 /// initialize this object to infinity value with the same sign.
837 /// * Otherwise if `other` has a zero value, then initialize this
838 /// object to zero with the same sign.
839 /// * Otherwise if `other` has an absolute value that is larger than
840 /// `std::numeric_limits<Decimal32>::max()` then store the value of
841 /// the macro `ERANGE` into `errno` and initialize this object to
842 /// infinity with the same sign as `other`.
843 /// * Otherwise if `other` has an absolute value that is smaller than
844 /// `std::numeric_limits<Decimal32>::min()` then store the value of
845 /// the macro `ERANGE` into `errno` and initialize this object to
846 /// zero with the same sign as `other`.
847 /// * Otherwise if `other` has a value that has more significant digits
848 /// than `std::numeric_limits<Decimal32>::max_digit` then initialize
849 /// this object to the value of `other` rounded according to the
850 /// rounding direction.
851 /// * Otherwise initialize this object to the value of the `other`.
852 explicit Decimal_Type32(float other);
853 explicit Decimal_Type32(double other);
854
855 /// Create a `Decimal32_Type` object having the value closest to the
856 /// value of the specified `other` following the conversion rules as
857 /// defined by IEEE-754:
858 ///
859 /// * If `value` is zero then initialize this object to a zero with an
860 /// unspecified sign and an unspecified exponent.
861 /// * Otherwise if `other` has a value that is not exactly
862 /// representable using `std::numeric_limits<Decimal32>::max_digit`
863 /// decimal digits then initialize this object to the value of
864 /// `other` rounded according to the rounding direction.
865 /// * Otherwise initialize this object to the value of `other` with
866 /// exponent 0.
867 explicit Decimal_Type32(int other);
868 explicit Decimal_Type32(unsigned int other);
869 explicit Decimal_Type32(long int other);
870 explicit Decimal_Type32(unsigned long int other);
871 explicit Decimal_Type32(long long other);
872 explicit Decimal_Type32(unsigned long long other);
873
874 Decimal32_Type(const Decimal32_Type& original) = default;
875 // Create a 'Decimal32_Type' object that is a copy of the specified
876 // 'original' as defined by the 'copy' operation of IEEE-754 2008:
877 //
878 //: o If 'other' is NaN, initialize this object to a NaN.
879 //:
880 //: o Otherwise initialize this object to the value of the 'other'.
881 //
882 // Note that since floating-point types may be NaN, and NaNs are
883 // unordered (do not compare equal even to themselves) it is possible
884 // that a copy of a decimal will not compare equal to the original;
885 // however it will behave as the original.
886
887 ~Decimal32_Type() = default;
888 // Destroy this object.
889
890 // MANIPULATORS
892 // Make this object a copy of the specified 'rhs' as defined by the
893 // 'copy' operation of IEEE-754 2008 and return a reference providing
894 // modifiable access to this object.
895 //
896 //: o If 'other' is NaN, set this object to a NaN.
897 //:
898 //: o Otherwise set this object to the value of the 'other'.
899 //
900 // Note that since floating-point types may be NaN, and NaNs are
901 // unordered (do not compare equal even to themselves) it is possible
902 // that, after an assignment, a decimal will not compare equal to the
903 // original; however it will behave as the original.
904
905 /// Add 1.0 to the value of this object and return a reference to it.
906 ///
907 /// \note Note that this is a floating-point value so this operation may not
908 /// change the value of this object at all (if the value is large) or it
909 /// may just set it to 1.0 (if the original value is small).
911
912 /// Add -1.0 to the value of this object and return a reference to it.
913 ///
914 /// \note Note that this is a floating-point value so this operation may not
915 /// change the value of this object at all (if the value is large) or it
916 /// may just set it to -1.0 (if the original value is small).
918
919 /// Add the value of the specified `rhs` object to the value of this as
920 /// described by IEEE-754, store the result in this object, and return a
921 /// reference to this object.
922 ///
923 /// * If either of this object or `rhs` is signaling NaN, then store
924 /// the value of the macro `EDOM` into `errno` and set this object to
925 /// a NaN.
926 /// * Otherwise if either of this object or `rhs` is NaN then set this
927 /// object to a NaN.
928 /// * Otherwise if this object and `rhs` have infinity value of
929 /// differing signs, store the value of the macro `EDOM` into `errno`
930 /// and set this object to a NaN.
931 /// * Otherwise if this object and `rhs` have infinite values of the
932 /// same sign, then do not change this object.
933 /// * Otherwise if `rhs` has a zero value (positive or negative), do
934 /// not change this object.
935 /// * Otherwise if the sum of this object and `rhs` has an absolute
936 /// value that is larger than `std::numeric_limits<Decimal32>::max()`
937 /// then store the value of the macro `ERANGE` into `errno` and
938 /// set this object to infinity with the same sign as that result.
939 /// * Otherwise set this object to the sum of the number represented by
940 /// `rhs` and the number represented by this object.
941 ///
942 ///
943 /// \note Note that this is a floating-point value so this operations may not
944 /// change the value of this object at all (if the value is large) or it
945 /// may seem to update it to the value of the `other` (if the original
946 /// value is small).
947 ///
948 /// Also note that when `rhs` is a `Decimal64`, this operation is
949 /// always performed with 64 bits precision to prevent loss of
950 /// precision of the `rhs` operand (prior to the operation). The
951 /// result is then rounded back to 32 bits and stored to this object.
952 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
953 /// specification.
954 ///
955 /// Also note that when `rhs` is a `Decimal128`, this operation is
956 /// always performed with 128 bits precision to prevent loss of
957 /// precision of the `rhs` operand (prior to the operation). The
958 /// result is then rounded back to 32 bits and stored to this object.
959 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
960 /// specification.
964
965 /// Add the specified `rhs` to the value of this object as described by
966 /// IEEE-754, store the result in this object, and return a reference to
967 /// this object.
968 ///
969 /// * If this object is signaling NaN, then store the value of the
970 /// macro `EDOM` into `errno` and set this object to a NaN.
971 /// * Otherwise if this object is NaN, then do not change this object.
972 /// * Otherwise if this object is infinity, then do not change it.
973 /// * Otherwise if the sum of this object and `rhs` has an absolute
974 /// value that is larger than `std::numeric_limits<Decimal32>::max()`
975 /// then store the value of the macro `ERANGE` into `errno` and
976 /// set this object to infinity with the same sign as that result.
977 /// * Otherwise set this object to sum of adding `rhs` and the number
978 /// represented by this object.
979 ///
980 ///
981 /// \note Note that this is a floating-point value so this operations may not
982 /// change the value of this object at all (if the value is large) or it
983 /// may seem to update it to the value of the `other` (if the original
984 /// value is small).
985 ///
986 /// Also note that this operation is always performed with 64 bits
987 /// precision to prevent loss of precision of the `rhs` operand (prior
988 /// to the operation). The result is then rounded back to 32 bits and
989 /// stored to this object. See IEEE-754 2008, 5.1, first paragraph,
990 /// second sentence for specification.
991 Decimal_Type32& operator+=(int rhs);
992 Decimal_Type32& operator+=(unsigned int rhs);
993 Decimal_Type32& operator+=(long rhs);
994 Decimal_Type32& operator+=(unsigned long rhs);
995 Decimal_Type32& operator+=(long long rhs);
996 Decimal_Type32& operator+=(unsigned long long rhs);
997
998
999 /// Subtract the value of the specified `rhs` from the value of this
1000 /// object as described by IEEE-754, store the result in this object,
1001 /// and return a reference to this object.
1002 ///
1003 /// * If this object is signaling NaN, then store the value of the
1004 /// macro `EDOM` into `errno` and set this object to a NaN.
1005 /// * Otherwise if either of this object or `rhs` is NaN then set this
1006 /// object to a NaN.
1007 /// * Otherwise if this object and `rhs` have infinity value of the
1008 /// same signs, store the value of the macro `EDOM` into `errno`
1009 /// and set this object to a NaN.
1010 /// * Otherwise if this object and the `rhs` have infinite values of
1011 /// differing signs, then do not change this object.
1012 /// * Otherwise if the `rhs` has a zero value (positive or negative),
1013 /// do not change this object.
1014 /// * Otherwise if subtracting the value of the `rhs` object from this
1015 /// results in an absolute value that is larger than
1016 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1017 /// the macro `ERANGE` into `errno` and set this object to infinity
1018 /// with the same sign as that result.
1019 /// * Otherwise set this object to the result of subtracting the value
1020 /// of `rhs` from the value of this object.
1021 ///
1022 ///
1023 /// \note Note that this is a floating-point value so this operations may not
1024 /// change the value of this object at all (if the value is large) or it
1025 /// may seem to update it to the value of the `other` (if the original
1026 /// value is small).
1027 ///
1028 /// Also note that when `rhs` is a `Decimal64`, this operation is
1029 /// always performed with 64 bits precision to prevent loss of
1030 /// precision of the `rhs` operand (prior to the operation). The
1031 /// result is then rounded back to 32 bits and stored to this object.
1032 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
1033 /// specification.
1034 ///
1035 /// Also note that when `rhs` is a `Decimal128`, this operation is
1036 /// always performed with 128 bits precision to prevent loss of
1037 /// precision of the `rhs` operand (prior to the operation). The
1038 /// result is then rounded back to 32 bits and stored to this object.
1039 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
1040 /// specification.
1044
1045 /// Subtract the specified `rhs` from the value of this object as
1046 /// described by IEEE-754, store the result in this object, and return a
1047 /// reference to this object.
1048 ///
1049 /// * If this object is signaling NaN, then store the value of the
1050 /// macro `EDOM` into `errno` and set this object to a NaN.
1051 /// * Otherwise if this object is NaN, then do not change this object.
1052 /// * Otherwise if this object is infinity, then do not change it.
1053 /// * Otherwise if subtracting `rhs` from this object's value results
1054 /// in an absolute value that is larger than
1055 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1056 /// the macro `ERANGE` into `errno` and set this object to infinity
1057 /// with the same sign as that result.
1058 /// * Otherwise set this object to the result of subtracting `rhs` from
1059 /// the value of this object.
1060 ///
1061 ///
1062 /// \note Note that this is a floating-point value so this operations may not
1063 /// change the value of this object at all (if the value is large) or it
1064 /// may seem to update it to the value of the `other` (if the original
1065 /// value is small).
1066 ///
1067 /// Also note that this operation is always performed with 64 bits
1068 /// precision to prevent loss of precision of the `rhs` operand (prior
1069 /// to the operation). The result is then rounded back to 32 bits and
1070 /// stored to this object. See IEEE-754 2008, 5.1, first paragraph,
1071 /// second sentence for specification.
1072 Decimal_Type32& operator-=(int rhs);
1073 Decimal_Type32& operator-=(unsigned int rhs);
1074 Decimal_Type32& operator-=(long rhs);
1075 Decimal_Type32& operator-=(unsigned long rhs);
1076 Decimal_Type32& operator-=(long long rhs);
1077 Decimal_Type32& operator-=(unsigned long long rhs);
1078
1079 /// Multiply the value of the specified `rhs` object by the value of
1080 /// this as described by IEEE-754, store the result in this object, and
1081 /// return a reference to this object.
1082 ///
1083 /// * If either of this object or `rhs` is signaling NaN, then store
1084 /// the value of the macro `EDOM` into `errno` and set this object to
1085 /// a NaN.
1086 /// * Otherwise if either of this object or `rhs` is NaN then set this
1087 /// object to a NaN.
1088 /// * Otherwise, if one of this object and `rhs` is zero (positive or
1089 /// negative) and the other is infinity (positive or negative), store
1090 /// the value of the macro `EDOM` into `errno` and set this object to
1091 /// a NaN.
1092 /// * Otherwise, if either this object or `rhs` is positive or negative
1093 /// infinity, set this object to infinity. The sign of this object
1094 /// will be positive if this object and `rhs` had the same sign, and
1095 /// negative otherwise.
1096 /// * Otherwise, if either this object or `rhs` is zero, set this
1097 /// object to zero. The sign of this object will be positive if this
1098 /// object and `rhs` had the same sign, and negative otherwise.
1099 /// * Otherwise if the product of this object and `rhs` has an absolute
1100 /// value that is larger than `std::numeric_limits<Decimal32>::max()`
1101 /// then store the value of the macro `ERANGE` into `errno` and set
1102 /// this object to infinity with the same sign of that result.
1103 /// * Otherwise if the product of this object and `rhs` has an absolute
1104 /// value that is smaller than
1105 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1106 /// the macro `ERANGE` into `errno` and set this object to zero value
1107 /// with the same sign as that result.
1108 /// * Otherwise set this object to the product of the value of `rhs`
1109 /// and the value of this object.
1110 ///
1111 ///
1112 /// \note Note that when `rhs` is a `Decimal64`, this operation is always
1113 /// performed with 64 bits precision to prevent loss of precision of the
1114 /// `rhs` operand (prior to the operation). The result is then rounded
1115 /// back to 32 bits and stored to this object. See IEEE-754 2008, 5.1,
1116 /// first paragraph, second sentence for specification.
1117 ///
1118 /// Also note that when `rhs` is a `Decimal128`, this operation is
1119 /// always performed with 128 bits precision to prevent loss of
1120 /// precision of the `rhs` operand (prior to the operation). The
1121 /// result is then rounded back to 32 bits and stored to this object.
1122 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
1123 /// specification.
1127
1128 /// Multiply the specified `rhs` by the value of this object as
1129 /// described by IEEE-754, store the result in this object, and return a
1130 /// reference to this object.
1131 ///
1132 /// * If this object is signaling NaN, then store the value of the
1133 /// macro `EDOM` into `errno` and set this object to a NaN.
1134 /// * Otherwise if this object is NaN, then do not change this object.
1135 /// * Otherwise if this object is infinity (positive or negative), and
1136 /// `rhs` is zero, then store the value of the macro `EDOM` into
1137 /// `errno` and set this object to a NaN.
1138 /// * Otherwise if this object is infinity (positive or negative), then
1139 /// do not change it.
1140 /// * Otherwise if `rhs` is zero, then set this object to zero with the
1141 /// same sign as its value had prior to this operation.
1142 /// * Otherwise if the product of `rhs` and the value of this object
1143 /// results in an absolute value that is larger than
1144 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1145 /// the macro `ERANGE` into `errno` and set this object to infinity
1146 /// with the same sign as that result.
1147 /// * Otherwise if the product of `rhs` and the value of this object
1148 /// results in an absolute value that is smaller than
1149 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1150 /// the macro `ERANGE` into `errno` and set this object to zero with
1151 /// the same sign as that result.
1152 /// * Otherwise set this object to the product of the value of this
1153 /// object and the value `rhs`.
1154 ///
1155 ///
1156 /// \note Note that this operation is always performed with 64 bits precision
1157 /// to prevent loss of precision of the `rhs` operand (prior to the
1158 /// operation). The result is then rounded back to 32 bits and stored
1159 /// to this object. See IEEE-754 2008, 5.1, first paragraph,
1160 Decimal_Type32& operator*=(int rhs);
1161 Decimal_Type32& operator*=(unsigned int rhs);
1162 Decimal_Type32& operator*=(long rhs);
1163 Decimal_Type32& operator*=(unsigned long rhs);
1164 Decimal_Type32& operator*=(long long rhs);
1165 Decimal_Type32& operator*=(unsigned long long rhs);
1166
1167 /// Divide the value of this object by the value of the specified `rhs`
1168 /// as described by IEEE-754, store the result in this object, and
1169 /// return a reference to this object.
1170 ///
1171 /// * If either of this object or `rhs` is signaling NaN, then store
1172 /// the value of the macro `EDOM` into `errno` and set this object to
1173 /// a NaN.
1174 /// * Otherwise if either of this object or `rhs` is NaN then set this
1175 /// object to a NaN.
1176 /// * Otherwise if this object and `rhs` are both infinity (positive or
1177 /// negative) or both zero (positive or negative) then store the
1178 /// value of the macro `EDOM` into `errno` and return a NaN.
1179 /// * Otherwise if `rhs` has a positive zero value, then store the
1180 /// value of the macro `ERANGE` into `errno` and set this object to
1181 /// infinity with the same sign as its original value.
1182 /// * Otherwise if `rhs` has a negative zero value, then store the
1183 /// value of the macro `ERANGE` into `errno` and set this object to
1184 /// infinity with the opposite sign as its original value.
1185 /// * Otherwise if dividing the value of this object by the value of
1186 /// `rhs` results in an absolute value that is larger than
1187 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1188 /// the macro `ERANGE` into `errno` and return infinity with the same
1189 /// sign as that result.
1190 /// * Otherwise if dividing the value of this object by the value of
1191 /// `rhs` results in an absolute value that is smaller than
1192 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1193 /// the macro `ERANGE` into `errno`and return zero with the same sign
1194 /// as that result.
1195 /// * Otherwise set this object to the result of dividing the value of
1196 /// this object by the value of `rhs`.
1197 ///
1198 ///
1199 /// \note Note that when `rhs` is a `Decimal64`, this operation is always
1200 /// performed with 64 bits precision to prevent loss of precision of the
1201 /// `rhs` operand (prior to the operation). The result is then rounded
1202 /// back to 32 bits and stored to this object. See IEEE-754 2008, 5.1,
1203 /// first paragraph, second sentence for specification.
1204 ///
1205 /// Also note that when `rhs` is a `Decimal128`, this operation is
1206 /// always performed with 128 bits precision to prevent loss of
1207 /// precision of the `rhs` operand (prior to the operation). The
1208 /// result is then rounded back to 32 bits and stored to this object.
1209 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
1210 /// specification.
1214
1215 /// Divide the value of this object by the specified `rhs` as described
1216 /// by IEEE-754, store the result in this object, and return a reference
1217 /// to this object.
1218 ///
1219 /// * If this object is signaling NaN, then store the value of the
1220 /// macro `EDOM` into `errno` and set this object to a NaN.
1221 /// * Otherwise if this object is NaN then set this object to a NaN.
1222 /// * Otherwise if this object is infinity (positive or negative) and
1223 /// `rhs` is positive value then set this object to infinity value
1224 /// with the same sign as its original value.
1225 /// * Otherwise if this object is infinity (positive or negative) and
1226 /// `rhs` is negative value then set this object to infinity value
1227 /// with the opposite sign as its original value.
1228 /// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
1229 /// into `errno` and set this object to infinity with the same sign
1230 /// it had prior to this operation.
1231 /// * Otherwise if dividing the value of this object by the value of
1232 /// `rhs` results in an absolute value that is larger than
1233 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1234 /// the macro `ERANGE` into `errno` and return infinity with the same
1235 /// sign as that result.
1236 /// * Otherwise if dividing the value of this object by the value of
1237 /// `rhs` results in an absolute value that is smaller than
1238 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1239 /// the macro `ERANGE` into `errno`and return zero with the same sign
1240 /// as that result.
1241 /// * Otherwise set this object to the result of dividing the value of
1242 /// this object by the value of `rhs`.
1243 ///
1244 ///
1245 /// \note Note that this operation is always performed with 64 bits precision
1246 /// to prevent loss of precision of the `rhs` operand (prior to the
1247 /// operation). The result is then rounded back to 32 bits and stored
1248 /// to this object. See IEEE-754 2008, 5.1, first paragraph,
1249 Decimal_Type32& operator/=(int rhs);
1250 Decimal_Type32& operator/=(unsigned int rhs);
1251 Decimal_Type32& operator/=(long rhs);
1252 Decimal_Type32& operator/=(unsigned long rhs);
1253 Decimal_Type32& operator/=(long long rhs);
1254 Decimal_Type32& operator/=(unsigned long long rhs);
1255
1256 /// Return a pointer providing modifiable access to the underlying
1257 /// implementation.
1259
1260 // Aspects
1261
1262 /// Assign to this object the value read from the specified input
1263 /// `stream` using the specified `version` format, and return a
1264 /// reference to `stream`. If `stream` is initially invalid, this
1265 /// operation has no effect. If `version` is not supported, this object
1266 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
1267 /// If `version` is supported but `stream` becomes invalid during this
1268 /// operation, this object has an undefined, but valid, state.
1269 ///
1270 /// \note Note that no version is read from `stream`. See the `bslx` package-level
1271 /// documentation for more information on BDEX streaming of
1272 /// value-semantic types and containers.
1273 template <class STREAM>
1274 STREAM& bdexStreamIn(STREAM& stream, int version);
1275
1276 // ACCESSORS
1277
1278 /// Return a pointer providing non-modifiable access to the underlying
1279 /// implementation.
1280 const DecimalImpUtil::ValueType32 *data() const;
1281
1282 /// Return the value of the underlying implementation.
1284
1285 // Aspects
1286
1287 /// Write the value of this object, using the specified `version`
1288 /// format, to the specified output `stream`, and return a reference to
1289 /// `stream`. If `stream` is initially invalid, this operation has no
1290 /// effect. If `version` is not supported, `stream` is invalidated, but otherwise unmodified.
1291 ///
1292 /// \note Note that `version` is not written to
1293 /// `stream`. See the `bslx` package-level documentation for more
1294 /// information on BDEX streaming of value-semantic types and
1295 /// containers.
1296 template <class STREAM>
1297 STREAM& bdexStreamOut(STREAM& stream, int version) const;
1298};
1299
1300// FREE OPERATORS
1301
1302/// Return a copy of the specified `value` if the value is not negative
1303/// zero, and return positive zero otherwise.
1305
1306/// Return the result of applying the unary - operator to the specified
1307/// `value` as described by IEEE-754, essentially reversing the sign bit.
1308///
1309/// \note Note that floating-point numbers have signed zero, so this operation is
1310/// not the same as `0 - value`.
1312
1313/// Apply the prefix ++ operator to the specified `value` and return its original value.
1314///
1315/// \note Note that this is a floating-point value so this
1316/// operation may not change the value of this object at all (if the value
1317/// is large) or it may just set it to 1.0 (if the original value is small).
1319
1320/// Apply the prefix -- operator to the specified `value` and return its original value.
1321///
1322/// \note Note that this is a floating-point value so this
1323/// operation may not change the value of this object at all (if the value
1324/// is large) or it may just set it to -1.0 (if the original value is
1325/// small).
1327
1328/// Add the value of the specified `rhs` to the value of the specified `lhs`
1329/// as described by IEEE-754 and return the result.
1330///
1331/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1332/// the macro `EDOM` into `errno` and return a NaN.
1333/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1334/// * Otherwise if `lhs` and `rhs` are infinities of differing signs, store
1335/// the value of the macro `EDOM` into `errno` and return a NaN.
1336/// * Otherwise if `lhs` and `rhs` are infinities of the same sign then
1337/// return infinity of that sign.
1338/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
1339/// larger than `std::numeric_limits<Decimal32>::max()` then store the
1340/// value of the macro `ERANGE` into `errno` and set this object to
1341/// infinity with the same sign as that result.
1342/// * Otherwise return the sum of the number represented by `lhs` and the
1343/// number represented by `rhs`.
1345
1346/// Add the specified `rhs` to the value of the specified `lhs` as described
1347/// by IEEE-754 and return the result.
1348///
1349/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1350/// into `errno` and return a NaN.
1351/// * Otherwise if `lhs` object is NaN, then return a NaN.
1352/// * Otherwise if `lhs` is infinity, then return infinity.
1353/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
1354/// larger than `std::numeric_limits<Decimal32>::max()` then store the
1355/// value of the macro `ERANGE` into `errno` and return infinity with the
1356/// same sign as that result.
1357/// * Otherwise return the sum of `rhs` and the number represented by
1358/// `lhs`.
1360Decimal32 operator+(Decimal32 lhs, unsigned int rhs);
1362Decimal32 operator+(Decimal32 lhs, unsigned long rhs);
1363Decimal32 operator+(Decimal32 lhs, long long rhs);
1364Decimal32 operator+(Decimal32 lhs, unsigned long long rhs);
1365
1366/// Add the specified `lhs` to the value of the specified `rhs` as described
1367/// by IEEE-754 and return the result.
1368///
1369/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1370/// into `errno` and return a NaN.
1371/// * Otherwise if `rhs` object is NaN, then return a NaN.
1372/// * Otherwise if `rhs` is infinity, then return infinity.
1373/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
1374/// larger than `std::numeric_limits<Decimal32>::max()` then store the
1375/// value of the macro `ERANGE` into `errno` and return infinity with the
1376/// same sign as that result.
1377/// * Otherwise return the sum of `lhs` and the number represented by
1378/// `rhs`.
1380Decimal32 operator+(unsigned int lhs, Decimal32 rhs);
1382Decimal32 operator+(unsigned long lhs, Decimal32 rhs);
1383Decimal32 operator+(long long lhs, Decimal32 rhs);
1384Decimal32 operator+(unsigned long long lhs, Decimal32 rhs);
1385
1386/// Subtract the value of the specified `rhs` from the value of the
1387/// specified `lhs` as described by IEEE-754 and return the result.
1388///
1389/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1390/// the macro `EDOM` into `errno` and return a NaN.
1391/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1392/// * Otherwise if `lhs` and the `rhs` have infinity values of the same
1393/// sign, store the value of the macro `EDOM` into `errno` and return a
1394/// NaN.
1395/// * Otherwise if `lhs` and the `rhs` have infinity values of differing
1396/// signs, then return `lhs`.
1397/// * Otherwise if the subtracting of `lhs` and `rhs` has an absolute value
1398/// that is larger than `std::numeric_limits<Decimal32>::max()` then
1399/// store the value of the macro `ERANGE` into `errno` and return
1400/// infinity with the same sign as that result.
1401/// * Otherwise return the result of subtracting the value of `rhs` from
1402/// the value of `lhs`.
1404
1405/// Subtract the specified `rhs` from the value of the specified `lhs` as
1406/// described by IEEE-754 and return a reference to this object.
1407///
1408/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1409/// into `errno` and return a NaN.
1410/// * Otherwise if `lhs` is NaN, then return a NaN.
1411/// * Otherwise if `lhs` is infinity, then return infinity.
1412/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
1413/// an absolute value that is larger than
1414/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1415/// macro `ERANGE` into `errno` and return infinity with the same sign as
1416/// that result.
1417/// * Otherwise return the result of subtracting `rhs` from the value of
1418/// `lhs`.
1420Decimal32 operator-(Decimal32 lhs, unsigned int rhs);
1422Decimal32 operator-(Decimal32 lhs, unsigned long rhs);
1423Decimal32 operator-(Decimal32 lhs, long long rhs);
1424Decimal32 operator-(Decimal32 lhs, unsigned long long rhs);
1425
1426/// Subtract the specified `rhs` from the value of the specified `lhs` as
1427/// described by IEEE-754 and return a reference to this object.
1428///
1429/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1430/// into `errno` and return a NaN.
1431/// * Otherwise if `rhs` is NaN, then return a NaN.
1432/// * Otherwise if `rhs` is infinity, then return infinity.
1433/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
1434/// an absolute value that is larger than
1435/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1436/// macro `ERANGE` into `errno` and return infinity with the same sign as
1437/// that result.
1438/// * Otherwise return the result of subtracting the value of `rhs` from
1439/// the number `lhs`.
1441Decimal32 operator-(unsigned int lhs, Decimal32 rhs);
1443Decimal32 operator-(unsigned long lhs, Decimal32 rhs);
1444Decimal32 operator-(long long lhs, Decimal32 rhs);
1445Decimal32 operator-(unsigned long long lhs, Decimal32 rhs);
1446
1447/// Multiply the value of the specified `lhs` object by the value of the
1448/// specified `rhs` as described by IEEE-754 and return the result.
1449///
1450/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1451/// the macro `EDOM` into `errno` and return a NaN.
1452/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1453/// * Otherwise if one of the operands is infinity (positive or negative)
1454/// and the other is zero (positive or negative), then store the value of
1455/// the macro `EDOM` into `errno` and return a NaN.
1456/// * Otherwise if both `lhs` and `rhs` are infinity (positive or
1457/// negative), return infinity. The sign of the returned value will be
1458/// positive if `lhs` and `rhs` have the same sign, and negative
1459/// otherwise.
1460/// * Otherwise, if either `lhs` or `rhs` is zero, return zero. The sign
1461/// of the returned value will be positive if `lhs` and `rhs` have the
1462/// same sign, and negative otherwise.
1463/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
1464/// that is larger than `std::numeric_limits<Decimal32>::max()` then
1465/// store the value of the macro `ERANGE` into `errno` and return
1466/// infinity with the same sign as that result.
1467/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
1468/// that is smaller than `std::numeric_limits<Decimal32>::min()` then
1469/// store the value of the macro `ERANGE` into `errno` and return zero
1470/// with the same sign as that result.
1471/// * Otherwise return the product of the value of `rhs` and the number
1472/// represented by `rhs`.
1474
1475/// Multiply the specified `rhs` by the value of the specified `lhs` as
1476/// described by IEEE-754, and return the result.
1477///
1478/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1479/// into `errno` and return a NaN.
1480/// * Otherwise if `lhs` is NaN, then return a NaN.
1481/// * Otherwise if `lhs` is infinity (positive or negative), and `rhs` is
1482/// zero, then store the value of the macro `EDOM` into `errno` and
1483/// return a NaN.
1484/// * Otherwise if `lhs` is infinity (positive or negative), then return
1485/// `lhs`.
1486/// * Otherwise if `rhs` is zero, then return zero with the sign of `lhs`.
1487/// * Otherwise if the product of `rhs` and the value of `lhs` results in
1488/// an absolute value that is larger than
1489/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1490/// macro `ERANGE` into `errno` and return infinity with the same sign as
1491/// that result.
1492/// * Otherwise if the product of `rhs` and the value of `lhs` results in
1493/// an absolute value that is smaller than
1494/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1495/// macro `ERANGE` into `errno` and return zero with the same sign as
1496/// that result.
1497/// * Otherwise return the product of the value of `lhs` and value `rhs`.
1499Decimal32 operator*(Decimal32 lhs, unsigned int rhs);
1501Decimal32 operator*(Decimal32 lhs, unsigned long rhs);
1502Decimal32 operator*(Decimal32 lhs, long long rhs);
1503Decimal32 operator*(Decimal32 lhs, unsigned long long rhs);
1504
1505/// Multiply the specified `lhs` by the value of the specified `rhs` as
1506/// described by IEEE-754, and return the result.
1507///
1508/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1509/// into `errno` and return a NaN.
1510/// * Otherwise if `rhs` is NaN, then return a NaN.
1511/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
1512/// zero, then store the value of the macro `EDOM` into `errno` and
1513/// return a NaN.
1514/// * Otherwise if `rhs` is infinity (positive or negative), then return
1515/// `rhs`.
1516/// * Otherwise if `lhs` is zero, then return zero with the sign of `rhs`.
1517/// * Otherwise if the product of `lhs` and the value of `rhs` results in
1518/// an absolute value that is larger than
1519/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1520/// macro `ERANGE` into `errno` and return infinity with the same sign as
1521/// that result.
1522/// * Otherwise if the product of `lhs` and the value of `rhs` results in
1523/// an absolute value that is smaller than
1524/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1525/// macro `ERANGE` into `errno` and return zero with the same sign as
1526/// that result.
1527/// * Otherwise return the product of the value of `lhs` and value `rhs`.
1529Decimal32 operator*(unsigned int lhs, Decimal32 rhs);
1531Decimal32 operator*(unsigned long lhs, Decimal32 rhs);
1532Decimal32 operator*(long long lhs, Decimal32 rhs);
1533Decimal32 operator*(unsigned long long lhs, Decimal32 rhs);
1534
1535/// Divide the value of the specified `lhs` by the value of the specified
1536/// `rhs` as described by IEEE-754, and return the result.
1537///
1538/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1539/// the macro `EDOM` into `errno` and return a NaN.
1540/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1541/// * Otherwise if `lhs` and `rhs` are both infinity (positive or negative)
1542/// or both zero (positive or negative) then store the value of the macro
1543/// `EDOM` into `errno` and return a NaN.
1544/// * Otherwise if `lhs` has a normal value and `rhs` has a positive zero
1545/// value, store the value of the macro `ERANGE` into `errno` and return
1546/// infinity with the sign of `lhs`.
1547/// * Otherwise if `lhs` has a normal value and `rhs` has a negative zero
1548/// value, store the value of the macro `ERANGE` into `errno` and return
1549/// infinity with the opposite sign as `lhs`.
1550/// * Otherwise if `lhs` has infinity value and `rhs` has a positive zero
1551/// value, return infinity with the sign of `lhs`.
1552/// * Otherwise if `lhs` has infinity value and `rhs` has a negative zero
1553/// value, return infinity with the opposite sign as `lhs`.
1554/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1555/// results in an absolute value that is larger than
1556/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1557/// macro `ERANGE` into `errno` and return infinity with the same sign as
1558/// that result.
1559/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1560/// results in an absolute value that is smaller than
1561/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1562/// macro `ERANGE` into `errno` and return zero with the same sign as
1563/// that result.
1564/// * Otherwise return the result of dividing the value of `lhs` by the
1565/// value of `rhs`.
1567
1568/// Divide the value of the specified `lhs` by the specified `rhs` as
1569/// described by IEEE-754, and return the result.
1570///
1571/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1572/// into `errno` and return a NaN.
1573/// * Otherwise if `lhs` is NaN then return a NaN.
1574/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
1575/// positive value then return infinity value with the same sign as its
1576/// original value.
1577/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
1578/// negative value then return infinity value with the opposite sign as
1579/// its original value.
1580/// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
1581/// into `errno` and return infinity with the same sign it had prior to
1582/// this operation.
1583/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1584/// results in an absolute value that is larger than
1585/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1586/// macro `ERANGE` into `errno` and return infinity with the same sign as
1587/// that result.
1588/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1589/// results in an absolute value that is smaller than
1590/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1591/// macro `ERANGE` into `errno` and return zero with the same sign as
1592/// that result.
1593/// * Otherwise return the result of dividing the value of `lhs` by the
1594/// value `rhs`.
1596Decimal32 operator/(Decimal32 lhs, unsigned int rhs);
1598Decimal32 operator/(Decimal32 lhs, unsigned long rhs);
1599Decimal32 operator/(Decimal32 lhs, long long rhs);
1600Decimal32 operator/(Decimal32 lhs, unsigned long long rhs);
1601
1602/// Divide the specified `lhs` by the value of the specified `rhs` as
1603/// described by IEEE-754, and return the result.
1604///
1605/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1606/// into `errno` and return a NaN.
1607/// * Otherwise if `rhs` is NaN then return a NaN.
1608/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
1609/// zero, store the value of the macro `ERANGE` into `errno` and return a
1610/// NaN.
1611/// * Otherwise if `rhs` is zero (positive or negative), store the value of
1612/// the macro `ERANGE` into `errno` and return infinity with the sign of
1613/// `lhs`.
1614/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1615/// results in an absolute value that is larger than
1616/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1617/// macro `ERANGE` into `errno` and return infinity with the same sign as
1618/// that result.
1619/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1620/// results in an absolute value that is smaller than
1621/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1622/// macro `ERANGE` into `errno` and return zero with the same sign as
1623/// that result.
1624/// * Otherwise return the result of dividing the value of `lhs` by the value `rhs`.
1625///
1626/// \note Note that this is a floating-point operation, not
1627/// integer.
1629Decimal32 operator/(unsigned int lhs, Decimal32 rhs);
1631Decimal32 operator/(unsigned long lhs, Decimal32 rhs);
1632Decimal32 operator/(long long lhs, Decimal32 rhs);
1633Decimal32 operator/(unsigned long long lhs, Decimal32 rhs);
1634
1635/// Return `true` if the specified `lhs` and `rhs` have the same value, and
1636/// `false` otherwise. Two `Decimal32` objects have the same value if the
1637/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
1638/// comparison) considers the underlying IEEE representations equal. In
1639/// other words, two `Decimal32` objects have the same value if:
1640///
1641/// * both have a zero value (positive or negative), or
1642/// * both have the same infinity value (both positive or negative), or
1643/// * both have the value of a real number that are equal, even if they are
1644/// represented differently (cohorts have the same value)
1645///
1646/// This operation stores the value of the macro `EDOM` into `errno` if
1647/// either or both operands are signaling NaN.
1648///
1649///
1650/// \note Note that a NaN is never equal to anything, including itself:
1651/// @code
1652/// Decimal32 aNaN = std::numeric_limits<Decimal32>::quiet_NaN();
1653/// assert(!(aNan == aNan));
1654/// @endcode
1655bool operator==(Decimal32 lhs, Decimal32 rhs);
1656
1657/// Return `true` if the specified `lhs` and `rhs` do not have the same
1658/// value, and `false` otherwise. Two `Decimal32` objects do not have the
1659/// same value if the `compareQuietEqual` operation (IEEE-754 defined,
1660/// non-total ordering comparison) considers the underlying IEEE
1661/// representations not equal. In other words, two `Decimal32` objects do
1662/// not have the same value if:
1663///
1664/// * both are NaN, or
1665/// * one is zero (positive or negative) and the other is not, or
1666/// * one is positive infinity and the other is not, or
1667/// * one is negative infinity and the other is not, or
1668/// * both have the value of a real number that are not equal, regardless
1669/// of their representation (cohorts are equal)
1670///
1671/// This operation stores the value of the macro `EDOM` into `errno` if
1672/// either or both operands are signaling NaN.
1673///
1674///
1675/// \note Note that a NaN is never equal to anything, including itself:
1676/// @code
1677/// Decimal32 aNaN = std::numeric_limits<Decimal32>::quiet_NaN();
1678/// assert(aNan != aNan);
1679/// @endcode
1680bool operator!=(Decimal32 lhs, Decimal32 rhs);
1681
1682/// Return `true` if the specified `lhs` has a value less than the specified
1683/// `rhs` and `false` otherwise. The value of a `Decimal32` object `lhs` is
1684/// less than that of an object `rhs` if the `compareQuietLess` operation
1685/// (IEEE-754 defined, non-total ordering comparison) considers the
1686/// underlying IEEE representation of `lhs` to be less than of that of
1687/// `rhs`. In other words, `lhs` is less than `rhs` if:
1688///
1689/// * neither `lhs` nor `rhs` are NaN, or
1690/// * `lhs` is zero (positive or negative) and `rhs` positive, or
1691/// * `rhs` is zero (positive or negative) and `lhs` negative, or
1692/// * `lhs` is not positive infinity, or
1693/// * `lhs` is negative infinity and `rhs` is not, or
1694/// * `lhs` and `rhs` both represent a real number and the real number of
1695/// `lhs` is less than that of `rhs`
1696///
1697/// This operation stores the value of the macro `EDOM` into `errno` if
1698/// either or both operands are signaling NaN.
1699bool operator<(Decimal32 lhs, Decimal32 rhs);
1700
1701/// Return `true` if the specified `lhs` has a value less than or equal the
1702/// value of the specified `rhs` and `false` otherwise. The value of a
1703/// `Decimal32` object `lhs` is less than or equal to the value of an object
1704/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
1705/// non-total ordering comparison) considers the underlying IEEE
1706/// representation of `lhs` to be less or equal to that of `rhs`. In other
1707/// words, `lhs` is less or equal than `rhs` if:
1708///
1709/// * neither `lhs` nor `rhs` are NaN, or
1710/// * `lhs` and `rhs` are both zero (positive or negative), or
1711/// * both `lhs` and `rhs` are positive infinity, or
1712/// * `lhs` is negative infinity, or
1713/// * `lhs` and `rhs` both represent a real number and the real number of
1714/// `lhs` is less or equal to that of `rhs`
1715///
1716/// This operation stores the value of the macro `EDOM` into `errno` if
1717/// either or both operands are signaling NaN.
1718bool operator<=(Decimal32 lhs, Decimal32 rhs);
1719
1720/// Return `true` if the specified `lhs` has a greater value than the
1721/// specified `rhs` and `false` otherwise. The value of a `Decimal32`
1722/// object `lhs` is greater than that of an object `rhs` if the
1723/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
1724/// comparison) considers the underlying IEEE representation of `lhs` to be
1725/// greater than of that of `rhs`. In other words, `lhs` is greater than
1726/// `rhs`if:
1727///
1728/// * neither `lhs` nor `rhs` are NaN, or
1729/// * `lhs` and `rhs` are not both zero (positive or negative), or
1730/// * `lhs` is not negative infinity, or
1731/// * `lhs` is positive infinity and `rhs` is not, or
1732/// * `lhs` and `rhs` both represent a real number and the real number of
1733/// `lhs` is greater than that of `rhs`
1734///
1735/// This operation stores the value of the macro `EDOM` into `errno` if
1736/// either or both operands are signaling NaN.
1737bool operator>(Decimal32 lhs, Decimal32 rhs);
1738
1739/// Return `true` if the specified `lhs` has a value greater than or equal
1740/// to the value of the specified `rhs` and `false` otherwise. The value of
1741/// a `Decimal32` object `lhs` is greater or equal to a `Decimal32` object
1742/// `rhs` if the `compareQuietGreaterEqual` operation (IEEE-754 defined,
1743/// non-total ordering comparison ) considers the underlying IEEE
1744/// representation of `lhs` to be greater or equal to that of `rhs`. In
1745/// other words, `lhs` is greater than or equal to `rhs` if:
1746///
1747/// * neither `lhs` nor `rhs` are NaN, or
1748/// * `lhs` and `rhs` are both zero (positive or negative), or
1749/// * both `lhs` and `rhs` are negative infinity, or
1750/// * `lhs` is positive infinity, or
1751/// * `lhs` and `rhs` both represent a real number and the real number of
1752/// `lhs` is greater or equal to that of `rhs`
1753///
1754/// This operation stores the value of the macro `EDOM` into `errno` if
1755/// either or both operands are signaling NaN.
1756bool operator>=(Decimal32 lhs, Decimal32 rhs);
1757
1758/// Read, into the specified `object`, from the specified input `stream` an
1759/// IEEE 32 bit decimal floating-point value as described in the IEEE-754
1760/// 2008 standard (5.12 Details of conversions between floating point
1761/// numbers and external character sequences) and return a reference
1762/// providing modifiable access to `stream`. If `stream` contains a NaN
1763/// value, it is unspecified if `object` will receive a quiet or signaling
1764/// `Nan`. If `stream` is not valid on entry `stream.good() == false`, this
1765/// operation has no effect other than setting `stream.fail()` to `true`.
1766/// If eof (end-of-file) is found before any non-whitespace characters
1767/// `stream.fail()` is set to `true` and `object` remains unchanged. If eof
1768/// is detected after some characters have been read (and successfully
1769/// interpreted as part of the textual representation of a floating-point
1770/// value as specified by IEEE-754) then `stream.eof()` is set to true. If
1771/// the first non-whitespace character sequence is not a valid textual
1772/// representation of a floating-point value (e.g., 12e or e12 or 1*2) the
1773/// `stream.fail()` is set to true and `object` will remain unchanged. If a
1774/// real number value is represented by the character sequence but it is a
1775/// large positive or negative value that cannot be stored into `object`
1776/// then store the value of the macro `ERANGE` into `errno` and positive or
1777/// negative infinity is stored into `object`, respectively. If a real
1778/// number value is represented by the character sequence but it is a small
1779/// positive or negative value that cannot be stored into `object` then
1780/// store the value of the macro `ERANGE` into `errno` and positive or
1781/// negative zero is stored into `object`, respectively. If a real number
1782/// value is represented by the character sequence but it cannot be stored
1783/// exactly into `object`, the value is rounded according to the current
1784/// rounding direction (of the environment) and then stored into `object`.
1785///
1786/// NOTE: This method does not yet fully support iostream flags or the
1787/// decimal floating point exception context.
1788template <class CHARTYPE, class TRAITS>
1789bsl::basic_istream<CHARTYPE, TRAITS>&
1790operator>>(bsl::basic_istream<CHARTYPE, TRAITS>& stream, Decimal32& object);
1791
1792/// Write the value of the specified `object` to the specified output
1793/// `stream` in a single line format as described in the IEEE-754 2008
1794/// standard (5.12 Details of conversions between floating point numbers and
1795/// external character sequences), and return a reference providing
1796/// modifiable access to `stream`. If `stream` is not valid on entry, this
1797/// operation has no effect.
1798///
1799/// NOTE: This method does not yet fully support iostream flags or the
1800/// decimal floating point exception context.
1801template <class CHARTYPE, class TRAITS>
1802bsl::basic_ostream<CHARTYPE, TRAITS>&
1803operator<<(bsl::basic_ostream<CHARTYPE, TRAITS>& stream, Decimal32 object);
1804
1805#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
1806 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
1807inline namespace literals {
1808inline namespace DecimalLiterals {
1809/// Produce an object of the indicated return type by parsing the specified
1810/// `str` having the specified `len` excluding the terminating null
1811/// character that represents a floating-point number written in both fixed
1812/// and scientific notations. These user-defined literal suffixes can be
1813/// applied to both numeric and string literals, (i.e., 1.2_d32, "1.2"_d32
1814/// or "inf"_d32). The resulting decimal object is initialized as follows:
1815///
1816/// * If `str` does not represent a floating-point value, then return a
1817/// decimal object of the indicated return type initialized to a NaN.
1818/// * Otherwise if `str` represents infinity (positive or negative), then
1819/// return a decimal object of the indicated return type initialized to
1820/// infinity value with the same sign.
1821/// * Otherwise if `str` represents zero (positive or negative), then
1822/// return a decimal object of the indicated return type initialized to
1823/// zero with the same sign.
1824/// * Otherwise if `str` represents a value that has an absolute value that
1825/// is larger than the maximum value supported by the indicated return
1826/// type, then store the value of the macro `ERANGE` into `errno` and
1827/// return a decimal object of the return type initialized to infinity
1828/// with the same sign.
1829/// * Otherwise if `str` represents a value that has an absolute value that
1830/// is smaller than min value of the indicated return type, then store
1831/// the value of the macro `ERANGE` into `errno` and return a decimal
1832/// object of the return type initialized to zero with the same sign.
1833/// * Otherwise if `str` has a value that is not exactly representable
1834/// using the maximum digit number supported by the indicated return
1835/// type, then return a decimal object of the return type initialized to
1836/// the value represented by `str` rounded according to the rounding
1837/// direction.
1838/// * Otherwise return a decimal object of the indicated return type
1839/// initialized to the decimal value representation of `str`.
1840///
1841///
1842/// \note Note that the parsing follows the rules as specified for the `strtod32`
1843/// function in section 9.6 of the ISO/EIC TR 247128 C Decimal
1844/// Floating-Point Technical Report.
1845///
1846/// Also note that the numeric literal version omits the optional leading
1847/// sign in `str`. For example, if the string is -1.2_d32 then the string
1848/// "1.2" is passed to the one-argument form, not "-1.2", because leading
1849/// signs are operators, not parts of literals. On the other hand, the
1850/// string literal version does not omit leading sign and if the string is
1851/// "-1.2"_d32 then the string "-1.2" is passed to the two-argument form.
1852///
1853/// Also note that the quantum of the resultant value is affected by the
1854/// number of decimal places in `str` string in both numeric and string
1855/// literal formats starting with the most significand digit and cannot
1856/// exceed the maximum number of digits necessary to differentiate all
1857/// values of the indicated return type, for example:
1858///
1859/// `0.015_d32; "0.015"_d32 => 15e-3`
1860/// `1.5_d32; "1.5"_d32 => 15e-1`
1861/// `1.500_d32; "1.500"d_32 => 1500e-3`
1862/// `1.2345678_d32; "1.2345678_d32" => 1234568e-6`
1863bdldfp::Decimal32 operator""_d32 (const char *str);
1864bdldfp::Decimal32 operator""_d32 (const char *str, bsl::size_t len);
1865
1866} // close DecimalLiterals namespace
1867} // close literals namespace
1868#endif
1869
1870// FREE FUNCTIONS
1871
1872/// Pass the specified `object` to the specified `hashAlg`. This function
1873/// integrates with the `bslh` modular hashing system and effectively provides a `bsl::hash` specialization for `Decimal32`.
1874///
1875/// \note Note that two
1876/// objects which have the same value but different representations will
1877/// hash to the same value.
1878template <class HASHALG>
1879void hashAppend(HASHALG& hashAlg, const Decimal32& object);
1880
1881 // ====================
1882 // class Decimal_Type64
1883 // ====================
1884
1885/// This value-semantic class implements the IEEE-754 64 bit decimal
1886/// floating-point format arithmetic type. This class is a standard layout
1887/// type that is `const` thread-safe and exception-neutral.
1888///
1889/// See @ref bdldfp_decimal
1891
1892 private:
1893 // DATA
1894 DecimalImpUtil::ValueType64 d_value; // The underlying IEEE representation
1895
1896 public:
1897 // CLASS METHODS
1898
1899 // Aspects
1900
1901 /// Return the maximum valid BDEX format version, as indicated by the
1902 /// specified `versionSelector`, to be passed to the `bdexStreamOut` method.
1903 ///
1904 /// \note Note that it is highly recommended that `versionSelector`
1905 /// be formatted as "YYYYMMDD", a date representation. Also note that
1906 /// `versionSelector` should be a *compile*-time-chosen value that
1907 /// selects a format version supported by both externalizer and
1908 /// unexternalizer. See the `bslx` package-level documentation for more
1909 /// information on BDEX streaming of value-semantic types and
1910 /// containers.
1911 static int maxSupportedBdexVersion();
1912 static int maxSupportedBdexVersion(int versionSelector);
1913
1914 // TRAITS
1917
1918 // CREATORS
1919
1920 /// Create a `Decimal64_Type` object having the value positive zero and
1921 /// the smallest exponent value.
1923
1924 /// Create a `Decimal64_Type` object having the specified `value`.
1926
1927 /// Create a `Decimal64_Type` object having the value of the specified
1928 /// `other` following the conversion rules as defined by IEEE-754:
1929 ///
1930 /// * If `other` is NaN, initialize this object to a NaN.
1931 /// * Otherwise if `other` is infinity (positive or negative), then
1932 /// initialize this object to infinity with the same sign.
1933 /// * Otherwise if `other` is zero, then initialize this object to zero
1934 /// with the same sign.
1935 /// * Otherwise initialize this object to the value of the `other`.
1936 Decimal_Type64(Decimal32 other); // IMPLICIT
1937
1938 /// Create a `Decimal64_Type` object having the value closest to the
1939 /// value of the specified `other` following the conversion rules as
1940 /// defined by IEEE-754:
1941 ///
1942 /// * If `other` is NaN, initialize this object to a NaN.
1943 /// * Otherwise if `other` is infinity (positive or negative), then
1944 /// initialize this object to infinity with the same sign.
1945 /// * Otherwise if `other` is zero, then initialize this object to
1946 /// zero with the same sign.
1947 /// * Otherwise if `other` has an absolute value that is larger than
1948 /// `std::numeric_limits<Decimal64>::max()` then store the value of
1949 /// the macro `ERANGE` into `errno` and initialize this object to
1950 /// infinity with the same sign as `other`.
1951 /// * Otherwise if `other` has an absolute value that is smaller than
1952 /// `std::numeric_limits<Decimal64>::min()` then store the value of
1953 /// the macro `ERANGE` into `errno` and initialize this object to
1954 /// zero with the same sign as `other`.
1955 /// * Otherwise if `other` has a value that has more significant
1956 /// digits than `std::numeric_limits<Decimal64>::max_digit` then
1957 /// initialize this object to the value of `other` rounded according
1958 /// to the rounding direction.
1959 /// * Otherwise initialize this object to the value as the `other`.
1960 explicit Decimal_Type64(Decimal128 other);
1961
1962 /// Create a `Decimal64_Type` object having the value closest to the
1963 /// value of the specified `other` value. *Warning:* clients requiring
1964 /// a conversion for an exact decimal value should use
1965 /// @ref bdldfp_decimalconvertutil (see *WARNING*: Conversions from
1966 /// `float` and `double`}. This conversion follows the conversion
1967 /// rules as defined by IEEE-754:
1968 ///
1969 /// * If `other` is NaN, initialize this object to a NaN.
1970 /// * Otherwise if `other` is infinity (positive or negative), then
1971 /// initialize this object to infinity value with the same sign.
1972 /// * Otherwise if `other` has a zero value, then initialize this
1973 /// object to zero with the same sign.
1974 /// * Otherwise if `other` has a value that needs more than
1975 /// `std::numeric_limits<Decimal64>::max_digit` significant decimal
1976 /// digits to represent then initialize this object to the value of
1977 /// `other` rounded according to the rounding direction.
1978 /// * Otherwise initialize this object to the value of the `other`.
1979 explicit Decimal_Type64(float other);
1980 explicit Decimal_Type64(double other);
1981
1982 /// Create a `Decimal64_Type` object having the value closest to the
1983 /// value of the specified `other` following the conversion rules as
1984 /// defined by IEEE-754:
1985 ///
1986 /// * Otherwise if `other` has a value that is not exactly
1987 /// representable using `std::numeric_limits<Decimal64>::max_digit`
1988 /// decimal digits then initialize this object to the value of
1989 /// `other` rounded according to the rounding direction.
1990 /// * Otherwise initialize this object to the value of `other` with
1991 /// exponent 0.
1992 explicit Decimal_Type64(int other);
1993 explicit Decimal_Type64(unsigned int other);
1994 explicit Decimal_Type64(long other);
1995 explicit Decimal_Type64(unsigned long other);
1996 explicit Decimal_Type64(long long other);
1997 explicit Decimal_Type64(unsigned long long other);
1998
1999 Decimal64_Type(const Decimal64_Type& original) = default;
2000 // Create a 'Decimal64_Type' object that is a copy of the specified
2001 // 'original' as defined by the 'copy' operation of IEEE-754 2008:
2002 //
2003 //: o If 'other' is NaN, initialize this object to a NaN.
2004 //:
2005 //: o Otherwise initialize this object to the value of the 'other'.
2006 //
2007 // Note that since floating-point types may be NaN, and NaNs are
2008 // unordered (do not compare equal even to themselves) it is possible
2009 // that a copy of a decimal will not compare equal to the original;
2010 // however it will behave as the original.
2011
2012 ~Decimal64_Type() = default;
2013 // Destroy this object.
2014
2015 // MANIPULATORS
2017 // Make this object a copy of the specified 'rhs' as defined by the
2018 // 'copy' operation of IEEE-754 2008 and return a reference providing
2019 // modifiable access to this object.
2020 //
2021 //: o If 'other' is NaN, set this object to a NaN.
2022 //:
2023 //: o Otherwise set this object to the value of the 'other'.
2024 //
2025 // Note that since floating-point types may be NaN, and NaNs are
2026 // unordered (do not compare equal even to themselves) it is possible
2027 // that, after an assignment, a decimal will not compare equal to the
2028 // original; however it will behave as the original.
2029
2030 /// Add 1.0 to the value of this object and return a reference to it.
2031 ///
2032 /// \note Note that this is a floating-point value so this operation may not
2033 /// change the value of this object at all (if the value is large) or it
2034 /// may just set it to 1.0 (if the original value is small).
2036
2037 /// Add -1.0 to the value of this object and return a reference to it.
2038 ///
2039 /// \note Note that this is a floating-point value so this operation may not
2040 /// change the value of this object at all (if the value is large) or it
2041 /// may just set it to -1.0 (if the original value is small).
2043
2044 /// Add the value of the specified `rhs` object to the value of this as
2045 /// described by IEEE-754, store the result in this object, and return a
2046 /// reference to this object.
2047 ///
2048 /// * If either of this object or `rhs` is signaling NaN, then store
2049 /// the value of the macro `EDOM` into `errno` and set this object to
2050 /// a NaN.
2051 /// * Otherwise if either of this object or `rhs` is NaN then set this
2052 /// object to a NaN.
2053 /// * Otherwise if this object and `rhs` have infinite values of
2054 /// differing signs, store the value of the macro `EDOM` into `errno`
2055 /// and set this object to a NaN.
2056 /// * Otherwise if this object and `rhs` have infinite values of the
2057 /// same sign, then do not change this object.
2058 /// * Otherwise if `rhs` has a zero value (positive or negative), do
2059 /// not change this object.
2060 /// * Otherwise if the sum of this object and `rhs` has an absolute
2061 /// value that is larger than `std::numeric_limits<Decimal64>::max()`
2062 /// then store the value of the macro `ERANGE` into `errno` and
2063 /// set this object to infinity with the same sign as that result.
2064 /// * Otherwise set this object to the sum of the number represented by
2065 /// `rhs` and the number represented by this object.
2066 ///
2067 ///
2068 /// \note Note that this is a floating-point value so this operations may not
2069 /// change the value of this object at all (if the value is large) or it
2070 /// may seem to update it to the value of the `other` (if the original
2071 /// value is small).
2072 ///
2073 ///
2074 /// \note Note that when `rhs` is a `Decimal128`, this operation is always
2075 /// performed with 128 bits precision to prevent loss of precision of
2076 /// the `rhs` operand (prior to the operation). The result is then
2077 /// rounded back to 64 bits and stored to this object. See IEEE-754
2078 /// 2008, 5.1, first paragraph, second sentence for specification.
2082
2083 /// Add the specified `rhs` to the value of this object as described by
2084 /// IEEE-754, store the result in this object, and return a reference to
2085 /// this object.
2086 ///
2087 /// * If this object is signaling NaN, then store the value of the
2088 /// macro `EDOM` into `errno` and set this object to a NaN.
2089 /// * Otherwise if this object is NaN, then do not change this object.
2090 /// * Otherwise if this object is infinity, then do not change it.
2091 /// * Otherwise if the sum of this object and `rhs` has an absolute
2092 /// value that is larger than `std::numeric_limits<Decimal64>::max()`
2093 /// then store the value of the macro `ERANGE` into `errno` and
2094 /// set this object to infinity with the same sign as that result.
2095 /// * Otherwise set this object to sum of adding `rhs` and the number
2096 /// represented by this object.
2097 ///
2098 ///
2099 /// \note Note that this is a floating-point value so this operations may not
2100 /// change the value of this object at all (if the value is large) or it
2101 /// may seem to update it to the value of the `other` (if the original
2102 /// value is small).
2103 Decimal_Type64& operator+=(int rhs);
2104 Decimal_Type64& operator+=(unsigned int rhs);
2105 Decimal_Type64& operator+=(long rhs);
2106 Decimal_Type64& operator+=(unsigned long rhs);
2107 Decimal_Type64& operator+=(long long rhs);
2108 Decimal_Type64& operator+=(unsigned long long rhs);
2109
2110 /// Subtract the value of the specified `rhs` from the value of this
2111 /// object as described by IEEE-754, store the result in this object,
2112 /// and return a reference to this object.
2113 ///
2114 /// * If this object is signaling NaN, then store the value of the
2115 /// macro `EDOM` into `errno` and set this object to a NaN.
2116 /// * Otherwise if either of this object or `rhs` is NaN then set this
2117 /// object to a NaN.
2118 /// * Otherwise if this object and `rhs` have infinity value of the
2119 /// same signs, store the value of the macro `EDOM` into `errno`
2120 /// and set this object to a NaN.
2121 /// * Otherwise if this object and the `rhs` have infinite values of
2122 /// differing signs, then do not change this object.
2123 /// * Otherwise if the `rhs` has a zero value (positive or negative),
2124 /// do not change this object.
2125 /// * Otherwise if subtracting the value of the `rhs` object from this
2126 /// results in an absolute value that is larger than
2127 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2128 /// the macro `ERANGE` into `errno` and set this object to infinity
2129 /// with the same sign as that result.
2130 /// * Otherwise set this object to the result of subtracting the value
2131 /// of `rhs` from the value of this object.
2132 ///
2133 ///
2134 /// \note Note that this is a floating-point value so this operations may not
2135 /// change the value of this object at all (if the value is large) or it
2136 /// may seem to update it to the value of the `other` (if the original
2137 /// value is small).
2138 ///
2139 ///
2140 /// \note Note that when `rhs` is a `Decimal128`, this operation is always
2141 /// performed with 128 bits precision to prevent loss of precision of
2142 /// the `rhs` operand (prior to the operation). The result is then
2143 /// rounded back to 64 bits and stored to this object. See IEEE-754
2144 /// 2008, 5.1, first paragraph, second sentence for specification.
2148
2149 /// Subtract the specified `rhs` from the value of this object as
2150 /// described by IEEE-754, store the result in this object, and return a
2151 /// reference to this object.
2152 ///
2153 /// * If this object is signaling NaN, then store the value of the
2154 /// macro `EDOM` into `errno` and set this object to a NaN.
2155 /// * Otherwise if this object is NaN, then do not change this object.
2156 /// * Otherwise if this object is infinity, then do not change it.
2157 /// * Otherwise if subtracting `rhs` from this object's value results
2158 /// in an absolute value that is larger than
2159 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2160 /// the macro `ERANGE` into `errno` and set this object to infinity
2161 /// with the same sign as that result.
2162 /// * Otherwise set this object to the result of subtracting `rhs` from
2163 /// the value of this object.
2164 ///
2165 ///
2166 /// \note Note that this is a floating-point value so this operations may not
2167 /// change the value of this object at all (if the value is large) or it
2168 /// may seem to update it to the value of the `other` (if the original
2169 /// value is small).
2170 Decimal_Type64& operator-=(int rhs);
2171 Decimal_Type64& operator-=(unsigned int rhs);
2172 Decimal_Type64& operator-=(long rhs);
2173 Decimal_Type64& operator-=(unsigned long rhs);
2174 Decimal_Type64& operator-=(long long rhs);
2175 Decimal_Type64& operator-=(unsigned long long rhs);
2176
2177 /// Multiply the value of the specified `rhs` object by the value of
2178 /// this as described by IEEE-754, store the result in this object, and
2179 /// return a reference to this object.
2180 ///
2181 /// * If either of this object or `rhs` is signaling NaN, then store
2182 /// the value of the macro `EDOM` into `errno` and set this object to
2183 /// a NaN.
2184 /// * Otherwise if either of this object or `rhs` is NaN then set this
2185 /// object to a NaN.
2186 /// * Otherwise, if one of this object and `rhs` is zero (positive or
2187 /// negative) and the other is infinity (positive or negative), store
2188 /// the value of the macro `EDOM` into `errno` and set this object to
2189 /// a NaN.
2190 /// * Otherwise, if either this object or `rhs` is positive or negative
2191 /// infinity, set this object to infinity. The sign of this object
2192 /// will be positive if this object and `rhs` had the same sign, and
2193 /// negative otherwise.
2194 /// * Otherwise, if either this object or `rhs` is zero, set this
2195 /// object to zero. The sign of this object will be positive if this
2196 /// object and `rhs` had the same sign, and negative otherwise.
2197 /// * Otherwise if the product of this object and `rhs` has an absolute
2198 /// value that is larger than `std::numeric_limits<Decimal64>::max()`
2199 /// then store the value of the macro `ERANGE` into `errno` and set
2200 /// this object to infinity with the same sign of that result.
2201 /// * Otherwise if the product of this object and `rhs` has an absolute
2202 /// value that is smaller than
2203 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2204 /// the macro `ERANGE` into `errno` and set this object to zero value
2205 /// with the same sign as that result.
2206 /// * Otherwise set this object to the product of the value of `rhs`
2207 /// and the value of this object.
2208 ///
2209 ///
2210 /// \note Note that when `rhs` is a `Decimal128`, this operation is always
2211 /// performed with 128 bits precision to prevent loss of precision of
2212 /// the `rhs` operand (prior to the operation). The result is then
2213 /// rounded back to 64 bits and stored to this object. See IEEE-754
2214 /// 2008, 5.1, first paragraph, second sentence for specification.
2218
2219 /// Multiply the specified `rhs` by the value of this object as
2220 /// described by IEEE-754, store the result in this object, and return a
2221 /// reference to this object.
2222 ///
2223 /// * If this object is signaling NaN, then store the value of the
2224 /// macro `EDOM` into `errno` and set this object to a NaN.
2225 /// * Otherwise if this object is NaN, then do not change this object.
2226 /// * Otherwise if this object is infinity (positive or negative), and
2227 /// `rhs` is zero, then store the value of the macro `EDOM` into
2228 /// `errno` and set this object to a NaN.
2229 /// * Otherwise if this object is infinity (positive or negative), then
2230 /// do not change it.
2231 /// * Otherwise if `rhs` is zero, then set this object to zero with the
2232 /// same sign as its value had prior to this operation.
2233 /// * Otherwise if the product of `rhs` and the value of this object
2234 /// results in an absolute value that is larger than
2235 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2236 /// the macro `ERANGE` into `errno` and set this object to infinity
2237 /// with the same sign as that result.
2238 /// * Otherwise if the product of `rhs` and the value of this object
2239 /// results in an absolute value that is smaller than
2240 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2241 /// the macro `ERANGE` into `errno` and set this object to zero with
2242 /// the same sign as that result.
2243 Decimal_Type64& operator*=(int rhs);
2244 Decimal_Type64& operator*=(unsigned int rhs);
2245 Decimal_Type64& operator*=(long rhs);
2246 Decimal_Type64& operator*=(unsigned long rhs);
2247 Decimal_Type64& operator*=(long long rhs);
2248 Decimal_Type64& operator*=(unsigned long long rhs);
2249
2250 /// Divide the value of this object by the value of the specified `rhs`
2251 /// as described by IEEE-754, store the result in this object, and
2252 /// return a reference to this object.
2253 ///
2254 /// * If either of this object or `rhs` is signaling NaN, then store
2255 /// the value of the macro `EDOM` into `errno` and set this object to
2256 /// a NaN.
2257 /// * Otherwise if either of this object or `rhs` is NaN then set this
2258 /// object to a NaN.
2259 /// * Otherwise if this object and `rhs` are both infinity (positive or
2260 /// negative) or both zero (positive or negative), then store the
2261 /// value of the macro `EDOM` into `errno` and return a NaN.
2262 /// * Otherwise if `rhs` has a positive zero value, then store the
2263 /// value of the macro `ERANGE` into `errno` and set this object to
2264 /// infinity with the same sign as its original value.
2265 /// * Otherwise if `rhs` has a negative zero value, then store the
2266 /// value of the macro `ERANGE` into `errno` and set this object to
2267 /// infinity with the opposite sign as its original value.
2268 /// * Otherwise if dividing the value of this object by the value of
2269 /// `rhs` results in an absolute value that is larger than
2270 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2271 /// the macro `ERANGE` into `errno` and return infinity with the same
2272 /// sign as that result.
2273 /// * Otherwise if dividing the value of this object by the value of
2274 /// `rhs` results in an absolute value that is smaller than
2275 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2276 /// the macro `ERANGE` into `errno`and return zero with the same sign
2277 /// as that result.
2278 /// * Otherwise set this object to the result of dividing the value of
2279 /// this object by the value of `rhs`.
2280 ///
2281 ///
2282 /// \note Note that when `rhs` is a `Decimal128`, this operation is always
2283 /// performed with 128 bits precision to prevent loss of precision of
2284 /// the `rhs` operand (prior to the operation). The result is then
2285 /// rounded back to 64 bits and stored to this object. See IEEE-754
2286 /// 2008, 5.1, first paragraph, second sentence for specification.
2290
2291 /// Divide the value of this object by the specified `rhs` as described
2292 /// by IEEE-754, store the result in this object, and return a reference
2293 /// to this object.
2294 ///
2295 /// * If this object is signaling NaN, then store the value of the
2296 /// macro `EDOM` into `errno` and set this object to a NaN.
2297 /// * Otherwise if this object is NaN then set this object to a NaN.
2298 /// * Otherwise if this object is infinity (positive or negative) and
2299 /// `rhs` is positive value then set this object to infinity value
2300 /// with the same sign as its original value.
2301 /// * Otherwise if this object is infinity (positive or negative) and
2302 /// `rhs` is negative value then set this object to infinity value
2303 /// with the opposite sign as its original value.
2304 /// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
2305 /// into `errno` and set this object to infinity with the same sign
2306 /// it had prior to this operation.
2307 /// * Otherwise if dividing the value of this object by the value of
2308 /// `rhs` results in an absolute value that is larger than
2309 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2310 /// the macro `ERANGE` into `errno` and return infinity with the same
2311 /// sign as that result.
2312 /// * Otherwise if dividing the value of this object by the value of
2313 /// `rhs` results in an absolute value that is smaller than
2314 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2315 /// the macro `ERANGE` into `errno`and return zero with the same sign
2316 /// as that result.
2317 /// * Otherwise set this object to the result of dividing the value of
2318 /// this object by the value of `rhs`.
2319 Decimal_Type64& operator/=(int rhs);
2320 Decimal_Type64& operator/=(unsigned int rhs);
2321 Decimal_Type64& operator/=(long rhs);
2322 Decimal_Type64& operator/=(unsigned long rhs);
2323 Decimal_Type64& operator/=(long long rhs);
2324 Decimal_Type64& operator/=(unsigned long long rhs);
2325
2326 /// Return a modifiable pointer to the underlying implementation.
2328
2329 // Aspects
2330
2331 /// Assign to this object the value read from the specified input
2332 /// `stream` using the specified `version` format, and return a
2333 /// reference to `stream`. If `stream` is initially invalid, this
2334 /// operation has no effect. If `version` is not supported, this object
2335 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
2336 /// If `version` is supported but `stream` becomes invalid during this
2337 /// operation, this object has an undefined, but valid, state.
2338 ///
2339 /// \note Note that no version is read from `stream`. See the `bslx` package-level
2340 /// documentation for more information on BDEX streaming of
2341 /// value-semantic types and containers.
2342 template <class STREAM>
2343 STREAM& bdexStreamIn(STREAM& stream, int version);
2344
2345 // ACCESSORS
2346
2347 /// Return a non-modifiable pointer to the underlying implementation.
2348 const DecimalImpUtil::ValueType64 *data() const;
2349
2350 /// Return the value of the underlying implementation.
2352
2353 // Aspects
2354
2355 /// Write the value of this object, using the specified `version`
2356 /// format, to the specified output `stream`, and return a reference to
2357 /// `stream`. If `stream` is initially invalid, this operation has no
2358 /// effect. If `version` is not supported, `stream` is invalidated, but otherwise unmodified.
2359 ///
2360 /// \note Note that `version` is not written to
2361 /// `stream`. See the `bslx` package-level documentation for more
2362 /// information on BDEX streaming of value-semantic types and
2363 /// containers.
2364 template <class STREAM>
2365 STREAM& bdexStreamOut(STREAM& stream, int version) const;
2366
2367 /// Write the value of this object to the specified output `stream` in a
2368 /// human-readable format, and return a reference to `stream`.
2369 /// Optionally specify an initial indentation `level`, whose absolute
2370 /// value is incremented recursively for nested objects. If `level` is
2371 /// specified, optionally specify `spacesPerLevel`, whose absolute value
2372 /// indicates the number of spaces per indentation level for this and
2373 /// all of its nested objects. If `level` is negative, suppress
2374 /// indentation of the first line. If `spacesPerLevel` is negative,
2375 /// format the entire output on one line, suppressing all but the
2376 /// initial indentation (as governed by `level`). If `stream` is not valid on entry, this operation has no effect.
2377 ///
2378 /// \note Note that this
2379 /// human-readable format is not fully specified, and can change without
2380 /// notice.
2381 bsl::ostream& print(bsl::ostream& stream,
2382 int level = 0,
2383 int spacesPerLevel = 4) const;
2384};
2385
2386// FREE OPERATORS
2387
2388/// Return a copy of the specified `value`.
2390
2391/// Return the result of applying the unary - operator to the specified `value` as described by IEEE-754.
2392///
2393/// \note Note that floating-point numbers have
2394/// signed zero, therefore this operation is not the same as `0-value`.
2396
2397/// Apply the prefix ++ operator to the specified `value` and return its original value.
2398///
2399/// \note Note that this is a floating-point value so this
2400/// operations may not change the value of this object at all (if the value
2401/// is large) or it may just set it to 1.0 (if the original value is small).
2403
2404/// Apply the prefix -- operator to the specified `value` and return its original value.
2405///
2406/// \note Note that this is a floating-point value so this
2407/// operations may not change the value of this object at all (if the value
2408/// is large) or it may just set it to -1.0 (if the original value is
2409/// small).
2411
2412/// Add the value of the specified `rhs` to the value of the specified `lhs`
2413/// as described by IEEE-754 and return the result.
2414///
2415/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2416/// the macro `EDOM` into `errno` and return a NaN.
2417/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2418/// * Otherwise if `lhs` and `rhs` are infinities of differing signs, store
2419/// the value of the macro `EDOM` into `errno` and return a NaN.
2420/// * Otherwise if `lhs` and `rhs` are infinities of the same sign then
2421/// return infinity of that sign.
2422/// * Otherwise if `rhs` is zero (positive or negative), return `lhs`.
2423/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
2424/// larger than `std::numeric_limits<Decimal64>::max()` then store the
2425/// value of the macro `ERANGE` into `errno` and set this object to
2426/// infinity with the same sign as that result.
2427/// * Otherwise return the sum of the number represented by `lhs` and the
2428/// number represented by `rhs`.
2432
2433/// Add the specified `rhs` to the value of the specified `lhs` as described
2434/// by IEEE-754 and return the result.
2435///
2436/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2437/// into `errno` and return a NaN.
2438/// * Otherwise if `lhs` object is NaN, then return a NaN.
2439/// * Otherwise if `lhs` is infinity, then return infinity.
2440/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
2441/// larger than `std::numeric_limits<Decimal64>::max()` then store the
2442/// value of the macro `ERANGE` into `errno` and return infinity with the
2443/// same sign as that result.
2444/// * Otherwise return the sum of `rhs` and the number represented by
2445/// `lhs`.
2447Decimal64 operator+(Decimal64 lhs, unsigned int rhs);
2449Decimal64 operator+(Decimal64 lhs, unsigned long rhs);
2450Decimal64 operator+(Decimal64 lhs, long long rhs);
2451Decimal64 operator+(Decimal64 lhs, unsigned long long rhs);
2452
2453/// Add the specified `lhs` to the value of the specified `rhs` as described
2454/// by IEEE-754 and return the result.
2455///
2456/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2457/// into `errno` and return a NaN.
2458/// * Otherwise if `rhs` object is NaN, then return a NaN.
2459/// * Otherwise if `rhs` is infinity, then return infinity.
2460/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
2461/// larger than `std::numeric_limits<Decimal64>::max()` then store the
2462/// value of the macro `ERANGE` into `errno` and return infinity with the
2463/// same sign as that result.
2464/// * Otherwise return the sum of `lhs` and the number represented by
2465/// `rhs`.
2467Decimal64 operator+(unsigned int lhs, Decimal64 rhs);
2469Decimal64 operator+(unsigned long lhs, Decimal64 rhs);
2470Decimal64 operator+(long long lhs, Decimal64 rhs);
2471Decimal64 operator+(unsigned long long lhs, Decimal64 rhs);
2472
2473/// Subtract the value of the specified `rhs` from the value of the
2474/// specified `lhs` as described by IEEE-754 and return the result.
2475///
2476/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2477/// the macro `EDOM` into `errno` and return a NaN.
2478/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2479/// * Otherwise if `lhs` and the `rhs` have infinity values of the same
2480/// sign, store the value of the macro `EDOM` into `errno` and return a
2481/// NaN.
2482/// * Otherwise if `lhs` and the `rhs` have infinity values of differing
2483/// signs, then return `lhs`.
2484/// * Otherwise if the subtracting of `lhs` and `rhs` has an absolute value
2485/// that is larger than `std::numeric_limits<Decimal64>::max()` then
2486/// store the value of the macro `ERANGE` into `errno` and return
2487/// infinity with the same sign as that result.
2488/// * Otherwise return the result of subtracting the value of `rhs`from the
2489/// value of `lhs`.
2493
2494/// Subtract the specified `rhs` from the value of the specified `lhs` as
2495/// described by IEEE-754 and return a reference to this object.
2496///
2497/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2498/// into `errno` and return a NaN.
2499/// * Otherwise if `lhs` is NaN, then return a NaN.
2500/// * Otherwise if `lhs` is infinity, then return infinity.
2501/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
2502/// an absolute value that is larger than
2503/// `std::numeric_limits<Decimal32>::max()` then store the value of the
2504/// macro `ERANGE` into `errno` and return infinity with the same sign as
2505/// that result.
2506/// * Otherwise return the result of subtracting `rhs` from the value of
2507/// `lhs`.
2509Decimal64 operator-(Decimal64 lhs, unsigned int rhs);
2511Decimal64 operator-(Decimal64 lhs, unsigned long rhs);
2512Decimal64 operator-(Decimal64 lhs, long long rhs);
2513Decimal64 operator-(Decimal64 lhs, unsigned long long rhs);
2514
2515/// Subtract the specified `rhs` from the value of the specified `lhs` as
2516/// described by IEEE-754 and return a reference to this object.
2517///
2518/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2519/// into `errno` and return a NaN.
2520/// * Otherwise if `rhs` is NaN, then return a NaN.
2521/// * Otherwise if `rhs` is infinity, then return infinity.
2522/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
2523/// an absolute value that is larger than
2524/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2525/// macro `ERANGE` into `errno` and return infinity with the same sign as
2526/// that result.
2527/// * Otherwise return the result of subtracting the value of `rhs` from
2528/// the number `lhs`.
2530Decimal64 operator-(unsigned int lhs, Decimal64 rhs);
2532Decimal64 operator-(unsigned long lhs, Decimal64 rhs);
2533Decimal64 operator-(long long lhs, Decimal64 rhs);
2534Decimal64 operator-(unsigned long long lhs, Decimal64 rhs);
2535
2536/// Multiply the value of the specified `lhs` object by the value of the
2537/// specified `rhs` as described by IEEE-754 and return the result.
2538///
2539/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2540/// the macro `EDOM` into `errno` and return a NaN.
2541/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2542/// * Otherwise if one of the operands is infinity (positive or negative)
2543/// and the other is zero (positive or negative), then store the value of
2544/// the macro `EDOM` into `errno` and return a NaN.
2545/// * Otherwise if both `lhs` and `rhs` are infinity (positive or
2546/// negative), return infinity. The sign of the returned value will be
2547/// positive if `lhs` and `rhs` have the same sign, and negative
2548/// otherwise.
2549/// * Otherwise, if either `lhs` or `rhs` is zero, return zero. The sign
2550/// of the returned value will be positive if `lhs` and `rhs` have the
2551/// same sign, and negative otherwise.
2552/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
2553/// that is larger than `std::numeric_limits<Decimal64>::max()` then
2554/// store the value of the macro `ERANGE` into `errno` and return an
2555/// infinity with the same sign as that result.
2556/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
2557/// that is smaller than `std::numeric_limits<Decimal64>::min()` then
2558/// store the value of the macro `ERANGE` into `errno` and return zero
2559/// with the same sign as that result.
2560/// * Otherwise return the product of the value of `rhs` and the number
2561/// represented by `rhs`.
2565
2566/// Multiply the specified `rhs` by the value of the specified `lhs` as
2567/// described by IEEE-754, and return the result.
2568///
2569/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2570/// into `errno` and return a NaN.
2571/// * Otherwise if `lhs` is NaN, then return a NaN.
2572/// * Otherwise if `lhs` is infinity (positive or negative), and `rhs` is
2573/// zero, then store the value of the macro `EDOM` into'errno' and return
2574/// a NaN.
2575/// * Otherwise if `lhs` is infinity (positive or negative), then return
2576/// `lhs`.
2577/// * Otherwise if `rhs` is zero, then return zero with the sign of `lhs`.
2578/// * Otherwise if the product of `rhs` and the value of `lhs` results in
2579/// an absolute value that is larger than
2580/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2581/// macro `ERANGE` into `errno` and return infinity with the same sign as
2582/// that result.
2583/// * Otherwise if the product of `rhs` and the value of `lhs` results in
2584/// an absolute value that is smaller than
2585/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2586/// macro `ERANGE` into `errno` and return zero with the same sign as
2587/// that result.
2588/// * Otherwise return the product of the value of `lhs` and value `rhs`.
2590Decimal64 operator*(Decimal64 lhs, unsigned int rhs);
2592Decimal64 operator*(Decimal64 lhs, unsigned long rhs);
2593Decimal64 operator*(Decimal64 lhs, long long rhs);
2594Decimal64 operator*(Decimal64 lhs, unsigned long long rhs);
2595
2596/// Multiply the specified `lhs` by the value of the specified `rhs` as
2597/// described by IEEE-754, and return the result.
2598///
2599/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2600/// into `errno` and return a NaN.
2601/// * Otherwise if `rhs` is NaN, then return a NaN.
2602/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
2603/// zero, then store the value of the macro `EDOM` into'errno' and return
2604/// a NaN.
2605/// * Otherwise if `rhs` is infinity (positive or negative), then return
2606/// `rhs`.
2607/// * Otherwise if `lhs` is zero, then return zero with the sign of `rhs`.
2608/// * Otherwise if the product of `lhs` and the value of `rhs` results in
2609/// an absolute value that is larger than
2610/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2611/// macro `ERANGE` into `errno` and return infinity with the same sign as
2612/// that result.
2613/// * Otherwise if the product of `lhs` and the value of `rhs` results in
2614/// an absolute value that is smaller than
2615/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2616/// macro `ERANGE` into `errno` and return zero with the same sign as
2617/// that result.
2618/// * Otherwise return the product of the value of `lhs` and value `rhs`.
2620Decimal64 operator*(unsigned int lhs, Decimal64 rhs);
2622Decimal64 operator*(unsigned long lhs, Decimal64 rhs);
2623Decimal64 operator*(long long lhs, Decimal64 rhs);
2624Decimal64 operator*(unsigned long long lhs, Decimal64 rhs);
2625
2626/// Divide the value of the specified `lhs` by the value of the specified
2627/// `rhs` as described by IEEE-754, and return the result.
2628///
2629/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2630/// the macro `EDOM` into `errno` and return a NaN.
2631/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2632/// * Otherwise if `lhs` and `rhs` are both infinity (positive or negative)
2633/// or both zero (positive or negative) then store the value of the macro
2634/// `EDOM` into `errno` and return a NaN.
2635/// * Otherwise if `lhs` has a normal value and `rhs` has a positive zero
2636/// value, store the value of the macro `ERANGE` into `errno` and return
2637/// infinity with the sign of `lhs`.
2638/// * Otherwise if `lhs` has a normal value and `rhs` has a negative zero
2639/// value, store the value of the macro `ERANGE` into `errno` and return
2640/// infinity with the opposite sign as `lhs`.
2641/// * Otherwise if `lhs` has infinity value and `rhs` has a positive zero
2642/// value, return infinity with the sign of `lhs`.
2643/// * Otherwise if `lhs` has infinity value and `rhs` has a negative zero
2644/// value, return infinity with the opposite sign as `lhs`.
2645/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2646/// results in an absolute value that is larger than
2647/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2648/// macro `ERANGE` into `errno` and return infinity with the same sign as
2649/// that result.
2650/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2651/// results in an absolute value that is smaller than
2652/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2653/// macro `ERANGE` into `errno` and return zero with the same sign as
2654/// that result.
2655/// * Otherwise return the result of dividing the value of `lhs` by the
2656/// value of `rhs`.
2660
2661/// Divide the value of the specified `lhs` by the specified `rhs` as
2662/// described by IEEE-754, and return the result.
2663///
2664/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2665/// into `errno` and return a NaN.
2666/// * Otherwise if `lhs` is NaN then return a NaN.
2667/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
2668/// positive value then return infinity value with the same sign as its
2669/// original value.
2670/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
2671/// negative value then return infinity value with the opposite sign as
2672/// its original value.
2673/// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
2674/// into `errno` and return infinity with the same sign it had prior to
2675/// this operation.
2676/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2677/// results in an absolute value that is larger than
2678/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2679/// macro `ERANGE` into `errno` and return infinity with the same sign as
2680/// that result.
2681/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2682/// results in an absolute value that is smaller than
2683/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2684/// macro `ERANGE` into `errno` and return zero with the same sign as
2685/// that result.
2686/// * Otherwise return the result of dividing the value of `lhs` by the
2687/// value `rhs`.
2689Decimal64 operator/(Decimal64 lhs, unsigned int rhs);
2691Decimal64 operator/(Decimal64 lhs, unsigned long rhs);
2692Decimal64 operator/(Decimal64 lhs, long long rhs);
2693Decimal64 operator/(Decimal64 lhs, unsigned long long rhs);
2694
2695/// Divide the specified `lhs` by the value of the specified `rhs` as
2696/// described by IEEE-754, and return the result.
2697///
2698/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2699/// into `errno` and return a NaN.
2700/// * Otherwise if `rhs` is NaN then return a NaN.
2701/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
2702/// zero, store the value of the macro `ERANGE` into `errno` and return a
2703/// NaN.
2704/// * Otherwise if `rhs` is zero (positive or negative), store the value of
2705/// the macro `ERANGE` into `errno` and return infinity with the sign of
2706/// `lhs`.
2707/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2708/// results in an absolute value that is larger than
2709/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2710/// macro `ERANGE` into `errno` and return infinity with the same sign as
2711/// that result.
2712/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2713/// results in an absolute value that is smaller than
2714/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2715/// macro `ERANGE` into `errno` and return zero with the same sign as
2716/// that result.
2717/// * Otherwise return the result of dividing the value of `lhs` by the value of `rhs`.
2718///
2719/// \note Note that this is a floating-point operation, not
2720/// integer.
2722Decimal64 operator/(unsigned int lhs, Decimal64 rhs);
2724Decimal64 operator/(unsigned long lhs, Decimal64 rhs);
2725Decimal64 operator/(long long lhs, Decimal64 rhs);
2726Decimal64 operator/(unsigned long long lhs, Decimal64 rhs);
2727
2728/// Return `true` if the specified `lhs` and `rhs` have the same value, and
2729/// `false` otherwise. Two `Decimal64` objects have the same value if the
2730/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
2731/// comparison) considers the underlying IEEE representations equal. In
2732/// other words, two `Decimal64` objects have the same value if:
2733///
2734/// * both have a zero value (positive or negative), or
2735/// * both have the same infinity value (both positive or negative), or
2736/// * both have the value of a real number that are equal, even if they are
2737/// represented differently (cohorts have the same value)
2738///
2739/// This operation stores the value of the macro `EDOM` into `errno` if
2740/// either or both operands are signaling NaN.
2741///
2742///
2743/// \note Note that a NaN is never equal to anything, including itself:
2744/// @code
2745/// Decimal64 aNaN = std::numeric_limits<Decimal64>::quiet_NaN();
2746/// assert(!(aNan == aNan));
2747/// @endcode
2748bool operator==(Decimal64 lhs, Decimal64 rhs);
2749
2750/// Return `true` if the specified `lhs` and `rhs` have the same value, and
2751/// `false` otherwise. Two decimal objects have the same value if the
2752/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
2753/// comparison) considers the underlying IEEE representations equal. In
2754/// other words, two decimal objects have the same value if:
2755///
2756/// * both have a zero value (positive or negative), or
2757/// * both have the same infinity value (both positive or negative), or
2758/// * both have the value of a real number that are equal, even if they are
2759/// represented differently (cohorts have the same value)
2760///
2761/// This operation stores the value of the macro `EDOM` into `errno` if
2762/// either or both operands are signaling NaN.
2763bool operator==(Decimal32 lhs, Decimal64 rhs);
2764bool operator==(Decimal64 lhs, Decimal32 rhs);
2765
2766/// Return `true` if the specified `lhs` and `rhs` do not have the same
2767/// value, and `false` otherwise. Two `Decimal64` objects do not have the
2768/// same value if the `compareQuietEqual` operation (IEEE-754 defined,
2769/// non-total ordering comparison) considers the underlying IEEE
2770/// representations not equal. In other words, two `Decimal64` objects do
2771/// not have the same value if:
2772///
2773/// * both are a NaN, or
2774/// * one has zero value (positive or negative) and the other does not, or
2775/// * one has the value of positive infinity and the other does not, or
2776/// * one has the value of negative infinity and the other does not, or
2777/// * both have the value of a real number that are not equal, regardless
2778/// of their representation (cohorts are equal)
2779///
2780/// This operation stores the value of the macro `EDOM` into `errno` if
2781/// either or both operands are signaling NaN.
2782///
2783///
2784/// \note Note that a NaN is never equal to anything, including itself:
2785/// @code
2786/// Decimal64 aNaN = std::numeric_limits<Decimal64>::quiet_NaN();
2787/// assert(aNan != aNan);
2788/// @endcode
2789bool operator!=(Decimal64 lhs, Decimal64 rhs);
2790
2791/// Return `true` if the specified `lhs` and `rhs` do not have the same
2792/// value, and `false` otherwise. Two decimal objects do not have the same
2793/// value if the `compareQuietEqual` operation (IEEE-754 defined, non-total
2794/// ordering comparison) considers the underlying IEEE representations not
2795/// equal. In other words, two decimal objects do not have the same value
2796/// if:
2797///
2798/// * both are NaN, or
2799/// * one has zero value (positive or negative) and the other does not, or
2800/// * one has the value of positive infinity and the other does not, or
2801/// * one has the value of negative infinity and the other does not, or
2802/// * both have the value of a real number that are not equal, regardless
2803/// of their representation (cohorts are equal)
2804///
2805/// This operation stores the value of the macro `EDOM` into `errno` if
2806/// either or both operands are signaling NaN.
2807bool operator!=(Decimal32 lhs, Decimal64 rhs);
2808bool operator!=(Decimal64 lhs, Decimal32 rhs);
2809
2810/// Return `true` if the specified `lhs` has a value less than the specified
2811/// `rhs` and `false` otherwise. The value of a `Decimal64` object `lhs` is
2812/// less than that of an object `rhs` if the `compareQuietLess` operation
2813/// (IEEE-754 defined, non-total ordering comparison) considers the
2814/// underlying IEEE representation of `lhs` to be less than of that of
2815/// `rhs`. In other words, `lhs` is less than `rhs` if:
2816///
2817/// * neither `lhs` nor `rhs` are NaN, or
2818/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
2819/// * `rhs` is zero (positive or negative) and `lhs` negative, or
2820/// * `lhs` is not positive infinity, or
2821/// * `lhs` is negative infinity and `rhs` is not, or
2822/// * `lhs` and `rhs` both represent a real number and the real number of
2823/// `lhs` is less than that of `rhs`
2824///
2825/// This operation stores the value of the macro `EDOM` into `errno` if
2826/// either or both operands are signaling NaN.
2827bool operator<(Decimal64 lhs, Decimal64 rhs);
2828
2829/// Return `true` if the specified `lhs` has a value less than the specified
2830/// `rhs` and `false` otherwise. The value of a decimal object `lhs` is
2831/// less than that of an object `rhs` if the `compareQuietLess` operation
2832/// (IEEE-754 defined, non-total ordering comparison) considers the
2833/// underlying IEEE representation of `lhs` to be less than of that of
2834/// `rhs`. In other words, `lhs` is less than `rhs` if:
2835///
2836/// * neither `lhs` nor `rhs` are NaN, or
2837/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
2838/// * `rhs` is zero (positive or negative) and `lhs` negative, or
2839/// * `lhs` is not positive infinity, or
2840/// * `lhs` is negative infinity and `rhs` is not, or
2841/// * `lhs` and `rhs` both represent a real number and the real number of
2842/// `lhs` is less than that of `rhs`
2843///
2844/// This operation stores the value of the macro `EDOM` into `errno` if
2845/// either or both operands are signaling NaN.
2846bool operator<(Decimal32 lhs, Decimal64 rhs);
2847bool operator<(Decimal64 lhs, Decimal32 rhs);
2848
2849/// Return `true` if the specified `lhs` has a value less than or equal the
2850/// value of the specified `rhs` and `false` otherwise. The value of a
2851/// `Decimal64` object `lhs` is less than or equal to the value of an object
2852/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
2853/// non-total ordering comparison) considers the underlying IEEE
2854/// representation of `lhs` to be less or equal to that of `rhs`. In other
2855/// words, `lhs` is less or equal than `rhs` if:
2856///
2857/// * neither `lhs` nor `rhs` are NaN, or
2858/// * `lhs` and `rhs` are both zero (positive or negative), or
2859/// * both `lhs` and `rhs` are positive infinity, or
2860/// * `lhs` is negative infinity, or
2861/// * `lhs` and `rhs` both represent a real number and the real number of
2862/// `lhs` is less or equal to that of `rhs`
2863///
2864/// This operation stores the value of the macro `EDOM` into `errno` if
2865/// either or both operands are signaling NaN.
2866bool operator<=(Decimal64 lhs, Decimal64 rhs);
2867
2868/// Return `true` if the specified `lhs` has a value less than or equal the
2869/// value of the specified `rhs` and `false` otherwise. The value of a
2870/// decimal object `lhs` is less than or equal to the value of an object
2871/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
2872/// non-total ordering comparison) considers the underlying IEEE
2873/// representation of `lhs` to be less or equal to that of `rhs`. In other
2874/// words, `lhs` is less or equal than `rhs` if:
2875///
2876/// * neither `lhs` nor `rhs` are NaN, or
2877/// * `lhs` and `rhs` are both zero (positive or negative), or
2878/// * both `lhs` and `rhs` are positive infinity, or
2879/// * `lhs` is negative infinity, or
2880/// * `lhs` and `rhs` both represent a real number and the real number of
2881/// `lhs` is less or equal to that of `rhs`
2882///
2883/// This operation stores the value of the macro `EDOM` into `errno` if
2884/// either or both operands are signaling NaN.
2885bool operator<=(Decimal32 lhs, Decimal64 rhs);
2886bool operator<=(Decimal64 lhs, Decimal32 rhs);
2887
2888/// Return `true` if the specified `lhs` has a greater value than the
2889/// specified `rhs` and `false` otherwise. The value of a `Decimal64`
2890/// object `lhs` is greater than that of an object `rhs` if the
2891/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
2892/// comparison) considers the underlying IEEE representation of `lhs` to be
2893/// greater than of that of `rhs`. In other words, `lhs` is greater than
2894/// `rhs` if:
2895///
2896/// * neither `lhs` nor `rhs` are NaN, or
2897/// * `rhs` is zero (positive or negative) and `lhs` positive, or
2898/// * `lhs` is zero (positive or negative) and `rhs` negative, or
2899/// * `lhs` is not negative infinity, or
2900/// * `lhs` is positive infinity and `rhs` is not, or
2901/// * `lhs` and `rhs` both represent a real number and the real number of
2902/// `lhs` is greater than that of `rhs`
2903///
2904/// This operation stores the value of the macro `EDOM` into `errno` if
2905/// either or both operands are signaling NaN.
2906bool operator>(Decimal64 lhs, Decimal64 rhs);
2907
2908/// Return `true` if the specified `lhs` has a greater value than the
2909/// specified `rhs` and `false` otherwise. The value of a decimal object
2910/// `lhs` is greater than that of an object `rhs` if the
2911/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
2912/// comparison) considers the underlying IEEE representation of `lhs` to be
2913/// greater than of that of `rhs`. In other words, `lhs` is greater than
2914/// `rhs` if:
2915///
2916/// * neither `lhs` nor `rhs` are NaN, or
2917/// * `rhs` is zero (positive or negative) and `lhs` positive, or
2918/// * `lhs` is zero (positive or negative) and `rhs` negative, or
2919/// * `lhs` is not negative infinity, or
2920/// * `lhs` is positive infinity and `rhs` is not, or
2921/// * `lhs` and `rhs` both represent a real number and the real number of
2922/// `lhs` is greater than that of `rhs`
2923///
2924/// This operation stores the value of the macro `EDOM` into `errno` if
2925/// either or both operands are signaling NaN.
2926bool operator>(Decimal32 lhs, Decimal64 rhs);
2927bool operator>(Decimal64 lhs, Decimal32 rhs);
2928
2929/// Return `true` if the specified `lhs` has a value greater than or equal
2930/// to the value of the specified `rhs` and `false` otherwise. The value of
2931/// a `Decimal64` object `lhs` is greater or equal to a `Decimal64` object
2932/// `rhs` if the `compareQuietGreaterEqual` operation (IEEE-754 defined,
2933/// non-total ordering comparison ) considers the underlying IEEE
2934/// representation of `lhs` to be greater or equal to that of `rhs`. In
2935/// other words, `lhs` is greater than or equal to `rhs` if:
2936///
2937/// * neither `lhs` nor `rhs` are NaN, or
2938/// * `lhs` and `rhs` are both zero (positive or negative), or
2939/// * both `lhs` and `rhs` are negative infinity, or
2940/// * `lhs` is positive infinity, or
2941/// * `lhs` and `rhs` both represent a real number and the real number of
2942/// `lhs` is greater or equal to that of `rhs`
2943///
2944/// This operation stores the value of the macro `EDOM` into `errno` if
2945/// either or both operands are signaling NaN.
2946bool operator>=(Decimal64 lhs, Decimal64 rhs);
2947
2948/// Return `true` if the specified `lhs` has a value greater than or equal
2949/// to the value of the specified `rhs` and `false` otherwise. The value of
2950/// a decimal object `lhs` is greater or equal to a decimal object `rhs` if
2951/// the `compareQuietGreaterEqual` operation (IEEE-754 defined, non-total
2952/// ordering comparison ) considers the underlying IEEE representation of
2953/// `lhs` to be greater or equal to that of `rhs`. In other words, `lhs` is
2954/// greater than or equal to `rhs` if:
2955///
2956/// * neither `lhs` nor `rhs` are NaN, or
2957/// * `lhs` and `rhs` are both zero (positive or negative), or
2958/// * both `lhs` and `rhs` are negative infinity, or
2959/// * `lhs` is positive infinity, or
2960/// * `lhs` and `rhs` both represent a real number and the real number of
2961/// `lhs` is greater or equal to that of `rhs`
2962///
2963/// This operation stores the value of the macro `EDOM` into `errno` if
2964/// either or both operands are signaling NaN.
2965bool operator>=(Decimal32 lhs, Decimal64 rhs);
2966bool operator>=(Decimal64 lhs, Decimal32 rhs);
2967
2968/// Read, into the specified `object`, from the specified input `stream` an
2969/// IEEE 64 bit decimal floating-point value as described in the IEEE-754
2970/// 2008 standard (5.12 Details of conversions between floating point
2971/// numbers and external character sequences) and return a reference
2972/// providing modifiable access to `stream`. If `stream` contains a Nan
2973/// value, it is unspecified if `object` will receive a quiet or signaling
2974/// `Nan`. If `stream` is not valid on entry `stream.good() == false`, this
2975/// operation has no effect other than setting `stream.fail()` to `true`.
2976/// If eof (end-of-file) is found before any non-whitespace characters
2977/// `stream.fail()` is set to `true` and `object` remains unchanged. If eof
2978/// is detected after some characters have been read (and successfully
2979/// interpreted as part of the textual representation of a floating-point
2980/// value as specified by IEEE-754) then `stream.eof()` is set to true. If
2981/// the first non-whitespace character sequence is not a valid textual
2982/// representation of a floating-point value (e.g., 12e or e12 or 1*2) the
2983/// `stream.fail()` is set to true and `object` will remain unchanged. If a
2984/// real number value is represented by the character sequence but it is a
2985/// large positive or negative value that cannot be stored into `object`
2986/// then store the value of the macro `ERANGE` into `errno` and positive or
2987/// negative infinity is stored into `object`, respectively. If a real
2988/// number value is represented by the character sequence but it is a small
2989/// positive or negative value that cannot be stored into `object` then
2990/// store the value of the macro `ERANGE` into `errno` and positive or
2991/// negative zero is stored into `object`, respectively. If a real number
2992/// value is represented by the character sequence but it cannot be stored
2993/// exactly into `object`, the value is rounded according to the current
2994/// rounding direction (of the environment) and then stored into `object`.
2995///
2996/// NOTE: This method does not yet fully support iostream flags or the
2997/// decimal floating point exception context.
2998template <class CHARTYPE, class TRAITS>
2999bsl::basic_istream<CHARTYPE, TRAITS>&
3000operator>> (bsl::basic_istream<CHARTYPE, TRAITS>& stream, Decimal64& object);
3001
3002/// Write the value of the specified `object` to the specified output
3003/// `stream` in a single line format as described in the IEEE-754 2008
3004/// standard (5.12 Details of conversions between floating point numbers and
3005/// external character sequences), and return a reference providing
3006/// modifiable access to `stream`. If `stream` is not valid on entry, this
3007/// operation has no effect.
3008///
3009/// NOTE: This method does not yet fully support iostream flags or the
3010/// decimal floating point exception context.
3011template <class CHARTYPE, class TRAITS>
3012bsl::basic_ostream<CHARTYPE, TRAITS>&
3013operator<< (bsl::basic_ostream<CHARTYPE, TRAITS>& stream, Decimal64 object);
3014
3015#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
3016 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
3017inline namespace literals {
3018inline namespace DecimalLiterals {
3019/// Produce an object of the indicated return type by parsing the specified
3020/// `str` having the specified `len` excluding the terminating null
3021/// character that represents a floating-point number written in both fixed
3022/// and scientific notations. These user-defined literal suffixes can be
3023/// applied to both numeric and string literals, (i.e., 1.2_d128, "1.2"_d64
3024/// or "inf"_d64). The resulting decimal object is initialized as follows:
3025///
3026/// * If `str` does not represent a floating-point value, then return a
3027/// decimal object of the indicated return type initialized to a NaN.
3028/// * Otherwise if `str` represents infinity (positive or negative), then
3029/// return a decimal object of the indicated return type initialized to
3030/// infinity value with the same sign.
3031/// * Otherwise if `str` represents zero (positive or negative), then
3032/// return a decimal object of the indicated return type initialized to
3033/// zero with the same sign.
3034/// * Otherwise if `str` represents a value that has an absolute value that
3035/// is larger than the maximum value supported by the indicated return
3036/// type, then store the value of the macro `ERANGE` into `errno` and
3037/// return a decimal object of the return type initialized to infinity
3038/// with the same sign.
3039/// * Otherwise if `str` represents a value that has an absolute value that
3040/// is smaller than min value of the indicated return type, then store
3041/// the value of the macro `ERANGE` into `errno` and return a decimal
3042/// object of the return type initialized to zero with the same sign.
3043/// * Otherwise if `str` has a value that is not exactly representable
3044/// using the maximum digit number supported by the indicated return
3045/// type, then return a decimal object of the return type initialized to
3046/// the value represented by `str` rounded according to the rounding
3047/// direction.
3048/// * Otherwise return a decimal object of the indicated return type
3049/// initialized to the decimal value representation of `str`.
3050///
3051///
3052/// \note Note that the parsing follows the rules as specified for the `strtod64`
3053/// function in section 9.6 of the ISO/EIC TR 247128 C Decimal
3054/// Floating-Point Technical Report.
3055///
3056/// Also note that the numeric literal version omits the optional leading
3057/// sign in `str`. For example, if the string is -1.2_d64 then the string
3058/// "1.2" is passed to the one-argument form, not "-1.2", because leading
3059/// signs are operators, not parts of literals. On the other hand, the
3060/// string literal version does not omit leading sign and if the string is
3061/// "-1.2"_d64 then the string "-1.2" is passed to the two-argument form.
3062///
3063/// Also note that the quantum of the resultant value is affected by the
3064/// number of decimal places in `str` string in both numeric and string
3065/// literal formats starting with the most significand digit and cannot
3066/// exceed the maximum number of digits necessary to differentiate all
3067/// values of the indicated return type, for example:
3068///
3069/// `0.015_d64; => 15e-3`
3070/// `1.5_d64; => 15e-1`
3071/// `1.500_d64; => 1500e-3`
3072/// `1.2345678901234567_d64; => 1234567890123458-15`
3073bdldfp::Decimal64 operator""_d64 (const char *str);
3074bdldfp::Decimal64 operator""_d64 (const char *str, bsl::size_t len);
3075
3076} // close DecimalLiterals namespace
3077} // close literals namespace
3078#endif
3079
3080// FREE FUNCTIONS
3081
3082/// Pass the specified `object` to the specified `hashAlg`. This function
3083/// integrates with the `bslh` modular hashing system and effectively provides a `bsl::hash` specialization for `Decimal64`.
3084///
3085/// \note Note that two
3086/// objects which have the same value but different representations will
3087/// hash to the same value.
3088template <class HASHALG>
3089void hashAppend(HASHALG& hashAlg, const Decimal64& object);
3090
3091
3092 // =====================
3093 // class Decimal_Type128
3094 // =====================
3095
3096/// This value-semantic class implements the IEEE-754 128 bit decimal
3097/// floating-point format arithmetic type. This class is a standard layout
3098/// type that is `const` thread-safe and exception-neutral.
3099///
3100/// See @ref bdldfp_decimal
3102
3103 private:
3104 // DATA
3106 // The underlying IEEE representation
3107
3108 public:
3109 // CLASS METHODS
3110
3111 // Aspects
3112
3113 /// Return the maximum valid BDEX format version, as indicated by the
3114 /// specified `versionSelector`, to be passed to the `bdexStreamOut` method.
3115 ///
3116 /// \note Note that it is highly recommended that `versionSelector`
3117 /// be formatted as "YYYYMMDD", a date representation. Also note that
3118 /// `versionSelector` should be a *compile*-time-chosen value that
3119 /// selects a format version supported by both externalizer and
3120 /// unexternalizer. See the `bslx` package-level documentation for more
3121 /// information on BDEX streaming of value-semantic types and
3122 /// containers.
3123 static int maxSupportedBdexVersion();
3124 static int maxSupportedBdexVersion(int versionSelector);
3125
3126 // TRAITS
3129
3130 // CREATORS
3131
3132 /// Create a `Decimal128_Type` object having the value positive zero and
3133 /// the smallest exponent value.
3135
3136 /// Create a `Decimal128_Type` object having the specified `value`.
3138
3139 /// Create a `Decimal128_Type` object having the specified `value`,
3140 /// subject to the conversion rules as defined by IEEE-754:
3141 ///
3142 /// * If `value` is NaN, initialize this object to a NaN.
3143 /// * Otherwise if `value` is infinity, then initialize this object to
3144 /// infinity with the same sign.
3145 /// * Otherwise if `value` is zero, then initialize this object to zero
3146 /// with the same sign.
3147 /// * Otherwise initialize this object to `value`.
3148 Decimal_Type128(Decimal32 value); // IMPLICIT
3149 Decimal_Type128(Decimal64 value); // IMPLICIT
3150
3151 /// Create a `Decimal128_Type` object having the value closest to the
3152 /// specified `other` value. *Warning:* clients requiring a conversion
3153 /// for an exact decimal value should use @ref bdldfp_decimalconvertutil
3154 /// (see *WARNING*: Conversions from `float` and `double`}. This
3155 /// conversion follows the conversion rules as defined by IEEE-754:
3156 ///
3157 /// * If `value` is NaN, initialize this object to a NaN.
3158 /// * Otherwise if `value` is infinity, then initialize this object to
3159 /// infinity value with the same sign.
3160 /// * Otherwise if `value` has a zero value, then initialize this
3161 /// object to zero with the same sign.
3162 /// * Otherwise initialize this object to `value`.
3163 explicit Decimal_Type128(float other);
3164 explicit Decimal_Type128(double other);
3165
3166 /// Create a `Decimal128_Type` object having the value closest to the
3167 /// specified `value` subject to the conversion rules as defined by
3168 /// IEEE-754:
3169 ///
3170 /// * If `value` has an absolute value that is larger than
3171 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3172 /// the macro `ERANGE` into `errno` and initialize this object to
3173 /// infinity with the same sign as `other`.
3174 /// * Otherwise if `value` has a value that is not exactly
3175 /// representable using `std::numeric_limits<Decimal128>::max_digit`
3176 /// decimal digits then initialize this object to the value of
3177 /// `value` rounded according to the rounding direction.
3178 /// * Otherwise initialize this object to `value` with exponent 0.
3179 explicit Decimal_Type128(int value);
3180 explicit Decimal_Type128(unsigned int value);
3181 explicit Decimal_Type128(long value);
3182 explicit Decimal_Type128(unsigned long value);
3183 explicit Decimal_Type128(long long value);
3184 explicit Decimal_Type128(unsigned long long value);
3185
3186 Decimal128_Type(const Decimal128_Type& original) = default;
3187 // Create a 'Decimal128_Type' object that is a copy of the specified
3188 // 'original' as defined by the 'copy' operation of IEEE-754 2008:
3189 //
3190 //: o If 'original' is NaN, initialize this object to a NaN.
3191 //:
3192 //: o Otherwise initialize this object to the value of the 'original'.
3193 //
3194 // Note that since floating-point types may be NaN, and NaNs are
3195 // unordered (do not compare equal even to themselves) it is possible
3196 // that a copy of a decimal will not compare equal to the original;
3197 // however it will behave as the original.
3198
3199 ~Decimal128_Type() = default;
3200 // Destroy this object.
3201
3202 // MANIPULATORS
3204 // Make this object a copy of the specified 'rhs' as defined by the
3205 // 'copy' operation of IEEE-754 2008 and return a reference providing
3206 // modifiable access to this object.
3207 //
3208 //: o If 'rhs' is NaN, set this object to a NaN.
3209 //:
3210 //: o Otherwise set this object to the value of the 'other'.
3211 //
3212 // Note that since floating-point types may be NaN, and NaNs are
3213 // unordered (do not compare equal even to themselves) it is possible
3214 // that, after an assignment, a decimal will not compare equal to the
3215 // original; however it will behave as the original.
3216
3217 /// Add 1.0 to the value of this object and return a reference to it.
3218 ///
3219 /// \note Note that this is a floating-point value so this operation may not
3220 /// change the value of this object at all (if the value is large) or it
3221 /// may just set it to 1.0 (if the original value is small).
3223
3224 /// Add -1.0 to the value of this object and return a reference to it.
3225 ///
3226 /// \note Note that this is a floating-point value so this operation may not
3227 /// change the value of this object at all (if the value is large) or it
3228 /// may just set it to -1.0 (if the original value is small).
3230
3231 /// Add the value of the specified `rhs` object to the value of this as
3232 /// described by IEEE-754, store the result in this object, and return a
3233 /// reference to this object.
3234 ///
3235 /// * If either of this object or `rhs` is signaling NaN, then store
3236 /// the value of the macro `EDOM` into `errno` and set this object to
3237 /// a NaN.
3238 /// * Otherwise if either of this object or `rhs` is NaN then set this
3239 /// object to a NaN.
3240 /// * Otherwise if this object and `rhs` have infinity value of
3241 /// differing signs, store the value of the macro `EDOM` into `errno`
3242 /// and set this object to a NaN.
3243 /// * Otherwise if this object and `rhs` have infinite values of the
3244 /// same sign, then do not change this object.
3245 /// * Otherwise if `rhs` has a zero value (positive or negative), do
3246 /// not change this object.
3247 /// * Otherwise if the sum of this object and `rhs` has an absolute
3248 /// value that is larger than
3249 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3250 /// the macro `ERANGE` into `errno` and set this object to infinity
3251 /// with the same sign as that result.
3252 /// * Otherwise set this object to the sum of the number represented by
3253 /// `rhs` and the number represented by this object.
3254 ///
3255 ///
3256 /// \note Note that this is a floating-point value so this operations may not
3257 /// change the value of this object at all (if the value is large) or it
3258 /// may seem to update it to the value of the `other` (if the original
3259 /// value is small).
3263
3264 /// Add the specified `rhs` to the value of this object as described by
3265 /// IEEE-754, store the result in this object, and return a reference to
3266 /// this object.
3267 ///
3268 /// * If this object is signaling NaN, then store the value of the
3269 /// macro `EDOM` into `errno` and set this object to a NaN.
3270 /// * Otherwise if this object is NaN, then do not change this object.
3271 /// * Otherwise if this object is infinity, then do not change it.
3272 /// * Otherwise if the sum of this object and `rhs` has an absolute
3273 /// value that is larger than
3274 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3275 /// the macro `ERANGE` into `errno` and set this object to infinity
3276 /// with the same sign as that result.
3277 /// * Otherwise set this object to sum of adding `rhs` and the number
3278 /// represented by this object.
3279 ///
3280 ///
3281 /// \note Note that this is a floating-point value so this operations may not
3282 /// change the value of this object at all (if the value is large) or it
3283 /// may seem to update it to the value of the `other` (if the original
3284 /// value is small).
3285 Decimal_Type128& operator+=(int rhs);
3286 Decimal_Type128& operator+=(unsigned int rhs);
3287 Decimal_Type128& operator+=(long rhs);
3288 Decimal_Type128& operator+=(unsigned long rhs);
3289 Decimal_Type128& operator+=(long long rhs);
3290 Decimal_Type128& operator+=(unsigned long long rhs);
3291
3292 /// Subtract the value of the specified `rhs` from the value of this
3293 /// object as described by IEEE-754, store the result in this object,
3294 /// and return a reference to this object.
3295 ///
3296 /// * If this object is signaling NaN, then store the value of the
3297 /// macro `EDOM` into `errno` and set this object to a NaN.
3298 /// * Otherwise if either of this object or `rhs` is NaN then set this
3299 /// object to a NaN.
3300 /// * Otherwise if this object and `rhs` have infinity value of the
3301 /// same signs, store the value of the macro `EDOM` into `errno`
3302 /// and set this object to a NaN.
3303 /// * Otherwise if this object and the `rhs` have infinite values of
3304 /// differing signs, then do not change this object.
3305 /// * Otherwise if the `rhs` has a zero value (positive or negative),
3306 /// do not change this object.
3307 /// * Otherwise if subtracting the value of the `rhs` object from this
3308 /// results in an absolute value that is larger than
3309 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3310 /// the macro `ERANGE` into `errno` and set this object to infinity
3311 /// with the same sign as that result.
3312 /// * Otherwise set this object to the result of subtracting the value
3313 /// of `rhs` from the value of this object.
3314 ///
3315 ///
3316 /// \note Note that this is a floating-point value so this operations may not
3317 /// change the value of this object at all (if the value is large) or it
3318 /// may seem to update it to the value of the `other` (if the original
3319 /// value is small).
3323
3324 /// Subtract the specified `rhs` from the value of this object as
3325 /// described by IEEE-754, store the result in this object, and return a
3326 /// reference to this object.
3327 ///
3328 /// * If this object is signaling NaN, then store the value of the
3329 /// macro `EDOM` into `errno` and set this object to a NaN.
3330 /// * Otherwise if this object is NaN, then do not change this object.
3331 /// * Otherwise if this object is infinity, then do not change it.
3332 /// * Otherwise if subtracting `rhs` from this object's value results
3333 /// in an absolute value that is larger than
3334 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3335 /// the macro `ERANGE` into `errno` and set this object to infinity
3336 /// with the same sign as that result.
3337 /// * Otherwise set this object to the result of subtracting `rhs` from
3338 /// the value of this object.
3339 ///
3340 ///
3341 /// \note Note that this is a floating-point value so this operations may not
3342 /// change the value of this object at all (if the value is large) or it
3343 /// may seem to update it to the value of the `other` (if the original
3344 /// value is small).
3345 Decimal_Type128& operator-=(int rhs);
3346 Decimal_Type128& operator-=(unsigned int rhs);
3347 Decimal_Type128& operator-=(long rhs);
3348 Decimal_Type128& operator-=(unsigned long rhs);
3349 Decimal_Type128& operator-=(long long rhs);
3350 Decimal_Type128& operator-=(unsigned long long rhs);
3351
3352 /// Multiply the value of the specified `rhs` object by the value of
3353 /// this as described by IEEE-754, store the result in this object, and
3354 /// return a reference to this object.
3355 ///
3356 /// * If either of this object or `rhs` is signaling NaN, then store
3357 /// the value of the macro `EDOM` into `errno` and set this object to
3358 /// a NaN.
3359 /// * Otherwise if either of this object or `rhs` is NaN then set this
3360 /// object to a NaN.
3361 /// * Otherwise, if one of this object and `rhs` is zero (positive or
3362 /// negative) and the other is infinity (positive or negative), store
3363 /// the value of the macro `EDOM` into `errno` and set this object to
3364 /// a NaN.
3365 /// * Otherwise, if either this object or `rhs` is positive or negative
3366 /// infinity, set this object to infinity. The sign of this object
3367 /// will be positive if this object and `rhs` had the same sign, and
3368 /// negative otherwise.
3369 /// * Otherwise, if either this object or `rhs` is zero, set this
3370 /// object to zero. The sign of this object will be positive if this
3371 /// object and `rhs` had the same sign, and negative otherwise.
3372 /// * Otherwise if the product of this object and `rhs` has an absolute
3373 /// value that is larger than
3374 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3375 /// the macro `ERANGE` into `errno` and set this object to infinity
3376 /// with the same sign of that result.
3377 /// * Otherwise if the product of this object and `rhs` has an absolute
3378 /// value that is smaller than
3379 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3380 /// the macro `ERANGE` into `errno` and set this object to zero value
3381 /// with the same sign as that result.
3382 /// * Otherwise set this object to the product of the value of `rhs`
3383 /// and the value of this object.
3387
3388 /// Multiply the specified `rhs` by the value of this object as
3389 /// described by IEEE-754, store the result in this object, and return a
3390 /// reference to this object.
3391 ///
3392 /// * If this object is signaling NaN, then store the value of the
3393 /// macro `EDOM` into `errno` and set this object to a NaN.
3394 /// * Otherwise if this object is NaN, then do not change this object.
3395 /// * Otherwise if this object is infinity (positive or negative), and
3396 /// `rhs` is zero, then store the value of the macro `EDOM` into
3397 /// `errno` and set this object to a NaN.
3398 /// * Otherwise if this object is infinity (positive or negative), then
3399 /// do not change it.
3400 /// * Otherwise if `rhs` is zero, then set this object to zero with the
3401 /// same sign as its value had prior to this operation.
3402 /// * Otherwise if the product of `rhs` and the value of this object
3403 /// results in an absolute value that is larger than
3404 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3405 /// the macro `ERANGE` into `errno` and set this object to infinity
3406 /// with the same sign as that result.
3407 /// * Otherwise if the product of `rhs` and the value of this object
3408 /// results in an absolute value that is smaller than
3409 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3410 /// the macro `ERANGE` into `errno` and set this object to zero with
3411 /// the same sign as that result.
3412 /// * Otherwise set this object to the product of the value of this
3413 /// object and the value `rhs`.
3414 Decimal_Type128& operator*=(int rhs);
3415 Decimal_Type128& operator*=(unsigned int rhs);
3416 Decimal_Type128& operator*=(long rhs);
3417 Decimal_Type128& operator*=(unsigned long rhs);
3418 Decimal_Type128& operator*=(long long rhs);
3419 Decimal_Type128& operator*=(unsigned long long rhs);
3420
3421 /// Divide the value of this object by the value of the specified `rhs`
3422 /// as described by IEEE-754, store the result in this object, and
3423 /// return a reference to this object.
3424 ///
3425 /// * If either of this object or `rhs` is signaling NaN, then store
3426 /// the value of the macro `EDOM` into `errno` and set this object to
3427 /// a NaN.
3428 /// * Otherwise if either of this object or `rhs` is NaN then set this
3429 /// object to a NaN.
3430 /// * Otherwise if this object and `rhs` are both infinity (positive or
3431 /// negative) or both zero (positive or negative) then store the
3432 /// value of the macro `EDOM` into `errno` and return a NaN.
3433 /// * Otherwise if `rhs` has a positive zero value, then store the
3434 /// value of the macro `ERANGE` into `errno` and set this object to
3435 /// infinity with the same sign as its original value.
3436 /// * Otherwise if `rhs` has a negative zero value, then store the
3437 /// value of the macro `ERANGE` into `errno` and set this object to
3438 /// infinity with the opposite sign as its original value.
3439 /// * Otherwise if dividing the value of this object by the value of
3440 /// `rhs` results in an absolute value that is larger than
3441 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3442 /// the macro `ERANGE` into `errno` and return infinity with the same
3443 /// sign as that result.
3444 /// * Otherwise if dividing the value of this object by the value of
3445 /// `rhs` results in an absolute value that is smaller than
3446 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3447 /// the macro `ERANGE` into `errno`and return zero with the same sign
3448 /// as that result.
3449 /// * Otherwise set this object to the result of dividing the value of
3450 /// this object by the value of `rhs`.
3454
3455 /// Divide the value of this object by the specified `rhs` as described
3456 /// by IEEE-754, store the result in this object, and return a reference
3457 /// to this object.
3458 ///
3459 /// * If this object is signaling NaN, then store the value of the
3460 /// macro `EDOM` into `errno` and set this object to a NaN.
3461 /// * Otherwise if this object is NaN then set this object to a NaN.
3462 /// * Otherwise if this object is infinity (positive or negative) and
3463 /// `rhs` is positive value then set this object to infinity value
3464 /// with the same sign as its original value.
3465 /// * Otherwise if this object is infinity (positive or negative) and
3466 /// `rhs` is negative value then set this object to infinity value
3467 /// with the opposite sign as its original value.
3468 /// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
3469 /// into `errno` and set this object to infinity with the same sign
3470 /// it had prior to this operation.
3471 /// * Otherwise if dividing the value of this object by the value of
3472 /// `rhs` results in an absolute value that is larger than
3473 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3474 /// the macro `ERANGE` into `errno` and return infinity with the same
3475 /// sign as that result.
3476 /// * Otherwise if dividing the value of this object by the value of
3477 /// `rhs` results in an absolute value that is smaller than
3478 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3479 /// the macro `ERANGE` into `errno`and return zero with the same sign
3480 /// as that result.
3481 /// * Otherwise set this object to the result of dividing the value of
3482 /// this object by the value of `rhs`.
3483 Decimal_Type128& operator/=(int rhs);
3484 Decimal_Type128& operator/=(unsigned int rhs);
3485 Decimal_Type128& operator/=(long rhs);
3486 Decimal_Type128& operator/=(unsigned long rhs);
3487 Decimal_Type128& operator/=(long long rhs);
3488 Decimal_Type128& operator/=(unsigned long long rhs);
3489
3490 /// Return a modifiable pointer to the underlying implementation.
3492
3493 // Aspects
3494
3495 /// Assign to this object the value read from the specified input
3496 /// `stream` using the specified `version` format, and return a
3497 /// reference to `stream`. If `stream` is initially invalid, this
3498 /// operation has no effect. If `version` is not supported, this object
3499 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
3500 /// If `version` is supported but `stream` becomes invalid during this
3501 /// operation, this object has an undefined, but valid, state.
3502 ///
3503 /// \note Note that no version is read from `stream`. See the `bslx` package-level
3504 /// documentation for more information on BDEX streaming of
3505 /// value-semantic types and containers.
3506 template <class STREAM>
3507 STREAM& bdexStreamIn(STREAM& stream, int version);
3508
3509 // ACCESSORS
3510
3511 /// Return a non-modifiable pointer to the underlying implementation.
3512 const DecimalImpUtil::ValueType128 *data() const;
3513
3514 /// Return the value of the underlying implementation.
3516
3517 // Aspects
3518
3519 /// Write the value of this object, using the specified `version`
3520 /// format, to the specified output `stream`, and return a reference to
3521 /// `stream`. If `stream` is initially invalid, this operation has no
3522 /// effect. If `version` is not supported, `stream` is invalidated, but otherwise unmodified.
3523 ///
3524 /// \note Note that `version` is not written to
3525 /// `stream`. See the `bslx` package-level documentation for more
3526 /// information on BDEX streaming of value-semantic types and
3527 /// containers.
3528 template <class STREAM>
3529 STREAM& bdexStreamOut(STREAM& stream, int version) const;
3530};
3531
3532// FREE OPERATORS
3533
3534/// Return a copy of the specified `value` if the value is not negative
3535/// zero, and return positive zero otherwise.
3537
3538/// Return the result of applying the unary - operator to the specified `value` as described by IEEE-754.
3539///
3540/// \note Note that floating-point numbers have
3541/// signed zero, therefore this operation is not the same as `0-value`.
3543
3544/// Apply the prefix ++ operator to the specified `value` and return its original value.
3545///
3546/// \note Note that this is a floating-point value so this
3547/// operations may not change the value of this object at all (if the value
3548/// is large) or it may just set it to 1.0 (if the original value is small).
3550
3551/// Apply the prefix -- operator to the specified `value` and return its original value.
3552///
3553/// \note Note that this is a floating-point value so this
3554/// operations may not change the value of this object at all (if the value
3555/// is large) or it may just set it to -1.0 (if the original value is
3556/// small).
3558
3559/// Add the value of the specified `rhs` to the value of the specified `lhs`
3560/// as described by IEEE-754 and return the result.
3561///
3562/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3563/// the macro `EDOM` into `errno` and return a NaN.
3564/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3565/// * Otherwise if `lhs` and `rhs` are infinities of differing signs, store
3566/// the value of the macro `EDOM` into `errno` and return a NaN.
3567/// * Otherwise if `lhs` and `rhs` are infinities of the same sign then
3568/// return infinity of that sign.
3569/// * Otherwise if `rhs` is zero (positive or negative), return `lhs`.
3570/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
3571/// larger than `std::numeric_limits<Decimal128>::max()` then store the
3572/// value of the macro `ERANGE` into `errno` and set this object to
3573/// infinity with the same sign as that result.
3574/// * Otherwise return the sum of the number represented by `lhs` and the
3575/// number represented by `rhs`.
3581
3582/// Add the specified `rhs` to the value of the specified `lhs` as described
3583/// by IEEE-754 and return the result.
3584///
3585/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3586/// into `errno` and return a NaN.
3587/// * Otherwise if `lhs` object is NaN, then return a NaN.
3588/// * Otherwise if `lhs` is infinity, then return infinity.
3589/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
3590/// larger than `std::numeric_limits<Decimal128>::max()` then store the
3591/// value of the macro `ERANGE` into `errno` and return infinity with the
3592/// same sign as that result.
3593/// * Otherwise return the sum of `rhs` and the number represented by
3594/// `lhs`.
3596Decimal128 operator+(Decimal128 lhs, unsigned int rhs);
3598Decimal128 operator+(Decimal128 lhs, unsigned long rhs);
3599Decimal128 operator+(Decimal128 lhs, long long rhs);
3600Decimal128 operator+(Decimal128 lhs, unsigned long long rhs);
3601
3602/// Add the specified `lhs` to the value of the specified `rhs` as described
3603/// by IEEE-754 and return the result.
3604///
3605/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3606/// into `errno` and return a NaN.
3607/// * Otherwise if `rhs` object is NaN, then return a NaN.
3608/// * Otherwise if `rhs` is infinity, then return infinity.
3609/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
3610/// larger than `std::numeric_limits<Decimal128>::max()` then store the
3611/// value of the macro `ERANGE` into `errno` and return infinity with the
3612/// same sign as that result.
3613/// * Otherwise return the sum of `lhs` and the number represented by
3614/// `rhs`.
3616Decimal128 operator+(unsigned int lhs, Decimal128 rhs);
3618Decimal128 operator+(unsigned long lhs, Decimal128 rhs);
3619Decimal128 operator+(long long lhs, Decimal128 rhs);
3620Decimal128 operator+(unsigned long long lhs, Decimal128 rhs);
3621
3622/// Subtract the value of the specified `rhs` from the value of the
3623/// specified `lhs` as described by IEEE-754 and return the result.
3624///
3625/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3626/// the macro `EDOM` into `errno` and return a NaN.
3627/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3628/// * Otherwise if `lhs` and the `rhs` have infinity values of the same
3629/// sign, store the value of the macro `EDOM` into `errno` and return a
3630/// NaN.
3631/// * Otherwise if `lhs` and the `rhs` have infinity values of differing
3632/// signs, then return `lhs`.
3633/// * Otherwise if the subtracting of `lhs` and `rhs` has an absolute value
3634/// that is larger than `std::numeric_limits<Decimal128>::max()` then
3635/// store the value of the macro `ERANGE` into `errno` and return
3636/// infinity with the same sign as that result.
3637/// * Otherwise return the result of subtracting the value of `rhs`from the
3638/// value of `lhs`.
3644
3645/// Subtract the specified `rhs` from the value of the specified `lhs` as
3646/// described by IEEE-754 and return a reference to this object.
3647///
3648/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3649/// into `errno` and return a NaN.
3650/// * Otherwise if `lhs` is NaN, then return a NaN.
3651/// * Otherwise if `lhs` is infinity, then return infinity.
3652/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
3653/// an absolute value that is larger than
3654/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3655/// macro `ERANGE` into `errno` and return infinity with the same sign as
3656/// that result.
3657/// * Otherwise return the result of subtracting `rhs` from the value of
3658/// `lhs`.
3660Decimal128 operator-(Decimal128 lhs, unsigned int rhs);
3662Decimal128 operator-(Decimal128 lhs, unsigned long rhs);
3663Decimal128 operator-(Decimal128 lhs, long long rhs);
3664Decimal128 operator-(Decimal128 lhs, unsigned long long rhs);
3665
3666/// Subtract the specified `rhs` from the value of the specified `lhs` as
3667/// described by IEEE-754 and return a reference to this object.
3668///
3669/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3670/// into `errno` and return a NaN.
3671/// * Otherwise if `rhs` is NaN, then return a NaN.
3672/// * Otherwise if `rhs` is infinity, then return infinity.
3673/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
3674/// an absolute value that is larger than
3675/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3676/// macro `ERANGE` into `errno` and return infinity with the same sign as
3677/// that result.
3678/// * Otherwise return the result of subtracting the value of `rhs` from
3679/// the number `lhs`.
3681Decimal128 operator-(unsigned int lhs, Decimal128 rhs);
3683Decimal128 operator-(unsigned long lhs, Decimal128 rhs);
3684Decimal128 operator-(long long lhs, Decimal128 rhs);
3685Decimal128 operator-(unsigned long long lhs, Decimal128 rhs);
3686
3687/// Multiply the value of the specified `lhs` object by the value of the
3688/// specified `rhs` as described by IEEE-754 and return the result.
3689///
3690/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3691/// the macro `EDOM` into `errno` and return a NaN.
3692/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3693/// * Otherwise if one of the operands is infinity (positive or negative)
3694/// and the other is zero (positive or negative), then store the value of
3695/// the macro `EDOM` into `errno` and return a NaN.
3696/// * Otherwise if both `lhs` and `rhs` are infinity (positive or
3697/// negative), return infinity. The sign of the returned value will be
3698/// positive if `lhs` and `rhs` have the same sign, and negative
3699/// otherwise.
3700/// * Otherwise, if either `lhs` or `rhs` is zero, return zero. The sign
3701/// of the returned value will be positive if `lhs` and `rhs` have the
3702/// same sign, and negative otherwise.
3703/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
3704/// that is larger than `std::numeric_limits<Decimal128>::max()` then
3705/// store the value of the macro `ERANGE` into `errno` and return an
3706/// infinity with the same sign as that result.
3707/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
3708/// that is smaller than `std::numeric_limits<Decimal128>::min()` then
3709/// store the value of the macro `ERANGE` into `errno` and return zero
3710/// with the same sign as that result.
3711/// * Otherwise return the product of the value of `rhs` and the number
3712/// represented by `rhs`.
3718
3719/// Multiply the specified `rhs` by the value of the specified `lhs` as
3720/// described by IEEE-754, and return the result.
3721///
3722/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3723/// into `errno` and return a NaN.
3724/// * Otherwise if `lhs` is NaN, then return a NaN.
3725/// * Otherwise if `lhs` is infinity (positive or negative), and `rhs` is
3726/// zero, then store the value of the macro `EDOM` into'errno' and return
3727/// a NaN.
3728/// * Otherwise if `lhs` is infinity (positive or negative), then return
3729/// `lhs`.
3730/// * Otherwise if `rhs` is zero, then return zero with the sign of `lhs`.
3731/// * Otherwise if the product of `rhs` and the value of `lhs` results in
3732/// an absolute value that is larger than
3733/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3734/// macro `ERANGE` into `errno` and return infinity with the same sign as
3735/// that result.
3736/// * Otherwise if the product of `rhs` and the value of `lhs` results in
3737/// an absolute value that is smaller than
3738/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3739/// macro `ERANGE` into `errno` and return zero with the same sign as
3740/// that result.
3741/// * Otherwise return the product of the value of `lhs` and value `rhs`.
3743Decimal128 operator*(Decimal128 lhs, unsigned int rhs);
3745Decimal128 operator*(Decimal128 lhs, unsigned long rhs);
3746Decimal128 operator*(Decimal128 lhs, long long rhs);
3747Decimal128 operator*(Decimal128 lhs, unsigned long long rhs);
3748
3749/// Multiply the specified `lhs` by the value of the specified `rhs` as
3750/// described by IEEE-754, and return the result.
3751///
3752/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3753/// into `errno` and return a NaN.
3754/// * Otherwise if `rhs` is NaN, then return a NaN.
3755/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
3756/// zero, then store the value of the macro `EDOM` into'errno' and return
3757/// a NaN.
3758/// * Otherwise if `rhs` is infinity (positive or negative), then return
3759/// `rhs`.
3760/// * Otherwise if `lhs` is zero, then return zero with the sign of `rhs`.
3761/// * Otherwise if the product of `lhs` and the value of `rhs` results in
3762/// an absolute value that is larger than
3763/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3764/// macro `ERANGE` into `errno` and return infinity with the same sign as
3765/// that result.
3766/// * Otherwise if the product of `lhs` and the value of `rhs` results in
3767/// an absolute value that is smaller than
3768/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3769/// macro `ERANGE` into `errno` and return zero with the same sign as
3770/// that result.
3771/// * Otherwise return the product of the value of `lhs` and value `rhs`.
3773Decimal128 operator*(unsigned int lhs, Decimal128 rhs);
3775Decimal128 operator*(unsigned long lhs, Decimal128 rhs);
3776Decimal128 operator*(long long lhs, Decimal128 rhs);
3777Decimal128 operator*(unsigned long long lhs, Decimal128 rhs);
3778
3779/// Divide the value of the specified `lhs` by the value of the specified
3780/// `rhs` as described by IEEE-754, and return the result.
3781///
3782/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3783/// the macro `EDOM` into `errno` and return a NaN.
3784/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3785/// * Otherwise if `lhs` and `rhs` are both infinity (positive or negative)
3786/// or both zero (positive or negative) then store the value of the macro
3787/// `EDOM` into `errno` and return a NaN.
3788/// * Otherwise if `lhs` has a normal value and `rhs` has a positive zero
3789/// value, store the value of the macro `ERANGE` into `errno` and return
3790/// infinity with the sign of `lhs`.
3791/// * Otherwise if `lhs` has a normal value and `rhs` has a negative zero
3792/// value, store the value of the macro `ERANGE` into `errno` and return
3793/// infinity with the opposite sign as `lhs`.
3794/// * Otherwise if `lhs` has infinity value and `rhs` has a positive zero
3795/// value, return infinity with the sign of `lhs`.
3796/// * Otherwise if `lhs` has infinity value and `rhs` has a negative zero
3797/// value, return infinity with the opposite sign as `lhs`.
3798/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3799/// results in an absolute value that is larger than
3800/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3801/// macro `ERANGE` into `errno` and return infinity with the same sign as
3802/// that result.
3803/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3804/// results in an absolute value that is smaller than
3805/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3806/// macro `ERANGE` into `errno` and return zero with the same sign as
3807/// that result.
3808/// * Otherwise return the result of dividing the value of `lhs` by the
3809/// value of `rhs`.
3815
3816/// Divide the value of the specified `lhs` by the specified `rhs` as
3817/// described by IEEE-754, and return the result.
3818///
3819/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3820/// into `errno` and return a NaN.
3821/// * Otherwise if `lhs` is NaN then return a NaN.
3822/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
3823/// positive value then return infinity value with the same sign as its
3824/// original value.
3825/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
3826/// negative value then return infinity value with the opposite sign as
3827/// its original value.
3828/// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
3829/// into `errno` and return infinity with the same sign it had prior to
3830/// this operation.
3831/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3832/// results in an absolute value that is larger than
3833/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3834/// macro `ERANGE` into `errno` and return infinity with the same sign as
3835/// that result.
3836/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3837/// results in an absolute value that is smaller than
3838/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3839/// macro `ERANGE` into `errno` and return zero with the same sign as
3840/// that result.
3841/// * Otherwise return the result of dividing the value of `lhs` by the
3842/// value of `rhs`.
3844Decimal128 operator/(Decimal128 lhs, unsigned int rhs);
3846Decimal128 operator/(Decimal128 lhs, unsigned long rhs);
3847Decimal128 operator/(Decimal128 lhs, long long rhs);
3848Decimal128 operator/(Decimal128 lhs, unsigned long long rhs);
3849
3850/// Divide the specified `lhs` by the value of the specified `rhs` as
3851/// described by IEEE-754, and return the result.
3852///
3853/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3854/// into `errno` and return a NaN.
3855/// * Otherwise if `rhs` is NaN then return a NaN.
3856/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
3857/// zero, store the value of the macro `ERANGE` into `errno` and return a
3858/// NaN.
3859/// * Otherwise if `rhs` is zero (positive or negative), store the value of
3860/// the macro `ERANGE` into `errno` and return infinity with the sign of
3861/// `lhs`.
3862/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3863/// results in an absolute value that is larger than
3864/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3865/// macro `ERANGE` into `errno` and return infinity with the same sign as
3866/// that result.
3867/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3868/// results in an absolute value that is smaller than
3869/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3870/// macro `ERANGE` into `errno` and return zero with the same sign as
3871/// that result.
3872/// * Otherwise return the result of dividing the value of `lhs` by the value of `rhs`.
3873///
3874/// \note Note that this is a floating-point operation, not
3875/// integer.
3877Decimal128 operator/(unsigned int lhs, Decimal128 rhs);
3879Decimal128 operator/(unsigned long lhs, Decimal128 rhs);
3880Decimal128 operator/(long long lhs, Decimal128 rhs);
3881Decimal128 operator/(unsigned long long lhs, Decimal128 rhs);
3882
3883/// Return `true` if the specified `lhs` and `rhs` have the same value, and
3884/// `false` otherwise. Two `Decimal128` objects have the same value if the
3885/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
3886/// comparison) considers the underlying IEEE representations equal. In
3887/// other words, two `Decimal128` objects have the same value if:
3888///
3889/// * both have a zero value (positive or negative), or
3890/// * both have the same infinity value (both positive or negative), or
3891/// * both have the value of a real number that are equal, even if they are
3892/// represented differently (cohorts have the same value)
3893///
3894/// This operation stores the value of the macro `EDOM` into `errno` if
3895/// either or both operands are signaling NaN.
3896///
3897///
3898/// \note Note that a NaN is never equal to anything, including itself:
3899/// @code
3900/// Decimal128 aNaN = std::numeric_limits<Decimal128>::quiet_NaN();
3901/// assert(!(aNan == aNan));
3902/// @endcode
3903bool operator==(Decimal128 lhs, Decimal128 rhs);
3904
3905/// Return `true` if the specified `lhs` and `rhs` have the same value, and
3906/// `false` otherwise. Two decimal objects have the same value if the
3907/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
3908/// comparison) considers the underlying IEEE representations equal. In
3909/// other words, two decimal objects have the same value if:
3910///
3911/// * both have a zero value (positive or negative), or
3912/// * both have the same infinity value (both positive or negative), or
3913/// * both have the value of a real number that are equal, even if they are
3914/// represented differently (cohorts have the same value)
3915///
3916/// This operation stores the value of the macro `EDOM` into `errno` if
3917/// either or both operands are signaling NaN.
3918bool operator==(Decimal32 lhs, Decimal128 rhs);
3919bool operator==(Decimal128 lhs, Decimal32 rhs);
3920bool operator==(Decimal64 lhs, Decimal128 rhs);
3921bool operator==(Decimal128 lhs, Decimal64 rhs);
3922
3923/// Return `true` if the specified `lhs` and `rhs` do not have the same
3924/// value, and `false` otherwise. Two `Decimal128` objects do not have the
3925/// same value if the `compareQuietEqual` operation (IEEE-754 defined,
3926/// non-total ordering comparison) considers the underlying IEEE
3927/// representations not equal. In other words, two `Decimal128` objects do
3928/// not have the same value if:
3929///
3930/// * both are a NaN, or
3931/// * one has zero value (positive or negative) and the other does not, or
3932/// * one has the value of positive infinity and the other does not, or
3933/// * one has the value of negative infinity and the other does not, or
3934/// * both have the value of a real number that are not equal, regardless
3935/// of their representation (cohorts are equal)
3936///
3937/// This operation stores the value of the macro `EDOM` into `errno` if
3938/// either or both operands are signaling NaN.
3939///
3940///
3941/// \note Note that a NaN is never equal to anything, including itself:
3942/// @code
3943/// Decimal128 aNaN = std::numeric_limits<Decimal128>::quiet_NaN();
3944/// assert(aNan != aNan);
3945/// @endcode
3946bool operator!=(Decimal128 lhs, Decimal128 rhs);
3947
3948/// Return `true` if the specified `lhs` and `rhs` do not have the same
3949/// value, and `false` otherwise. Two decimal objects do not have the same
3950/// value if the `compareQuietEqual` operation (IEEE-754 defined, non-total
3951/// ordering comparison) considers the underlying IEEE representations not
3952/// equal. In other words, two decimal objects do not have the same value
3953/// if:
3954///
3955/// * both are NaN, or
3956/// * one has zero value (positive or negative) and the other does not, or
3957/// * one has the value of positive infinity and the other does not, or
3958/// * one has the value of negative infinity and the other does not, or
3959/// * both have the value of a real number that are not equal, regardless
3960/// of their representation (cohorts are equal)
3961///
3962/// This operation stores the value of the macro `EDOM` into `errno` if
3963/// either or both operands are signaling NaN.
3964bool operator!=(Decimal32 lhs, Decimal128 rhs);
3965bool operator!=(Decimal128 lhs, Decimal32 rhs);
3966bool operator!=(Decimal64 lhs, Decimal128 rhs);
3967bool operator!=(Decimal128 lhs, Decimal64 rhs);
3968
3969/// Return `true` if the specified `lhs` has a value less than the specified
3970/// `rhs` and `false` otherwise. The value of a `Decimal128` object `lhs`
3971/// is less than that of an object `rhs` if the `compareQuietLess` operation
3972/// (IEEE-754 defined, non-total ordering comparison) considers the
3973/// underlying IEEE representation of `lhs` to be less than of that of
3974/// `rhs`. In other words, `lhs` is less than `rhs` if:
3975///
3976/// * neither `lhs` nor `rhs` are NaN, or
3977/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
3978/// * `rhs` is zero (positive or negative) and `lhs` negative, or
3979/// * `lhs` is not positive infinity, or
3980/// * `lhs` is negative infinity and `rhs` is not, or
3981/// * `lhs` and `rhs` both represent a real number and the real number of
3982/// `lhs` is less than that of `rhs`
3983///
3984/// This operation stores the value of the macro `EDOM` into `errno` if
3985/// either or both operands are signaling NaN.
3986bool operator<(Decimal128 lhs, Decimal128 rhs);
3987
3988/// Return `true` if the specified `lhs` has a value less than the specified
3989/// `rhs` and `false` otherwise. The value of a decimal object `lhs` is
3990/// less than that of an object `rhs` if the `compareQuietLess` operation
3991/// (IEEE-754 defined, non-total ordering comparison) considers the
3992/// underlying IEEE representation of `lhs` to be less than of that of
3993/// `rhs`. In other words, `lhs` is less than `rhs` if:
3994///
3995/// * neither `lhs` nor `rhs` are NaN, or
3996/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
3997/// * `rhs` is zero (positive or negative) and `lhs` negative, or
3998/// * `lhs` is not positive infinity, or
3999/// * `lhs` is negative infinity and `rhs` is not, or
4000/// * `lhs` and `rhs` both represent a real number and the real number of
4001/// `lhs`is less than that of `rhs`
4002///
4003/// This operation stores the value of the macro `EDOM` into `errno` if
4004/// either or both operands are signaling NaN.
4005bool operator<(Decimal32 lhs, Decimal128 rhs);
4006bool operator<(Decimal128 lhs, Decimal32 rhs);
4007bool operator<(Decimal64 lhs, Decimal128 rhs);
4008bool operator<(Decimal128 lhs, Decimal64 rhs);
4009
4010/// Return `true` if the specified `lhs` has a value less than or equal the
4011/// value of the specified `rhs` and `false` otherwise. The value of a
4012/// `Decimal128` object `lhs` is less than or equal to the value of an
4013/// object `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
4014/// non-total ordering comparison) considers the underlying IEEE
4015/// representation of `lhs` to be less or equal to that of `rhs`. In other
4016/// words, `lhs` is less or equal than `rhs` if:
4017///
4018/// * neither `lhs` nor `rhs` are NaN, or
4019/// * `lhs` and `rhs` are both zero (positive or negative), or
4020/// * both `lhs` and `rhs` are positive infinity, or
4021/// * `lhs` is negative infinity, or
4022/// * `lhs` and `rhs` both represent a real number and the real number of
4023/// `lhs` is less or equal to that of `rhs`
4024///
4025/// This operation stores the value of the macro `EDOM` into `errno` if
4026/// either or both operands are signaling NaN.
4027bool operator<=(Decimal128 lhs, Decimal128 rhs);
4028
4029/// Return `true` if the specified `lhs` has a value less than or equal the
4030/// value of the specified `rhs` and `false` otherwise. The value of a
4031/// decimal object `lhs` is less than or equal to the value of an object
4032/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
4033/// non-total ordering comparison) considers the underlying IEEE
4034/// representation of `lhs` to be less or equal to that of `rhs`. In other
4035/// words, `lhs` is less or equal than `rhs` if:
4036///
4037/// * neither `lhs` nor `rhs` are NaN, or
4038/// * `lhs` and `rhs` are both zero (positive or negative), or
4039/// * both `lhs` and `rhs` are positive infinity, or
4040/// * `lhs` is negative infinity, or
4041/// * `lhs` and `rhs` both represent a real number and the real number of
4042/// `lhs` is less or equal to that of `rhs`
4043///
4044/// This operation stores the value of the macro `EDOM` into `errno` if
4045/// either or both operands are signaling NaN.
4046bool operator<=(Decimal32 lhs, Decimal128 rhs);
4047bool operator<=(Decimal128 lhs, Decimal32 rhs);
4048bool operator<=(Decimal64 lhs, Decimal128 rhs);
4049bool operator<=(Decimal128 lhs, Decimal64 rhs);
4050
4051/// Return `true` if the specified `lhs` has a greater value than the
4052/// specified `rhs` and `false` otherwise. The value of a `Decimal128`
4053/// object `lhs` is greater than that of an object `rhs` if the
4054/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
4055/// comparison) considers the underlying IEEE representation of `lhs` to be
4056/// greater than of that of `rhs`. In other words, `lhs` is greater than
4057/// `rhs` if:
4058///
4059/// * neither `lhs` nor `rhs` are NaN, or
4060/// * `rhs` is zero (positive or negative) and `lhs` positive, or
4061/// * `lhs` is zero (positive or negative) and `rhs` negative, or
4062/// * `lhs` is not negative infinity, or
4063/// * `lhs` is positive infinity and `rhs` is not, or
4064/// * `lhs` and `rhs` both represent a real number and the real number of
4065/// `lhs` is greater than that of `rhs`
4066///
4067/// This operation stores the value of the macro `EDOM` into `errno` if
4068/// either or both operands are signaling NaN.
4069bool operator>(Decimal128 lhs, Decimal128 rhs);
4070
4071/// Return `true` if the specified `lhs` has a greater value than the
4072/// specified `rhs` and `false` otherwise. The value of a decimal object
4073/// `lhs` is greater than that of an object `rhs` if the
4074/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
4075/// comparison) considers the underlying IEEE representation of `lhs` to be
4076/// greater than of that of `rhs`. In other words, `lhs` is greater than
4077/// `rhs` if:
4078///
4079/// * neither `lhs` nor `rhs` are NaN, or
4080/// * `rhs` is zero (positive or negative) and `lhs` positive, or
4081/// * `lhs` is zero (positive or negative) and `rhs` negative, or
4082/// * `lhs` is not negative infinity, or
4083/// * `lhs` is positive infinity and `rhs` is not, or
4084/// * `lhs` and `rhs` both represent a real number and the real number of
4085/// `lhs` is greater than that of `rhs`
4086///
4087/// This operation stores the value of the macro `EDOM` into `errno` if
4088/// either or both operands are signaling NaN.
4089bool operator>(Decimal32 lhs, Decimal128 rhs);
4090bool operator>(Decimal128 lhs, Decimal32 rhs);
4091bool operator>(Decimal64 lhs, Decimal128 rhs);
4092bool operator>(Decimal128 lhs, Decimal64 rhs);
4093
4094/// Return `true` if the specified `lhs` has a value greater than or equal
4095/// to the value of the specified `rhs` and `false` otherwise. The value of
4096/// a `Decimal128` object `lhs` is greater or equal to a `Decimal128` object
4097/// `rhs` if the `compareQuietGreaterEqual` operation (IEEE-754 defined,
4098/// non-total ordering comparison ) considers the underlying IEEE
4099/// representation of `lhs` to be greater or equal to that of `rhs`. In
4100/// other words, `lhs` is greater than or equal to `rhs` if:
4101///
4102/// * neither `lhs` nor `rhs` are NaN, or
4103/// * `lhs` and `rhs` are both zero (positive or negative), or
4104/// * both `lhs` and `rhs` are negative infinity, or
4105/// * `lhs` is positive infinity, or
4106/// * `lhs` and `rhs` both represent a real number and the real number of
4107/// `lhs` is greater or equal to that of `rhs`
4108///
4109/// This operation stores the value of the macro `EDOM` into `errno` if
4110/// either or both operands are signaling NaN.
4111bool operator>=(Decimal128 lhs, Decimal128 rhs);
4112
4113/// Return `true` if the specified `lhs` has a value greater than or equal
4114/// to the value of the specified `rhs` and `false` otherwise. The value of
4115/// a decimal object `lhs` is greater or equal to a decimal object `rhs` if
4116/// the `compareQuietGreaterEqual` operation (IEEE-754 defined, non-total
4117/// ordering comparison ) considers the underlying IEEE representation of
4118/// `lhs` to be greater or equal to that of `rhs`. In other words, `lhs` is
4119/// greater than or equal to `rhs` if:
4120///
4121/// * neither `lhs` nor `rhs` are NaN, or
4122/// * `lhs` and `rhs` are both zero (positive or negative), or
4123/// * both `lhs` and `rhs` are negative infinity, or
4124/// * `lhs` is positive infinity, or
4125/// * `lhs` and `rhs` both represent a real number and the real number of
4126/// `lhs` is greater or equal to that of `rhs`
4127///
4128/// This operation stores the value of the macro `EDOM` into `errno` if
4129/// either or both operands are signaling NaN.
4130bool operator>=(Decimal32 lhs, Decimal128 rhs);
4131bool operator>=(Decimal128 lhs, Decimal32 rhs);
4132bool operator>=(Decimal64 lhs, Decimal128 rhs);
4133bool operator>=(Decimal128 lhs, Decimal64 rhs);
4134
4135/// Read, into the specified `object`, from the specified input `stream` an
4136/// IEEE 128 bit decimal floating-point value as described in the IEEE-754
4137/// 2008 standard (5.12 Details of conversions between floating point
4138/// numbers and external character sequences) and return a reference
4139/// providing modifiable access to `stream`. If `stream` contains a Nan
4140/// value, it is unspecified if `object` will receive a quiet or signaling
4141/// `Nan`. If `stream` is not valid on entry `stream.good() == false`, this
4142/// operation has no effect other than setting `stream.fail()` to `true`.
4143/// If eof (end-of-file) is found before any non-whitespace characters
4144/// `stream.fail()` is set to `true` and `object` remains unchanged. If eof
4145/// is detected after some characters have been read (and successfully
4146/// interpreted as part of the textual representation of a floating-point
4147/// value as specified by IEEE-754) then `stream.eof()` is set to true. If
4148/// the first non-whitespace character sequence is not a valid textual
4149/// representation of a floating-point value (e.g., 12e or e12 or 1*2) the
4150/// `stream.fail()` is set to true and `object` will remain unchanged. If a
4151/// real number value is represented by the character sequence but it is a
4152/// large positive or negative value that cannot be stored into `object`
4153/// then store the value of the macro `ERANGE` into `errno` and positive or
4154/// negative infinity is stored into `object`, respectively. If a real
4155/// number value is represented by the character sequence but it is a small
4156/// positive or negative value that cannot be stored into `object` then
4157/// store the value of the macro `ERANGE` into `errno` and positive or
4158/// negative zero is stored into `object`, respectively. If a real number
4159/// value is represented by the character sequence but it cannot be stored
4160/// exactly into `object`, the value is rounded according to the current
4161/// rounding direction (of the environment) and then stored into `object`.
4162///
4163/// NOTE: This method does not yet fully support iostream flags or the
4164/// decimal floating point exception context.
4165template <class CHARTYPE, class TRAITS>
4166bsl::basic_istream<CHARTYPE, TRAITS>&
4167operator>> (bsl::basic_istream<CHARTYPE, TRAITS>& stream, Decimal128& object);
4168
4169/// Write the value of the specified `object` to the specified output
4170/// `stream` in a single line format as described in the IEEE-754 2008
4171/// standard (5.12 Details of conversions between floating point numbers and
4172/// external character sequences), and return a reference providing
4173/// modifiable access to `stream`. If `stream` is not valid on entry, this
4174/// operation has no effect.
4175///
4176/// NOTE: This method does not yet fully support iostream flags or the
4177/// decimal floating point exception context.
4178template <class CHARTYPE, class TRAITS>
4179bsl::basic_ostream<CHARTYPE, TRAITS>&
4180operator<< (bsl::basic_ostream<CHARTYPE, TRAITS>& stream, Decimal128 object);
4181
4182#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
4183 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
4184inline namespace literals {
4185inline namespace DecimalLiterals {
4186/// Produce an object of the indicated return type by parsing the specified
4187/// `str` having the specified `len` excluding the terminating null
4188/// character that represents a floating-point number written in both fixed
4189/// and scientific notations. These user-defined literal suffixes can be
4190/// applied to both numeric and string literals, (i.e., 1.2_d128, "1.2"_d128
4191/// or "inf"_d128). The resulting decimal object is initialized as follows:
4192///
4193/// * If `str` does not represent a floating-point value, then return a
4194/// decimal object of the indicated return type initialized to a NaN.
4195/// * Otherwise if `str` represents infinity (positive or negative), then
4196/// return a decimal object of the indicated return type initialized to
4197/// infinity value with the same sign.
4198/// * Otherwise if `str` represents zero (positive or negative), then
4199/// return a decimal object of the indicated return type initialized to
4200/// zero with the same sign.
4201/// * Otherwise if `str` represents a value that has an absolute value that
4202/// is larger than the maximum value supported by the indicated return
4203/// type, then store the value of the macro `ERANGE` into `errno` and
4204/// return a decimal object of the return type initialized to infinity
4205/// with the same sign.
4206/// * Otherwise if `str` represents a value that has an absolute value that
4207/// is smaller than min value of the indicated return type, then store
4208/// the value of the macro `ERANGE` into `errno` and return a decimal
4209/// object of the return type initialized to zero with the same sign.
4210/// * Otherwise if `str` has a value that is not exactly representable
4211/// using the maximum digit number supported by the indicated return
4212/// type, then return a decimal object of the return type initialized to
4213/// the value represented by `str` rounded according to the rounding
4214/// direction.
4215/// * Otherwise return a decimal object of the indicated return type
4216/// initialized to the decimal value representation of `str`.
4217///
4218///
4219/// \note Note that the parsing follows the rules as specified for the `strtod128`
4220/// function in section 9.6 of the ISO/EIC TR 247128 C Decimal
4221/// Floating-Point Technical Report.
4222///
4223/// Also note that the numeric literal version omits the optional leading
4224/// sign in `str`. For example, if the string is -1.2_d128 then the string
4225/// "1.2" is passed to the one-argument form, not "-1.2", because leading
4226/// signs are operators, not parts of literals. On the other hand, the
4227/// string literal version does not omit leading sign and if the string is
4228/// "-1.2"_d128 then the string "-1.2" is passed to the two-argument form.
4229///
4230/// Also note that the quantum of the resultant value is affected by the
4231/// number of decimal places in `str` string in both numeric and string
4232/// literal formats starting with the most significand digit and cannot
4233/// exceed the maximum number of digits necessary to differentiate all
4234/// values of the indicated return type, for example:
4235///
4236/// `0.015_d128; => 15e-3`
4237/// `1.5_d128; => 15e-1`
4238/// `1.500_d128; => 1500e-3`
4239/// '1.2345678901234567890123456789012349_d128;
4240/// => 1234567890123456789012345678901235e-33'
4241bdldfp::Decimal128 operator""_d128(const char *str);
4242bdldfp::Decimal128 operator""_d128(const char *str, bsl::size_t len);
4243
4244} // close DecimalLiterals namespace
4245} // close literals namespace
4246#endif
4247
4248// FREE FUNCTIONS
4249
4250/// Pass the specified `object` to the specified `hashAlg`. This function
4251/// integrates with the `bslh` modular hashing system and effectively provides a `bsl::hash` specialization for `Decimal128`.
4252///
4253/// \note Note that two
4254/// objects which have the same value but different representations will
4255/// hash to the same value.
4256template <class HASHALG>
4257void hashAppend(HASHALG& hashAlg, const Decimal128& object);
4258
4259 // MISCELLANEOUS RELATED TYPES
4260
4261 // ===================
4262 // class DecimalNumGet
4263 // ===================
4264
4265/// A facet type (mechanism) used in reading decimal floating-point types.
4266///
4267/// \note Note that this type does not follow BDE conventions because its content
4268/// is dictated by the C++ standard and native standard library
4269/// implementations. See ISO/IEC TR 24733 3.10.2 for details.
4270///
4271/// See @ref bdldfp_decimal
4272template <class CHARTYPE,
4273 class INPUTITERATOR = bsl::istreambuf_iterator<CHARTYPE> >
4274class DecimalNumGet : public bsl::locale::facet {
4275
4276#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
4277 private:
4278 // ACCESSORS
4279 bsl::locale::id& __get_id() const;
4280 // The function __get_id() is a pure virtual function in the Rogue
4281 // Wave implementation of locales. It is in violation with the
4282 // standard. We have to define it as a workaround.
4283#endif
4284
4285 public:
4286 // -dk:TODO make private while making the output operator a friend
4287
4288 // CLASS METHODS
4290 // TBD
4291
4292 public:
4293 // PUBLIC TYPES
4294 static bsl::locale::id id; // The locale identifier
4295
4296 typedef CHARTYPE char_type;
4297 typedef INPUTITERATOR iter_type;
4298
4299 // CREATORS
4300
4301 /// Constructs a `DecimalNumGet` object. Optionally specify starting
4302 /// reference count `refs`, which will default to 0. If `refs` is
4303 /// non-zero, the `DecimalNumGet` object will not be deleted when the
4304 /// last locale referencing it goes out of scope.
4305 explicit DecimalNumGet(bsl::size_t refs = 0);
4306
4307 // ACCESSORS
4308
4309 /// Forward to, and return using the specified `begin`, `end`, `str`,
4310 /// `err`, and `value`, the results of
4311 /// `this->do_get(begin, end, str, err, value)`.
4313 iter_type end,
4314 bsl::ios_base& str,
4315 bsl::ios_base::iostate& err,
4316 Decimal32& value) const;
4318 iter_type end,
4319 bsl::ios_base& str,
4320 bsl::ios_base::iostate& err,
4321 Decimal64& value) const;
4323 iter_type end,
4324 bsl::ios_base& str,
4325 bsl::ios_base::iostate& err,
4326 Decimal128& value) const;
4327
4328 protected:
4329 // CREATORS
4330
4331 /// Destroy this object.
4332 /// \note Note that the destructor is virtual.
4334
4335 // ACCESSORS
4336
4337 /// Interpret characters from the half-open iterator range denoted by
4338 /// the specified `begin` and `end`, generate a decimal floating-point
4339 /// number and store it into the specified `value`. During conversion
4340 /// the formatting flags of the specified `str` (`str.flags()`) are
4341 /// obeyed; character classifications are determined by the `bsl::ctype`
4342 /// while punctuation characters are determined by the `bsl::numpunct`
4343 /// facet imbued to the `str` stream-base. Use the specified `err` to
4344 /// report back failure or EOF streams states. For further, more
4345 /// detailed information please consult the section [lib.facet.num.get.virtuals] of the C++ Standard.
4346 ///
4347 /// \note Note that for the
4348 /// conversions to the `Decimal32`, 64 and 128 types the conversion
4349 /// specifiers are %Hg, %Dg and %DDg, respectively. Also note that
4350 /// these (possibly overridden) `do_get` virtual function are used by
4351 /// every formatted C++ stream input operator call (`in >> aDecNumber`).
4353 iter_type end,
4354 bsl::ios_base& str,
4355 bsl::ios_base::iostate& err,
4356 Decimal32& value) const;
4358 iter_type end,
4359 bsl::ios_base& str,
4360 bsl::ios_base::iostate& err,
4361 Decimal64& value) const;
4363 iter_type end,
4364 bsl::ios_base& str,
4365 bsl::ios_base::iostate& err,
4366 Decimal128& value) const;
4367};
4368
4369 // ============================================
4370 // template <class CHARTYPE, bool WCHAR_8_BITS>
4371 // class WideBufferWrapper
4372 // ============================================
4373
4374/// This class provides a wrapper around a buffer of the specified (template
4375/// parameter) `CHARTYPE`. `CHARTYPE` shall be either plain character type
4376/// `char` or wide character type `wchar_t`. The width of `wchar_t` is
4377/// compiler-specific and can be as small as 8 bits. The template parameter
4378/// `WCHAR_8_BITS` shall be `true` if `wchar_t` and `char` widths are the
4379/// same, i.e. 8 bits, and `false` otherwise. This class provides accessors
4380/// to the beginning and the end of the buffer of `CHARTYPE` characters.
4381template <class CHARTYPE, bool WCHAR_8_BITS>
4383
4384 // ========================================================
4385 // template <bool WCHAR_8_BIT>
4386 // class DecimalNumPut_WideBufferWrapper<char, WCHAR_8_BIT>
4387 // ========================================================
4388
4389/// This class is specialization of the template
4390/// `WideBufferWrapper<CHARTYPE, WCHAR_8_BITS>` for `char` type and
4391/// `wchar_t` type which width is 8 bits.
4392template <bool WCHAR_8_BIT>
4393class DecimalNumPut_WideBufferWrapper<char, WCHAR_8_BIT> {
4394
4395 // DATA
4396 const char *d_begin; // pointer to the beginning of plain character buffer
4397 const char *d_end; // pointer to the end of plain character buffer
4398
4399 private:
4400 // NOT IMPLEMENTED
4404
4405 public:
4406 // CREATORS
4407
4408 /// Create a wide buffer wrapper for the specified `buffer` of the
4409 /// specified length `len`.
4410 DecimalNumPut_WideBufferWrapper(const char *buffer,
4411 int len,
4412 const bsl::locale&);
4413
4414 // ACCESSORS
4415
4416 /// Return a pointer to the beginning of the buffer of plain characters
4417 /// provided in this class constructor.
4418 const char *begin() const;
4419
4420 /// Return a pointer to the end of the buffer of plain characters
4421 /// provided in this class constructor.
4422 const char *end() const;
4423};
4424
4425 // =====================================================
4426 // template <>
4427 // class DecimalNumPut_WideBufferWrapper<wchar_t, false>
4428 // =====================================================
4429
4430/// This class is specialization of the template
4431/// `WideBufferWrapper<CHARTYPE, WCHAR_8_BIT>` for `wchar_t` type which
4432/// width exceeds 8 bits.
4433template <>
4434class DecimalNumPut_WideBufferWrapper<wchar_t, false> {
4435
4436 // DATA
4437 wchar_t *d_buffer_p; // Buffer of wide characters
4438 size_t d_len; // Length of the buffer
4439
4440 private:
4441 // NOT IMPLEMENTED
4445
4446 public:
4447 // CREATORS
4448
4449 /// Create a wide buffer wrapper for the specified `buffer` of the
4450 /// specified length `len`. Use the specified locale `loc` to widen
4451 /// character in the buffer into wide characters representation.
4452 inline
4453 DecimalNumPut_WideBufferWrapper(const char *buffer,
4454 int len,
4455 const bsl::locale& loc);
4456
4457 /// Destroy this object.
4459
4460 // ACCESSORS
4461
4462 /// Return a pointer to the beginning of the buffer of wide characters.
4463 const wchar_t *begin() const;
4464
4465 /// Return a pointer to the end the buffer of wide characters.
4466 const wchar_t *end() const;
4467};
4468
4469 // =============================================
4470 // template class Decimal_FormatterSpecification
4471 // =============================================
4472
4473/// This template is the implementation of the `bsl::format` specification for
4474/// `bdldfp::Decimal*` types. It parses as well as postprocesses format
4475/// specifications for `bdldfp::Decimal*` type formatted arguments, as well as
4476/// stores the results of that pasring: the specification.
4477///
4478/// See @ref bdldfp_decimal
4479template <class t_CHAR>
4481
4482 // PUBLIC TYPES
4483
4484 /// This enumeration is used as an indication of the format-type letter in
4485 /// a decimal floating point format string.
4487 e_TYPE_UNASSIGNED, /// Default value
4488
4489 // Decimal floating point types
4497 };
4498
4499 private:
4500 // PRIVATE TYPES
4501
4502 /// Just an abbreviation for shorter lines.
4504
4505 // DATA
4506 typename Parser::ProcessingState d_parsingStatus; // the state of parsing
4507
4508 Parser d_parser; // specification parser
4509
4510 FormatType d_formatType; // what type was
4511 // requested
4512
4513 // PRIVATE MANIPULATORS
4514
4515 /// Parse, from the specified `typeString`, the requested format-type and
4516 /// load it into the `d_formatType`. This method will throw a
4517 /// `bsl::format_error` exception in case the `typeString` is not empty or
4518 /// a valid, single format character.
4519 BSLS_KEYWORD_CONSTEXPR_CPP20 void parseType(
4520 const bsl::basic_string_view<t_CHAR>& typeString);
4521
4522 // PRIVATE ACCESSORS
4523
4524 /// If `d_parsingStatus` is not yet at least `e_PARSED` throw a
4525 /// `bsl::format_error` exception, otherwise if `d_parsingStatus` is at
4526 /// least `e_PARSED` or higher (later in the process) do nothing.
4527 BSLS_KEYWORD_CONSTEXPR_CPP20 void ensureParsingComplete() const;
4528
4529 /// If `d_parsingStatus` is not `e_STATE_POSTPROCESSED` (the final
4530 /// state) throw a `bsl::format_error` exception, otherwise if
4531 /// `d_parsingStatus` is `e_STATE_POSTPROCESSED` do nothing.
4532 BSLS_KEYWORD_CONSTEXPR_CPP20 void ensurePostprocessingComplete() const;
4533
4534 public:
4535 // CREATORS
4536
4537 /// Create an uninitialized `Decimal_FormatterSpecification` object.
4539
4540 // MANIPULATORS
4541
4542 /// Parse a decimal floating point format string using the iterator-range
4543 /// from the specified `context` and if successful load the results into
4544 /// this object as well as set its status to `e_PARSED`; otherwise, if the
4545 /// format specification denoted by the `context` iterator-range is not a
4546 /// valid decimal floating point format specification throw a
4547 /// `bsl::format_error` exception.
4548 template <class t_PARSE_CONTEXT>
4549 BSLS_KEYWORD_CONSTEXPR_CPP20 void parse(t_PARSE_CONTEXT *context);
4550
4551 /// Postprocess this object using the argument values provided by the
4552 /// specified `context` to fill in the values of nested width or precision
4553 /// parameters if such deferred parameters exist and set the status to
4554 /// `e_STATE_POSTPROCESSED`. By nested format parameters we mean
4555 /// parameters whose value comes from an argument to the formatter
4556 /// function, and not an literal integer value within the format string.
4557 /// In case of an error throw a `bsl::format_error` exception.
4558 template <typename t_FORMAT_CONTEXT>
4559 void postprocess(const t_FORMAT_CONTEXT& context);
4560
4561 // ACCESSORS
4562
4563 /// Return a pointer to the character array that stored the parsed filler
4564 /// character that may be a multibyte code point or just a single character
4565 /// unless the status is not `e_STATE_POSTPROCESSED` in which case throw
4566 /// a `bsl::format_error` exception indicating that error. See also
4567 /// `numFillerCharacters()` that provides the number of characters in the
4568 /// array returned by this function (at least one).
4569 BSLS_KEYWORD_CONSTEXPR_CPP20 const t_CHAR *filler() const;
4570
4571 /// Return the number of filler characters in the array returned by
4572 /// `filler()`unless the status is not `e_STATE_POSTPROCESSED` in which
4573 /// case throw a `bsl::format_error` exception indicating that error.
4574 BSLS_KEYWORD_CONSTEXPR_CPP20 int fillerCharacters() const;
4575
4576 /// Return the display width of the code point represented by the array
4577 /// returned by `filler()`.
4578 BSLS_KEYWORD_CONSTEXPR_CPP20 int fillerCodePointDisplayWidth() const;
4579
4580 /// Return the enumerator representing the requested alignment unless the
4581 /// status is not at least `e_STATE_PARSED` in which case throw a
4582 /// `bsl::format_error` exception indicating that error.
4583 BSLS_KEYWORD_CONSTEXPR_CPP20 typename Parser::Alignment alignment() const;
4584
4585 /// Return the enumerator representing the requested sign-treatment option
4586 /// unless the status is not at least `e_STATE_PARSED` in which case
4587 /// throw a `bsl::format_error` exception indicating that error.
4588 BSLS_KEYWORD_CONSTEXPR_CPP20 typename Parser::Sign sign() const;
4589
4590 /// Return a boolean indicating if alternative formatting was requested
4591 /// unless the status is not at least `e_STATE_PARSED` in which case
4592 /// throw a `bsl::format_error` exception indicating that error.
4593 BSLS_KEYWORD_CONSTEXPR_CPP20 bool alternativeFlag() const;
4594
4595 /// Return a boolean indicating if zero padding was requested unless the
4596 /// status is not at least `e_STATE_PARSED` in which case throw a
4597 /// `bsl::format_error` exception indicating that error.
4598 BSLS_KEYWORD_CONSTEXPR_CPP20 bool zeroPaddingFlag() const;
4599
4600 /// Return an optional value representing the requested width unless the
4601 /// status is not `e_STATE_POSTPROCESSED` in which case throw a `bsl::format_error` exception indicating that error.
4602 ///
4603 /// \note Note that the
4604 /// returned type is capable of representing more than just an optional
4605 /// integer, but after preprocessing it will have only two possible states:
4606 /// no value, or an integer value.
4609 postprocessedWidth() const;
4610
4611 /// Return an optional value representing the requested precision unless
4612 /// the status is not `e_STATE_POSTPROCESSED` in which case throw a `bsl::format_error` exception indicating that error.
4613 ///
4614 /// \note Note that the
4615 /// returned type is capable of representing more than just an optional
4616 /// integer, but after preprocessing it will have only two possible states:
4617 /// no value, or an integer value.
4620 postprocessedPrecision() const;
4621
4622 /// Return a boolean indicating if the locale specific flag was present in
4623 /// the format specification unless the status is not at least
4624 /// `e_STATE_PARSED` in which case throw a `bsl::format_error` exception indicating that error.
4625 ///
4626 /// \note Note that the locale specific flag is not yet
4627 /// supported hence the attempt to format with a specification that has
4628 /// this flags set will result in an exception indicating that.
4629 BSLS_KEYWORD_CONSTEXPR_CPP20 bool localeSpecificFlag() const;
4630
4631 /// Return the format-type requested unless the status is not at least
4632 /// `e_STATE_PARSED` in which case throw a `bsl::format_error` exception
4633 /// indicating that error.
4634 BSLS_KEYWORD_CONSTEXPR_CPP20 FormatType formatType() const;
4635};
4636
4637 // ===========================================
4638 // template struct Decimal_BslFmtFormatterImpl
4639 // ===========================================
4640
4641/// This class template provides the implementation for all possible decimal
4642/// floating point formatting styles and the parsing of the format
4643/// specification. The specified `t_VALUE` template type argument determines
4644/// the type of decimal floating point value use, while the specified `t_CHAR`
4645/// determines both the formatting string and the output's character type.
4646///
4647/// \pre The behavior is undefined unless `t_VALUE` is one of `Decimal32`, `Decimal64,
4648/// or `Decimal128``, and `t_CHAR` is on of `char` or `wchar_t`.
4649///
4650/// See @ref bdldfp_decimal
4651template <class t_VALUE, class t_CHAR>
4653 private:
4654 // PRIVATE CLASS TYPES
4655
4656 /// A type alias for the `FormatterSpecificationDecimal<t_CHAR>`.
4658
4659 // DATA
4660 Specification d_spec; /// Parsed specification.
4661
4662 // PRIVATE CONSTANTS
4663
4664 /// A constant representing the case when a position is not found in a
4665 /// string-search.
4666 static const size_t k_NO_POS = (size_t)(-1);
4667
4668 private:
4669 // PRIVATE MANIPULATORS
4670
4671 /// Copy the specified `numberBuffer` of size `numberLength` aligned with
4672 /// fills according to the specified `finalSpec` to the output iterator of
4673 /// the `formatContext` and return an iterator one-past the last written.
4674 ///
4675 /// \pre The behavior is undefined unless `t_FORMAT_CONTEXT` is either
4676 /// `std::format_context` if that is supported, or otherwise
4677 /// `bslfmt::format_context`.
4678 template <class t_FORMAT_CONTEXT>
4679 typename t_FORMAT_CONTEXT::iterator alignAndCopy(
4680 const char *numberBuffer,
4681 size_t numberLength,
4682 t_FORMAT_CONTEXT& formatContext,
4683 const Specification& finalSpec) const;
4684 public:
4685 // MANIPULATORS
4686
4687 /// Create string representation of the specified `value`, customized in
4688 /// accordance with the requested format and the specified `formatContext`,
4689 /// and copy it to the output that the output iterator of the `formatContext` points to.
4690 ///
4691 /// \pre The behavior is undefined unless
4692 /// `t_FORMAT_CONTEXT` is either `std::format_context` if that is
4693 /// supported, or otherwise `bslfmt::format_context`.
4694 template <class t_FORMAT_CONTEXT>
4695 typename t_FORMAT_CONTEXT::iterator format(
4696 const t_VALUE& value,
4697 t_FORMAT_CONTEXT& formatContext) const;
4698
4699 /// Parse the specified `parseContext` and return an iterator, pointing to
4700 /// the beginning of the unparsed section of the format string.
4701 ///
4702 /// \pre The behavior is undefined unless `t_PARSE_CONTEXT` is either
4703 /// `std::parse_context` if that is supported, or otherwise
4704 /// `bslfmt::parse_context`.
4705 template <class t_PARSE_CONTEXT>
4707 typename t_PARSE_CONTEXT::iterator
4708 parse(t_PARSE_CONTEXT& parseContext);
4709};
4710
4711// ============================================================================
4712// INLINE DEFINITIONS
4713// ============================================================================
4714
4715 // -------------------------------------------
4716 // class DecimalNumPut_WideBufferWrapper<char>
4717 // -------------------------------------------
4718
4719//CREATORS
4720template <bool WCHAR_8_BIT>
4721inline
4723DecimalNumPut_WideBufferWrapper(const char *buffer,
4724 int len,
4725 const bsl::locale&)
4726: d_begin(buffer)
4727, d_end(buffer + len)
4728{
4729 BSLS_ASSERT(buffer);
4730 BSLS_ASSERT(len >= 0);
4731}
4732
4733// ACCESSORS
4734template <bool WCHAR_8_BIT>
4735inline
4737{
4738 return d_begin;
4739}
4740
4741template <bool WCHAR_8_BIT>
4742inline
4744{
4745 return d_end;
4746}
4747
4748 // ----------------------------------------------
4749 // class DecimalNumPut_WideBufferWrapper<wchar_t>
4750 // ----------------------------------------------
4751
4752//CREATORS
4753inline
4755DecimalNumPut_WideBufferWrapper(const char *buffer,
4756 int len,
4757 const bsl::locale& loc)
4758: d_buffer_p(0)
4759, d_len(len)
4760{
4761 BSLS_ASSERT(buffer);
4762 BSLS_ASSERT(len >= 0);
4763
4765
4766 d_buffer_p = (wchar_t *)allocator->allocate(sizeof(wchar_t) * len);
4767
4768 bsl::use_facet<std::ctype<wchar_t> >(loc).widen(buffer,
4769 buffer + len,
4770 d_buffer_p);
4771}
4772
4773inline
4780
4781 // ACCESSORS
4782inline
4784{
4785 return d_buffer_p;
4786}
4787
4788inline
4790{
4791 return d_buffer_p + d_len;
4792}
4793
4794 // ===================
4795 // class DecimalNumPut
4796 // ===================
4797
4798/// A facet type (mechanism) used in writing decimal floating-point types.
4799///
4800/// \note Note that this type does not follow BDE conventions because its content
4801/// is dictated by the C++ standard and native standard library
4802/// implementations. See ISO/IEC TR 24733 3.10.3 for details.
4803///
4804/// See @ref bdldfp_decimal
4805template <class CHARTYPE,
4806 class OUTPUTITERATOR = bsl::ostreambuf_iterator<CHARTYPE> >
4807class DecimalNumPut : public bsl::locale::facet {
4808
4809#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
4810 private:
4811 // ACCESSORS
4812 bsl::locale::id& __get_id() const;
4813 // The function __get_id() is a pure virtual function in the Rogue Wave
4814 // implementation of locales. It is in violation with the standard.
4815 // We have to define it as a workaround.
4816#endif
4817
4818 public:
4819 // -dk:TODO make private while making the output operator a friend
4820
4821 // CLASS METHODS
4823 // TBD
4824
4825 public:
4826 // PUBLIC TYPES
4827 static bsl::locale::id id; // The locale identifier
4828
4829 typedef CHARTYPE char_type;
4830 typedef OUTPUTITERATOR iter_type;
4831
4832 // CREATORS
4833
4834 /// Constructs a `DecimalNumPut` object. Optionally specify starting
4835 /// reference count `refs`, which will default to 0. If `refs` is
4836 /// non-zero, the `DecimalNumPut` object will not be deleted when the
4837 /// last locale referencing it goes out of scope.
4838 explicit DecimalNumPut(bsl::size_t refs = 0);
4839
4840 // ACCESSORS
4841
4842 /// Forward to, and return using the specified `out`, `str`, `fill`, and
4843 /// `value`, the results of `this->do_put(out, str, fill, value)`.
4845 bsl::ios_base& str,
4846 char_type fill,
4847 Decimal32 value) const;
4849 bsl::ios_base& str,
4850 char_type fill,
4851 Decimal64 value) const;
4853 bsl::ios_base& str,
4854 char_type fill,
4855 Decimal128 value) const;
4856
4857 protected:
4858 // CREATORS
4859
4860 /// Destroy this object.
4861 /// \note Note that the destructor is virtual.
4863
4864 // ACCESSORS
4865
4866 /// Write characters (of @ref char_type ) that represent the specified
4867 /// `value` to the output stream determined by the specified `out`
4868 /// output iterator. Use the `bsl::ctype` and the `bsl::numpunct`
4869 /// facets imbued to the specified stream-base @ref ios_format as well as
4870 /// the formatting flags of the @ref ios_format (`bsl.flags()`) to generate
4871 /// the properly localized output. The specified `fill` character will
4872 /// be used as a placeholder character in padded output. For further,
4873 /// more detailed information please consult the section
4874 /// [lib.facet.num.put.virtuals] of the C++ Standard noting that the
4875 /// length modifiers "H", "D" and "DD" are added to the conversion
4876 /// specifiers of for the types Decimal32, 64 and 128, respectively.
4877 /// Also note that these (possibly overridden) `do_put` virtual function
4878 /// are used by every formatted C++ stream output operator call (`out << aDecNumber`).
4879 ///
4880 /// \note Note that currently, only the width,
4881 /// capitalization, justification, fixed and scientific formatting flags
4882 /// are supported, and the operators only support code pages that
4883 /// include the ASCII sub-range. Because of potential future
4884 /// improvements to support additional formatting flags, the operations
4885 /// should not be used for serialization.
4887 bsl::ios_base& ios_format,
4888 char_type fill,
4889 Decimal32 value) const;
4891 bsl::ios_base& ios_format,
4892 char_type fill,
4893 Decimal64 value) const;
4895 bsl::ios_base& ios_format,
4896 char_type fill,
4897 Decimal128 value) const;
4898
4899 /// Write characters that represent the specified `value` into a string
4900 /// of the specified @ref char_type , and output the represented decimal
4901 /// number to the specified `out`, adjusting for the formatting flags in
4902 /// the specified @ref ios_format and using the specified `fill` character.
4903 /// Currently, formatting for the formatting flags of justification,
4904 /// width, uppercase, showpos, fixed and scientific are supported.
4905 template <class DECIMAL>
4907 bsl::ios_base& ios_format,
4908 char_type fill,
4909 DECIMAL value) const;
4910};
4911
4912 // =====================================
4913 // class Decimal_StandardNamespaceCanary
4914 // =====================================
4915
4916/// An empty class used for error detection when looking for the original
4917/// name of the standard namespace. Do not use it.
4918///
4919/// See @ref bdldfp_decimal
4922
4923 // =================================================================
4924 // template<...> class faux_numeric_limits<NUMERIC_TYPE, DUMMY_TYPE>
4925 // =================================================================
4926
4927/// This class is used as a base-class for manifest constants in the
4928/// `std::numeric_limits` specializations to overcome a Sun compiler issue.
4929template<class NUMERIC_TYPE, class DUMMY_TYPE = void>
4931
4932 // ===============================================================
4933 // class faux_numeric_limits<Decimal_StandardNamespaceCanary, ...>
4934 // ===============================================================
4935
4936/// Explicit full specialization of the standard "traits" template
4937/// `std::numeric_limits` for the type `BloombergLP::bdldfp::Decimal_StandardNamespaceCanary`.
4938///
4939/// \note Note that this
4940/// specialization is required for technical reasons and it is identical to
4941/// the non-specialized default traits.
4942template<class DUMMY_TYPE>
4944{
4945
4946 public:
4947 // CLASS DATA
4948
4949 /// `BloombergLP::bdldfp::Decimal_StandardNamespaceCanary` is not a
4950 /// numeric type.
4951 static const bool is_specialized = false;
4952};
4953
4954 // ==============================================================
4955 // template<...> class faux_numeric_limits<Decimal32, DUMMY_TYPE>
4956 // ==============================================================
4957
4958template<class DUMMY_TYPE>
4959class faux_numeric_limits<BloombergLP::bdldfp::Decimal32, DUMMY_TYPE> {
4960 // Explicit full specialization of the standard "traits" template
4961 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal32'.
4962
4963 public:
4964 // CLASS DATA
4965
4966 /// The template instance
4967 /// `std::numeric_limits<BloombergLP::bdldfp::Decimal32>` is
4968 /// meaningfully specialized. Also means that
4969 /// `BloombergLP::bdldfp::Decimal32` is a numeric type.
4970 static const bool is_specialized = true;
4971
4972 /// The maximum number of significant digits, in the native (10) radix
4973 /// of the `BloombergLP::bdldfp::Decimal32` type that the type is able
4974 /// to represent. Defined to be 7 by IEEE-754.
4975 static const int digits = 7;
4976
4977 /// The maximum number of significant decimal digits that the
4978 /// `BloombergLP::bdldfp::Decimal32` type is able to represent. Defined
4979 /// to be 7 by IEEE-754.
4980 static const int digits10 = digits;
4981
4982 /// The number of significant decimal digits necessary to uniquely
4983 /// represent the significant digits of any `BloombergLP::bdldfp::Decimal32` value.
4984 ///
4985 /// \note Note that max_digit10 is
4986 /// the same as digits10 for decimal floating-point values.
4987 static const int max_digits10 = digits;
4988
4989 /// `BloombergLP::bdldfp::Decimal32` is a signed type.
4990 static const bool is_signed = true;
4991
4992 /// `BloombergLP::bdldfp::Decimal32` is not an integer type.
4993 static const bool is_integer = false;
4994
4995 /// `BloombergLP::bdldfp::Decimal32` is not an exact type, i.e.:
4996 /// calculations done on the type are not free of rounding errors.
4997 ///
4998 /// \note Note that integer and possibly rational types may be exact,
4999 /// floating-point types are never exact.
5000 static const bool is_exact = false;
5001
5002 /// The base for `BloombergLP::bdldfp::Decimal32` is decimal or 10.
5003 static const int radix = 10;
5004
5005 /// The lowest possible negative exponent for the native base of the
5006 /// `BloombergLP::bdldfp::Decimal32` type that does not yet represent a
5007 /// denormal number. Defined to be -95 by IEEE-754.
5008 static const int min_exponent = -95;
5009
5010 /// The lowest possible negative decimal exponent in the
5011 /// `BloombergLP::bdldfp::Decimal32` type that does not yet represent a
5012 /// denormal number. Defined to be -95 by IEEE-754.
5013 ///
5014 /// \note Note that @ref min_exponent10 is the same as @ref min_exponent for decimal types.
5015 static const int min_exponent10 = min_exponent;
5016
5017 /// The highest possible positive exponent for the native base of the
5018 /// `BloombergLP::bdldfp::Decimal32` type that represents a finite
5019 /// value. Defined to be 96 by IEEE-754.
5020 static const int max_exponent = 96;
5021
5022 /// The highest possible positive decimal exponent of the
5023 /// `BloombergLP::bdldfp::Decimal32` type that represents a finite value. Defined to be 97 by IEEE-754.
5024 ///
5025 /// \note Note that @ref max_exponent10 is
5026 /// the same as @ref max_exponent for decimal types.
5027 static const int max_exponent10 = max_exponent;
5028
5029 /// `BloombergLP::bdldfp::Decimal32` can represent infinity.
5030 static const bool has_infinity = true;
5031
5032 /// `BloombergLP::bdldfp::Decimal32` can be a non-signaling Not a
5033 /// Number.
5034 static const bool has_quiet_NaN = true;
5035
5036 /// `BloombergLP::bdldfp::Decimal32` can be a signaling Not a Number.
5037 static const bool has_signaling_NaN = true;
5038
5039 /// `BloombergLP::bdldfp::Decimal32` may contain denormal values.
5041 static const std::float_denorm_style has_denorm = std::denorm_present;
5042
5043 /// `BloombergLP::bdldfp::Decimal32` is able to distinguish loss of
5044 /// precision (floating-point underflow) due to denormalization from
5045 /// other causes.
5046 static const bool has_denorm_loss = true;
5047
5048 /// Decimal floating-point types represent a finite set of values.
5049 static const bool is_bounded = true;
5050
5051 /// Decimal floating-point is not covered by the IEC 559 standard.
5052 static const bool is_iec559 = false;
5053
5054 /// Decimal floating-point types do not have modulo representation.
5055 static const bool is_modulo = false;
5056
5057 /// Decimal floating-point types are able to detect if a value is too
5058 /// small to represent as a normalized value before rounding it.
5059 static const bool tinyness_before = true;
5060
5061 /// Decimal floating-point types implement traps to report arithmetic
5062 /// exceptions (required by IEEE-754).
5063 static const bool traps = true;
5064
5065 /// The highest possible precision in the
5066 /// `BloombergLP::bdldfp::Decimal32` type that is large enough to
5067 /// output the smallest non-zero denormalized value in fixed notation.
5068 static const int max_precision = digits10 - 1 + (-min_exponent10);
5069
5070 // Rounding style
5071
5072 /// Decimal floating-point rounding style is defined to be indeterminate
5073 /// by the C and C++ Decimal TRs.
5074 static const std::float_round_style round_style = std::round_indeterminate;
5075};
5076
5077 // ==============================================================
5078 // template<...> class faux_numeric_limits<Decimal64, DUMMY_TYPE>
5079 // ==============================================================
5080
5081template<class DUMMY_TYPE>
5082class faux_numeric_limits<BloombergLP::bdldfp::Decimal64, DUMMY_TYPE> {
5083 // Explicit full specialization of the standard "traits" template
5084 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal64'.
5085
5086 public:
5087 // CLASS DATA
5088
5089 /// The template instance
5090 /// `std::numeric_limits<BloombergLP::bdldfp::Decimal64>` is
5091 /// meaningfully specialized. Also means that
5092 /// `BloombergLP::bdldfp::Decimal64` is a numeric type.
5093 static const bool is_specialized = true;
5094
5095 /// The maximum number of significant digits, in the native (10) radix
5096 /// of the `BloombergLP::bdldfp::Decimal64` type that the type is able
5097 /// to represent. Defined to be 16 by IEEE-754.
5098 static const int digits = 16;
5099
5100 /// The maximum number of significant decimal digits that the
5101 /// `BloombergLP::bdldfp::Decimal64` type is able to represent. Defined
5102 /// to be 16 by IEEE-754.
5103 static const int digits10 = digits;
5104
5105 /// The number of significant decimal digits necessary to uniquely
5106 /// represent the significant digits of any `BloombergLP::bdldfp::Decimal64` value.
5107 ///
5108 /// \note Note that max_digit10 is
5109 /// the same as digits10 for decimal floating-point values.
5110 static const int max_digits10 = digits;
5111
5112 /// `BloombergLP::bdldfp::Decimal64` is a signed type.
5113 static const bool is_signed = true;
5114
5115 /// `BloombergLP::bdldfp::Decimal64` is not an integer type.
5116 static const bool is_integer = false;
5117
5118 /// `BloombergLP::bdldfp::Decimal64` is not an exact type, i.e.:
5119 /// calculations done on the type are not free of rounding errors.
5120 ///
5121 /// \note Note that integer and possibly rational types may be exact,
5122 /// floating-point types are never exact.
5123 static const bool is_exact = false;
5124
5125 /// The base for `BloombergLP::bdldfp::Decimal64` is decimal or 10.
5126 static const int radix = 10;
5127
5128 /// The lowest possible negative exponent for the native base of the
5129 /// `BloombergLP::bdldfp::Decimal64` type that does not yet represent a
5130 /// denormal number. Defined to be -383 by IEEE-754.
5131 static const int min_exponent = -383;
5132
5133 /// The lowest possible negative decimal exponent in the
5134 /// `BloombergLP::bdldfp::Decimal64` type that does not yet represent a
5135 /// denormal number. Defined to be -382 by IEEE-754.
5136 ///
5137 /// \note Note that @ref min_exponent10 is the same as @ref min_exponent for decimal types.
5138 static const int min_exponent10 = min_exponent;
5139
5140 /// The highest possible positive exponent for the native base of the
5141 /// `BloombergLP::bdldfp::Decimal64` type that represents a finite
5142 /// value. Defined to be 384 by IEEE-754.
5143 static const int max_exponent = 384;
5144
5145 /// The highest possible positive decimal exponent of the
5146 /// `BloombergLP::bdldfp::Decimal64` type that represents a finite value. Defined to be 384 by IEEE-754.
5147 ///
5148 /// \note Note that @ref max_exponent10
5149 /// is the same as @ref max_exponent for decimal types.
5150 static const int max_exponent10 = max_exponent;
5151
5152 /// `BloombergLP::bdldfp::Decimal64` can represent infinity.
5153 static const bool has_infinity = true;
5154
5155 /// `BloombergLP::bdldfp::Decimal64` can be a non-signaling Not a
5156 /// Number.
5157 static const bool has_quiet_NaN = true;
5158
5159 /// `BloombergLP::bdldfp::Decimal64` can be a signaling Not a Number.
5160 static const bool has_signaling_NaN = true;
5161
5162 /// `BloombergLP::bdldfp::Decimal64` may contain denormal values.
5164 static const std::float_denorm_style has_denorm = std::denorm_present;
5165
5166 /// `BloombergLP::bdldfp::Decimal64` is able to distinguish loss of
5167 /// precision (floating-point underflow) due to denormalization from
5168 /// other causes.
5169 static const bool has_denorm_loss = true;
5170
5171 /// Decimal floating-point is not covered by the IEC 559 standard.
5172 static const bool is_iec559 = false;
5173
5174 /// Decimal floating-point types represent a finite set of values.
5175 static const bool is_bounded = true;
5176
5177 /// Decimal floating-point types do not have modulo representation.
5178 static const bool is_modulo = false;
5179
5180 /// Decimal floating-point types implement traps to report arithmetic
5181 /// exceptions (required by IEEE-754).
5182 static const bool traps = true;
5183
5184 /// Decimal floating-point types are able to detect if a value is too
5185 /// small to represent as a normalized value before rounding it.
5186 static const bool tinyness_before = true;
5187
5188 /// The highest possible precision in the
5189 /// `BloombergLP::bdldfp::Decimal64` type that is large enough to
5190 /// output the smallest non-zero denormalized value in fixed notation.
5191 static const int max_precision = digits10 - 1 + (-min_exponent10);
5192
5193 /// Decimal floating-point rounding style is defined to be indeterminate
5194 /// by the C and C++ Decimal TRs.
5195 static const std::float_round_style round_style = std::round_indeterminate;
5196};
5197
5198 // ===============================================================
5199 // template<...> class faux_numeric_limits<Decimal128, DUMMY_TYPE>
5200 // ===============================================================
5201
5202template<class DUMMY_TYPE>
5203class faux_numeric_limits<BloombergLP::bdldfp::Decimal128, DUMMY_TYPE> {
5204 // Explicit full specialization of the standard "traits" template
5205 // 'std::numeric_limits' for the type
5206 // 'BloombergLP::bdldfp::Decimal128'.
5207
5208 public:
5209 // CLASS DATA
5210
5211 /// The template instance
5212 /// `std::numeric_limits<BloombergLP::bdldfp::Decimal128>` is
5213 /// meaningfully specialized. Also means that
5214 /// `BloombergLP::bdldfp::Decimal128` is a numeric type.
5215 static const bool is_specialized = true;
5216
5217 /// The maximum number of significant digits, in the native (10) radix
5218 /// of the `BloombergLP::bdldfp::Decimal128` type that the type is able
5219 /// to represent. Defined to be 34 by IEEE-754.
5220 static const int digits = 34;
5221
5222 /// The maximum number of significant decimal digits that the
5223 /// `BloombergLP::bdldfp::Decimal128` type is able to represent.
5224 /// Defined to be 34 by IEEE-754.
5225 static const int digits10 = digits;
5226
5227 /// The number of significant decimal digits necessary to uniquely
5228 /// represent the significant digits of any `BloombergLP::bdldfp::Decimal128` value.
5229 ///
5230 /// \note Note that max_digit10 is
5231 /// the same as digits10 for decimal floating-point values.
5232 static const int max_digits10 = digits;
5233
5234 /// `BloombergLP::bdldfp::Decimal128` is a signed type.
5235 static const bool is_signed = true;
5236
5237 /// `BloombergLP::bdldfp::Decimal128` is not an integer type.
5238 static const bool is_integer = false;
5239
5240 /// `BloombergLP::bdldfp::Decimal128` is not an exact type, i.e.:
5241 /// calculations done on the type are not free of rounding errors.
5242 ///
5243 /// \note Note that integer and possibly rational types may be exact,
5244 /// floating-point types are never exact.
5245 static const bool is_exact = false;
5246
5247 /// The base for `BloombergLP::bdldfp::Decimal128` is decimal or 10.
5248 static const int radix = 10;
5249
5250 /// The lowest possible negative exponent for the native base of the
5251 /// `BloombergLP::bdldfp::Decimal128` type that does not yet represent a
5252 /// denormal number. Defined to be -6143 by IEEE-754.
5253 static const int min_exponent = -6143;
5254
5255 /// The lowest possible negative decimal exponent in the
5256 /// `BloombergLP::bdldfp::Decimal128` type that does not yet represent a
5257 /// denormal number. Defined to be -6142 by IEEE-754.
5258 ///
5259 /// \note Note that @ref min_exponent10 is the same as @ref min_exponent for decimal types.
5260 static const int min_exponent10 = min_exponent;
5261
5262 /// The highest possible positive exponent for the native base of the
5263 /// `BloombergLP::bdldfp::Decimal128` type that represents a finite
5264 /// value. Defined to be 385 by IEEE-754.
5265 static const int max_exponent = 6144;
5266
5267 /// The highest possible positive decimal exponent of the
5268 /// `BloombergLP::bdldfp::Decimal128` type that represents a finite value. Defined to be 6145 by IEEE-754.
5269 ///
5270 /// \note Note that @ref max_exponent10
5271 /// is the same as @ref max_exponent for decimal types.
5272 static const int max_exponent10 = max_exponent;
5273
5274 /// `BloombergLP::bdldfp::Decimal128` can represent infinity.
5275 static const bool has_infinity = true;
5276
5277 /// `BloombergLP::bdldfp::Decimal128` can be a non-signaling Not a
5278 /// Number.
5279 static const bool has_quiet_NaN = true;
5280
5281 /// `BloombergLP::bdldfp::Decimal128` can be a signaling Not a Number.
5282 static const bool has_signaling_NaN = true;
5283
5284 /// `BloombergLP::bdldfp::Decimal128` may contain denormal values.
5286 static const std::float_denorm_style has_denorm = std::denorm_present;
5287
5288 /// `BloombergLP::bdldfp::Decimal128` is able to distinguish loss of
5289 /// precision (floating-point underflow) due to denormalization from
5290 /// other causes.
5291 static const bool has_denorm_loss = true;
5292
5293 /// Decimal floating-point is not covered by the IEC 559 standard.
5294 static const bool is_iec559 = false;
5295
5296 /// Decimal floating-point types represent a finite set of values.
5297 static const bool is_bounded = true;
5298
5299 /// Decimal floating-point types do not have modulo representation.
5300 static const bool is_modulo = false;
5301
5302 /// Decimal floating-point types implement traps to report arithmetic
5303 /// exceptions (required by IEEE-754).
5304 static const bool traps = true;
5305
5306 /// Decimal floating-point types are able to detect if a value is too
5307 /// small to represent as a normalized value before rounding it.
5308 static const bool tinyness_before = true;
5309
5310 /// The highest possible precision in the
5311 /// `BloombergLP::bdldfp::Decimal128` type that is large enough to
5312 /// output the smallest non-zero denormalized value in fixed notation.
5313 static const int max_precision = digits10 - 1 + (-min_exponent10);
5314
5315 /// Decimal floating-point rounding style is defined to be indeterminate
5316 /// by the C and C++ Decimal TRs.
5317 static const std::float_round_style round_style = std::round_indeterminate;
5318
5319};
5320
5321 // --------------------------------------------------
5322 // faux_numeric_limits<Decimal32, ...> member storage
5323 // --------------------------------------------------
5324
5325template<class DUMMY_TYPE>
5327
5328template<class DUMMY_TYPE>
5330
5331template<class DUMMY_TYPE>
5333
5334template<class DUMMY_TYPE>
5336
5337template<class DUMMY_TYPE>
5339
5340template<class DUMMY_TYPE>
5342
5343template<class DUMMY_TYPE>
5345
5346template<class DUMMY_TYPE>
5348
5349template<class DUMMY_TYPE>
5351
5352template<class DUMMY_TYPE>
5354
5355template<class DUMMY_TYPE>
5357
5358template<class DUMMY_TYPE>
5360
5361template<class DUMMY_TYPE>
5363
5364template<class DUMMY_TYPE>
5366
5367template<class DUMMY_TYPE>
5369
5370template<class DUMMY_TYPE>
5371const std::float_denorm_style
5373
5374template<class DUMMY_TYPE>
5376
5377template<class DUMMY_TYPE>
5379
5380template<class DUMMY_TYPE>
5382
5383template<class DUMMY_TYPE>
5385
5386template<class DUMMY_TYPE>
5388
5389template<class DUMMY_TYPE>
5391
5392template<class DUMMY_TYPE>
5393const std::float_round_style
5395
5396 // --------------------------------------------------
5397 // faux_numeric_limits<Decimal64, ...> member storage
5398 // --------------------------------------------------
5399
5400template<class DUMMY_TYPE>
5402
5403template<class DUMMY_TYPE>
5405
5406template<class DUMMY_TYPE>
5408
5409template<class DUMMY_TYPE>
5411
5412template<class DUMMY_TYPE>
5414
5415template<class DUMMY_TYPE>
5417
5418template<class DUMMY_TYPE>
5420
5421template<class DUMMY_TYPE>
5423
5424template<class DUMMY_TYPE>
5426
5427template<class DUMMY_TYPE>
5429
5430template<class DUMMY_TYPE>
5432
5433template<class DUMMY_TYPE>
5435
5436template<class DUMMY_TYPE>
5438
5439template<class DUMMY_TYPE>
5441
5442template<class DUMMY_TYPE>
5444
5445template<class DUMMY_TYPE>
5446const std::float_denorm_style
5448
5449template<class DUMMY_TYPE>
5451
5452template<class DUMMY_TYPE>
5454
5455template<class DUMMY_TYPE>
5457
5458template<class DUMMY_TYPE>
5460
5461template<class DUMMY_TYPE>
5463
5464template<class DUMMY_TYPE>
5466
5467template<class DUMMY_TYPE>
5468const std::float_round_style
5470
5471 // ---------------------------------------------------
5472 // faux_numeric_limits<Decimal128, ...> member storage
5473 // ---------------------------------------------------
5474
5475template<class DUMMY_TYPE>
5477
5478template<class DUMMY_TYPE>
5480
5481template<class DUMMY_TYPE>
5483
5484template<class DUMMY_TYPE>
5486
5487template<class DUMMY_TYPE>
5489
5490template<class DUMMY_TYPE>
5492
5493template<class DUMMY_TYPE>
5495
5496template<class DUMMY_TYPE>
5498
5499template<class DUMMY_TYPE>
5501
5502template<class DUMMY_TYPE>
5504
5505template<class DUMMY_TYPE>
5507
5508template<class DUMMY_TYPE>
5510
5511template<class DUMMY_TYPE>
5513
5514template<class DUMMY_TYPE>
5516
5517template<class DUMMY_TYPE>
5519
5520template<class DUMMY_TYPE>
5521const std::float_denorm_style
5523
5524template<class DUMMY_TYPE>
5526
5527template<class DUMMY_TYPE>
5529
5530template<class DUMMY_TYPE>
5532
5533template<class DUMMY_TYPE>
5535
5536template<class DUMMY_TYPE>
5538
5539template<class DUMMY_TYPE>
5541
5542template<class DUMMY_TYPE>
5543const std::float_round_style
5545
5546} // close package namespace
5547
5548
5549namespace std {
5550
5551 // ========================================================================
5552 // template<> class numeric_limits<bdldfp::Decimal_StandardNamespaceCanary>
5553 // ========================================================================
5554
5555/// Explicit full specialization of the standard "traits" template
5556/// `std::numeric_limits` for the type `BloombergLP::bdldfp::Decimal_StandardNamespaceCanary`.
5557///
5558/// \note Note that this
5559/// specialization is required for technical reasons and it is identical to
5560/// the non-specialized default traits.
5561template<>
5562class numeric_limits<BloombergLP::bdldfp::Decimal_StandardNamespaceCanary>
5563 : public BloombergLP::bdldfp::faux_numeric_limits<
5564 BloombergLP::bdldfp::Decimal_StandardNamespaceCanary> {
5565};
5566
5567 // ==================================================
5568 // template<> class numeric_limits<bdldfp::Decimal32>
5569 // ==================================================
5570
5571template<>
5572class numeric_limits<BloombergLP::bdldfp::Decimal32>
5573 : public BloombergLP::bdldfp::faux_numeric_limits<
5574 BloombergLP::bdldfp::Decimal32> {
5575 // Explicit full specialization of the standard "traits" template
5576 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal32'.
5577
5578 public:
5579 // CLASS METHODS
5580
5581 /// Return the smallest positive (also non-zero) number
5582 /// `BloombergLP::bdldfp::Decimal32` can represent (IEEE-754: +1e-95).
5583 static BloombergLP::bdldfp::Decimal32 min() BSLS_KEYWORD_NOEXCEPT;
5584
5585 /// Return the largest number `BloombergLP::bdldfp::Decimal32` can
5586 /// represent (IEEE-754: +9.999999e+96).
5587 static BloombergLP::bdldfp::Decimal32 max() BSLS_KEYWORD_NOEXCEPT;
5588
5589 /// Return the difference between 1 and the smallest value representable
5590 /// by the `BloombergLP::bdldfp::Decimal32` type. (IEEE-754: +1e-6)
5591 static BloombergLP::bdldfp::Decimal32 epsilon() BSLS_KEYWORD_NOEXCEPT;
5592
5593 /// Return the maximum rounding error for the
5594 /// `BloombergLP::bdldfp::Decimal32` type. The actual value returned
5595 /// depends on the current decimal floating point rounding setting.
5596 static BloombergLP::bdldfp::Decimal32 round_error() BSLS_KEYWORD_NOEXCEPT;
5597
5598 /// Return the smallest non-zero denormalized value for the
5599 /// `BloombergLP::bdldfp::Decimal32` type. (IEEE-754: +0.000001E-95)
5600 static BloombergLP::bdldfp::Decimal32 denorm_min() BSLS_KEYWORD_NOEXCEPT;
5601
5602 /// Return the value that represents positive infinity for the
5603 /// `BloombergLP::bdldfp::Decimal32` type.
5604 static BloombergLP::bdldfp::Decimal32 infinity() BSLS_KEYWORD_NOEXCEPT;
5605
5606 /// Return a value that represents non-signaling NaN for the
5607 /// `BloombergLP::bdldfp::Decimal32` type.
5608 static BloombergLP::bdldfp::Decimal32 quiet_NaN() BSLS_KEYWORD_NOEXCEPT;
5609
5610 /// Return a value that represents signaling NaN for the
5611 /// `BloombergLP::bdldfp::Decimal32` type.
5612 static
5613 BloombergLP::bdldfp::Decimal32 signaling_NaN() BSLS_KEYWORD_NOEXCEPT;
5614};
5615
5616 // ==================================================
5617 // template<> class numeric_limits<bdldfp::Decimal64>
5618 // ==================================================
5619
5620template<>
5621class numeric_limits<BloombergLP::bdldfp::Decimal64>
5622 : public BloombergLP::bdldfp::faux_numeric_limits<
5623 BloombergLP::bdldfp::Decimal64> {
5624 // Explicit full specialization of the standard "traits" template
5625 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal64'.
5626
5627 public:
5628 // CLASS METHODS
5629
5630 /// Return the smallest positive (also non-zero) number
5631 /// `BloombergLP::bdldfp::Decimal64` can represent (IEEE-754: +1e-383).
5632 static BloombergLP::bdldfp::Decimal64 min() BSLS_KEYWORD_NOEXCEPT;
5633
5634 /// Return the largest number `BloombergLP::bdldfp::Decimal64` can
5635 /// represent (IEEE-754: +9.999999999999999e+384).
5636 static BloombergLP::bdldfp::Decimal64 max() BSLS_KEYWORD_NOEXCEPT;
5637
5638 /// Return the difference between 1 and the smallest value representable
5639 /// by the `BloombergLP::bdldfp::Decimal64` type. (IEEE-754: +1e-15)
5640 static BloombergLP::bdldfp::Decimal64 epsilon() BSLS_KEYWORD_NOEXCEPT;
5641
5642 /// Return the maximum rounding error for the
5643 /// `BloombergLP::bdldfp::Decimal64` type. The actual value returned
5644 /// depends on the current decimal floating point rounding setting.
5645 static BloombergLP::bdldfp::Decimal64 round_error() BSLS_KEYWORD_NOEXCEPT;
5646
5647 /// Return the smallest non-zero denormalized value for the
5648 /// `BloombergLP::bdldfp::Decimal64` type. (IEEE-754:
5649 /// +0.000000000000001e-383)
5650 static BloombergLP::bdldfp::Decimal64 denorm_min() BSLS_KEYWORD_NOEXCEPT;
5651
5652 /// Return the value that represents positive infinity for the
5653 /// `BloombergLP::bdldfp::Decimal64` type.
5654 static BloombergLP::bdldfp::Decimal64 infinity() BSLS_KEYWORD_NOEXCEPT;
5655
5656 /// Return a value that represents non-signaling NaN for the
5657 /// `BloombergLP::bdldfp::Decimal64` type.
5658 static BloombergLP::bdldfp::Decimal64 quiet_NaN() BSLS_KEYWORD_NOEXCEPT;
5659
5660 /// Return a value that represents signaling NaN for the
5661 /// `BloombergLP::bdldfp::Decimal64` type.
5662 static
5663 BloombergLP::bdldfp::Decimal64 signaling_NaN() BSLS_KEYWORD_NOEXCEPT;
5664
5665};
5666
5667 // ===================================================
5668 // template<> class numeric_limits<bdldfp::Decimal128>
5669 // ===================================================
5670
5671template<>
5672class numeric_limits<BloombergLP::bdldfp::Decimal128>
5673 : public BloombergLP::bdldfp::faux_numeric_limits<
5674 BloombergLP::bdldfp::Decimal128> {
5675 // Explicit full specialization of the standard "traits" template
5676 // 'std::numeric_limits' for the type
5677 // 'BloombergLP::bdldfp::Decimal128'.
5678
5679 public:
5680 // CLASS METHODS
5681
5682 /// Return the smallest positive (also non-zero) number
5683 /// `BloombergLP::bdldfp::Decimal128` can represent (IEEE-754:
5684 /// +1e-6143).
5685 static BloombergLP::bdldfp::Decimal128 min() BSLS_KEYWORD_NOEXCEPT;
5686
5687 /// Return the largest number `BloombergLP::bdldfp::Decimal128` can
5688 /// represent (IEEE-754: +9.999999999999999999999999999999999e+6144).
5689 static BloombergLP::bdldfp::Decimal128 max() BSLS_KEYWORD_NOEXCEPT;
5690
5691 /// Return the difference between 1 and the smallest value representable
5692 /// by the `BloombergLP::bdldfp::Decimal128` type. (IEEE-754: +1e-33)
5693 static BloombergLP::bdldfp::Decimal128 epsilon() BSLS_KEYWORD_NOEXCEPT;
5694
5695 /// Return the maximum rounding error for the
5696 /// `BloombergLP::bdldfp::Decimal128` type. The actual value returned
5697 /// depends on the current decimal floating point rounding setting.
5698 static BloombergLP::bdldfp::Decimal128 round_error() BSLS_KEYWORD_NOEXCEPT;
5699
5700 /// Return the smallest non-zero denormalized value for the
5701 /// `BloombergLP::bdldfp::Decimal128` type. (IEEE-754:
5702 /// +0.000000000000000000000000000000001e-6143)
5703 static BloombergLP::bdldfp::Decimal128 denorm_min() BSLS_KEYWORD_NOEXCEPT;
5704
5705 /// Return the value that represents positive infinity for the
5706 /// `BloombergLP::bdldfp::Decimal128` type.
5707 static BloombergLP::bdldfp::Decimal128 infinity() BSLS_KEYWORD_NOEXCEPT;
5708
5709 /// Return a value that represents non-signaling NaN for the
5710 /// `BloombergLP::bdldfp::Decimal128` type.
5711 static BloombergLP::bdldfp::Decimal128 quiet_NaN() BSLS_KEYWORD_NOEXCEPT;
5712
5713 /// Return a value that represents signaling NaN for the
5714 /// `BloombergLP::bdldfp::Decimal128` type.
5715 static
5716 BloombergLP::bdldfp::Decimal128 signaling_NaN() BSLS_KEYWORD_NOEXCEPT;
5717};
5718
5719} // close namespace std
5720
5721// ============================================================================
5722// INLINE DEFINITIONS
5723// ============================================================================
5724
5725
5726namespace bdldfp {
5727
5728 // THE DECIMAL FLOATING-POINT TYPES
5729
5730 // --------------------
5731 // class Decimal_Type32
5732 // --------------------
5733
5734// CLASS METHODS
5735
5736 // Aspects
5737inline
5738int Decimal_Type32::maxSupportedBdexVersion()
5739{
5740 return 1;
5741}
5742
5743inline
5744int Decimal_Type32::maxSupportedBdexVersion(int /* versionSelector */)
5745{
5746 return 1;
5747}
5748
5749// CREATORS
5750inline
5751Decimal_Type32::Decimal_Type32()
5752{
5753 bsl::memset(&d_value, 0, sizeof(d_value));
5754}
5755
5756inline
5757Decimal_Type32::Decimal_Type32(DecimalImpUtil::ValueType32 value)
5758: d_value(value)
5759{
5760}
5761
5762inline
5764: d_value(DecimalImpUtil::convertToDecimal32(*other.data()))
5765{
5766}
5767
5768inline
5770: d_value(DecimalImpUtil::convertToDecimal32(*other.data()))
5771{
5772}
5773
5774inline
5776: d_value(DecimalImpUtil::binaryToDecimal32(other))
5777{
5778}
5779
5780inline
5782: d_value(DecimalImpUtil::binaryToDecimal32(other))
5783{
5784}
5785
5786inline
5788: d_value(DecimalImpUtil::int32ToDecimal32(other))
5789{
5790}
5791
5792inline
5794: d_value(DecimalImpUtil::uint32ToDecimal32(other))
5795{
5796}
5797
5798inline
5800: d_value(DecimalImpUtil::int64ToDecimal32(other))
5801{
5802}
5803
5804inline
5805Decimal_Type32::Decimal_Type32(unsigned long int other)
5806: d_value(DecimalImpUtil::uint64ToDecimal32(other))
5807{
5808}
5809
5810inline
5812: d_value(DecimalImpUtil::int64ToDecimal32(other))
5813{
5814}
5815
5816inline
5817Decimal_Type32::Decimal_Type32(unsigned long long other)
5818: d_value(DecimalImpUtil::uint64ToDecimal32(other))
5819{
5820}
5821
5822// MANIPULATORS
5823
5824 // Incrementation and Decrementation
5825
5827{
5828 return *this += Decimal32(1);
5829}
5830
5832{
5833 return *this -= Decimal32(1);
5834}
5835
5836 // Addition
5837
5839{
5840 this->d_value = DecimalImpUtil::add(this->d_value, rhs.d_value);
5841 return *this;
5842}
5843
5845{
5846 return *this = Decimal32(Decimal64(*this) + rhs);
5847}
5848
5850{
5851 return *this = Decimal32(Decimal128(*this) + rhs);
5852}
5853
5855{
5856 return *this += Decimal64(rhs);
5857}
5858
5860{
5861 return *this += Decimal64(rhs);
5862}
5863
5865{
5866 return *this += Decimal64(rhs);
5867}
5868
5870{
5871 return *this += Decimal64(rhs);
5872}
5873
5875{
5876 return *this += Decimal128(rhs);
5877}
5878
5879inline Decimal_Type32& Decimal_Type32::operator+=(unsigned long long rhs)
5880{
5881 return *this += Decimal128(rhs);
5882}
5883
5884 // Subtraction
5885
5887{
5888 this->d_value = DecimalImpUtil::subtract(this->d_value, rhs.d_value);
5889 return *this;
5890}
5891
5893{
5894 return *this = Decimal32(Decimal64(*this) - rhs);
5895}
5896
5898{
5899 return *this = Decimal32(Decimal128(*this) - rhs);
5900}
5901
5903{
5904 return *this -= Decimal64(rhs);
5905}
5906
5908{
5909 return *this -= Decimal64(rhs);
5910}
5911
5913{
5914 return *this -= Decimal64(rhs);
5915}
5916
5918{
5919 return *this -= Decimal64(rhs);
5920}
5921
5923{
5924 return *this -= Decimal128(rhs);
5925}
5926
5927inline Decimal_Type32& Decimal_Type32::operator-=(unsigned long long rhs)
5928{
5929 return *this -= Decimal128(rhs);
5930}
5931
5932 // Multiplication
5933
5935{
5936 this->d_value = DecimalImpUtil::multiply(this->d_value, rhs.d_value);
5937 return *this;
5938}
5939
5941{
5942 return *this = Decimal32(Decimal64(*this) * rhs);
5943}
5944
5946{
5947 return *this = Decimal32(Decimal128(*this) * rhs);
5948}
5949
5951{
5952 return *this *= Decimal64(rhs);
5953}
5954
5956{
5957 return *this *= Decimal64(rhs);
5958}
5959
5961{
5962 return *this *= Decimal64(rhs);
5963}
5964
5966{
5967 return *this *= Decimal64(rhs);
5968}
5969
5971{
5972 return *this *= Decimal128(rhs);
5973}
5974
5975inline Decimal_Type32& Decimal_Type32::operator*=(unsigned long long rhs)
5976{
5977 return *this *= Decimal128(rhs);
5978}
5979
5980 // Division
5981
5983{
5984 this->d_value = DecimalImpUtil::divide(this->d_value, rhs.d_value);
5985 return *this;
5986}
5987
5989{
5990 return *this = Decimal32(Decimal64(*this) / rhs);
5991}
5992
5994{
5995 return *this = Decimal32(Decimal128(*this) / rhs);
5996}
5997
5999{
6000 return *this /= Decimal64(rhs);
6001}
6002
6004{
6005 return *this /= Decimal64(rhs);
6006}
6007
6009{
6010 return *this /= Decimal64(rhs);
6011}
6012
6014{
6015 return *this /= Decimal64(rhs);
6016}
6017
6019{
6020 return *this /= Decimal128(rhs);
6021}
6022
6023inline Decimal_Type32& Decimal_Type32::operator/=(unsigned long long rhs)
6024{
6025 return *this /= Decimal128(rhs);
6026}
6027
6028
6029inline
6031{
6032 return &d_value;
6033}
6034
6035 // Aspects
6036
6037template <class STREAM>
6038STREAM& Decimal_Type32::bdexStreamIn(STREAM& stream, int version)
6039{
6040 if (stream) {
6041 switch (version) { // switch on the schema version
6042 case 1: {
6044 stream.getUint32(bidVal);
6045
6046 if (stream) {
6047 d_value.d_raw = bidVal;
6048 }
6049 else {
6050 stream.invalidate();
6051 }
6052 } break;
6053 default: {
6054 stream.invalidate(); // unrecognized version number
6055 }
6056 }
6057 }
6058 return stream;
6059}
6060
6061inline
6063{
6064 return &d_value;
6065}
6066
6067inline
6069{
6070 return d_value;
6071}
6072
6073 // Aspects
6074
6075template <class STREAM>
6076STREAM& Decimal_Type32::bdexStreamOut(STREAM& stream, int version) const
6077{
6078 if (stream) {
6079 switch (version) { // switch on the schema version
6080 case 1: {
6081 stream.putUint32(d_value.d_raw);
6082 } break;
6083 default: {
6084 stream.invalidate(); // unrecognized version number
6085 }
6086 }
6087 }
6088 return stream;
6089}
6090
6091 // --------------------
6092 // class Decimal_Type64
6093 // --------------------
6094
6095// CLASS METHODS
6096
6097 // Aspects
6098inline
6100{
6101 return 1;
6102}
6103
6104inline
6105int Decimal_Type64::maxSupportedBdexVersion(int /* versionSelector */)
6106{
6107 return 1;
6108}
6109
6110// CREATORS
6111inline
6113{
6114 bsl::memset(&d_value, 0, sizeof(d_value));
6115}
6116
6117inline
6119: d_value(value)
6120{
6121}
6122
6123inline
6125: d_value(DecimalImpUtil::convertToDecimal64(*other.data()))
6126{
6127}
6128
6129inline
6131: d_value(DecimalImpUtil::convertToDecimal64(*other.data()))
6132{
6133}
6134
6135 // Numerical Conversion Constructors
6136
6137inline
6139: d_value(DecimalImpUtil::binaryToDecimal64(other))
6140{
6141}
6142
6143inline
6145: d_value(DecimalImpUtil::binaryToDecimal64(other))
6146{
6147}
6148
6149 // Integral Conversion Constructors
6150
6151inline
6153: d_value(DecimalImpUtil::int32ToDecimal64(other))
6154{
6155}
6156
6157inline
6159: d_value(DecimalImpUtil::uint32ToDecimal64(other))
6160{
6161}
6162
6163inline
6165: d_value(DecimalImpUtil::int64ToDecimal64(other))
6166{
6167}
6168
6169inline
6171: d_value(DecimalImpUtil::uint64ToDecimal64(other))
6172{
6173}
6174
6175inline
6177: d_value(DecimalImpUtil::int64ToDecimal64(other))
6178{
6179}
6180
6181inline
6182Decimal_Type64::Decimal_Type64(unsigned long long other)
6183: d_value(DecimalImpUtil::uint64ToDecimal64(other))
6184{
6185}
6186
6187
6188// MANIPULATORS
6189
6190 // Incrementation and Decrementation
6191
6193{
6194 return *this += Decimal64(1);
6195}
6196
6198{
6199 return *this -= Decimal64(1);
6200}
6201
6202 // Addition
6203
6205{
6206 return *this += Decimal64(rhs);
6207}
6208
6210{
6211 this->d_value = DecimalImpUtil::add(this->d_value, rhs.d_value);
6212 return *this;
6213}
6214
6216{
6217 return *this = Decimal64(Decimal128(*this) + rhs);
6218}
6219
6221{
6222 return *this += Decimal64(rhs);
6223}
6224
6226{
6227 return *this += Decimal64(rhs);
6228}
6229
6231{
6232 return *this += Decimal64(rhs);
6233}
6234
6236{
6237 return *this += Decimal64(rhs);
6238}
6239
6241{
6242 return *this += Decimal128(rhs);
6243}
6244
6245inline Decimal_Type64& Decimal_Type64::operator+=(unsigned long long rhs)
6246{
6247 return *this += Decimal128(rhs);
6248}
6249
6250 // Subtraction
6251
6253{
6254 return *this -= Decimal64(rhs);
6255}
6256
6258{
6259 this->d_value = DecimalImpUtil::subtract(this->d_value, rhs.d_value);
6260 return *this;
6261}
6262
6264{
6265 return *this = Decimal64(Decimal128(*this) - rhs);
6266}
6267
6269{
6270 return *this -= Decimal64(rhs);
6271}
6272
6274{
6275 return *this -= Decimal64(rhs);
6276}
6277
6279{
6280 return *this -= Decimal64(rhs);
6281}
6282
6284{
6285 return *this -= Decimal64(rhs);
6286}
6287
6289{
6290 return *this -= Decimal128(rhs);
6291}
6292
6293inline Decimal_Type64& Decimal_Type64::operator-=(unsigned long long rhs)
6294{
6295 return *this -= Decimal128(rhs);
6296}
6297
6298 // Multiplication
6299
6301{
6302 return *this *= Decimal64(rhs);
6303}
6304
6306{
6307 this->d_value = DecimalImpUtil::multiply(this->d_value, rhs.d_value);
6308 return *this;
6309}
6310
6312{
6313 return *this = Decimal64(Decimal128(*this) * rhs);
6314}
6315
6317{
6318 return *this *= Decimal64(rhs);
6319}
6320
6322{
6323 return *this *= Decimal64(rhs);
6324}
6325
6327{
6328 return *this *= Decimal64(rhs);
6329}
6330
6332{
6333 return *this *= Decimal64(rhs);
6334}
6335
6337{
6338 return *this *= Decimal128(rhs);
6339}
6340
6341inline Decimal_Type64& Decimal_Type64::operator*=(unsigned long long rhs)
6342{
6343 return *this *= Decimal128(rhs);
6344}
6345
6346 // Division
6347
6349{
6350 return *this /= Decimal64(rhs);
6351}
6352
6354{
6355 this->d_value = DecimalImpUtil::divide(this->d_value, rhs.d_value);
6356 return *this;
6357}
6358
6360{
6361 return *this = Decimal64(Decimal128(*this) / rhs);
6362}
6363
6365{
6366 return *this /= Decimal64(rhs);
6367}
6368
6370{
6371 return *this /= Decimal64(rhs);
6372}
6373
6375{
6376 return *this /= Decimal64(rhs);
6377}
6378
6380{
6381 return *this /= Decimal64(rhs);
6382}
6383
6385{
6386 return *this /= Decimal128(rhs);
6387}
6388
6389inline Decimal_Type64& Decimal_Type64::operator/=(unsigned long long rhs)
6390{
6391 return *this /= Decimal128(rhs);
6392}
6393
6394 // Aspects
6395
6396template <class STREAM>
6397STREAM& Decimal_Type64::bdexStreamIn(STREAM& stream, int version)
6398{
6399 if (stream) {
6400 switch (version) { // switch on the schema version
6401 case 1: {
6403 stream.getUint64(bidVal);
6404
6405 if (stream) {
6406 d_value.d_raw = bidVal;
6407 }
6408 else {
6409 stream.invalidate();
6410 }
6411 } break;
6412 default: {
6413 stream.invalidate(); // unrecognized version number
6414 }
6415 }
6416 }
6417
6418 return stream;
6419}
6420
6421//ACCESSORS
6422
6423 // Internals Accessors
6424
6426{
6427 return &d_value;
6428}
6429
6431{
6432 return &d_value;
6433}
6434
6436{
6437 return d_value;
6438}
6439
6440 // Aspects
6441
6442template <class STREAM>
6443STREAM& Decimal_Type64::bdexStreamOut(STREAM& stream, int version) const
6444{
6445 if (stream) {
6446 switch (version) { // switch on the schema version
6447 case 1: {
6448 stream.putUint64(d_value.d_raw);
6449 } break;
6450 default: {
6451 stream.invalidate(); // unrecognized version number
6452 }
6453 }
6454 }
6455 return stream;
6456}
6457
6458 // ---------------------
6459 // class Decimal_Type128
6460 // ---------------------
6461
6462// CLASS METHODS
6463
6464 // Aspects
6465inline
6467{
6468 return 1;
6469}
6470
6471inline
6472int Decimal_Type128::maxSupportedBdexVersion(int /* versionSelector */)
6473{
6474 return 1;
6475}
6476
6477// CREATORS
6478inline
6480{
6481 bsl::memset(&d_value, 0, sizeof(d_value));
6482}
6483
6484inline
6489
6490inline
6492: d_value(DecimalImpUtil::convertToDecimal128(*value.data()))
6493{
6494}
6495
6496inline
6498: d_value(DecimalImpUtil::convertToDecimal128(*value.data()))
6499{
6500}
6501
6502inline
6504: d_value(DecimalImpUtil::binaryToDecimal128(other))
6505{
6506}
6507
6508inline
6510: d_value(DecimalImpUtil::binaryToDecimal128(other))
6511{
6512}
6513
6514inline
6516: d_value(DecimalImpUtil::int32ToDecimal128(value))
6517{
6518}
6519
6520inline Decimal_Type128::Decimal_Type128(unsigned int value)
6521: d_value(DecimalImpUtil::uint32ToDecimal128(value))
6522{
6523}
6524
6526: d_value(DecimalImpUtil::int64ToDecimal128(value))
6527{
6528}
6529
6530inline Decimal_Type128::Decimal_Type128(unsigned long value)
6531: d_value(DecimalImpUtil::uint64ToDecimal128(value))
6532{
6533}
6534
6536: d_value(DecimalImpUtil::int64ToDecimal128(value))
6537{
6538}
6539
6540inline Decimal_Type128::Decimal_Type128(unsigned long long value)
6541: d_value(DecimalImpUtil::uint64ToDecimal128(value))
6542{
6543}
6544
6545
6546inline
6548{
6549 return *this += Decimal128(1);
6550}
6551
6552inline
6554{
6555 return *this -= Decimal128(1);
6556}
6557
6558 // Addition
6559
6560inline
6562{
6563 return *this += Decimal128(rhs);
6564}
6565
6566inline
6568{
6569 return *this += Decimal128(rhs);
6570}
6571
6572inline
6574{
6575 this->d_value = DecimalImpUtil::add(this->d_value, rhs.d_value);
6576 return *this;
6577}
6578
6579inline
6581{
6582 return *this += Decimal128(rhs);
6583}
6584
6585inline
6587{
6588 return *this += Decimal128(rhs);
6589}
6590
6591inline
6593{
6594 return *this += Decimal128(rhs);
6595}
6596
6597inline
6599{
6600 return *this += Decimal128(rhs);
6601}
6602
6603inline
6605{
6606 return *this += Decimal128(rhs);
6607}
6608
6609inline
6611{
6612 return *this += Decimal128(rhs);
6613}
6614
6615 // Subtraction
6616
6617inline
6619{
6620 return *this -= Decimal128(rhs);
6621}
6622
6623inline
6625{
6626 return *this -= Decimal128(rhs);
6627}
6628
6629inline
6631{
6632 this->d_value = DecimalImpUtil::subtract(this->d_value, rhs.d_value);
6633 return *this;
6634}
6635
6636
6637inline
6639{
6640 return *this -= Decimal128(rhs);
6641}
6642
6643inline
6645{
6646 return *this -= Decimal128(rhs);
6647}
6648
6649inline
6651{
6652 return *this -= Decimal128(rhs);
6653}
6654
6655inline
6657{
6658 return *this -= Decimal128(rhs);
6659}
6660
6661inline
6663{
6664 return *this -= Decimal128(rhs);
6665}
6666
6667inline
6669{
6670 return *this -= Decimal128(rhs);
6671}
6672
6673 // Multiplication
6674
6675inline
6677{
6678 return *this *= Decimal128(rhs);
6679}
6680
6681inline
6683{
6684 return *this *= Decimal128(rhs);
6685}
6686
6687inline
6689{
6690 this->d_value = DecimalImpUtil::multiply(this->d_value, rhs.d_value);
6691 return *this;
6692}
6693
6694
6695inline
6697{
6698 return *this *= Decimal128(rhs);
6699}
6700
6701inline
6703{
6704 return *this *= Decimal128(rhs);
6705}
6706
6707inline
6709{
6710 return *this *= Decimal128(rhs);
6711}
6712
6713inline
6715{
6716 return *this *= Decimal128(rhs);
6717}
6718
6719inline
6721{
6722 return *this *= Decimal128(rhs);
6723}
6724
6725inline
6727{
6728 return *this *= Decimal128(rhs);
6729}
6730
6731 // Division
6732
6733inline
6735{
6736 return *this /= Decimal128(rhs);
6737}
6738
6739inline
6741{
6742 return *this /= Decimal128(rhs);
6743}
6744
6745inline
6747{
6748 this->d_value = DecimalImpUtil::divide(this->d_value, rhs.d_value);
6749 return *this;
6750}
6751
6752
6753inline
6755{
6756 return *this /= Decimal128(rhs);
6757}
6758
6759inline
6761{
6762 return *this /= Decimal128(rhs);
6763}
6764
6765inline
6767{
6768 return *this /= Decimal128(rhs);
6769}
6770
6771inline
6773{
6774 return *this /= Decimal128(rhs);
6775}
6776
6777inline
6779{
6780 return *this /= Decimal128(rhs);
6781}
6782
6783inline
6785{
6786 return *this /= Decimal128(rhs);
6787}
6788
6789 // Internals Accessors
6790
6791inline
6793{
6794 return &d_value;
6795}
6796
6797 // Aspects
6798
6799template <class STREAM>
6800STREAM& Decimal_Type128::bdexStreamIn(STREAM& stream, int version)
6801{
6802 if (stream) {
6803 switch (version) { // switch on the schema version
6804 case 1: {
6806 const int len = sizeof(DecimalStorage::Type128)
6807 / sizeof(unsigned char);
6808
6809 unsigned char *value_p =
6810 reinterpret_cast<unsigned char *>(&bidVal);
6811
6812#ifdef BSLS_PLATFORM_IS_BIG_ENDIAN
6813 for (int i(0); i < len; ++i) {
6814 stream.getUint8(*(value_p + i));
6815 }
6816#elif defined(BSLS_PLATFORM_IS_LITTLE_ENDIAN)
6817 for (int i(len - 1); i >= 0; --i) {
6818 stream.getUint8(*(value_p + i));
6819 }
6820#endif
6821 if (stream) {
6822 d_value.d_raw = bidVal;
6823 }
6824 else {
6825 stream.invalidate();
6826 }
6827 } break;
6828 default: {
6829 stream.invalidate(); // unrecognized version number
6830 }
6831 }
6832 }
6833 return stream;
6834}
6835
6836inline
6838{
6839 return &d_value;
6840}
6841
6842inline
6844{
6845 return d_value;
6846}
6847
6848 // Aspects
6849
6850template <class STREAM>
6851STREAM& Decimal_Type128::bdexStreamOut(STREAM& stream, int version) const
6852{
6853 if (stream) {
6854 switch (version) { // switch on the schema version
6855 case 1: {
6856 const int len = sizeof(DecimalStorage::Type128)
6857 / sizeof(unsigned char);
6858
6859 const unsigned char *value_p =
6860 reinterpret_cast<const unsigned char *>(&d_value.d_raw);
6861
6862#ifdef BSLS_PLATFORM_IS_BIG_ENDIAN
6863 for (int i(0); i < len; ++i) {
6864 stream.putUint8(*(value_p + i));
6865 }
6866#elif defined(BSLS_PLATFORM_IS_LITTLE_ENDIAN)
6867 for (int i(len - 1); i >= 0; --i) {
6868 stream.putUint8(*(value_p + i));
6869 }
6870#endif
6871 } break;
6872 default: {
6873 stream.invalidate(); // unrecognized version number
6874 }
6875 }
6876 }
6877 return stream;
6878}
6879
6880 // ------------------------------------
6881 // class Decimal_FormatterSpecification
6882 // ------------------------------------
6883
6884// PRIVATE MANIPULATORS
6885template <class t_CHAR>
6888 const bsl::basic_string_view<t_CHAR>& typeString)
6889{
6890 // Handle empty string or empty specification.
6891 if (typeString.empty()) {
6892 d_formatType = e_FORMAT_DEFAULT;
6893 return; // RETURN
6894 }
6895
6896 // Standard format strings only allow a single type character.
6897 if (typeString.size() > 1) {
6898 d_formatType = e_TYPE_UNASSIGNED;
6899 BSLS_THROW(bsl::format_error( // THROW
6900 "Decimal floating point format types are single-character"));
6901 }
6902
6903 const t_CHAR frontChar = typeString.front();
6904
6905 // The type character can only be ASCII so we can do a simple cast.
6906 const char typeChar = (frontChar >= 0 && frontChar <= 0x7f)
6907 ? static_cast<char>(frontChar)
6908 : static_cast<char>(0);
6909
6910 switch (typeChar) {
6911 case 'e': {
6912 d_formatType = e_FORMAT_SCIENTIFIC;
6913 } break;
6914 case 'E': {
6915 d_formatType = e_FORMAT_SCIENTIFIC_UC;
6916 } break;
6917 case 'f': {
6918 d_formatType = e_FORMAT_FIXED;
6919 } break;
6920 case 'F': {
6921 d_formatType = e_FORMAT_FIXED_UC;
6922 } break;
6923 case 'g': {
6924 d_formatType = e_FORMAT_GENERAL;
6925 } break;
6926 case 'G': {
6927 d_formatType = e_FORMAT_GENERAL_UC;
6928 } break;
6929 default: {
6930 d_formatType = e_TYPE_UNASSIGNED;
6931 BSLS_THROW(bsl::format_error(
6932 "Invalid format type for decimal floating points")); // THROW
6933 }
6934 }
6935
6936 if (e_TYPE_UNASSIGNED == d_formatType)
6937 BSLS_THROW(bsl::format_error( // THROW
6938 "Failed to parse decimal floating point format type "
6939 "(reason unknown)"));
6940
6941 return;
6942}
6943
6944// PRIVATE ACCESSORS
6945template <class t_CHAR>
6947void Decimal_FormatterSpecification<t_CHAR>::ensureParsingComplete() const
6948{
6949 if (d_parsingStatus == Parser::e_STATE_UNPARSED) {
6950 BSLS_THROW(bsl::format_error( // THROW
6951 "Decimal format specification '.parse()' was not called"));
6952 }
6953}
6954
6955template <class t_CHAR>
6957Decimal_FormatterSpecification<t_CHAR>::ensurePostprocessingComplete() const
6958{
6959 if (d_parsingStatus != Parser::e_STATE_POSTPROCESSED) {
6960 BSLS_THROW(bsl::format_error( // THROW
6961 "Decimal format specification '.postprocess()' was not called"));
6962 }
6963}
6964
6965// CREATORS
6966template <class t_CHAR>
6969: d_parsingStatus(Parser::e_STATE_UNPARSED)
6970, d_parser()
6971, d_formatType(e_TYPE_UNASSIGNED)
6972{
6973}
6974
6975// ACCESSORS
6976template <class t_CHAR>
6979{
6980 ensurePostprocessingComplete();
6981 return d_parser.filler();
6982}
6983
6984template <class t_CHAR>
6987{
6988 ensurePostprocessingComplete();
6989 return d_parser.numFillerCharacters();
6990}
6991
6992template <class t_CHAR>
6995{
6996 ensurePostprocessingComplete();
6997 return d_parser.fillerCodePointDisplayWidth();
6998}
6999
7000template <class t_CHAR>
7004{
7005 ensureParsingComplete();
7006 return d_parser.alignment();
7007}
7008
7009template <class t_CHAR>
7013{
7014 ensureParsingComplete();
7015 return d_parser.sign();
7016}
7017
7018template <class t_CHAR>
7021{
7022 ensureParsingComplete();
7023 return d_parser.alternativeFlag();
7024}
7025
7026template <class t_CHAR>
7029{
7030 ensureParsingComplete();
7031 return d_parser.zeroPaddingFlag();
7032}
7033
7034template <class t_CHAR>
7038{
7039 ensurePostprocessingComplete();
7040 return d_parser.postprocessedWidth();
7041}
7042
7043template <class t_CHAR>
7047{
7048 ensurePostprocessingComplete();
7049 return d_parser.postprocessedPrecision();
7050}
7051
7052template <class t_CHAR>
7055{
7056 ensureParsingComplete();
7057 return d_parser.localeSpecificFlag();
7058}
7059
7060template <class t_CHAR>
7064{
7065 ensureParsingComplete();
7066 return d_formatType;
7067}
7068
7069// CLASS METHODS
7070template <class t_CHAR>
7071template <class t_PARSE_CONTEXT>
7074{
7075 BSLMF_ASSERT((
7076 bsl::is_same<typename bsl::iterator_traits<
7077 typename t_PARSE_CONTEXT::const_iterator>::value_type,
7078 t_CHAR>::value));
7079
7080 d_parsingStatus = Parser::e_STATE_PARSED;
7081
7082 const typename Parser::Sections sect =
7083 static_cast<typename Parser::Sections>(
7084 Parser::e_SECTIONS_FILL_ALIGN |
7085 Parser::e_SECTIONS_SIGN_FLAG |
7086 Parser::e_SECTIONS_ALTERNATE_FLAG |
7087 Parser::e_SECTIONS_ZERO_PAD_FLAG |
7088 Parser::e_SECTIONS_WIDTH |
7089 Parser::e_SECTIONS_PRECISION |
7090 Parser::e_SECTIONS_LOCALE_FLAG |
7091 Parser::e_SECTIONS_REMAINING_SPEC);
7092
7093 d_parser.parse(context, sect);
7094
7095 parseType(d_parser.remainingSpec());
7096
7097 if (context->begin() == context->end() || *context->begin() == '}') {
7098 return; // RETURN
7099 }
7100
7101 BSLS_THROW(bsl::format_error( // THROW
7102 "Decimal floating point specification parse failure "
7103 "(invalid character)"));
7104}
7105
7106template <class t_CHAR>
7107template <typename t_FORMAT_CONTEXT>
7109 const t_FORMAT_CONTEXT& context)
7110{
7111 ensureParsingComplete();
7112
7113 d_parser.postprocess(context);
7114
7115 switch (d_parser.postprocessedWidth().category()) {
7117
7119 if (d_parser.postprocessedWidth().value() <= 0)
7120 BSLS_THROW(bsl::format_error("Zero or negative width value"));
7121 // THROW
7122 } break;
7123 default: {
7124 BSLS_THROW(bsl::format_error("Failed to find valid width value"));
7125 // THROW
7126 }
7127 }
7128
7129 switch (d_parser.postprocessedPrecision().category()) {
7131
7133 if (d_parser.postprocessedPrecision().value() < 0)
7134 BSLS_THROW(bsl::format_error("Negative precision value")); // THROW
7135 } break;
7136 default: {
7137 BSLS_THROW(bsl::format_error("Failed to find valid precision value"));
7138 // THROW
7139 }
7140 }
7141
7142 d_parsingStatus = Parser::e_STATE_POSTPROCESSED;
7143}
7144
7145 // -------------------------------------------
7146 // template struct Decimal_BslFmtFormatterImpl
7147 // -------------------------------------------
7148
7149// PRIVATE MANIPULATORS
7150template <class t_VALUE, class t_CHAR>
7151template <class t_FORMAT_CONTEXT>
7152typename t_FORMAT_CONTEXT::iterator
7154 const char *numberBuffer,
7155 size_t numberLength,
7156 t_FORMAT_CONTEXT& formatContext,
7157 const Specification& finalSpec) const
7158{
7159 typedef bslfmt::FormatterSpecificationNumericValue NumericValue;
7161 typedef bslfmt::PadUtil<t_CHAR> PadUtil;
7162 typedef bslfmt::FormatterCharUtil<t_CHAR> FormatterCharUtil;
7163
7164 NumericValue finalWidth(finalSpec.postprocessedWidth());
7165
7166 std::ptrdiff_t leftPadFillerCopiesNum = 0;
7167 std::ptrdiff_t rightPadFillerCopiesNum = 0;
7168 std::ptrdiff_t zeroPadFillerCopiesNum = 0;
7169
7170 const char signChar = *numberBuffer == '-'
7171 ? *numberBuffer
7172 : *numberBuffer == '+'
7173 ? *numberBuffer
7174 : *numberBuffer == ' '
7175 ? *numberBuffer
7176 : '\0';
7177 const bool hasSignChar = (signChar != 0);
7178
7179 if (hasSignChar) {
7180 // We are going to add the sign back "by hand"
7181 ++numberBuffer;
7182 --numberLength;
7183 }
7184
7185 // Check if we have a non-numerical value of "inf" or "nan", in which case
7186 // we must no use zero padding.
7187 const char lastChar = numberBuffer[numberLength - 1];
7188 const bool specialValue = 'f' == lastChar || 'n' == lastChar
7189 || 'F' == lastChar || 'N' == lastChar;
7190
7191 if ((NumericValue::e_DEFAULT != finalWidth.category()) &&
7192 (numberLength + hasSignChar <
7193 static_cast<size_t>(finalWidth.value()))) {
7194 // We need to fill the remaining space.
7195
7196 if (!specialValue &&
7197 Parser::e_ALIGN_DEFAULT == finalSpec.alignment() &&
7198 finalSpec.zeroPaddingFlag()) {
7199 // Space will be filled with zeros.
7200
7201 zeroPadFillerCopiesNum =
7202 finalWidth.value() - (numberLength + hasSignChar);
7203 }
7204 else {
7205 // Alignment with appropriate symbol is required.
7206
7207 PadUtil::computePadding(&leftPadFillerCopiesNum,
7208 &rightPadFillerCopiesNum,
7209 finalWidth,
7210 numberLength + hasSignChar,
7211 d_spec.alignment(),
7212 Parser::e_ALIGN_RIGHT);
7213 }
7214 }
7215
7216 // Assembling the final string.
7217
7218 typename t_FORMAT_CONTEXT::iterator outIterator = formatContext.out();
7219 const bsl::basic_string_view<t_CHAR> filler(finalSpec.filler(),
7220 finalSpec.fillerCharacters());
7221
7222 outIterator = PadUtil::pad(outIterator, leftPadFillerCopiesNum, filler);
7223
7224 if (hasSignChar) {
7225 outIterator = FormatterCharUtil::outputFromChar(signChar, outIterator);
7226 }
7227
7228 outIterator = PadUtil::pad(outIterator, zeroPadFillerCopiesNum, '0');
7229
7230 outIterator = FormatterCharUtil::outputFromChar(
7231 numberBuffer,
7232 numberBuffer + numberLength,
7233 outIterator);
7234
7235 outIterator = PadUtil::pad(outIterator, rightPadFillerCopiesNum, filler);
7236
7237 return outIterator;
7238}
7239
7240template <class t_VALUE, class t_CHAR>
7241template <class t_PARSE_CONTEXT>
7242BSLS_KEYWORD_CONSTEXPR_CPP20 typename t_PARSE_CONTEXT::iterator
7244 t_PARSE_CONTEXT& parseContext)
7245{
7246 d_spec.parse(&parseContext);
7247
7248 if (d_spec.localeSpecificFlag()) {
7249 BSLS_THROW(bsl::format_error( // THROW
7250 "Formatting with the L specifier is not supported"));
7251 }
7252
7253 return parseContext.begin();
7254}
7255
7256template <class t_VALUE, class t_CHAR>
7257template <class t_FORMAT_CONTEXT>
7258typename t_FORMAT_CONTEXT::iterator
7260 const t_VALUE& value,
7261 t_FORMAT_CONTEXT& formatContext) const
7262{
7263
7264 typedef bslfmt::FormatterSpecificationNumericValue NumericValue;
7266
7267 Specification finalSpec(d_spec);
7268 finalSpec.postprocess(formatContext);
7269
7270 const int precision = NumericValue::e_DEFAULT ==
7271 finalSpec.postprocessedPrecision().category()
7272 ? -1
7273 : finalSpec.postprocessedPrecision().value();
7274
7275 DecimalFormatConfig cfg(precision);
7276
7277 bool upperCase = false;
7278
7279 switch (finalSpec.formatType()) {
7280 case Specification::e_FORMAT_SCIENTIFIC_UC:
7281 upperCase = true;
7283 case Specification::e_FORMAT_SCIENTIFIC: {
7285 } break;
7286
7287 case Specification::e_FORMAT_FIXED_UC:
7288 upperCase = true;
7290 case Specification::e_FORMAT_FIXED: {
7292 } break;
7293
7294 // These are all the default "natural" format
7295 case Specification::e_FORMAT_GENERAL_UC:
7296 upperCase = true;
7298 case Specification::e_FORMAT_DEFAULT: BSLA_FALLTHROUGH;
7299 case Specification::e_FORMAT_GENERAL: break;
7300
7301 default: {
7302 BSLS_THROW(bsl::format_error("Unknown decimal floating point format"));
7303 }
7304 }
7305
7306 switch (finalSpec.sign()) {
7307 case Parser::e_SIGN_DEFAULT: BSLA_FALLTHROUGH;
7308 case Parser::e_SIGN_NEGATIVE: {
7310 } break;
7311 case Parser::e_SIGN_POSITIVE: {
7313 } break;
7314 case Parser::e_SIGN_SPACE: {
7316 } break;
7317 }
7318
7319 if (finalSpec.alternativeFlag()) {
7321 }
7322 if (upperCase) {
7323 cfg.setInfinity("INF");
7324 cfg.setNan("NAN");
7325 cfg.setSNan("NAN");
7326 cfg.setExponent('E');
7327 }
7328 else {
7329 cfg.setInfinity("inf");
7330 cfg.setNan("nan");
7331 cfg.setSNan("nan");
7332 cfg.setExponent('e');
7333 }
7334
7335 typedef bsl::numeric_limits<t_VALUE> Limits;
7336 const int effectivePrecision = precision > Limits::max_precision
7337 ? precision
7338 : Limits::max_precision;
7339
7340 const int k_STACK_BUF_LEN = 1 // sign
7341 + 1 + Limits::max_exponent10 // integer part
7342 + 1 // decimal point
7343 + Limits::max_precision; // partial part
7344
7345 const int reqdBufferSize = 1 // sign
7346 + 1 + Limits::max_exponent10 // integer part
7347 + 1 // decimal point
7348 + effectivePrecision; // partial part
7349 // The size of the buffer sufficient to store max 'DECIMAL' value in
7350 // fixed notation with the max precision supported by 'DECIMAL' type,
7351 // or the requested precision if it is larger than the maximum.
7352
7353 char sbuf[k_STACK_BUF_LEN];
7354 char *dbuf = 0;
7355 char *buffer = sbuf;
7356
7358 if (reqdBufferSize > k_STACK_BUF_LEN) {
7359 dbuf = allocator.allocate(reqdBufferSize);
7360 buffer = dbuf;
7361 }
7363 allocator,
7364 dbuf,
7365 dbuf ? reqdBufferSize : 0);
7366
7367 const int len = DecimalImpUtil::format(buffer,
7368 reqdBufferSize,
7369 *value.data(),
7370 cfg);
7371 BSLS_ASSERT(len <= reqdBufferSize);
7372
7373 return alignAndCopy(buffer, len, formatContext, finalSpec);
7374}
7375
7376} // close package namespace
7377
7378
7379// FREE OPERATORS
7380
7381inline
7383{
7384 return value;
7385}
7386
7387inline
7389{
7390 return Decimal32(DecimalImpUtil::negate(value.value()));
7391}
7392
7393inline
7395{
7396 bdldfp::Decimal32 result(value);
7397 ++value;
7398 return result;
7399}
7400
7401inline
7403{
7404 bdldfp::Decimal32 result(value);
7405 --value;
7406 return result;
7407}
7408
7409 // Addition
7410
7411inline
7414{
7415 return DecimalImpUtil::add(*lhs.data(), *rhs.data());
7416}
7417
7418inline
7420 int rhs)
7421{
7422 return Decimal32(lhs + Decimal64(rhs));
7423}
7424
7425inline
7427 unsigned int rhs)
7428{
7429 return Decimal32(lhs + Decimal64(rhs));
7430}
7431
7432inline
7434 long rhs)
7435{
7436 return Decimal32(lhs + Decimal64(rhs));
7437}
7438
7439inline
7441 unsigned long rhs)
7442{
7443 return Decimal32(lhs + Decimal64(rhs));
7444}
7445
7446inline
7448 long long rhs)
7449{
7450 return Decimal32(lhs + Decimal128(rhs));
7451}
7452
7453inline
7455 unsigned long long rhs)
7456{
7457 return Decimal32(lhs + Decimal128(rhs));
7458}
7459
7460inline
7463{
7464 return Decimal32(Decimal64(lhs) + rhs);
7465}
7466
7467inline
7468bdldfp::Decimal32 bdldfp::operator+(unsigned int lhs,
7470{
7471 return Decimal32(Decimal64(lhs) + rhs);
7472}
7473
7474inline
7477{
7478 return Decimal32(Decimal64(lhs) + rhs);
7479}
7480
7481inline
7482bdldfp::Decimal32 bdldfp::operator+(unsigned long lhs,
7484{
7485 return Decimal32(Decimal64(lhs) + rhs);
7486}
7487
7488inline
7491{
7492 return Decimal32(Decimal128(lhs) + rhs);
7493}
7494
7495inline
7496bdldfp::Decimal32 bdldfp::operator+(unsigned long long lhs,
7498{
7499 return Decimal32(Decimal128(lhs) + rhs);
7500}
7501
7502
7503 // Subtraction
7504
7505inline
7508{
7509 return DecimalImpUtil::subtract(*lhs.data(), *rhs.data());
7510}
7511
7512inline
7514 int rhs)
7515{
7516 return Decimal32(lhs - Decimal64(rhs));
7517}
7518
7519inline
7521 unsigned int rhs)
7522{
7523 return Decimal32(lhs - Decimal64(rhs));
7524}
7525
7526inline
7528 long rhs)
7529{
7530 return Decimal32(lhs - Decimal64(rhs));
7531}
7532
7533inline
7535 unsigned long rhs)
7536{
7537 return Decimal32(lhs - Decimal64(rhs));
7538}
7539
7540inline
7542 long long rhs)
7543{
7544 return Decimal32(lhs - Decimal128(rhs));
7545}
7546
7547inline
7549 unsigned long long rhs)
7550{
7551 return Decimal32(lhs - Decimal128(rhs));
7552}
7553
7554inline
7557{
7558 return Decimal32(Decimal64(lhs) - rhs);
7559}
7560
7561inline
7562bdldfp::Decimal32 bdldfp::operator-(unsigned int lhs,
7564{
7565 return Decimal32(Decimal64(lhs) - rhs);
7566}
7567
7568inline
7571{
7572 return Decimal32(Decimal64(lhs) - rhs);
7573}
7574
7575inline
7576bdldfp::Decimal32 bdldfp::operator-(unsigned long lhs,
7578{
7579 return Decimal32(Decimal64(lhs) - rhs);
7580}
7581
7582inline
7585{
7586 return Decimal32(Decimal128(lhs) - Decimal64(rhs));
7587}
7588
7589inline
7590bdldfp::Decimal32 bdldfp::operator-(unsigned long long lhs,
7592{
7593 return Decimal32(Decimal128(lhs) - Decimal64(rhs));
7594}
7595
7596 // Multiplication
7597
7600{
7601 return DecimalImpUtil::multiply(*lhs.data(), *rhs.data());
7602}
7603
7604inline
7606 int rhs)
7607{
7608 return Decimal32(lhs * Decimal64(rhs));
7609}
7610
7611inline
7613 unsigned int rhs)
7614{
7615 return Decimal32(lhs * Decimal64(rhs));
7616}
7617
7618inline
7620 long rhs)
7621{
7622 return Decimal32(lhs * Decimal64(rhs));
7623}
7624
7625inline
7627 unsigned long rhs)
7628{
7629 return Decimal32(lhs * Decimal64(rhs));
7630}
7631
7632inline
7634 long long rhs)
7635{
7636 return Decimal32(lhs * Decimal128(rhs));
7637}
7638
7639inline
7641 unsigned long long rhs)
7642{
7643 return Decimal32(lhs * Decimal128(rhs));
7644}
7645
7646inline
7649{
7650 return Decimal32(Decimal64(lhs) * rhs);
7651}
7652
7653inline
7654bdldfp::Decimal32 bdldfp::operator*(unsigned int lhs,
7656{
7657 return Decimal32(Decimal64(lhs) * rhs);
7658}
7659
7660inline
7663{
7664 return Decimal32(Decimal64(lhs) * rhs);
7665}
7666
7667inline
7668bdldfp::Decimal32 bdldfp::operator*(unsigned long lhs,
7670{
7671 return Decimal32(Decimal64(lhs) * rhs);
7672}
7673
7674inline
7677{
7678 return Decimal32(Decimal128(lhs) * rhs);
7679}
7680
7681inline
7682bdldfp::Decimal32 bdldfp::operator*(unsigned long long lhs,
7684{
7685 return Decimal32(Decimal128(lhs) * rhs);
7686}
7687
7688 // Division
7689
7690inline
7693{
7694 return DecimalImpUtil::divide(*lhs.data(), *rhs.data());
7695}
7696
7697inline
7699 int rhs)
7700{
7701 return Decimal32(lhs / Decimal64(rhs));
7702}
7703
7704inline
7706 unsigned int rhs)
7707{
7708 return Decimal32(lhs / Decimal64(rhs));
7709}
7710
7711inline
7713 long rhs)
7714{
7715 return Decimal32(lhs / Decimal64(rhs));
7716}
7717
7718inline
7720 unsigned long rhs)
7721{
7722 return Decimal32(lhs / Decimal64(rhs));
7723}
7724
7725inline
7727 long long rhs)
7728{
7729 return Decimal32(lhs / Decimal128(rhs));
7730}
7731
7732inline
7734 unsigned long long rhs)
7735{
7736 return Decimal32(lhs / Decimal128(rhs));
7737}
7738
7739inline
7742{
7743 return Decimal32(Decimal64(lhs) / rhs);
7744}
7745
7746inline
7747bdldfp::Decimal32 bdldfp::operator/(unsigned int lhs,
7749{
7750 return Decimal32(Decimal64(lhs) / rhs);
7751}
7752
7753inline
7756{
7757 return Decimal32(Decimal64(lhs) / Decimal64(rhs));
7758}
7759
7760inline
7761bdldfp::Decimal32 bdldfp::operator/(unsigned long lhs,
7763{
7764 return Decimal32(Decimal64(lhs) / rhs);
7765}
7766
7767inline
7770{
7771 return Decimal32(Decimal128(lhs) / rhs);
7772}
7773
7774inline
7775bdldfp::Decimal32 bdldfp::operator/(unsigned long long lhs,
7777{
7778 return Decimal32(Decimal128(lhs) / rhs);
7779}
7780
7781
7782inline
7784{
7785 return DecimalImpUtil::equal(*lhs.data(), *rhs.data());
7786}
7787
7788inline
7790{
7791 return DecimalImpUtil::notEqual(*lhs.data(), *rhs.data());
7792}
7793
7794inline
7796{
7797 return DecimalImpUtil::less(*lhs.data(), *rhs.data());
7798}
7799
7800inline
7802{
7803 return DecimalImpUtil::lessEqual(*lhs.data(), *rhs.data());
7804}
7805
7806inline
7808{
7809 return DecimalImpUtil::greater(*lhs.data(), *rhs.data());
7810}
7811
7812inline
7814{
7815 return DecimalImpUtil::greaterEqual(*lhs.data(), *rhs.data());
7816}
7817
7818#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
7819 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
7820inline
7821bdldfp::Decimal32 bdldfp::DecimalLiterals::operator""_d32(const char *str)
7822{
7823 return DecimalImpUtil::parse32(str);
7824}
7825
7826inline
7827bdldfp::Decimal32 bdldfp::DecimalLiterals::operator""_d32(
7828 const char *str, bsl::size_t)
7829{
7830 return DecimalImpUtil::parse32(str);
7831}
7832#endif
7833
7834// FREE OPERATORS
7835inline
7837{
7838 return value;
7839}
7840
7841inline
7843{
7844 return DecimalImpUtil::negate(*value.data());
7845}
7846
7847inline
7849{
7850 bdldfp::Decimal64 result(value);
7851 ++value;
7852 return result;
7853}
7854
7855inline
7857{
7858 bdldfp::Decimal64 result(value);
7859 --value;
7860 return result;
7861}
7862
7863 // Addition
7864
7865inline
7868{
7869 return Decimal64(DecimalImpUtil::add(*lhs.data(), *rhs.data()));
7870}
7871
7872inline
7875{
7876 return Decimal64(lhs) + rhs;
7877}
7878
7879inline
7882{
7883 return lhs + Decimal64(rhs);
7884}
7885
7886inline
7888 int rhs)
7889{
7890 return lhs + Decimal64(rhs);
7891}
7892
7893inline
7895 unsigned int rhs)
7896{
7897 return lhs + Decimal64(rhs);
7898}
7899
7900inline
7902 long rhs)
7903{
7904 return lhs + Decimal64(rhs);
7905}
7906
7907inline
7909 unsigned long rhs)
7910{
7911 return lhs + Decimal64(rhs);
7912}
7913
7914inline
7916 long long rhs)
7917{
7918 return Decimal64(lhs + Decimal128(rhs));
7919}
7920
7921inline
7923 unsigned long long rhs)
7924{
7925 return Decimal64(lhs + Decimal128(rhs));
7926}
7927
7928inline
7931{
7932 return Decimal64(lhs) + rhs;
7933}
7934
7935inline
7936bdldfp::Decimal64 bdldfp::operator+(unsigned int lhs,
7938{
7939 return Decimal64(lhs) + rhs;
7940}
7941
7942inline
7945{
7946 return Decimal64(lhs) + rhs;
7947}
7948
7949inline
7950bdldfp::Decimal64 bdldfp::operator+(unsigned long lhs,
7952{
7953 return Decimal64(lhs) + rhs;
7954}
7955
7956inline
7959{
7960 return Decimal64(Decimal128(lhs) + rhs);
7961}
7962
7963inline
7964bdldfp::Decimal64 bdldfp::operator+(unsigned long long lhs,
7966{
7967 return Decimal64(Decimal128(lhs) + rhs);
7968}
7969
7970 // Subtraction
7971
7972inline
7975{
7976 return Decimal64(DecimalImpUtil::subtract(*lhs.data(), *rhs.data()));
7977}
7978
7979inline
7982{
7983 return Decimal64(lhs) - rhs;
7984}
7985
7986inline
7989{
7990 return lhs - Decimal64(rhs);
7991}
7992
7993inline
7995 int rhs)
7996{
7997 return lhs - Decimal64(rhs);
7998}
7999
8000inline
8002 unsigned int rhs)
8003{
8004 return lhs - Decimal64(rhs);
8005}
8006
8007inline
8009 long rhs)
8010{
8011 return lhs - Decimal64(rhs);
8012}
8013
8014inline
8016 unsigned long rhs)
8017{
8018 return lhs - Decimal64(rhs);
8019}
8020
8021inline
8023 long long rhs)
8024{
8025 return Decimal64(lhs - Decimal128(rhs));
8026}
8027
8028inline
8030 unsigned long long rhs)
8031{
8032 return Decimal64(lhs - Decimal128(rhs));
8033}
8034
8035inline
8038{
8039 return Decimal64(lhs) - rhs;
8040}
8041
8042inline
8043bdldfp::Decimal64 bdldfp::operator-(unsigned int lhs,
8045{
8046 return Decimal64(lhs) - rhs;
8047}
8048
8049inline
8052{
8053 return Decimal64(lhs) - rhs;
8054}
8055
8056inline
8057bdldfp::Decimal64 bdldfp::operator-(unsigned long lhs,
8059{
8060 return Decimal64(lhs) - rhs;
8061}
8062
8063inline
8066{
8067 return Decimal64(Decimal128(lhs) - rhs);
8068}
8069
8070inline
8071bdldfp::Decimal64 bdldfp::operator-(unsigned long long lhs,
8073{
8074 return Decimal64(Decimal128(lhs) - rhs);
8075}
8076
8077 // Multiplication
8078
8081{
8082 return Decimal64(DecimalImpUtil::multiply(*lhs.data(), *rhs.data()));
8083}
8084
8087{
8088 return Decimal64(lhs) * rhs;
8089}
8090
8093{
8094 return lhs * Decimal64(rhs);
8095}
8096
8098 int rhs)
8099{
8100 return lhs * Decimal64(rhs);
8101}
8102
8104 unsigned int rhs)
8105{
8106 return lhs * Decimal64(rhs);
8107}
8108
8110 long rhs)
8111{
8112 return lhs * Decimal64(rhs);
8113}
8114
8116 unsigned long rhs)
8117{
8118 return lhs * Decimal64(rhs);
8119}
8120
8122 long long rhs)
8123{
8124 return Decimal64(lhs * Decimal128(rhs));
8125}
8126
8128 unsigned long long rhs)
8129{
8130 return Decimal64(lhs * Decimal128(rhs));
8131}
8132
8135{
8136 return Decimal64(lhs) * rhs;
8137}
8138
8139inline bdldfp::Decimal64 bdldfp::operator*(unsigned int lhs,
8141{
8142 return Decimal64(lhs) * rhs;
8143}
8144
8145inline bdldfp::Decimal64 bdldfp::operator*(long lhs,
8147{
8148 return Decimal64(lhs) * rhs;
8149}
8150
8151inline bdldfp::Decimal64 bdldfp::operator*(unsigned long lhs,
8153{
8154 return Decimal64(lhs) * rhs;
8155}
8156
8157inline bdldfp::Decimal64 bdldfp::operator*(long long lhs,
8159{
8160 return Decimal64(Decimal128(lhs) * rhs);
8161}
8162
8163inline bdldfp::Decimal64 bdldfp::operator*(unsigned long long lhs,
8165{
8166 return Decimal64(Decimal128(lhs) * rhs);
8167}
8168
8169 // Division
8170
8173{
8174 return Decimal64(DecimalImpUtil::divide(*lhs.data(), *rhs.data()));
8175}
8176
8179{
8180 return Decimal64(lhs) / rhs;
8181}
8182
8185{
8186 return lhs / Decimal64(rhs);
8187}
8188
8190 int rhs)
8191{
8192 return lhs / Decimal64(rhs);
8193}
8194
8196 unsigned int rhs)
8197{
8198 return lhs / Decimal64(rhs);
8199}
8200
8202 long rhs)
8203{
8204 return lhs / Decimal64(rhs);
8205}
8206
8208 unsigned long rhs)
8209{
8210 return lhs / Decimal64(rhs);
8211}
8212
8214 long long rhs)
8215{
8216 return Decimal64(lhs / Decimal128(rhs));
8217}
8218
8220 unsigned long long rhs)
8221{
8222 return Decimal64(lhs / Decimal128(rhs));
8223}
8224
8227{
8228 return Decimal64(lhs) / rhs;
8229}
8230
8231inline bdldfp::Decimal64 bdldfp::operator/(unsigned int lhs,
8233{
8234 return Decimal64(lhs) / rhs;
8235}
8236
8237inline bdldfp::Decimal64 bdldfp::operator/(long lhs,
8239{
8240 return Decimal64(lhs) / rhs;
8241}
8242
8243inline bdldfp::Decimal64 bdldfp::operator/(unsigned long lhs,
8245{
8246 return Decimal64(lhs) / rhs;
8247}
8248
8249inline bdldfp::Decimal64 bdldfp::operator/(long long lhs,
8251{
8252 return Decimal64(Decimal128(lhs) / rhs);
8253}
8254
8255inline bdldfp::Decimal64 bdldfp::operator/(unsigned long long lhs,
8257{
8258 return Decimal64(Decimal128(lhs) / rhs);
8259}
8260
8261 // Equality
8262
8264{
8265 return DecimalImpUtil::equal(*lhs.data(), *rhs.data());
8266}
8267
8269{
8270 return Decimal64(lhs) == rhs;
8271}
8272
8274{
8275 return lhs == Decimal64(rhs);
8276}
8277
8278 // Inequality
8279
8281{
8282 return DecimalImpUtil::notEqual(*lhs.data(), *rhs.data());
8283}
8284
8286{
8287 return Decimal64(lhs) != rhs;
8288}
8289
8291{
8292 return lhs != Decimal64(rhs);
8293}
8294
8295 // Less Than
8296
8298{
8299 return DecimalImpUtil::less(*lhs.data(), *rhs.data());
8300}
8301
8303{
8304 return Decimal64(lhs) < rhs;
8305}
8306
8308{
8309 return lhs < Decimal64(rhs);
8310}
8311
8312 // Less Equal
8313
8315{
8316 return DecimalImpUtil::lessEqual(*lhs.data(), *rhs.data());
8317}
8318
8320{
8321 return Decimal64(lhs) <= rhs;
8322}
8323
8325{
8326 return lhs <= Decimal64(rhs);
8327}
8328
8329 // Greater Than
8330
8332{
8333 return DecimalImpUtil::greater(*lhs.data(), *rhs.data());
8334}
8335
8337{
8338 return Decimal64(lhs) > rhs;
8339}
8340
8342{
8343 return lhs > Decimal64(rhs);
8344}
8345
8346 // Greater Equal
8347
8349{
8350 return DecimalImpUtil::greaterEqual(*lhs.data(), *rhs.data());
8351}
8352
8354{
8355 return Decimal64(lhs) >= rhs;
8356}
8357
8359{
8360 return lhs >= Decimal64(rhs);
8361}
8362
8363#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
8364 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
8365inline
8366bdldfp::Decimal64 bdldfp::DecimalLiterals::operator""_d64(const char *str)
8367{
8368 return DecimalImpUtil::parse64(str);
8369}
8370
8371inline
8372bdldfp::Decimal64 bdldfp::DecimalLiterals::operator""_d64(
8373 const char *str, bsl::size_t)
8374{
8375 return DecimalImpUtil::parse64(str);
8376}
8377#endif
8378
8379// FREE OPERATORS
8380
8381inline
8383{
8384 return value;
8385}
8386
8387inline
8389{
8390 return Decimal128(DecimalImpUtil::negate(*value.data()));
8391}
8392
8393inline
8395{
8396 Decimal128 result = value;
8397 ++value;
8398 return result;
8399}
8400
8401inline
8403{
8404 Decimal128 result = value;
8405 --value;
8406 return result;
8407}
8408
8409 // Addition
8410
8411inline
8414{
8415 return Decimal128(DecimalImpUtil::add(*lhs.data(), *rhs.data()));
8416}
8417
8418inline
8421{
8422 return Decimal128(lhs) + rhs;
8423}
8424
8425inline
8428{
8429 return lhs + Decimal128(rhs);
8430}
8431
8432inline
8435{
8436 return Decimal128(lhs) + rhs;
8437}
8438
8439inline
8442{
8443 return lhs + Decimal128(rhs);
8444}
8445
8446inline
8448 int rhs)
8449{
8450 return lhs + Decimal128(rhs);
8451}
8452
8453inline
8455 unsigned int rhs)
8456{
8457 return lhs + Decimal128(rhs);
8458}
8459
8460inline
8462 long rhs)
8463{
8464 return lhs + Decimal128(rhs);
8465}
8466
8467inline
8469 unsigned long rhs)
8470{
8471 return lhs + Decimal128(rhs);
8472}
8473
8474inline
8476 long long rhs)
8477{
8478 return lhs + Decimal128(rhs);
8479}
8480
8481inline
8483 unsigned long long rhs)
8484{
8485 return lhs + Decimal128(rhs);
8486}
8487
8488inline
8491{
8492 return Decimal128(lhs) + rhs;
8493}
8494
8495inline
8496bdldfp::Decimal128 bdldfp::operator+(unsigned int lhs,
8498{
8499 return Decimal128(lhs) + rhs;
8500}
8501
8502inline
8505{
8506 return Decimal128(lhs) + rhs;
8507}
8508
8509inline
8510bdldfp::Decimal128 bdldfp::operator+(unsigned long lhs,
8512{
8513 return Decimal128(lhs) + rhs;
8514}
8515
8516inline
8519{
8520 return Decimal128(lhs) + rhs;
8521}
8522
8523inline
8524bdldfp::Decimal128 bdldfp::operator+(unsigned long long lhs,
8526{
8527 return Decimal128(lhs) + rhs;
8528}
8529
8530 // Subtraction
8531
8532inline
8535{
8536 return Decimal128(DecimalImpUtil::subtract(*lhs.data(), *rhs.data()));
8537}
8538
8539inline
8542{
8543 return Decimal128(lhs) - rhs;
8544}
8545
8546inline
8549{
8550 return lhs - Decimal128(rhs);
8551}
8552
8553inline
8556{
8557 return Decimal128(lhs) - rhs;
8558}
8559
8560inline
8563{
8564 return lhs - Decimal128(rhs);
8565}
8566
8567inline
8569 int rhs)
8570{
8571 return lhs - Decimal128(rhs);
8572}
8573
8574inline
8576 unsigned int rhs)
8577{
8578 return lhs - Decimal128(rhs);
8579}
8580
8581inline
8583 long rhs)
8584{
8585 return lhs - Decimal128(rhs);
8586}
8587
8588inline
8590 unsigned long rhs)
8591{
8592 return lhs - Decimal128(rhs);
8593}
8594
8595inline
8597 long long rhs)
8598{
8599 return lhs - Decimal128(rhs);
8600}
8601
8602inline
8604 unsigned long long rhs)
8605{
8606 return lhs - Decimal128(rhs);
8607}
8608
8609inline
8612{
8613 return Decimal128(lhs) - rhs;
8614}
8615
8616inline
8617bdldfp::Decimal128 bdldfp::operator-(unsigned int lhs,
8619{
8620 return Decimal128(lhs) - rhs;
8621}
8622
8623inline
8626{
8627 return Decimal128(lhs) - rhs;
8628}
8629
8630inline
8631bdldfp::Decimal128 bdldfp::operator-(unsigned long lhs,
8633{
8634 return Decimal128(lhs) - rhs;
8635}
8636
8637inline
8640{
8641 return Decimal128(lhs) - rhs;
8642}
8643
8644inline
8645bdldfp::Decimal128 bdldfp::operator-(unsigned long long lhs,
8647{
8648 return Decimal128(lhs) - rhs;
8649}
8650
8651 // Multiplication
8652
8653inline
8656{
8657 return Decimal128(DecimalImpUtil::multiply(*lhs.data(), *rhs.data()));
8658}
8659
8660inline
8663{
8664 return Decimal128(lhs) * rhs;
8665}
8666
8667inline
8670{
8671 return lhs * Decimal128(rhs);
8672}
8673
8674inline
8677{
8678 return Decimal128(lhs) * rhs;
8679}
8680
8681inline
8684{
8685 return lhs * Decimal128(rhs);
8686}
8687
8688inline
8690 int rhs)
8691{
8692 return lhs * Decimal128(rhs);
8693}
8694
8695inline
8697 unsigned int rhs)
8698{
8699 return lhs * Decimal128(rhs);
8700}
8701
8702inline
8704 long rhs)
8705{
8706 return lhs * Decimal128(rhs);
8707}
8708
8709inline
8711 unsigned long rhs)
8712{
8713 return lhs * Decimal128(rhs);
8714}
8715
8716inline
8718 long long rhs)
8719{
8720 return lhs * Decimal128(rhs);
8721}
8722
8723inline
8725 unsigned long long rhs)
8726{
8727 return lhs * Decimal128(rhs);
8728}
8729
8730inline
8733{
8734 return Decimal128(lhs) * rhs;
8735}
8736
8737inline
8738bdldfp::Decimal128 bdldfp::operator*(unsigned int lhs,
8740{
8741 return Decimal128(lhs) * rhs;
8742}
8743
8744inline
8747{
8748 return Decimal128(lhs) * rhs;
8749}
8750
8751inline
8752bdldfp::Decimal128 bdldfp::operator*(unsigned long lhs,
8754{
8755 return Decimal128(lhs) * rhs;
8756}
8757
8758inline
8761{
8762 return Decimal128(lhs) * rhs;
8763}
8764
8765inline
8766bdldfp::Decimal128 bdldfp::operator*(unsigned long long lhs,
8768{
8769 return Decimal128(lhs) * rhs;
8770}
8771
8772 // Division
8773
8774inline
8777{
8778 return Decimal128(DecimalImpUtil::divide(*lhs.data(), *rhs.data()));
8779}
8780
8781inline
8784{
8785 return Decimal128(lhs) / rhs;
8786}
8787
8788inline
8791{
8792 return lhs / Decimal128(rhs);
8793}
8794
8795inline
8798{
8799 return Decimal128(lhs) / rhs;
8800}
8801
8802inline
8805{
8806 return lhs / Decimal128(rhs);
8807}
8808
8809inline
8811 int rhs)
8812{
8813 return lhs / Decimal128(rhs);
8814}
8815
8816inline
8818 unsigned int rhs)
8819{
8820 return lhs / Decimal128(rhs);
8821}
8822
8823inline
8825 long rhs)
8826{
8827 return lhs / Decimal128(rhs);
8828}
8829
8830inline
8832 unsigned long rhs)
8833{
8834 return lhs / Decimal128(rhs);
8835}
8836
8837inline
8839 long long rhs)
8840{
8841 return lhs / Decimal128(rhs);
8842}
8843
8844inline
8846 unsigned long long rhs)
8847{
8848 return lhs / Decimal128(rhs);
8849}
8850
8851inline
8854{
8855 return Decimal128(lhs) / rhs;
8856}
8857
8858inline
8859bdldfp::Decimal128 bdldfp::operator/(unsigned int lhs,
8861{
8862 return Decimal128(lhs) / rhs;
8863}
8864
8865inline
8868{
8869 return Decimal128(lhs) / rhs;
8870}
8871
8872inline
8873bdldfp::Decimal128 bdldfp::operator/(unsigned long lhs,
8875{
8876 return Decimal128(lhs) / rhs;
8877}
8878
8879inline
8882{
8883 return Decimal128(lhs) / rhs;
8884}
8885
8886inline
8887bdldfp::Decimal128 bdldfp::operator/(unsigned long long lhs,
8889{
8890 return Decimal128(lhs) / rhs;
8891}
8892
8893 // Equality
8894
8895inline
8897{
8898 return DecimalImpUtil::equal(*lhs.data(), *rhs.data());
8899}
8900
8901inline
8903{
8904 return Decimal128(lhs) == rhs;
8905}
8906
8907inline
8909{
8910 return lhs == Decimal128(rhs);
8911}
8912
8913inline
8915{
8916 return Decimal128(lhs) == rhs;
8917}
8918
8919inline
8921{
8922 return lhs == Decimal128(rhs);
8923}
8924
8925 // Inequality
8926
8927inline
8929{
8930 return DecimalImpUtil::notEqual(*lhs.data(), *rhs.data());
8931}
8932
8933inline
8935{
8936 return Decimal128(lhs) != rhs;
8937}
8938
8939inline
8941{
8942 return lhs != Decimal128(rhs);
8943}
8944
8945inline
8947{
8948 return Decimal128(lhs) != rhs;
8949}
8950
8951inline
8953{
8954 return lhs != Decimal128(rhs);
8955}
8956
8957 // Less Than
8958
8959inline
8961{
8962 return DecimalImpUtil::less(*lhs.data(), *rhs.data());
8963}
8964
8965inline
8967{
8968 return Decimal128(lhs) < rhs;
8969}
8970
8971inline
8973{
8974 return lhs < Decimal128(rhs);
8975}
8976
8977inline
8979{
8980 return Decimal128(lhs) < rhs;
8981}
8982
8983inline
8985{
8986 return lhs < Decimal128(rhs);
8987}
8988
8989 // Less Equal
8990
8991inline
8993{
8994 return DecimalImpUtil::lessEqual(*lhs.data(), *rhs.data());
8995}
8996
8997inline
8999{
9000 return Decimal128(lhs) <= rhs;
9001}
9002
9003inline
9005{
9006 return lhs <= Decimal128(rhs);
9007}
9008
9009inline
9011{
9012 return Decimal128(lhs) <= rhs;
9013}
9014
9015inline
9017{
9018 return lhs <= Decimal128(rhs);
9019}
9020
9021 // Greater
9022
9023inline
9025{
9026 return DecimalImpUtil::greater(*lhs.data(), *rhs.data());
9027}
9028
9029inline
9031{
9032 return Decimal128(lhs) > rhs;
9033}
9034
9035inline
9037{
9038 return lhs > Decimal128(rhs);
9039}
9040
9041inline
9043{
9044 return Decimal128(lhs) > rhs;
9045}
9046
9047inline
9049{
9050 return lhs > Decimal128(rhs);
9051}
9052
9053 // Greater Equal
9054
9055inline
9057{
9058 return DecimalImpUtil::greaterEqual(*lhs.data(), *rhs.data());
9059}
9060
9061inline
9063{
9064 return Decimal128(lhs) >= rhs;
9065}
9066
9067inline
9069{
9070 return lhs >= Decimal128(rhs);
9071}
9072
9073inline
9075{
9076 return Decimal128(lhs) >= rhs;
9077}
9078
9079inline
9081{
9082 return lhs >= Decimal128(rhs);
9083}
9084
9085#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
9086 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
9087inline
9088bdldfp::Decimal128 bdldfp::DecimalLiterals::operator""_d128(const char *str)
9089{
9090 return DecimalImpUtil::parse128(str);
9091}
9092
9093inline
9094bdldfp::Decimal128 bdldfp::DecimalLiterals::operator""_d128(
9095 const char *str, bsl::size_t)
9096{
9097 return DecimalImpUtil::parse128(str);
9098}
9099#endif
9100
9101// FREE FUNCTIONS
9102template <class HASHALG>
9103inline
9104void bdldfp::hashAppend(HASHALG& hashAlg, const bdldfp::Decimal32& object)
9105{
9106 using ::BloombergLP::bslh::hashAppend;
9107
9109 object.value());
9110 hashAlg(&normalizedObject, sizeof(normalizedObject));
9111}
9112
9113template <class HASHALG>
9114inline
9115void bdldfp::hashAppend(HASHALG& hashAlg, const bdldfp::Decimal64& object)
9116{
9117 using ::BloombergLP::bslh::hashAppend;
9118
9120 object.value());
9121
9122 hashAlg(&normalizedObject, sizeof(normalizedObject));
9123}
9124
9125template <class HASHALG>
9126inline
9127void bdldfp::hashAppend(HASHALG& hashAlg, const bdldfp::Decimal128& object)
9128{
9129 using ::BloombergLP::bslh::hashAppend;
9130
9132 object.value());
9133
9134 hashAlg(&normalizedObject, sizeof(normalizedObject));
9135}
9136
9137
9138
9139// FORMATTER SPECIALIZATIONS
9140namespace bsl {
9141
9142/// This template partial specialization defines `bsl::formatter` for
9143/// `bdldfp::Decimal32` values for both (`char` and `wchar_t`) character types.
9144template <class t_CHAR>
9145struct formatter<BloombergLP::bdldfp::Decimal32, t_CHAR>
9146: BloombergLP::bdldfp::Decimal_BslFmtFormatterImpl<
9147 BloombergLP::bdldfp::Decimal32,
9148 t_CHAR>
9149{ };
9150
9151/// This template partial specialization defines `bsl::formatter` for
9152/// `bdldfp::Decimal64` values for both (`char` and `wchar_t`) character types.
9153template <class t_CHAR>
9154struct formatter<BloombergLP::bdldfp::Decimal64, t_CHAR>
9155: BloombergLP::bdldfp::Decimal_BslFmtFormatterImpl<
9156 BloombergLP::bdldfp::Decimal64,
9157 t_CHAR>
9158{ };
9159
9160/// This template partial specialization defines `bsl::formatter` for
9161/// `bdldfp::Decimal128` values for both (`char` & `wchar_t`) character types.
9162template <class t_CHAR>
9163struct formatter<BloombergLP::bdldfp::Decimal128, t_CHAR>
9164: BloombergLP::bdldfp::Decimal_BslFmtFormatterImpl<
9165 BloombergLP::bdldfp::Decimal128,
9166 t_CHAR>
9167{ };
9168
9169} // close namespace bsl
9170
9171
9172#endif
9173
9174// ----------------------------------------------------------------------------
9175// Copyright 2014 Bloomberg Finance L.P.
9176//
9177// Licensed under the Apache License, Version 2.0 (the "License");
9178// you may not use this file except in compliance with the License.
9179// You may obtain a copy of the License at
9180//
9181// http://www.apache.org/licenses/LICENSE-2.0
9182//
9183// Unless required by applicable law or agreed to in writing, software
9184// distributed under the License is distributed on an "AS IS" BASIS,
9185// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9186// See the License for the specific language governing permissions and
9187// limitations under the License.
9188// ----------------------------- END-OF-FILE ----------------------------------
9189
9190/** @} */
9191/** @} */
9192/** @} */
Definition bdldfp_decimalformatconfig.h:120
@ e_FIXED
Definition bdldfp_decimalformatconfig.h:132
@ e_SCIENTIFIC
Definition bdldfp_decimalformatconfig.h:131
void setNan(const char *value)
Definition bdldfp_decimalformatconfig.h:395
void setShowpoint(bool value)
Definition bdldfp_decimalformatconfig.h:421
void setSNan(const char *value)
Definition bdldfp_decimalformatconfig.h:402
void setStyle(Style value)
Set the style attribute of this object to the specified value.
Definition bdldfp_decimalformatconfig.h:376
void setInfinity(const char *value)
Definition bdldfp_decimalformatconfig.h:388
void setSign(Sign value)
Set the sign attribute of this object to the specified value.
Definition bdldfp_decimalformatconfig.h:382
@ e_NEGATIVE_ONLY
Definition bdldfp_decimalformatconfig.h:125
@ e_ALWAYS
Definition bdldfp_decimalformatconfig.h:126
@ e_POSITIVE_AS_SPACE
Definition bdldfp_decimalformatconfig.h:127
void setExponent(char value)
Definition bdldfp_decimalformatconfig.h:415
Definition bdldfp_decimalimputil.h:238
static ValueType32 normalize(ValueType32 original)
static bool lessEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2764
static ValueType64 parse64(const char *input)
Definition bdldfp_decimalimputil.h:3107
static ValueType32 parse32(const char *input)
Definition bdldfp_decimalimputil.h:3100
static bool notEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2842
static bool less(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2712
Imp::ValueType64 ValueType64
Definition bdldfp_decimalimputil.h:250
static bool greater(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2738
static ValueType32 multiply(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1676
static ValueType32 divide(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1704
Imp::ValueType128 ValueType128
Definition bdldfp_decimalimputil.h:251
static int format(char *buffer, int length, ValueType32 value, const DecimalFormatConfig &cfg)
static ValueType128 parse128(const char *input)
Definition bdldfp_decimalimputil.h:3114
static ValueType32 subtract(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1650
static bool equal(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2816
static ValueType32 negate(ValueType32 value)
Definition bdldfp_decimalimputil.h:2687
static bool greaterEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2790
static ValueType32 add(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1625
Imp::ValueType32 ValueType32
Definition bdldfp_decimalimputil.h:249
Definition bdldfp_decimal.h:4274
~DecimalNumGet() BSLS_KEYWORD_OVERRIDE
INPUTITERATOR iter_type
Definition bdldfp_decimal.h:4297
iter_type get(iter_type begin, iter_type end, bsl::ios_base &str, bsl::ios_base::iostate &err, Decimal64 &value) const
static const DecimalNumGet< CHARTYPE, INPUTITERATOR > & object()
static bsl::locale::id id
Definition bdldfp_decimal.h:4294
iter_type get(iter_type begin, iter_type end, bsl::ios_base &str, bsl::ios_base::iostate &err, Decimal32 &value) const
CHARTYPE char_type
Definition bdldfp_decimal.h:4296
iter_type get(iter_type begin, iter_type end, bsl::ios_base &str, bsl::ios_base::iostate &err, Decimal128 &value) const
DecimalNumGet(bsl::size_t refs=0)
virtual iter_type do_get(iter_type begin, iter_type end, bsl::ios_base &str, bsl::ios_base::iostate &err, Decimal32 &value) const
Definition bdldfp_decimal.h:4382
Definition bdldfp_decimal.h:4807
iter_type put(iter_type out, bsl::ios_base &str, char_type fill, Decimal64 value) const
iter_type put(iter_type out, bsl::ios_base &str, char_type fill, Decimal32 value) const
OUTPUTITERATOR iter_type
Definition bdldfp_decimal.h:4830
static const DecimalNumPut< CHARTYPE, OUTPUTITERATOR > & object()
virtual iter_type do_put(iter_type out, bsl::ios_base &ios_format, char_type fill, Decimal32 value) const
CHARTYPE char_type
Definition bdldfp_decimal.h:4829
~DecimalNumPut() BSLS_KEYWORD_OVERRIDE
iter_type put(iter_type out, bsl::ios_base &str, char_type fill, Decimal128 value) const
DecimalNumPut(bsl::size_t refs=0)
iter_type do_put_impl(iter_type out, bsl::ios_base &ios_format, char_type fill, DECIMAL value) const
static bsl::locale::id id
Definition bdldfp_decimal.h:4827
Definition bdldfp_decimal.h:4920
Definition bdldfp_decimal.h:3101
Decimal_Type128 & operator++()
Definition bdldfp_decimal.h:6547
Decimal_Type128 & operator/=(Decimal32 rhs)
Definition bdldfp_decimal.h:6734
Decimal_Type128()
Definition bdldfp_decimal.h:6479
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdldfp_decimal.h:6800
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdldfp_decimal.h:6851
Decimal_Type128 & operator*=(Decimal32 rhs)
Definition bdldfp_decimal.h:6676
Decimal128_Type & operator=(const Decimal128_Type &rhs)=default
static int maxSupportedBdexVersion()
Definition bdldfp_decimal.h:6466
Decimal_Type128 & operator+=(Decimal32 rhs)
Definition bdldfp_decimal.h:6561
Decimal_Type128 & operator--()
Definition bdldfp_decimal.h:6553
DecimalImpUtil::ValueType128 * data()
Return a modifiable pointer to the underlying implementation.
Definition bdldfp_decimal.h:6792
Decimal128_Type(const Decimal128_Type &original)=default
Decimal_Type128 & operator-=(Decimal32 rhs)
Definition bdldfp_decimal.h:6618
DecimalImpUtil::ValueType128 value() const
Return the value of the underlying implementation.
Definition bdldfp_decimal.h:6843
BSLMF_NESTED_TRAIT_DECLARATION(Decimal_Type128, bsl::is_trivially_copyable)
Definition bdldfp_decimal.h:765
Decimal_Type32 & operator-=(Decimal32 rhs)
Definition bdldfp_decimal.h:5886
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdldfp_decimal.h:6038
DecimalImpUtil::ValueType32 * data()
Definition bdldfp_decimal.h:6030
Decimal_Type32 & operator--()
Definition bdldfp_decimal.h:5831
Decimal_Type32()
Definition bdldfp_decimal.h:5751
Decimal32_Type(const Decimal32_Type &original)=default
DecimalImpUtil::ValueType32 value() const
Return the value of the underlying implementation.
Definition bdldfp_decimal.h:6068
Decimal_Type32 & operator++()
Definition bdldfp_decimal.h:5826
Decimal_Type32 & operator+=(Decimal32 rhs)
Definition bdldfp_decimal.h:5838
Decimal32_Type & operator=(const Decimal32_Type &rhs)=default
static int maxSupportedBdexVersion()
Definition bdldfp_decimal.h:5738
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdldfp_decimal.h:6076
Decimal_Type32 & operator*=(Decimal32 rhs)
Definition bdldfp_decimal.h:5934
BSLMF_NESTED_TRAIT_DECLARATION(Decimal_Type32, bsl::is_trivially_copyable)
Decimal_Type32 & operator/=(Decimal32 rhs)
Definition bdldfp_decimal.h:5982
Definition bdldfp_decimal.h:1890
Decimal_Type64 & operator*=(Decimal32 rhs)
Definition bdldfp_decimal.h:6300
Decimal_Type64 & operator+=(Decimal32 rhs)
Definition bdldfp_decimal.h:6204
Decimal_Type64 & operator/=(Decimal32 rhs)
Definition bdldfp_decimal.h:6348
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdldfp_decimal.h:6443
DecimalImpUtil::ValueType64 value() const
Return the value of the underlying implementation.
Definition bdldfp_decimal.h:6435
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdldfp_decimal.h:6397
Decimal64_Type & operator=(const Decimal64_Type &rhs)=default
Decimal_Type64 & operator++()
Definition bdldfp_decimal.h:6192
static int maxSupportedBdexVersion()
Definition bdldfp_decimal.h:6099
BSLMF_NESTED_TRAIT_DECLARATION(Decimal_Type64, bsl::is_trivially_copyable)
Decimal_Type64()
Definition bdldfp_decimal.h:6112
Decimal64_Type(const Decimal64_Type &original)=default
Decimal_Type64 & operator--()
Definition bdldfp_decimal.h:6197
DecimalImpUtil::ValueType64 * data()
Return a modifiable pointer to the underlying implementation.
Definition bdldfp_decimal.h:6425
Decimal_Type64 & operator-=(Decimal32 rhs)
Definition bdldfp_decimal.h:6252
Definition bdldfp_decimal.h:4930
Definition bslstl_stringview.h:471
BSLS_KEYWORD_CONSTEXPR size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the length of this view.
Definition bslstl_stringview.h:1904
BSLS_KEYWORD_CONSTEXPR_CPP14 const_reference front() const
Definition bslstl_stringview.h:1966
BSLS_KEYWORD_CONSTEXPR bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this view has length 0, and false otherwise.
Definition bslstl_stringview.h:1931
Definition bslma_polymorphicallocator.h:460
BSLS_ANNOTATION_NODISCARD TYPE * allocate(std::size_t n)
Definition bslma_polymorphicallocator.h:963
Definition bslfmt_formatspecificationparser.h:151
Definition bslma_allocator.h:545
virtual void deallocate(void *address)=0
virtual void * allocate(size_type size)=0
Definition bslma_deallocatebytesproctor.h:272
static BloombergLP::bdldfp::Decimal128 min() BSLS_KEYWORD_NOEXCEPT
static BloombergLP::bdldfp::Decimal32 min() BSLS_KEYWORD_NOEXCEPT
static BloombergLP::bdldfp::Decimal64 min() BSLS_KEYWORD_NOEXCEPT
#define BSLA_FALLTHROUGH
Definition bsla_fallthrough.h:188
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_ANNOTATION_DEPRECATED
Definition bsls_annotation.h:324
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_THROW(X)
Definition bsls_exceptionutil.h:374
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR_CPP20
Definition bsls_keyword.h:645
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition bdldfp_decimal.h:747
Decimal_Type128 Decimal128
Definition bdldfp_decimal.h:754
bsl::basic_istream< CHARTYPE, TRAITS > & operator>>(bsl::basic_istream< CHARTYPE, TRAITS > &stream, Decimal32 &object)
Decimal32 operator/(Decimal32 lhs, Decimal32 rhs)
bsl::basic_ostream< CHARTYPE, TRAITS > & operator<<(bsl::basic_ostream< CHARTYPE, TRAITS > &stream, Decimal32 object)
bool operator!=(Decimal32 lhs, Decimal32 rhs)
bool operator<(Decimal32 lhs, Decimal32 rhs)
Decimal_Type32 Decimal32
Definition bdldfp_decimal.h:749
void hashAppend(HASHALG &hashAlg, const Decimal32 &object)
Decimal32 operator--(Decimal32 &value, int)
Decimal_Type64 Decimal64
Definition bdldfp_decimal.h:750
Decimal32 operator-(Decimal32 value)
Decimal32 operator*(Decimal32 lhs, Decimal32 rhs)
bool operator>(Decimal32 lhs, Decimal32 rhs)
bool operator>=(Decimal32 lhs, Decimal32 rhs)
bool operator<=(Decimal32 lhs, Decimal32 rhs)
Decimal32 operator++(Decimal32 &value, int)
Decimal32 operator+(Decimal32 value)
bool operator==(Decimal32 lhs, Decimal32 rhs)
Definition bdlat_valuetypefunctions.h:939
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
Definition bdldfp_decimal.h:5549
BID_UINT128 Type128
Definition bdldfp_decimalstorage.h:86
BID_UINT64 Type64
Definition bdldfp_decimalstorage.h:85
BID_UINT32 Type32
Definition bdldfp_decimalstorage.h:84
Definition bdldfp_decimal.h:4652
BSLS_KEYWORD_CONSTEXPR_CPP20 t_PARSE_CONTEXT::iterator parse(t_PARSE_CONTEXT &parseContext)
Definition bdldfp_decimal.h:7243
t_FORMAT_CONTEXT::iterator format(const t_VALUE &value, t_FORMAT_CONTEXT &formatContext) const
Definition bdldfp_decimal.h:7259
Definition bdldfp_decimal.h:4480
BSLS_KEYWORD_CONSTEXPR_CPP20 Parser::Alignment alignment() const
Definition bdldfp_decimal.h:7003
BSLS_KEYWORD_CONSTEXPR_CPP20 FormatType formatType() const
Definition bdldfp_decimal.h:7063
BSLS_KEYWORD_CONSTEXPR_CPP20 bool localeSpecificFlag() const
Definition bdldfp_decimal.h:7054
BSLS_KEYWORD_CONSTEXPR_CPP20 const t_CHAR * filler() const
Definition bdldfp_decimal.h:6978
BSLS_KEYWORD_CONSTEXPR_CPP20 bool alternativeFlag() const
Definition bdldfp_decimal.h:7020
BSLS_KEYWORD_CONSTEXPR_CPP20 bool zeroPaddingFlag() const
Definition bdldfp_decimal.h:7028
BSLS_KEYWORD_CONSTEXPR_CPP20 int fillerCharacters() const
Definition bdldfp_decimal.h:6986
FormatType
Definition bdldfp_decimal.h:4486
@ e_FORMAT_DEFAULT
Default value.
Definition bdldfp_decimal.h:4490
@ e_FORMAT_SCIENTIFIC
none
Definition bdldfp_decimal.h:4491
@ e_FORMAT_GENERAL
F
Definition bdldfp_decimal.h:4495
@ e_FORMAT_FIXED
E
Definition bdldfp_decimal.h:4493
@ e_FORMAT_FIXED_UC
f
Definition bdldfp_decimal.h:4494
@ e_FORMAT_GENERAL_UC
g
Definition bdldfp_decimal.h:4496
@ e_TYPE_UNASSIGNED
Definition bdldfp_decimal.h:4487
@ e_FORMAT_SCIENTIFIC_UC
e
Definition bdldfp_decimal.h:4492
BSLS_KEYWORD_CONSTEXPR_CPP20 int fillerCodePointDisplayWidth() const
Definition bdldfp_decimal.h:6994
BSLS_KEYWORD_CONSTEXPR_CPP20 const bslfmt::FormatterSpecificationNumericValue postprocessedPrecision() const
Definition bdldfp_decimal.h:7046
BSLS_KEYWORD_CONSTEXPR_CPP20 Parser::Sign sign() const
Definition bdldfp_decimal.h:7012
BSLS_KEYWORD_CONSTEXPR_CPP20 const bslfmt::FormatterSpecificationNumericValue postprocessedWidth() const
Definition bdldfp_decimal.h:7037
void postprocess(const t_FORMAT_CONTEXT &context)
Definition bdldfp_decimal.h:7108
BSLS_KEYWORD_CONSTEXPR_CPP20 void parse(t_PARSE_CONTEXT *context)
Definition bdldfp_decimal.h:7073
BSLS_KEYWORD_CONSTEXPR_CPP20 Decimal_FormatterSpecification()
Create an uninitialized Decimal_FormatterSpecification object.
Definition bdldfp_decimal.h:6968
Definition bslfmt_formatterbase.h:426
Definition bslmf_issame.h:146
Definition bslmf_istriviallycopyable.h:324
Alignment
Definition bslfmt_formatspecificationparser.h:114
Sections
Definition bslfmt_formatspecificationparser.h:128
Sign
Definition bslfmt_formatspecificationparser.h:121
Definition bslfmt_formattercharutil.h:138
Definition bslfmt_formatterspecificationnumericvalue.h:100
@ e_VALUE
Definition bslfmt_formatterspecificationnumericvalue.h:105
@ e_DEFAULT
Definition bslfmt_formatterspecificationnumericvalue.h:104
BSLS_KEYWORD_CONSTEXPR_CPP20 int value() const
Definition bslfmt_formatterspecificationnumericvalue.h:399
BSLS_KEYWORD_CONSTEXPR_CPP20 Category category() const
Return the category attribute of this object.
Definition bslfmt_formatterspecificationnumericvalue.h:416
Definition bslfmt_padutil.h:151
static Allocator * allocator(Allocator *basicAllocator=0)
Definition bslma_default.h:913