BDE 4.14.0 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-formatting"> Decimal Number Formatting </a>
49/// * <a href="#bdldfp_decimal-user-defined-literals"> User-defined literals </a>
50/// * <a href="#bdldfp_decimal-usage"> Usage </a>
51/// * <a href="#bdldfp_decimal-example-1-portable-initialization-of-non-integer-constant-values"> Example 1: Portable Initialization of Non-Integer, Constant Values </a>
52/// * <a href="#bdldfp_decimal-example-2-precise-calculations-with-decimal-values"> Example 2: Precise Calculations with Decimal Values </a>
53///
54/// # Purpose {#bdldfp_decimal-purpose}
55/// Provide IEEE-754 decimal floating-point types.
56///
57/// # Classes {#bdldfp_decimal-classes}
58///
59/// - bdldfp::Decimal32: 32bit IEEE-754 decimal floating-point type
60/// - bdldfp::Decimal64: 64bit IEEE-754 decimal floating-point type
61/// - bdldfp::Decimal128: 128bit IEEE-754 decimal floating-point type
62/// - bdldfp::DecimalNumGet: Stream Input Facet
63/// - bdldfp::DecimalNumPut: Stream Output Facet
64///
65/// # Macros {#bdldfp_decimal-macros}
66///
67/// - BDLDFP_DECIMAL_DF: Portable Decimal32 literal macro
68/// - BDLDFP_DECIMAL_DD: Portable Decimal64 literal macro
69/// - BDLDFP_DECIMAL_DL: Portable Decimal128 literal macro
70///
71/// @see bdldfp_decimalutil, bdldfp_decimalconvertutil,
72/// bdldfp_decimalplatform
73///
74/// # Description {#bdldfp_decimal-description}
75/// This component provides classes that implement decimal
76/// floating-point types that conform in layout, encoding and operations to the
77/// IEEE-754 2008 standard. This component also provides two facets to support
78/// standard C++ streaming operators as specified by ISO/IEC TR-24733:2009.
79/// These classes are `bdldfp::Decimal32` for 32-bit Decimal floating point
80/// numbers, `bdldfp::Decimal64` for 64-bit Decimal floating point numbers, and
81/// `bdldfp::Decimal128` for 128-bit decimal floating point numbers.
82///
83/// Decimal encoded floating-point numbers are important where exact
84/// representation of decimal fractions is required, such as in financial
85/// transactions. Binary encoded floating-point numbers are generally optimal
86/// for complex computation but cannot exactly represent commonly encountered
87/// numbers such as 0.1, 0.2, and 0.99.
88///
89/// NOTE: Interconversion between binary and decimal floating-point values is
90/// fraught with misunderstanding and must be done carefully and with intent,
91/// taking into account the provenance of the data. See the discussion on
92/// conversion below and in the @ref bdldfp_decimalconvertutil component.
93///
94/// The BDE decimal floating-point system has been designed from the ground up
95/// to be portable and support writing portable decimal floating-point user
96/// code, even for systems that do not have compiler or native library support
97/// for it; while taking advantage of native support (such as ISO/IEC TR
98/// 24732 - C99 decimal TR) when available.
99///
100/// `bdldfp::DecimalNumGet` and `bdldfp::DecimalNumPut` are IO stream facets.
101///
102/// ## Floating-Point Primer {#bdldfp_decimal-floating-point-primer}
103///
104///
105/// There are several ways of represent numbers when using digital computers.
106/// The simplest would be an integer format, however such a format severely
107/// limits the range of numbers that can be represented; and it cannot represent
108/// real (non-integer) numbers directly at all. Integers might be used to
109/// represent real numbers of limited precision by treating them as a multiple
110/// of the real value being represented; these are often known as fixed-point
111/// numbers. However general computations require higher precision and a larger
112/// range than integer and fixed point types are able to efficiently provide.
113/// Floating-point numbers provide what integers cannot. They are able to
114/// represent a large range of real values (although not precisely) while using
115/// a fixed (and reasonable) amount of storage.
116///
117/// Floating-point numbers are constructed from a set of significant digits of a
118/// radix on a sliding scale, where their position is determined by an exponent
119/// over the same radix. For example let's see some 32bit decimal (radix 10)
120/// floating-point numbers that have maximum 7 significant digits (significand):
121/// @code
122/// Significand | Exponent | Value |
123/// -------------+----------+--------------+ In the Value column you may
124/// 1234567 | 0 | 1234567.0 | observer how the decimal point
125/// 1234567 | 1 | 12345670.0 | is "floating" about the digits
126/// 1234567 | 2 | 123456700.0 | of the significand.
127/// 1234567 | -1 | 123456.7 |
128/// 1234567 | -2 | 12345.67 |
129/// @endcode
130/// Floating-point numbers are standardized by IEEE-754 2008, in two major
131/// flavors: binary and decimal. Binary floating-point numbers are supported by
132/// most computer systems in the forms of the `float`, `double` and
133/// `long double` fundamental data types. While they are not required to be
134/// binary that is almost always the choice on modern binary computer
135/// architectures.
136///
137/// ### Floating-Point Peculiarities {#bdldfp_decimal-floating-point-peculiarities}
138///
139///
140/// Floating-point approximation of real numbers creates a deliberate illusion.
141/// While it looks like we are working with real numbers, floating-point
142/// encodings are not able to represent real numbers precisely since they have a
143/// restricted number of digits in the significand. In fact, a 64 bit
144/// floating-point type can represent fewer distinct values than a 64 bit binary
145/// integer. Yet, because floating-point encodings can represent numbers over a
146/// much larger range, including extremely small (fractional) numbers, they are
147/// useful in practice.
148///
149/// Floating-point peculiarities may be split into three categories: those that
150/// are due to the (binary) radix/base, those that are inherent properties of
151/// any floating-point representation and finally those that are introduced by
152/// the IEEE-754 2008 standard. Decimal floating-point addresses the first set
153/// of surprises only; so users still need to be aware of the rest.
154///
155/// 1. Floating-point types cannot exactly represent every number in their
156/// range. The consequences are surprising and unexpected for the newcomer.
157/// For example: when using binary floating-point numbers, the following
158/// expression is typically *false*: `0.1 + 0.2 == 0.3`. The problem is not
159/// limited to binary floating-point. Decimal floating-point cannot
160/// represent the value of one third exactly.
161/// 2. Unlike with real numbers, the order of operations on floating-point
162/// numbers is significant, due to accumulation of round off errors.
163/// Therefore floating-point arithmetic is neither commutative nor
164/// transitive. E.g., 2e-30 + 1e30 - 1e-30 - 1e30 will typically produce 0
165/// (unless your significand can hold 60 decimal digits). Alternatively,
166/// 1e30 - 1e30 + 2e-30 - 1e-30 will typically produce 1e-30.
167///
168/// 3. IEEE floating-point types can have special values: negative zero,
169/// negative and positive infinity; and they can be NaN (Not a Number, in two
170/// variants: quiet or signaling). A NaN (any variant) is never equal to
171/// anything else - including NaN or itself!
172/// 4. In IEEE floating-point there are at least two representations of 0, the
173/// positive zero and negative zero. Consequently unary - operators change
174/// the sign of the value 0; therefore leading to surprising results: if
175/// `f == 0.0` then `0 - f` and `-f` will not result in the same value,
176/// because `0 - f` will be +0.0' while `-f` will be -0.0.
177/// 5. Most IEEE floating-point operations (like arithmetic) have implicit input
178/// parameters and output parameters (that do not show up in function
179/// signatures. The implicit input parameters are called *attributes* by
180/// IEEE while the outputs are called status flags. The C/C++ programming
181/// language defines a so-called floating-point environment that contains
182/// those attributes and flags (`<fenv.h>` C and `<cfenv>` C++ headers). To
183/// learn more about the floating point environment read the subsection of
184/// the same title, but first make sure you read the next point as well.
185/// 6. IEEE floating-points overloads some very common programming language
186/// terms: *exception*, *signal* and *handler* with IEEE floating-point
187/// specific meanings that are not to be confused with C or C++ or Posix
188/// terms of the same spelling. Floating-point exceptions are events that
189/// occur when a floating-point operations on the specified operands is
190/// unable to produce a perfect outcome; such as when the result of an
191/// operation is inexact. When a floating point exception occurs the
192/// (floating-point) - and reporting it is requested by a so-called trap
193/// attribute - the implementation signals the user(*) by invoking a default
194/// or a user-defined handler. None of the words *exception*, *signal*, and
195/// *handler* used above have nothing to do with C++ exceptions, Posix
196/// signals and the handlers of those. (To complicate matters more, C and
197/// Posix has decided to implement IEEE floating-point exception reporting as
198/// C/Posix signals - and therefore rendered them mostly useless.)
199/// 7. While a 32bit integer is a quite useful type for (integer) calculations,
200/// a 32bit floating-point type has such low accuracy (its significand is so
201/// short) that it is all but useless for calculation. Such types are called
202/// "interchange formats" by the IEEE standard and should not be used for
203/// calculations. (Except in special circumstances and by floating-point
204/// experts. Even a 16 bit binary floating-point type can be useful for an
205/// expert in special circumstances, for example in graphics acceleration
206/// hardware.)
207///
208/// Notes:
209/// (*) IEEE Floating-point user is any person, hardware or software that uses
210/// the IEEE floating-point implementation.
211///
212/// ### Floating-Point Environment {#bdldfp_decimal-floating-point-environment}
213///
214///
215/// NOTE: We currently do not give access to the user to the floating-point
216/// environment used by our decimal system, so description of it here is
217/// preliminary and generic. Note that since compilers and the C library
218/// already provides a (possibly binary floating-point only) environment and we
219/// cannot change that, our decimal floating-point environment implementation
220/// cannot conform to the C and C++ TRs (because those require extending the
221/// existing standard C library functions).
222///
223/// The floating-point environment provides implicit input and output parameters
224/// to floating-point operations (that are defined to use them). IEEE defined
225/// those parameters in principle, but how they are provided is left up to be
226/// designed/defined by the implementors of the programming languages.
227///
228/// C (and consequently C++) decided to provide a so-called floating-point
229/// environment that has "thread storage duration", meaning that each thread of
230/// a multi-threaded program will have its own distinct floating-point
231/// environment.
232///
233/// The C/C++ floating-point environment consists of 3 major parts: the rounding
234/// mode, the traps and the status flags.
235///
236/// #### Rounding Direction in The Environment {#bdldfp_decimal-rounding-direction-in-the-environment}
237///
238///
239/// A floating-point *rounding direction* determines how is the significand of a
240/// higher (or infinite) precision number get rounded to fit into the limited
241/// number of significant digits (significand) of the floating-point
242/// representation that needs to store it as a result of an operation. Note
243/// that the rounding is done in the radix of the representation, so binary
244/// floating-point will do binary rounding while decimal floating-point will do
245/// decimal rounding - and not all rounding modes are useful with all radixes.
246/// An example of a generally applicable rounding mode would be `FE_TOWARDZERO`
247/// (round towards zero).
248///
249/// Most floating point operations in C and C++ do not take a rounding direction
250/// parameter (and the ones that are implemented as operators simply could not).
251/// When such operations (that do not have an explicit rounding direction
252/// parameter) need to do rounding, they use the rounding direction set in the
253/// floating-point environment (of their thread of execution).
254///
255/// #### Status Flags {#bdldfp_decimal-status-flags}
256///
257///
258/// Floating point operations in C and C++ do not take a status flag output
259/// parameter. They report an important events (such as underflow, overflow or
260/// in inexact (rounded) result) by setting the appropriate status flag in the
261/// floating-point environment (of their thread of execution). (Note that this
262/// is very similar to how flags work in CPUs, and that is not a coincidence.)
263/// The flags work much like individual, boolean `errno` values. Operations may
264/// set them to true. Users may examine them (when interested) and also reset
265/// them (set them to 0) before an operation.
266///
267/// #### Floating-Point Traps {#bdldfp_decimal-floating-point-traps}
268///
269///
270/// IEEE says that certain floating-point events are floating-point exceptions
271/// and they result in invoking a handler. It may be a default handler (set a
272/// status flag and continue) or a user defined handler. Floating point traps
273/// are a C invention to enable "sort-of handlers" for floating point
274/// exceptions, but unfortunately they all go to the same handler: the `SIGFPE`
275/// handler. To add insult to injury, setting what traps are active (what will)
276/// cause a `SIGFPE`) is not standardized. So floating-point exceptions and
277/// handlers are considered pretty much useless in C. (All is not lost, since
278/// we do have the status flags. An application that wants to know about
279/// floating-point events can clear the flags prior to an operation and check
280/// their values afterwards.)
281///
282/// #### Error Reporting {#bdldfp_decimal-error-reporting}
283///
284///
285/// The @ref bdldfp_decimalutil utility component provides a set of decimal math
286/// functions that parallel those provided for binary floating point in the C++
287/// standard math library. Errors during computation of these functions (e.g.,
288/// domain errors) will be reported through the setting of `errno` as described
289/// in the "Status Flags" section above. (Note that this method of reporting
290/// errors is atypical for BDE-provided interfaces, but matches the style used
291/// by the standard functions.)
292///
293/// ### Floating-Point Terminology {#bdldfp_decimal-floating-point-terminology}
294///
295///
296/// A floating-point representation of a number is defined as follows:
297/// `sign * significand * BASE^exponent`, where sign is -1 or +1, significand is
298/// an integer, BASE is a positive integer (but usually 2 or 10) and exponent is
299/// a negative or positive integer. Concrete examples of (decimal) numbers in
300/// the so-called scientific notation are: 123.4567 is 1.234567e2, while
301/// -0.000000000000000000000000000000000000001234567 would be -1.234567e-41.
302///
303/// "base":
304/// the number base of the scaling used by the exponent; and by the
305/// significand
306///
307/// "bias":
308/// the number added to the exponent before it is stored in memory; 101, 398
309/// and 6176 for the 32, 64 and 128 bit types respectively.
310///
311/// "exponent":
312/// the scaling applied to the significand is calculated by raising the base
313/// to the exponent (which may be also negative)
314///
315/// "quantum":
316/// (IEEE-754) the value of one unit at the last significant digit
317/// position; in other words the smallest difference that can be
318/// represented by a floating-point number without changing its exponent.
319///
320/// "mantissa":
321/// the old name for the significand
322///
323/// "radix":
324/// another name for base
325///
326/// "sign":
327/// +1 or -1, determines if the number is positive or negative. It is
328/// normally represented by a single sign bit.
329///
330/// "significand":
331/// the significant digits of the floating-point number; the value of the
332/// number is: `sign * significand * base^exponent`
333///
334/// "precision":
335/// the significant digits of the floating-point type in its base
336///
337/// "decimal precision":
338/// the maximum significant decimal digits of the floating-point type
339///
340/// "range":
341/// the smallest and largest number the type can represent. Note that for
342/// floating-point types there are at least *two* interpretations of
343/// minimum. It may be the largest negative number *or* the smallest number
344/// in absolute value) that can be represented.
345///
346/// "normalized number":
347/// `1 <= significand <= base`
348///
349/// "normalization":
350/// finding the exponent such as `1 <= significand <= base`
351///
352/// "denormal number":
353/// `significand < 1`
354///
355/// "densely packed decimal":
356/// one of the two IEEE significand encoding schemes
357///
358/// "binary integer significand":
359/// one of the two IEEE significand encoding schemes
360///
361/// "cohorts":
362/// equal numbers encoded using different exponents (to signify accuracy)
363///
364/// ## Decimal Floating-Point {#bdldfp_decimal-decimal-floating-point}
365///
366///
367/// Binary floating-point formats give best accuracy, they are the fastest (on
368/// binary computers), and were carefully designed by IEEE to minimize rounding
369/// errors (errors due to the inherent imprecision of floating-point types)
370/// during a lengthy calculation. This makes them the best solution for and
371/// serious scientific computation. However, they have a fatal flow when it
372/// comes to numbers and calculations that involve humans. Humans think in base
373/// 10 - decimal. And as the example has shown earlier, binary floating-point
374/// formats are unable to precisely represent very common decimal real numbers;
375/// with binary floating-point `0.1 + 0.2 != 0.3`. (Why? Because none of the
376/// three numbers in that expression have an exact binary floating-point
377/// representation.)
378///
379/// Financial calculations are governed by laws and expectations that are based
380/// on decimal (10 based) thinking. Due to the inherent limitations of the
381/// binary floating-point format, doing such decimal based calculations and
382/// algorithms using binary floating-point numbers is so involved and hard that
383/// that it is considered not feasible. The IEEE-754 committee have recognized
384/// the issue and added specifications for 3 decimal floating-point types into
385/// their 2008 standard: the 32, 64 and 128 bits decimal floating-point formats.
386///
387/// Floating-point types are carefully designed trade-offs between saving space
388/// (in memory), CPU cycles (for calculations) and still provide useful accuracy
389/// for computations. Decimal floating-point types represent further
390/// compromises (compared to binary floating-points) in being able to represent
391/// less numbers (than their binary counterparts) and being slower, but
392/// providing exact representations for the numbers humans care about.
393///
394/// In decimal floating-point world `0.1 + 0.2 == 0.3`, as humans expect;
395/// because each of those 3 numbers can be represented *exactly* in a decimal
396/// floating-point format.
397///
398/// ### WARNING: Conversions from float and double {#bdldfp_decimal-warning-conversions-from-float-and-double}
399///
400///
401/// Clients should *be* *careful* when using the conversions from `float` and
402/// `double` provided by this component. In situations where a `float` or
403/// `double` was originally obtained from a decimal floating point
404/// representation (e.g., a `bdldfp::Decimal`, or a string, like "4.1"), the
405/// conversions in @ref bdldfp_decimalconvertutil will provide the correct
406/// conversion back to a decimal floating point value. The conversions in this
407/// component provide the closest decimal floating point value to the supplied
408/// binary floating point representation, which may replicate imprecisions
409/// required to initially approximate the value in a binary representation.
410/// The conversions in this component are typically useful when converting
411/// binary floating point values that have undergone mathematical operations
412/// that require rounding (so they are already in-exact approximations).
413///
414/// ### Cohorts {#bdldfp_decimal-cohorts}
415///
416///
417/// In the binary floating-point world the formats are optimized for the highest
418/// precision, range and speed. They are stored normalized and therefore store
419/// no information about their accuracy. In finances, the area that decimal
420/// floating-point types target, accuracy of a number is usually very important.
421/// We may have a number that is 1, but we know it may be 1.001 or 1.002 etc.
422/// And we may have another number 1, which we know to be accurate to 6
423/// significant digits. We would display the former number as `1.00` and the
424/// latter number as `1.00000`. The decimal floating-point types are able to
425/// store both numbers *and* their precision using so called cohorts. The
426/// `1.00` will be stored as `100e-2` while `1.00000` will be stored as
427/// `100000e-5`.
428///
429/// Cohorts compare equal, and mostly behave the same way in calculation except
430/// when it comes to the accuracy of the result. If I have a number that is
431/// accurate to 5 digits only, it would be a mistake to try to expect more than
432/// 5 digits accuracy from a calculation involving it. The IEEE-754 rules of
433/// cohorts (in calculations) ensures that results will be a cohort that
434/// indicates the proper expected accuracy.
435///
436/// ## Standards Conformance {#bdldfp_decimal-standards-conformance}
437///
438///
439/// The component has also been designed to resemble the C++ Decimal
440/// Floating-Point Technical Report ISO/IEC TR-24733 of 2009 and its C++11
441/// updates of ISO/IEC JTC1 SC22 WG21 N3407=12-0097 of 2012 as much as it is
442/// possible with C++03 compilers and environments that do not provide decimal
443/// floating-point support in any form.
444///
445/// At the time of writing there is just one standard about decimal-floating
446/// point, the IEEE-754 2008 standard and the content of this component conforms
447/// to it. The component does not fully implement all required IEEE-754
448/// functionality because due to our architectural design guidelines some of
449/// these must go into a separate so-called utility component.)
450///
451/// The component uses the ISO/IEC TR 24732 - the C Decimal Floating-Point
452/// TR - in its implementation where it is available.
453///
454/// The component closely resembles ISO/IEC TR 24733 - the C++ Decimal
455/// Floating-Point TR - but does not fully conform to it for several reasons.
456/// The major reasons are: it is well known that TR 24733 has to change before
457/// it is included into the C++ standard; the TR would require us to change
458/// system header files we do not have access to.
459///
460/// In the following subsections the differences to the C++ technical report are
461/// explained in detail, including a short rationale.
462///
463/// ### No Namespace Level Named Functions {#bdldfp_decimal-no-namespace-level-named-functions}
464///
465///
466/// BDE design guidelines do not allow namespace level functions other than
467/// operators and aspects. According to BDE design principles all such
468/// functions are placed into a utility component.
469///
470/// ### All Converting Constructors from Integer Types are Explicit {#bdldfp_decimal-all-converting-constructors-from-integer-types-are-explicit}
471///
472///
473/// This change is necessary to disable the use of comparison operators without
474/// explicit casting. See No Heterogeneous Comparisons Without Casting.
475///
476/// ### No Heterogeneous Comparisons Without Casting {#bdldfp_decimal-no-heterogeneous-comparisons-without-casting}
477///
478///
479/// The C and C++ Decimal TRs refer to IEEE-754 for specifications of the
480/// heterogeneous comparison operators (comparing decimal floating-point types
481/// to binary floating-point types and integer types); however IEEE-754 does
482/// *not* specify such operations - leaving them unspecified. To make matters
483/// worse, there are two possible ways to implement those operators (convert the
484/// decimal to the other type, or convert the other type to decimal first) and
485/// depending on which one is chosen, the result of the operator will be
486/// different. Also, the C committee is considering the removal of those
487/// operators. We have removed them until we know how to implement them.
488/// Comparing decimal types to those other types is still possible, it just
489/// requires explicit casting/conversion from the user code.
490///
491/// ### Arithmetic And Computing Support For Decimal32 {#bdldfp_decimal-arithmetic-and-computing-support-for-decimal32}
492///
493///
494/// IEEE-754 designates the 32 bit floating-point types "interchange formats"
495/// and does not require or recommend arithmetic or computing support of any
496/// kind for them. The C (and consequently the C++) TR goes against the IEEE
497/// design and requires `_Decimal32` (and `std::decimal32`) to provide computing
498/// support, however, in a twist, allows it to be performed using one of the
499/// larger types (64 or 128 bits). The rationale from the C committee is that
500/// small embedded systems may need to do their calculations using the small
501/// type (so they have made it mandatory for everyone). To conform the
502/// requirement we provide arithmetic and computing support for Decimal32 type
503/// but users need to be aware of the drawbacks of calculations using the small
504/// type. Industry experience with the `float` C type (32bit floating-point
505/// type, usually binary) has shown that enabling computing using small
506/// floating-point types are a mistake that causes novice programmers to write
507/// calculations that are very slow and inaccurate.
508///
509/// We recommend what IEEE recommends: convert your 32 bit types on receipt to a
510/// type with higher precision (usually 64 bit will suffice), so you
511/// calculations using that larger type, and convert it back to 32 bit type only
512/// if your output interchange format requires it.
513///
514/// ### Non-Standard Member Functions {#bdldfp_decimal-non-standard-member-functions}
515///
516///
517/// Due to BDE rules of design and some implementation needs we have extended
518/// the C++ TR mandated interface of the decimal floating-point types to include
519/// support for accessing the underlying data (type), to parse literals for the
520/// portable literal support.
521///
522/// Note that using any of these public member functions will render your code
523/// non-portable to non-BDE (but standards conforming) implementations.
524///
525/// ## Decimal32 Type {#bdldfp_decimal-decimal32-type}
526///
527///
528/// A basic format type that supports input, output, relational operators
529/// construction from the TR mandates data types and arithmetic or operations.
530/// The type has the size of exactly 32 bits. It supports 7 significant decimal
531/// digits and an exponent range of -95 to 96. The smallest non-zero value that
532/// can be represented is 1e-101.
533///
534/// Portable `Decimal32` literals are created using the `BDLDFP_DECIMAL_DF`
535/// macro.
536///
537/// ## Decimal64 Type {#bdldfp_decimal-decimal64-type}
538///
539///
540/// A basic format type that supports input, output, relational operators
541/// construction from the TR mandates data types and arithmetic or operations.
542/// The type has the size of exactly 64 bits. It supports 16 significant
543/// decimal digits and an exponent range of -383 to 384. The smallest non-zero
544/// value that can be represented is 1e-398.
545///
546/// Portable `Decimal64` literals are created using the `BDLDFP_DECIMAL_DD`
547/// macro.
548///
549/// ## Decimal128 Type {#bdldfp_decimal-decimal128-type}
550///
551///
552/// A basic format type that supports input, output, relational operators
553/// construction from the TR mandates data types and arithmetic or operations.
554/// The type has the size of exactly 128 bits. It supports 34 significant
555/// decimal digits and an exponent range of -6143 to 6144. The smallest
556/// non-zero value that can be represented is 1e-6176.
557///
558/// Portable `Decimal128` literals are created using the `BDLDFP_DECIMAL_DL`
559/// macro.
560///
561/// ## Decimal Number Formatting {#bdldfp_decimal-decimal-number-formatting}
562///
563///
564/// Streaming decimal floating point numbers to an output stream supports
565/// formatting flags for width, capitalization and justification and flags used
566/// to output numbers in natural, scientific and fixed notations. When
567/// scientific or fixed flags are set then the precision manipulator specifies
568/// how many digits of the decimal number are to be printed, otherwise all
569/// significant digits of the decimal number are output using native notation.
570///
571/// ## User-defined literals {#bdldfp_decimal-user-defined-literals}
572///
573///
574/// The user-defined literal `operator "" _d32`, `operator "" _d64`, and
575/// `operator "" _d128` are declared for the `bdldfp::Decimal32`,
576/// `bdldfp::Decimal64`, and `bdldfp::Decimal128` types respectively . These
577/// user-defined literal suffixes can be applied to both numeric and string
578/// literals, (i.e., 1.2_d128, "1.2"_d128 or "inf"_d128) to produce a decimal
579/// floating-point value of the indicated type by parsing the argument string
580/// or numeric value:
581/// @code
582/// using namespace bdldfp::DecimalLiterals;
583///
584/// bdldfp::Decimal32 d0 = "1.2"_d32;
585/// bdldfp::Decimal32 d1 = 1.2_d32;
586/// assert(d0 == d1);
587///
588/// bdldfp::Decimal64 d2 = "3.45678901234"_d64;
589/// bdldfp::Decimal64 d3 = 3.45678901234_d64;
590/// assert(d2 == d3);
591///
592/// bdldfp::Decimal128 inf = "inf"_d128;
593/// bdldfp::Decimal128 nan = "nan"_d128;
594/// @endcode
595/// The operators providing literals are available in the
596/// `BloombergLP::bdldfp::literals::DecimalLiterals` namespace (where `literals`
597/// and `DecimalLiterals` are both inline namespaces). Because of inline
598/// namespaces, there are several viable options for a using declaration, but
599/// *we* *recommend* `using namespace bdldfp::DecimalLiterals`, which minimizes
600/// the scope of the using declaration.
601///
602/// Note that the parsing follows the rules as specified for the `strtod32`,
603/// `strtod64` and `strtod128` functions in section 9.6 of the ISO/EIC TR 247128
604/// C Decimal Floating-Point Technical Report.
605///
606/// Also note that these operators can be used only if the compiler supports
607/// C++11 standard.
608///
609/// ## Usage {#bdldfp_decimal-usage}
610///
611///
612/// In this section, we show the intended usage of this component.
613///
614/// ### Example 1: Portable Initialization of Non-Integer, Constant Values {#bdldfp_decimal-example-1-portable-initialization-of-non-integer-constant-values}
615///
616///
617/// If your compiler does not support the C Decimal TR, it does not support
618/// decimal floating-point literals, only binary floating-point literals. The
619/// problem with binary floating-point literals is the same as with binary
620/// floating-point numbers in general: they cannot represent the decimal numbers
621/// we care about. To solve this problem there are 3 macros provided by this
622/// component that can be used to initialize decimal floating-point types with
623/// non-integer values, precisely. These macros will evaluate to real, C
624/// language literals where those are supported and to a runtime-parsed solution
625/// otherwise. The following code demonstrates the use of these macros as well
626/// as mixed-type arithmetics and comparisons:
627/// @code
628/// bdldfp::Decimal32 d32( BDLDFP_DECIMAL_DF(0.1));
629/// bdldfp::Decimal64 d64( BDLDFP_DECIMAL_DD(0.2));
630/// bdldfp::Decimal128 d128(BDLDFP_DECIMAL_DL(0.3));
631///
632/// assert(d32 + d64 == d128);
633/// assert(bdldfp::Decimal64(d32) * 10 == bdldfp::Decimal64(1));
634/// assert(d64 * 10 == bdldfp::Decimal64(2));
635/// assert(d128 * 10 == bdldfp::Decimal128(3));
636/// @endcode
637///
638/// ### Example 2: Precise Calculations with Decimal Values {#bdldfp_decimal-example-2-precise-calculations-with-decimal-values}
639///
640///
641/// Suppose we need to add two (decimal) numbers and then tell if the result is
642/// a particular decimal number or not. That can get difficult with binary
643/// floating-point, but easy with decimal:
644/// @code
645/// if (std::numeric_limits<double>::radix == 2) {
646/// assert(.1 + .2 != .3);
647/// }
648/// assert(BDLDFP_DECIMAL_DD(0.1) + BDLDFP_DECIMAL_DD(0.2)
649/// == BDLDFP_DECIMAL_DD(0.3));
650/// @endcode
651/// @}
652/** @} */
653/** @} */
654
655/** @addtogroup bdl
656 * @{
657 */
658/** @addtogroup bdldfp
659 * @{
660 */
661/** @addtogroup bdldfp_decimal
662 * @{
663 */
664
665#include <bdldfp_decimal.fwd.h>
666
667#include <bdlscm_version.h>
668
671
672#include <bslh_hash.h>
673
674#include <bslma_default.h>
675
678
679#include <bsls_assert.h>
681#include <bsls_keyword.h>
682#include <bsls_libraryfeatures.h>
683#include <bsls_platform.h>
684
685#include <bsl_cstddef.h>
686#include <bsl_cstring.h>
687#include <bsl_ios.h>
688#include <bsl_iosfwd.h>
689#include <bsl_iterator.h>
690#include <bsl_limits.h>
691#include <bsl_locale.h>
692
693
694#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
695#include <bslalg_typetraits.h>
696
697#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
698
699
700 // Portable decimal floating-point literal support
701
702#define BDLDFP_DECIMAL_DF(lit) \
703 BloombergLP::bdldfp::Decimal32(BDLDFP_DECIMALIMPUTIL_DF(lit))
704
705#define BDLDFP_DECIMAL_DD(lit) \
706 BloombergLP::bdldfp::Decimal64(BDLDFP_DECIMALIMPUTIL_DD(lit))
707
708#define BDLDFP_DECIMAL_DL(lit) \
709 BloombergLP::bdldfp::Decimal128(BDLDFP_DECIMALIMPUTIL_DL(lit))
710
711
712namespace bdldfp {
713
716
717/// The decimal floating-point types are typedefs to the unspecified
718/// implementation types.
720
721 // ====================
722 // class Decimal_Type32
723 // ====================
724
725/// This value-semantic class implements the IEEE-754 32 bit decimal
726/// floating-point interchange format type. This class is a standard layout
727/// type that is `const` thread-safe and exception-neutral.
728///
729/// See @ref bdldfp_decimal
731
732 private:
733 // DATA
734 DecimalImpUtil::ValueType32 d_value; // The underlying IEEE representation
735
736 public:
737 // CLASS METHODS
738
739 // Aspects
740
741 static int maxSupportedBdexVersion();
742 /// Return the maximum valid BDEX format version, as indicated by the
743 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
744 /// method. Note that it is highly recommended that `versionSelector`
745 /// be formatted as "YYYYMMDD", a date representation. Also note that
746 /// `versionSelector` should be a *compile*-time-chosen value that
747 /// selects a format version supported by both externalizer and
748 /// unexternalizer. See the `bslx` package-level documentation for more
749 /// information on BDEX streaming of value-semantic types and
750 /// containers.
751 static int maxSupportedBdexVersion(int versionSelector);
752
753 // TRAITS
756
757 // CREATORS
758
759 /// Create a `Decimal32_Type` object having the value positive zero and
760 /// the smallest exponent value.
762
763 /// Create a `Decimal32_Type` object having the specified `value`.
765
766 /// Create a `Decimal32_Type` object having the value closest to the
767 /// value of the specified `other` following the conversion rules as
768 /// defined by IEEE-754:
769 ///
770 explicit Decimal_Type32(Decimal_Type64 other);
771 /// * If `other` is NaN, initialize this object to a NaN.
772 /// * Otherwise if `other` is infinity (positive or negative), then
773 /// initialize this object to infinity with the same sign.
774 /// * Otherwise if `other` has a zero value, then initialize this
775 /// object to zero with the same sign.
776 /// * Otherwise if `other` has an absolute value that is larger than
777 /// `std::numeric_limits<Decimal32>::max()` then store the value of
778 /// the macro `ERANGE` into `errno` and initialize this object to
779 /// infinity with the same sign as `other`.
780 /// * Otherwise if `other` has an absolute value that is smaller than
781 /// `std::numeric_limits<Decimal32>::min()` then store the value of
782 /// the macro `ERANGE` into `errno` and initialize this object to
783 /// zero with the same sign as `other`.
784 /// * Otherwise if `other` has a value that has more significant digits
785 /// than `std::numeric_limits<Decimal32>::max_digit` then initialize
786 /// this object to the value of `other` rounded according to the
787 /// rounding direction.
788 /// * Otherwise initialize this object to the value of the `other`.
789 explicit Decimal_Type32(Decimal_Type128 other);
790
791 /// Create a `Decimal32_Type` object having the value closest to the
792 /// value of the specified `other` value. *Warning:* clients requiring
793 /// a conversion for an exact decimal value should use
794 /// @ref bdldfp_decimalconvertutil (see *WARNING*: Conversions from
795 /// `float` and `double`}. This conversion follows the conversion
796 /// rules as defined by IEEE-754:
797 ///
798 explicit Decimal_Type32(float other);
799 /// * If `other` is NaN, initialize this object to a NaN.
800 /// * Otherwise if `other` is infinity (positive or negative), then
801 /// initialize this object to infinity value with the same sign.
802 /// * Otherwise if `other` has a zero value, then initialize this
803 /// object to zero with the same sign.
804 /// * Otherwise if `other` has an absolute value that is larger than
805 /// `std::numeric_limits<Decimal32>::max()` then store the value of
806 /// the macro `ERANGE` into `errno` and initialize this object to
807 /// infinity with the same sign as `other`.
808 /// * Otherwise if `other` has an absolute value that is smaller than
809 /// `std::numeric_limits<Decimal32>::min()` then store the value of
810 /// the macro `ERANGE` into `errno` and initialize this object to
811 /// zero with the same sign as `other`.
812 /// * Otherwise if `other` has a value that has more significant digits
813 /// than `std::numeric_limits<Decimal32>::max_digit` then initialize
814 /// this object to the value of `other` rounded according to the
815 /// rounding direction.
816 /// * Otherwise initialize this object to the value of the `other`.
817 explicit Decimal_Type32(double other);
818
819 /// Create a `Decimal32_Type` object having the value closest to the
820 /// value of the specified `other` following the conversion rules as
821 /// defined by IEEE-754:
822 ///
823 explicit Decimal_Type32(int other);
824 explicit Decimal_Type32(unsigned int other);
825 explicit Decimal_Type32(long int other);
826 explicit Decimal_Type32(unsigned long int other);
827 explicit Decimal_Type32(long long other);
828 /// * If `value` is zero then initialize this object to a zero with an
829 /// unspecified sign and an unspecified exponent.
830 /// * Otherwise if `other` has a value that is not exactly
831 /// representable using `std::numeric_limits<Decimal32>::max_digit`
832 /// decimal digits then initialize this object to the value of
833 /// `other` rounded according to the rounding direction.
834 /// * Otherwise initialize this object to the value of `other` with
835 /// exponent 0.
836 explicit Decimal_Type32(unsigned long long other);
837
838 Decimal32_Type(const Decimal32_Type& original) = default;
839 // Create a 'Decimal32_Type' object that is a copy of the specified
840 // 'original' as defined by the 'copy' operation of IEEE-754 2008:
841 //
842 //: o If 'other' is NaN, initialize this object to a NaN.
843 //:
844 //: o Otherwise initialize this object to the value of the 'other'.
845 //
846 // Note that since floating-point types may be NaN, and NaNs are
847 // unordered (do not compare equal even to themselves) it is possible
848 // that a copy of a decimal will not compare equal to the original;
849 // however it will behave as the original.
850
851 ~Decimal32_Type() = default;
852 // Destroy this object.
853
854 // MANIPULATORS
856 // Make this object a copy of the specified 'rhs' as defined by the
857 // 'copy' operation of IEEE-754 2008 and return a reference providing
858 // modifiable access to this object.
859 //
860 //: o If 'other' is NaN, set this object to a NaN.
861 //:
862 //: o Otherwise set this object to the value of the 'other'.
863 //
864 // Note that since floating-point types may be NaN, and NaNs are
865 // unordered (do not compare equal even to themselves) it is possible
866 // that, after an assignment, a decimal will not compare equal to the
867 // original; however it will behave as the original.
868
869 /// Add 1.0 to the value of this object and return a reference to it.
870 /// Note that this is a floating-point value so this operation may not
871 /// change the value of this object at all (if the value is large) or it
872 /// may just set it to 1.0 (if the original value is small).
874
875 /// Add -1.0 to the value of this object and return a reference to it.
876 /// Note that this is a floating-point value so this operation may not
877 /// change the value of this object at all (if the value is large) or it
878 /// may just set it to -1.0 (if the original value is small).
880
881 /// Add the value of the specified `rhs` object to the value of this as
882 /// described by IEEE-754, store the result in this object, and return a
883 /// reference to this object.
884 ///
885 /// * If either of this object or `rhs` is signaling NaN, then store
886 /// the value of the macro `EDOM` into `errno` and set this object to
887 /// a NaN.
888 /// * Otherwise if either of this object or `rhs` is NaN then set this
889 /// object to a NaN.
890 /// * Otherwise if this object and `rhs` have infinity value of
891 /// differing signs, store the value of the macro `EDOM` into `errno`
892 /// and set this object to a NaN.
893 /// * Otherwise if this object and `rhs` have infinite values of the
894 /// same sign, then do not change this object.
895 /// * Otherwise if `rhs` has a zero value (positive or negative), do
896 /// not change this object.
897 /// * Otherwise if the sum of this object and `rhs` has an absolute
898 /// value that is larger than `std::numeric_limits<Decimal32>::max()`
899 /// then store the value of the macro `ERANGE` into `errno` and
900 /// set this object to infinity with the same sign as that result.
901 /// * Otherwise set this object to the sum of the number represented by
902 /// `rhs` and the number represented by this object.
903 ///
904 /// Note that this is a floating-point value so this operations may not
905 /// change the value of this object at all (if the value is large) or it
906 /// may seem to update it to the value of the `other` (if the original
907 /// value is small).
908 ///
909 /// Also note that when `rhs` is a `Decimal64`, this operation is
910 /// always performed with 64 bits precision to prevent loss of
911 /// precision of the `rhs` operand (prior to the operation). The
912 /// result is then rounded back to 32 bits and stored to this object.
913 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
914 /// specification.
915 ///
916 /// Also note that when `rhs` is a `Decimal128`, this operation is
917 /// always performed with 128 bits precision to prevent loss of
918 /// precision of the `rhs` operand (prior to the operation). The
919 /// result is then rounded back to 32 bits and stored to this object.
920 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
921 /// specification.
925
926 /// Add the specified `rhs` to the value of this object as described by
927 /// IEEE-754, store the result in this object, and return a reference to
928 /// this object.
929 ///
930 /// * If this object is signaling NaN, then store the value of the
931 /// macro `EDOM` into `errno` and set this object to a NaN.
932 /// * Otherwise if this object is NaN, then do not change this object.
933 /// * Otherwise if this object is infinity, then do not change it.
934 /// * Otherwise if the sum of this object and `rhs` has an absolute
935 /// value that is larger than `std::numeric_limits<Decimal32>::max()`
936 /// then store the value of the macro `ERANGE` into `errno` and
937 /// set this object to infinity with the same sign as that result.
938 /// * Otherwise set this object to sum of adding `rhs` and the number
939 /// represented by this object.
940 ///
941 /// Note that this is a floating-point value so this operations may not
942 /// change the value of this object at all (if the value is large) or it
943 /// may seem to update it to the value of the `other` (if the original
944 /// value is small).
945 ///
946 /// Also note that this operation is always performed with 64 bits
947 /// precision to prevent loss of precision of the `rhs` operand (prior
948 /// to the operation). The result is then rounded back to 32 bits and
949 /// stored to this object. See IEEE-754 2008, 5.1, first paragraph,
950 /// second sentence for specification.
951 Decimal_Type32& operator+=(int rhs);
952 Decimal_Type32& operator+=(unsigned int rhs);
953 Decimal_Type32& operator+=(long rhs);
954 Decimal_Type32& operator+=(unsigned long rhs);
955 Decimal_Type32& operator+=(long long rhs);
956 Decimal_Type32& operator+=(unsigned long long rhs);
957
958
959 /// Subtract the value of the specified `rhs` from the value of this
960 /// object as described by IEEE-754, store the result in this object,
961 /// and return a reference to this object.
962 ///
963 /// * If this object is signaling NaN, then store the value of the
964 /// macro `EDOM` into `errno` and set this object to a NaN.
965 /// * Otherwise if either of this object or `rhs` is NaN then set this
966 /// object to a NaN.
967 /// * Otherwise if this object and `rhs` have infinity value of the
968 /// same signs, store the value of the macro `EDOM` into `errno`
969 /// and set this object to a NaN.
970 /// * Otherwise if this object and the `rhs` have infinite values of
971 /// differing signs, then do not change this object.
972 /// * Otherwise if the `rhs` has a zero value (positive or negative),
973 /// do not change this object.
974 /// * Otherwise if subtracting the value of the `rhs` object from this
975 /// results in an absolute value that is larger than
976 /// `std::numeric_limits<Decimal32>::max()` then store the value of
977 /// the macro `ERANGE` into `errno` and set this object to infinity
978 /// with the same sign as that result.
979 /// * Otherwise set this object to the result of subtracting the value
980 /// of `rhs` from the value of this object.
981 ///
982 /// Note that this is a floating-point value so this operations may not
983 /// change the value of this object at all (if the value is large) or it
984 /// may seem to update it to the value of the `other` (if the original
985 /// value is small).
986 ///
987 /// Also note that when `rhs` is a `Decimal64`, this operation is
988 /// always performed with 64 bits precision to prevent loss of
989 /// precision of the `rhs` operand (prior to the operation). The
990 /// result is then rounded back to 32 bits and stored to this object.
991 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
992 /// specification.
993 ///
994 /// Also note that when `rhs` is a `Decimal128`, this operation is
995 /// always performed with 128 bits precision to prevent loss of
996 /// precision of the `rhs` operand (prior to the operation). The
997 /// result is then rounded back to 32 bits and stored to this object.
998 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
999 /// specification.
1003
1004 /// Subtract the specified `rhs` from the value of this object as
1005 /// described by IEEE-754, store the result in this object, and return a
1006 /// reference to this object.
1007 ///
1008 /// * If this object is signaling NaN, then store the value of the
1009 /// macro `EDOM` into `errno` and set this object to a NaN.
1010 /// * Otherwise if this object is NaN, then do not change this object.
1011 /// * Otherwise if this object is infinity, then do not change it.
1012 /// * Otherwise if subtracting `rhs` from this object's value results
1013 /// in an absolute value that is larger than
1014 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1015 /// the macro `ERANGE` into `errno` and set this object to infinity
1016 /// with the same sign as that result.
1017 /// * Otherwise set this object to the result of subtracting `rhs` from
1018 /// the value of this object.
1019 ///
1020 /// Note that this is a floating-point value so this operations may not
1021 /// change the value of this object at all (if the value is large) or it
1022 /// may seem to update it to the value of the `other` (if the original
1023 /// value is small).
1024 ///
1025 /// Also note that this operation is always performed with 64 bits
1026 /// precision to prevent loss of precision of the `rhs` operand (prior
1027 /// to the operation). The result is then rounded back to 32 bits and
1028 /// stored to this object. See IEEE-754 2008, 5.1, first paragraph,
1029 /// second sentence for specification.
1030 Decimal_Type32& operator-=(int rhs);
1031 Decimal_Type32& operator-=(unsigned int rhs);
1032 Decimal_Type32& operator-=(long rhs);
1033 Decimal_Type32& operator-=(unsigned long rhs);
1034 Decimal_Type32& operator-=(long long rhs);
1035 Decimal_Type32& operator-=(unsigned long long rhs);
1036
1037 /// Multiply the value of the specified `rhs` object by the value of
1038 /// this as described by IEEE-754, store the result in this object, and
1039 /// return a reference to this object.
1040 ///
1041 /// * If either of this object or `rhs` is signaling NaN, then store
1042 /// the value of the macro `EDOM` into `errno` and set this object to
1043 /// a NaN.
1044 /// * Otherwise if either of this object or `rhs` is NaN then set this
1045 /// object to a NaN.
1046 /// * Otherwise, if one of this object and `rhs` is zero (positive or
1047 /// negative) and the other is infinity (positive or negative), store
1048 /// the value of the macro `EDOM` into `errno` and set this object to
1049 /// a NaN.
1050 /// * Otherwise, if either this object or `rhs` is positive or negative
1051 /// infinity, set this object to infinity. The sign of this object
1052 /// will be positive if this object and `rhs` had the same sign, and
1053 /// negative otherwise.
1054 /// * Otherwise, if either this object or `rhs` is zero, set this
1055 /// object to zero. The sign of this object will be positive if this
1056 /// object and `rhs` had the same sign, and negative otherwise.
1057 /// * Otherwise if the product of this object and `rhs` has an absolute
1058 /// value that is larger than `std::numeric_limits<Decimal32>::max()`
1059 /// then store the value of the macro `ERANGE` into `errno` and set
1060 /// this object to infinity with the same sign of that result.
1061 /// * Otherwise if the product of this object and `rhs` has an absolute
1062 /// value that is smaller than
1063 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1064 /// the macro `ERANGE` into `errno` and set this object to zero value
1065 /// with the same sign as that result.
1066 /// * Otherwise set this object to the product of the value of `rhs`
1067 /// and the value of this object.
1068 ///
1069 /// Note that when `rhs` is a `Decimal64`, this operation is always
1070 /// performed with 64 bits precision to prevent loss of precision of the
1071 /// `rhs` operand (prior to the operation). The result is then rounded
1072 /// back to 32 bits and stored to this object. See IEEE-754 2008, 5.1,
1073 /// first paragraph, second sentence for specification.
1074 ///
1075 /// Also note that when `rhs` is a `Decimal128`, this operation is
1076 /// always performed with 128 bits precision to prevent loss of
1077 /// precision of the `rhs` operand (prior to the operation). The
1078 /// result is then rounded back to 32 bits and stored to this object.
1079 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
1080 /// specification.
1084
1085 /// Multiply the specified `rhs` by the value of this object as
1086 /// described by IEEE-754, store the result in this object, and return a
1087 /// reference to this object.
1088 ///
1089 /// * If this object is signaling NaN, then store the value of the
1090 /// macro `EDOM` into `errno` and set this object to a NaN.
1091 /// * Otherwise if this object is NaN, then do not change this object.
1092 /// * Otherwise if this object is infinity (positive or negative), and
1093 /// `rhs` is zero, then store the value of the macro `EDOM` into
1094 /// `errno` and set this object to a NaN.
1095 /// * Otherwise if this object is infinity (positive or negative), then
1096 /// do not change it.
1097 /// * Otherwise if `rhs` is zero, then set this object to zero with the
1098 /// same sign as its value had prior to this operation.
1099 /// * Otherwise if the product of `rhs` and the value of this object
1100 /// results in an absolute value that is larger than
1101 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1102 /// the macro `ERANGE` into `errno` and set this object to infinity
1103 /// with the same sign as that result.
1104 /// * Otherwise if the product of `rhs` and the value of this object
1105 /// results in an absolute value that is smaller than
1106 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1107 /// the macro `ERANGE` into `errno` and set this object to zero with
1108 /// the same sign as that result.
1109 /// * Otherwise set this object to the product of the value of this
1110 /// object and the value `rhs`.
1111 ///
1112 /// Note that this operation is always performed with 64 bits precision
1113 /// to prevent loss of precision of the `rhs` operand (prior to the
1114 /// operation). The result is then rounded back to 32 bits and stored
1115 /// to this object. See IEEE-754 2008, 5.1, first paragraph,
1116 Decimal_Type32& operator*=(int rhs);
1117 Decimal_Type32& operator*=(unsigned int rhs);
1118 Decimal_Type32& operator*=(long rhs);
1119 Decimal_Type32& operator*=(unsigned long rhs);
1120 Decimal_Type32& operator*=(long long rhs);
1121 Decimal_Type32& operator*=(unsigned long long rhs);
1122
1123 /// Divide the value of this object by the value of the specified `rhs`
1124 /// as described by IEEE-754, store the result in this object, and
1125 /// return a reference to this object.
1126 ///
1127 /// * If either of this object or `rhs` is signaling NaN, then store
1128 /// the value of the macro `EDOM` into `errno` and set this object to
1129 /// a NaN.
1130 /// * Otherwise if either of this object or `rhs` is NaN then set this
1131 /// object to a NaN.
1132 /// * Otherwise if this object and `rhs` are both infinity (positive or
1133 /// negative) or both zero (positive or negative) then store the
1134 /// value of the macro `EDOM` into `errno` and return a NaN.
1135 /// * Otherwise if `rhs` has a positive zero value, then store the
1136 /// value of the macro `ERANGE` into `errno` and set this object to
1137 /// infinity with the same sign as its original value.
1138 /// * Otherwise if `rhs` has a negative zero value, then store the
1139 /// value of the macro `ERANGE` into `errno` and set this object to
1140 /// infinity with the opposite sign as its original value.
1141 /// * Otherwise if dividing the value of this object by the value of
1142 /// `rhs` results in an absolute value that is larger than
1143 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1144 /// the macro `ERANGE` into `errno` and return infinity with the same
1145 /// sign as that result.
1146 /// * Otherwise if dividing the value of this object by the value of
1147 /// `rhs` results in an absolute value that is smaller than
1148 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1149 /// the macro `ERANGE` into `errno`and return zero with the same sign
1150 /// as that result.
1151 /// * Otherwise set this object to the result of dividing the value of
1152 /// this object by the value of `rhs`.
1153 ///
1154 /// Note that when `rhs` is a `Decimal64`, this operation is always
1155 /// performed with 64 bits precision to prevent loss of precision of the
1156 /// `rhs` operand (prior to the operation). The result is then rounded
1157 /// back to 32 bits and stored to this object. See IEEE-754 2008, 5.1,
1158 /// first paragraph, second sentence for specification.
1159 ///
1160 /// Also note that when `rhs` is a `Decimal128`, this operation is
1161 /// always performed with 128 bits precision to prevent loss of
1162 /// precision of the `rhs` operand (prior to the operation). The
1163 /// result is then rounded back to 32 bits and stored to this object.
1164 /// See IEEE-754 2008, 5.1, first paragraph, second sentence for
1165 /// specification.
1169
1170 /// Divide the value of this object by the specified `rhs` as described
1171 /// by IEEE-754, store the result in this object, and return a reference
1172 /// to this object.
1173 ///
1174 /// * If this object is signaling NaN, then store the value of the
1175 /// macro `EDOM` into `errno` and set this object to a NaN.
1176 /// * Otherwise if this object is NaN then set this object to a NaN.
1177 /// * Otherwise if this object is infinity (positive or negative) and
1178 /// `rhs` is positive value then set this object to infinity value
1179 /// with the same sign as its original value.
1180 /// * Otherwise if this object is infinity (positive or negative) and
1181 /// `rhs` is negative value then set this object to infinity value
1182 /// with the opposite sign as its original value.
1183 /// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
1184 /// into `errno` and set this object to infinity with the same sign
1185 /// it had prior to this operation.
1186 /// * Otherwise if dividing the value of this object by the value of
1187 /// `rhs` results in an absolute value that is larger than
1188 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1189 /// the macro `ERANGE` into `errno` and return infinity with the same
1190 /// sign as that result.
1191 /// * Otherwise if dividing the value of this object by the value of
1192 /// `rhs` results in an absolute value that is smaller than
1193 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1194 /// the macro `ERANGE` into `errno`and return zero with the same sign
1195 /// as that result.
1196 /// * Otherwise set this object to the result of dividing the value of
1197 /// this object by the value of `rhs`.
1198 ///
1199 /// Note that this operation is always performed with 64 bits precision
1200 /// to prevent loss of precision of the `rhs` operand (prior to the
1201 /// operation). The result is then rounded back to 32 bits and stored
1202 /// to this object. See IEEE-754 2008, 5.1, first paragraph,
1203 Decimal_Type32& operator/=(int rhs);
1204 Decimal_Type32& operator/=(unsigned int rhs);
1205 Decimal_Type32& operator/=(long rhs);
1206 Decimal_Type32& operator/=(unsigned long rhs);
1207 Decimal_Type32& operator/=(long long rhs);
1208 Decimal_Type32& operator/=(unsigned long long rhs);
1209
1210 /// Return a pointer providing modifiable access to the underlying
1211 /// implementation.
1213
1214 // Aspects
1215
1216 /// Assign to this object the value read from the specified input
1217 /// `stream` using the specified `version` format, and return a
1218 /// reference to `stream`. If `stream` is initially invalid, this
1219 /// operation has no effect. If `version` is not supported, this object
1220 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
1221 /// If `version` is supported but `stream` becomes invalid during this
1222 /// operation, this object has an undefined, but valid, state. Note
1223 /// that no version is read from `stream`. See the `bslx` package-level
1224 /// documentation for more information on BDEX streaming of
1225 /// value-semantic types and containers.
1226 template <class STREAM>
1227 STREAM& bdexStreamIn(STREAM& stream, int version);
1228
1229 // ACCESSORS
1230
1231 /// Return a pointer providing non-modifiable access to the underlying
1232 /// implementation.
1233 const DecimalImpUtil::ValueType32 *data() const;
1234
1235 /// Return the value of the underlying implementation.
1237
1238 // Aspects
1239
1240 /// Write the value of this object, using the specified `version`
1241 /// format, to the specified output `stream`, and return a reference to
1242 /// `stream`. If `stream` is initially invalid, this operation has no
1243 /// effect. If `version` is not supported, `stream` is invalidated, but
1244 /// otherwise unmodified. Note that `version` is not written to
1245 /// `stream`. See the `bslx` package-level documentation for more
1246 /// information on BDEX streaming of value-semantic types and
1247 /// containers.
1248 template <class STREAM>
1249 STREAM& bdexStreamOut(STREAM& stream, int version) const;
1250};
1251
1252// FREE OPERATORS
1253
1254/// Return a copy of the specified `value` if the value is not negative
1255/// zero, and return positive zero otherwise.
1257
1258/// Return the result of applying the unary - operator to the specified
1259/// `value` as described by IEEE-754, essentially reversing the sign bit.
1260/// Note that floating-point numbers have signed zero, so this operation is
1261/// not the same as `0 - value`.
1263
1264/// Apply the prefix ++ operator to the specified `value` and return its
1265/// original value. Note that this is a floating-point value so this
1266/// operation may not change the value of this object at all (if the value
1267/// is large) or it may just set it to 1.0 (if the original value is small).
1269
1270/// Apply the prefix -- operator to the specified `value` and return its
1271/// original value. Note that this is a floating-point value so this
1272/// operation may not change the value of this object at all (if the value
1273/// is large) or it may just set it to -1.0 (if the original value is
1274/// small).
1276
1277/// Add the value of the specified `rhs` to the value of the specified `lhs`
1278/// as described by IEEE-754 and return the result.
1279///
1280/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1281/// the macro `EDOM` into `errno` and return a NaN.
1282/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1283/// * Otherwise if `lhs` and `rhs` are infinities of differing signs, store
1284/// the value of the macro `EDOM` into `errno` and return a NaN.
1285/// * Otherwise if `lhs` and `rhs` are infinities of the same sign then
1286/// return infinity of that sign.
1287/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
1288/// larger than `std::numeric_limits<Decimal32>::max()` then store the
1289/// value of the macro `ERANGE` into `errno` and set this object to
1290/// infinity with the same sign as that result.
1291/// * Otherwise return the sum of the number represented by `lhs` and the
1292/// number represented by `rhs`.
1294
1295/// Add the specified `rhs` to the value of the specified `lhs` as described
1296/// by IEEE-754 and return the result.
1297///
1298/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1299/// into `errno` and return a NaN.
1300/// * Otherwise if `lhs` object is NaN, then return a NaN.
1301/// * Otherwise if `lhs` is infinity, then return infinity.
1302/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
1303/// larger than `std::numeric_limits<Decimal32>::max()` then store the
1304/// value of the macro `ERANGE` into `errno` and return infinity with the
1305/// same sign as that result.
1306/// * Otherwise return the sum of `rhs` and the number represented by
1307/// `lhs`.
1309Decimal32 operator+(Decimal32 lhs, unsigned int rhs);
1311Decimal32 operator+(Decimal32 lhs, unsigned long rhs);
1312Decimal32 operator+(Decimal32 lhs, long long rhs);
1313Decimal32 operator+(Decimal32 lhs, unsigned long long rhs);
1314
1315/// Add the specified `lhs` to the value of the specified `rhs` as described
1316/// by IEEE-754 and return the result.
1317///
1318/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1319/// into `errno` and return a NaN.
1320/// * Otherwise if `rhs` object is NaN, then return a NaN.
1321/// * Otherwise if `rhs` is infinity, then return infinity.
1322/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
1323/// larger than `std::numeric_limits<Decimal32>::max()` then store the
1324/// value of the macro `ERANGE` into `errno` and return infinity with the
1325/// same sign as that result.
1326/// * Otherwise return the sum of `lhs` and the number represented by
1327/// `rhs`.
1329Decimal32 operator+(unsigned int lhs, Decimal32 rhs);
1331Decimal32 operator+(unsigned long lhs, Decimal32 rhs);
1332Decimal32 operator+(long long lhs, Decimal32 rhs);
1333Decimal32 operator+(unsigned long long lhs, Decimal32 rhs);
1334
1335/// Subtract the value of the specified `rhs` from the value of the
1336/// specified `lhs` as described by IEEE-754 and return the result.
1337///
1338/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1339/// the macro `EDOM` into `errno` and return a NaN.
1340/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1341/// * Otherwise if `lhs` and the `rhs` have infinity values of the same
1342/// sign, store the value of the macro `EDOM` into `errno` and return a
1343/// NaN.
1344/// * Otherwise if `lhs` and the `rhs` have infinity values of differing
1345/// signs, then return `lhs`.
1346/// * Otherwise if the subtracting of `lhs` and `rhs` has an absolute value
1347/// that is larger than `std::numeric_limits<Decimal32>::max()` then
1348/// store the value of the macro `ERANGE` into `errno` and return
1349/// infinity with the same sign as that result.
1350/// * Otherwise return the result of subtracting the value of `rhs` from
1351/// the value of `lhs`.
1353
1354/// Subtract the specified `rhs` from the value of the specified `lhs` as
1355/// described by IEEE-754 and return a reference to this object.
1356///
1357/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1358/// into `errno` and return a NaN.
1359/// * Otherwise if `lhs` is NaN, then return a NaN.
1360/// * Otherwise if `lhs` is infinity, then return infinity.
1361/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
1362/// an absolute value that is larger than
1363/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1364/// macro `ERANGE` into `errno` and return infinity with the same sign as
1365/// that result.
1366/// * Otherwise return the result of subtracting `rhs` from the value of
1367/// `lhs`.
1369Decimal32 operator-(Decimal32 lhs, unsigned int rhs);
1371Decimal32 operator-(Decimal32 lhs, unsigned long rhs);
1372Decimal32 operator-(Decimal32 lhs, long long rhs);
1373Decimal32 operator-(Decimal32 lhs, unsigned long long rhs);
1374
1375/// Subtract the specified `rhs` from the value of the specified `lhs` as
1376/// described by IEEE-754 and return a reference to this object.
1377///
1378/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1379/// into `errno` and return a NaN.
1380/// * Otherwise if `rhs` is NaN, then return a NaN.
1381/// * Otherwise if `rhs` is infinity, then return infinity.
1382/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
1383/// an absolute value that is larger than
1384/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1385/// macro `ERANGE` into `errno` and return infinity with the same sign as
1386/// that result.
1387/// * Otherwise return the result of subtracting the value of `rhs` from
1388/// the number `lhs`.
1390Decimal32 operator-(unsigned int lhs, Decimal32 rhs);
1392Decimal32 operator-(unsigned long lhs, Decimal32 rhs);
1393Decimal32 operator-(long long lhs, Decimal32 rhs);
1394Decimal32 operator-(unsigned long long lhs, Decimal32 rhs);
1395
1396/// Multiply the value of the specified `lhs` object by the value of the
1397/// specified `rhs` as described by IEEE-754 and return the result.
1398///
1399/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1400/// the macro `EDOM` into `errno` and return a NaN.
1401/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1402/// * Otherwise if one of the operands is infinity (positive or negative)
1403/// and the other is zero (positive or negative), then store the value of
1404/// the macro `EDOM` into `errno` and return a NaN.
1405/// * Otherwise if both `lhs` and `rhs` are infinity (positive or
1406/// negative), return infinity. The sign of the returned value will be
1407/// positive if `lhs` and `rhs` have the same sign, and negative
1408/// otherwise.
1409/// * Otherwise, if either `lhs` or `rhs` is zero, return zero. The sign
1410/// of the returned value will be positive if `lhs` and `rhs` have the
1411/// same sign, and negative otherwise.
1412/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
1413/// that is larger than `std::numeric_limits<Decimal32>::max()` then
1414/// store the value of the macro `ERANGE` into `errno` and return
1415/// infinity with the same sign as that result.
1416/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
1417/// that is smaller than `std::numeric_limits<Decimal32>::min()` then
1418/// store the value of the macro `ERANGE` into `errno` and return zero
1419/// with the same sign as that result.
1420/// * Otherwise return the product of the value of `rhs` and the number
1421/// represented by `rhs`.
1423
1424/// Multiply the specified `rhs` by the value of the specified `lhs` as
1425/// described by IEEE-754, and return the result.
1426///
1427/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1428/// into `errno` and return a NaN.
1429/// * Otherwise if `lhs` is NaN, then return a NaN.
1430/// * Otherwise if `lhs` is infinity (positive or negative), and `rhs` is
1431/// zero, then store the value of the macro `EDOM` into `errno` and
1432/// return a NaN.
1433/// * Otherwise if `lhs` is infinity (positive or negative), then return
1434/// `lhs`.
1435/// * Otherwise if `rhs` is zero, then return zero with the sign of `lhs`.
1436/// * Otherwise if the product of `rhs` and the value of `lhs` results in
1437/// an absolute value that is larger than
1438/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1439/// macro `ERANGE` into `errno` and return infinity with the same sign as
1440/// that result.
1441/// * Otherwise if the product of `rhs` and the value of `lhs` results in
1442/// an absolute value that is smaller than
1443/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1444/// macro `ERANGE` into `errno` and return zero with the same sign as
1445/// that result.
1446/// * Otherwise return the product of the value of `lhs` and value `rhs`.
1448Decimal32 operator*(Decimal32 lhs, unsigned int rhs);
1450Decimal32 operator*(Decimal32 lhs, unsigned long rhs);
1451Decimal32 operator*(Decimal32 lhs, long long rhs);
1452Decimal32 operator*(Decimal32 lhs, unsigned long long rhs);
1453
1454/// Multiply the specified `lhs` by the value of the specified `rhs` as
1455/// described by IEEE-754, and return the result.
1456///
1457/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1458/// into `errno` and return a NaN.
1459/// * Otherwise if `rhs` is NaN, then return a NaN.
1460/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
1461/// zero, then store the value of the macro `EDOM` into `errno` and
1462/// return a NaN.
1463/// * Otherwise if `rhs` is infinity (positive or negative), then return
1464/// `rhs`.
1465/// * Otherwise if `lhs` is zero, then return zero with the sign of `rhs`.
1466/// * Otherwise if the product of `lhs` and the value of `rhs` results in
1467/// an absolute value that is larger than
1468/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1469/// macro `ERANGE` into `errno` and return infinity with the same sign as
1470/// that result.
1471/// * Otherwise if the product of `lhs` and the value of `rhs` results in
1472/// an absolute value that is smaller than
1473/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1474/// macro `ERANGE` into `errno` and return zero with the same sign as
1475/// that result.
1476/// * Otherwise return the product of the value of `lhs` and value `rhs`.
1478Decimal32 operator*(unsigned int lhs, Decimal32 rhs);
1480Decimal32 operator*(unsigned long lhs, Decimal32 rhs);
1481Decimal32 operator*(long long lhs, Decimal32 rhs);
1482Decimal32 operator*(unsigned long long lhs, Decimal32 rhs);
1483
1484/// Divide the value of the specified `lhs` by the value of the specified
1485/// `rhs` as described by IEEE-754, and return the result.
1486///
1487/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
1488/// the macro `EDOM` into `errno` and return a NaN.
1489/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
1490/// * Otherwise if `lhs` and `rhs` are both infinity (positive or negative)
1491/// or both zero (positive or negative) then store the value of the macro
1492/// `EDOM` into `errno` and return a NaN.
1493/// * Otherwise if `lhs` has a normal value and `rhs` has a positive zero
1494/// value, store the value of the macro `ERANGE` into `errno` and return
1495/// infinity with the sign of `lhs`.
1496/// * Otherwise if `lhs` has a normal value and `rhs` has a negative zero
1497/// value, store the value of the macro `ERANGE` into `errno` and return
1498/// infinity with the opposite sign as `lhs`.
1499/// * Otherwise if `lhs` has infinity value and `rhs` has a positive zero
1500/// value, return infinity with the sign of `lhs`.
1501/// * Otherwise if `lhs` has infinity value and `rhs` has a negative zero
1502/// value, return infinity with the opposite sign as `lhs`.
1503/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1504/// results in an absolute value that is larger than
1505/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1506/// macro `ERANGE` into `errno` and return infinity with the same sign as
1507/// that result.
1508/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1509/// results in an absolute value that is smaller than
1510/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1511/// macro `ERANGE` into `errno` and return zero with the same sign as
1512/// that result.
1513/// * Otherwise return the result of dividing the value of `lhs` by the
1514/// value of `rhs`.
1516
1517/// Divide the value of the specified `lhs` by the specified `rhs` as
1518/// described by IEEE-754, and return the result.
1519///
1520/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
1521/// into `errno` and return a NaN.
1522/// * Otherwise if `lhs` is NaN then return a NaN.
1523/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
1524/// positive value then return infinity value with the same sign as its
1525/// original value.
1526/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
1527/// negative value then return infinity value with the opposite sign as
1528/// its original value.
1529/// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
1530/// into `errno` and return infinity with the same sign it had prior to
1531/// this operation.
1532/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1533/// results in an absolute value that is larger than
1534/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1535/// macro `ERANGE` into `errno` and return infinity with the same sign as
1536/// that result.
1537/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1538/// results in an absolute value that is smaller than
1539/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1540/// macro `ERANGE` into `errno` and return zero with the same sign as
1541/// that result.
1542/// * Otherwise return the result of dividing the value of `lhs` by the
1543/// value `rhs`.
1545Decimal32 operator/(Decimal32 lhs, unsigned int rhs);
1547Decimal32 operator/(Decimal32 lhs, unsigned long rhs);
1548Decimal32 operator/(Decimal32 lhs, long long rhs);
1549Decimal32 operator/(Decimal32 lhs, unsigned long long rhs);
1550
1551/// Divide the specified `lhs` by the value of the specified `rhs` as
1552/// described by IEEE-754, and return the result.
1553///
1554/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
1555/// into `errno` and return a NaN.
1556/// * Otherwise if `rhs` is NaN then return a NaN.
1557/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
1558/// zero, store the value of the macro `ERANGE` into `errno` and return a
1559/// NaN.
1560/// * Otherwise if `rhs` is zero (positive or negative), store the value of
1561/// the macro `ERANGE` into `errno` and return infinity with the sign of
1562/// `lhs`.
1563/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1564/// results in an absolute value that is larger than
1565/// `std::numeric_limits<Decimal32>::max()` then store the value of the
1566/// macro `ERANGE` into `errno` and return infinity with the same sign as
1567/// that result.
1568/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
1569/// results in an absolute value that is smaller than
1570/// `std::numeric_limits<Decimal32>::min()` then store the value of the
1571/// macro `ERANGE` into `errno` and return zero with the same sign as
1572/// that result.
1573/// * Otherwise return the result of dividing the value of `lhs` by the
1574/// value `rhs`. Note that this is a floating-point operation, not
1575/// integer.
1577Decimal32 operator/(unsigned int lhs, Decimal32 rhs);
1579Decimal32 operator/(unsigned long lhs, Decimal32 rhs);
1580Decimal32 operator/(long long lhs, Decimal32 rhs);
1581Decimal32 operator/(unsigned long long lhs, Decimal32 rhs);
1582
1583/// Return `true` if the specified `lhs` and `rhs` have the same value, and
1584/// `false` otherwise. Two `Decimal32` objects have the same value if the
1585/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
1586/// comparison) considers the underlying IEEE representations equal. In
1587/// other words, two `Decimal32` objects have the same value if:
1588///
1589/// * both have a zero value (positive or negative), or
1590/// * both have the same infinity value (both positive or negative), or
1591/// * both have the value of a real number that are equal, even if they are
1592/// represented differently (cohorts have the same value)
1593///
1594/// This operation stores the value of the macro `EDOM` into `errno` if
1595/// either or both operands are signaling NaN.
1596///
1597/// Note that a NaN is never equal to anything, including itself:
1598/// @code
1599/// Decimal32 aNaN = std::numeric_limits<Decimal32>::quiet_NaN();
1600/// assert(!(aNan == aNan));
1601/// @endcode
1602bool operator==(Decimal32 lhs, Decimal32 rhs);
1603
1604/// Return `true` if the specified `lhs` and `rhs` do not have the same
1605/// value, and `false` otherwise. Two `Decimal32` objects do not have the
1606/// same value if the `compareQuietEqual` operation (IEEE-754 defined,
1607/// non-total ordering comparison) considers the underlying IEEE
1608/// representations not equal. In other words, two `Decimal32` objects do
1609/// not have the same value if:
1610///
1611/// * both are NaN, or
1612/// * one is zero (positive or negative) and the other is not, or
1613/// * one is positive infinity and the other is not, or
1614/// * one is negative infinity and the other is not, or
1615/// * both have the value of a real number that are not equal, regardless
1616/// of their representation (cohorts are equal)
1617///
1618/// This operation stores the value of the macro `EDOM` into `errno` if
1619/// either or both operands are signaling NaN.
1620///
1621/// Note that a NaN is never equal to anything, including itself:
1622/// @code
1623/// Decimal32 aNaN = std::numeric_limits<Decimal32>::quiet_NaN();
1624/// assert(aNan != aNan);
1625/// @endcode
1626bool operator!=(Decimal32 lhs, Decimal32 rhs);
1627
1628/// Return `true` if the specified `lhs` has a value less than the specified
1629/// `rhs` and `false` otherwise. The value of a `Decimal32` object `lhs` is
1630/// less than that of an object `rhs` if the `compareQuietLess` operation
1631/// (IEEE-754 defined, non-total ordering comparison) considers the
1632/// underlying IEEE representation of `lhs` to be less than of that of
1633/// `rhs`. In other words, `lhs` is less than `rhs` if:
1634///
1635/// * neither `lhs` nor `rhs` are NaN, or
1636/// * `lhs` is zero (positive or negative) and `rhs` positive, or
1637/// * `rhs` is zero (positive or negative) and `lhs` negative, or
1638/// * `lhs` is not positive infinity, or
1639/// * `lhs` is negative infinity and `rhs` is not, or
1640/// * `lhs` and `rhs` both represent a real number and the real number of
1641/// `lhs` is less than that of `rhs`
1642///
1643/// This operation stores the value of the macro `EDOM` into `errno` if
1644/// either or both operands are signaling NaN.
1645bool operator<(Decimal32 lhs, Decimal32 rhs);
1646
1647/// Return `true` if the specified `lhs` has a value less than or equal the
1648/// value of the specified `rhs` and `false` otherwise. The value of a
1649/// `Decimal32` object `lhs` is less than or equal to the value of an object
1650/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
1651/// non-total ordering comparison) considers the underlying IEEE
1652/// representation of `lhs` to be less or equal to that of `rhs`. In other
1653/// words, `lhs` is less or equal than `rhs` if:
1654///
1655/// * neither `lhs` nor `rhs` are NaN, or
1656/// * `lhs` and `rhs` are both zero (positive or negative), or
1657/// * both `lhs` and `rhs` are positive infinity, or
1658/// * `lhs` is negative infinity, or
1659/// * `lhs` and `rhs` both represent a real number and the real number of
1660/// `lhs` is less or equal to that of `rhs`
1661///
1662/// This operation stores the value of the macro `EDOM` into `errno` if
1663/// either or both operands are signaling NaN.
1664bool operator<=(Decimal32 lhs, Decimal32 rhs);
1665
1666/// Return `true` if the specified `lhs` has a greater value than the
1667/// specified `rhs` and `false` otherwise. The value of a `Decimal32`
1668/// object `lhs` is greater than that of an object `rhs` if the
1669/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
1670/// comparison) considers the underlying IEEE representation of `lhs` to be
1671/// greater than of that of `rhs`. In other words, `lhs` is greater than
1672/// `rhs`if:
1673///
1674/// * neither `lhs` nor `rhs` are NaN, or
1675/// * `lhs` and `rhs` are not both zero (positive or negative), or
1676/// * `lhs` is not negative infinity, or
1677/// * `lhs` is positive infinity and `rhs` is not, or
1678/// * `lhs` and `rhs` both represent a real number and the real number of
1679/// `lhs` is greater than that of `rhs`
1680///
1681/// This operation stores the value of the macro `EDOM` into `errno` if
1682/// either or both operands are signaling NaN.
1683bool operator>(Decimal32 lhs, Decimal32 rhs);
1684
1685/// Return `true` if the specified `lhs` has a value greater than or equal
1686/// to the value of the specified `rhs` and `false` otherwise. The value of
1687/// a `Decimal32` object `lhs` is greater or equal to a `Decimal32` object
1688/// `rhs` if the `compareQuietGreaterEqual` operation (IEEE-754 defined,
1689/// non-total ordering comparison ) considers the underlying IEEE
1690/// representation of `lhs` to be greater or equal to that of `rhs`. In
1691/// other words, `lhs` is greater than or equal to `rhs` if:
1692///
1693/// * neither `lhs` nor `rhs` are NaN, or
1694/// * `lhs` and `rhs` are both zero (positive or negative), or
1695/// * both `lhs` and `rhs` are negative infinity, or
1696/// * `lhs` is positive infinity, or
1697/// * `lhs` and `rhs` both represent a real number and the real number of
1698/// `lhs` is greater or equal to that of `rhs`
1699///
1700/// This operation stores the value of the macro `EDOM` into `errno` if
1701/// either or both operands are signaling NaN.
1702bool operator>=(Decimal32 lhs, Decimal32 rhs);
1703
1704/// Read, into the specified `object`, from the specified input `stream` an
1705/// IEEE 32 bit decimal floating-point value as described in the IEEE-754
1706/// 2008 standard (5.12 Details of conversions between floating point
1707/// numbers and external character sequences) and return a reference
1708/// providing modifiable access to `stream`. If `stream` contains a NaN
1709/// value, it is unspecified if `object` will receive a quiet or signaling
1710/// `Nan`. If `stream` is not valid on entry `stream.good() == false`, this
1711/// operation has no effect other than setting `stream.fail()` to `true`.
1712/// If eof (end-of-file) is found before any non-whitespace characters
1713/// `stream.fail()` is set to `true` and `object` remains unchanged. If eof
1714/// is detected after some characters have been read (and successfully
1715/// interpreted as part of the textual representation of a floating-point
1716/// value as specified by IEEE-754) then `stream.eof()` is set to true. If
1717/// the first non-whitespace character sequence is not a valid textual
1718/// representation of a floating-point value (e.g., 12e or e12 or 1*2) the
1719/// `stream.fail()` is set to true and `object` will remain unchanged. If a
1720/// real number value is represented by the character sequence but it is a
1721/// large positive or negative value that cannot be stored into `object`
1722/// then store the value of the macro `ERANGE` into `errno` and positive or
1723/// negative infinity is stored into `object`, respectively. If a real
1724/// number value is represented by the character sequence but it is a small
1725/// positive or negative value that cannot be stored into `object` then
1726/// store the value of the macro `ERANGE` into `errno` and positive or
1727/// negative zero is stored into `object`, respectively. If a real number
1728/// value is represented by the character sequence but it cannot be stored
1729/// exactly into `object`, the value is rounded according to the current
1730/// rounding direction (of the environment) and then stored into `object`.
1731///
1732/// NOTE: This method does not yet fully support iostream flags or the
1733/// decimal floating point exception context.
1734template <class CHARTYPE, class TRAITS>
1735bsl::basic_istream<CHARTYPE, TRAITS>&
1736operator>>(bsl::basic_istream<CHARTYPE, TRAITS>& stream, Decimal32& object);
1737
1738/// Write the value of the specified `object` to the specified output
1739/// `stream` in a single line format as described in the IEEE-754 2008
1740/// standard (5.12 Details of conversions between floating point numbers and
1741/// external character sequences), and return a reference providing
1742/// modifiable access to `stream`. If `stream` is not valid on entry, this
1743/// operation has no effect.
1744///
1745/// NOTE: This method does not yet fully support iostream flags or the
1746/// decimal floating point exception context.
1747template <class CHARTYPE, class TRAITS>
1748bsl::basic_ostream<CHARTYPE, TRAITS>&
1749operator<<(bsl::basic_ostream<CHARTYPE, TRAITS>& stream, Decimal32 object);
1750
1751#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
1752 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
1753inline namespace literals {
1754inline namespace DecimalLiterals {
1755/// Produce an object of the indicated return type by parsing the specified
1756/// `str` having the specified `len` excluding the terminating null
1757/// character that represents a floating-point number written in both fixed
1758/// and scientific notations. These user-defined literal suffixes can be
1759/// applied to both numeric and string literals, (i.e., 1.2_d32, "1.2"_d32
1760/// or "inf"_d32). The resulting decimal object is initialized as follows:
1761///
1762/// * If `str` does not represent a floating-point value, then return a
1763/// decimal object of the indicated return type initialized to a NaN.
1764/// * Otherwise if `str` represents infinity (positive or negative), then
1765/// return a decimal object of the indicated return type initialized to
1766/// infinity value with the same sign.
1767/// * Otherwise if `str` represents zero (positive or negative), then
1768/// return a decimal object of the indicated return type initialized to
1769/// zero with the same sign.
1770/// * Otherwise if `str` represents a value that has an absolute value that
1771/// is larger than the maximum value supported by the indicated return
1772/// type, then store the value of the macro `ERANGE` into `errno` and
1773/// return a decimal object of the return type initialized to infinity
1774/// with the same sign.
1775/// * Otherwise if `str` represents a value that has an absolute value that
1776/// is smaller than min value of the indicated return type, then store
1777/// the value of the macro `ERANGE` into `errno` and return a decimal
1778/// object of the return type initialized to zero with the same sign.
1779/// * Otherwise if `str` has a value that is not exactly representable
1780/// using the maximum digit number supported by the indicated return
1781/// type, then return a decimal object of the return type initialized to
1782/// the value represented by `str` rounded according to the rounding
1783/// direction.
1784/// * Otherwise return a decimal object of the indicated return type
1785/// initialized to the decimal value representation of `str`.
1786///
1787/// Note that the parsing follows the rules as specified for the `strtod32`
1788/// function in section 9.6 of the ISO/EIC TR 247128 C Decimal
1789/// Floating-Point Technical Report.
1790///
1791/// Also note that the numeric literal version omits the optional leading
1792/// sign in `str`. For example, if the string is -1.2_d32 then the string
1793/// "1.2" is passed to the one-argument form, not "-1.2", because leading
1794/// signs are operators, not parts of literals. On the other hand, the
1795/// string literal version does not omit leading sign and if the string is
1796/// "-1.2"_d32 then the string "-1.2" is passed to the two-argument form.
1797///
1798/// Also note that the quantum of the resultant value is affected by the
1799/// number of decimal places in `str` string in both numeric and string
1800/// literal formats starting with the most significand digit and cannot
1801/// exceed the maximum number of digits necessary to differentiate all
1802/// values of the indicated return type, for example:
1803///
1804/// `0.015_d32; "0.015"_d32 => 15e-3`
1805/// `1.5_d32; "1.5"_d32 => 15e-1`
1806/// `1.500_d32; "1.500"d_32 => 1500e-3`
1807/// `1.2345678_d32; "1.2345678_d32" => 1234568e-6`
1808bdldfp::Decimal32 operator "" _d32 (const char *str);
1809bdldfp::Decimal32 operator "" _d32 (const char *str, bsl::size_t len);
1810
1811} // close DecimalLiterals namespace
1812} // close literals namespace
1813#endif
1814
1815// FREE FUNCTIONS
1816
1817/// Pass the specified `object` to the specified `hashAlg`. This function
1818/// integrates with the `bslh` modular hashing system and effectively
1819/// provides a `bsl::hash` specialization for `Decimal32`. Note that two
1820/// objects which have the same value but different representations will
1821/// hash to the same value.
1822template <class HASHALG>
1823void hashAppend(HASHALG& hashAlg, const Decimal32& object);
1824
1825 // ====================
1826 // class Decimal_Type64
1827 // ====================
1828
1829/// This value-semantic class implements the IEEE-754 64 bit decimal
1830/// floating-point format arithmetic type. This class is a standard layout
1831/// type that is `const` thread-safe and exception-neutral.
1832///
1833/// See @ref bdldfp_decimal
1835
1836 private:
1837 // DATA
1838 DecimalImpUtil::ValueType64 d_value; // The underlying IEEE representation
1839
1840 public:
1841 // CLASS METHODS
1842
1843 // Aspects
1844
1845 static int maxSupportedBdexVersion();
1846 /// Return the maximum valid BDEX format version, as indicated by the
1847 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
1848 /// method. Note that it is highly recommended that `versionSelector`
1849 /// be formatted as "YYYYMMDD", a date representation. Also note that
1850 /// `versionSelector` should be a *compile*-time-chosen value that
1851 /// selects a format version supported by both externalizer and
1852 /// unexternalizer. See the `bslx` package-level documentation for more
1853 /// information on BDEX streaming of value-semantic types and
1854 /// containers.
1855 static int maxSupportedBdexVersion(int versionSelector);
1856
1857 // TRAITS
1860
1861 // CREATORS
1862
1863 /// Create a `Decimal64_Type` object having the value positive zero and
1864 /// the smallest exponent value.
1866
1867 /// Create a `Decimal64_Type` object having the specified `value`.
1869
1870 /// Create a `Decimal64_Type` object having the value of the specified
1871 /// `other` following the conversion rules as defined by IEEE-754:
1872 ///
1873 /// * If `other` is NaN, initialize this object to a NaN.
1874 /// * Otherwise if `other` is infinity (positive or negative), then
1875 /// initialize this object to infinity with the same sign.
1876 /// * Otherwise if `other` is zero, then initialize this object to zero
1877 /// with the same sign.
1878 /// * Otherwise initialize this object to the value of the `other`.
1879 Decimal_Type64(Decimal32 other); // IMPLICIT
1880
1881 /// Create a `Decimal64_Type` object having the value closest to the
1882 /// value of the specified `other` following the conversion rules as
1883 /// defined by IEEE-754:
1884 ///
1885 /// * If `other` is NaN, initialize this object to a NaN.
1886 /// * Otherwise if `other` is infinity (positive or negative), then
1887 /// initialize this object to infinity with the same sign.
1888 /// * Otherwise if `other` is zero, then initialize this object to
1889 /// zero with the same sign.
1890 /// * Otherwise if `other` has an absolute value that is larger than
1891 /// `std::numeric_limits<Decimal64>::max()` then store the value of
1892 /// the macro `ERANGE` into `errno` and initialize this object to
1893 /// infinity with the same sign as `other`.
1894 /// * Otherwise if `other` has an absolute value that is smaller than
1895 /// `std::numeric_limits<Decimal64>::min()` then store the value of
1896 /// the macro `ERANGE` into `errno` and initialize this object to
1897 /// zero with the same sign as `other`.
1898 /// * Otherwise if `other` has a value that has more significant
1899 /// digits than `std::numeric_limits<Decimal64>::max_digit` then
1900 /// initialize this object to the value of `other` rounded according
1901 /// to the rounding direction.
1902 /// * Otherwise initialize this object to the value as the `other`.
1903 explicit Decimal_Type64(Decimal128 other);
1904
1905 /// Create a `Decimal64_Type` object having the value closest to the
1906 /// value of the specified `other` value. *Warning:* clients requiring
1907 /// a conversion for an exact decimal value should use
1908 /// @ref bdldfp_decimalconvertutil (see *WARNING*: Conversions from
1909 /// `float` and `double`}. This conversion follows the conversion
1910 /// rules as defined by IEEE-754:
1911 ///
1912 explicit Decimal_Type64(float other);
1913 /// * If `other` is NaN, initialize this object to a NaN.
1914 /// * Otherwise if `other` is infinity (positive or negative), then
1915 /// initialize this object to infinity value with the same sign.
1916 /// * Otherwise if `other` has a zero value, then initialize this
1917 /// object to zero with the same sign.
1918 /// * Otherwise if `other` has a value that needs more than
1919 /// `std::numeric_limits<Decimal64>::max_digit` significant decimal
1920 /// digits to represent then initialize this object to the value of
1921 /// `other` rounded according to the rounding direction.
1922 /// * Otherwise initialize this object to the value of the `other`.
1923 explicit Decimal_Type64(double other);
1924
1925 /// Create a `Decimal64_Type` object having the value closest to the
1926 /// value of the specified `other` following the conversion rules as
1927 /// defined by IEEE-754:
1928 ///
1929 explicit Decimal_Type64(int other);
1930 explicit Decimal_Type64(unsigned int other);
1931 explicit Decimal_Type64(long other);
1932 explicit Decimal_Type64(unsigned long other);
1933 explicit Decimal_Type64(long long other);
1934 /// * Otherwise if `other` has a value that is not exactly
1935 /// representable using `std::numeric_limits<Decimal64>::max_digit`
1936 /// decimal digits then initialize this object to the value of
1937 /// `other` rounded according to the rounding direction.
1938 /// * Otherwise initialize this object to the value of `other` with
1939 /// exponent 0.
1940 explicit Decimal_Type64(unsigned long long other);
1941
1942 Decimal64_Type(const Decimal64_Type& original) = default;
1943 // Create a 'Decimal64_Type' object that is a copy of the specified
1944 // 'original' as defined by the 'copy' operation of IEEE-754 2008:
1945 //
1946 //: o If 'other' is NaN, initialize this object to a NaN.
1947 //:
1948 //: o Otherwise initialize this object to the value of the 'other'.
1949 //
1950 // Note that since floating-point types may be NaN, and NaNs are
1951 // unordered (do not compare equal even to themselves) it is possible
1952 // that a copy of a decimal will not compare equal to the original;
1953 // however it will behave as the original.
1954
1955 ~Decimal64_Type() = default;
1956 // Destroy this object.
1957
1958 // MANIPULATORS
1960 // Make this object a copy of the specified 'rhs' as defined by the
1961 // 'copy' operation of IEEE-754 2008 and return a reference providing
1962 // modifiable access to this object.
1963 //
1964 //: o If 'other' is NaN, set this object to a NaN.
1965 //:
1966 //: o Otherwise set this object to the value of the 'other'.
1967 //
1968 // Note that since floating-point types may be NaN, and NaNs are
1969 // unordered (do not compare equal even to themselves) it is possible
1970 // that, after an assignment, a decimal will not compare equal to the
1971 // original; however it will behave as the original.
1972
1973 /// Add 1.0 to the value of this object and return a reference to it.
1974 /// Note that this is a floating-point value so this operation may not
1975 /// change the value of this object at all (if the value is large) or it
1976 /// may just set it to 1.0 (if the original value is small).
1978
1979 /// Add -1.0 to the value of this object and return a reference to it.
1980 /// Note that this is a floating-point value so this operation may not
1981 /// change the value of this object at all (if the value is large) or it
1982 /// may just set it to -1.0 (if the original value is small).
1984
1985 /// Add the value of the specified `rhs` object to the value of this as
1986 /// described by IEEE-754, store the result in this object, and return a
1987 /// reference to this object.
1988 ///
1989 /// * If either of this object or `rhs` is signaling NaN, then store
1990 /// the value of the macro `EDOM` into `errno` and set this object to
1991 /// a NaN.
1992 /// * Otherwise if either of this object or `rhs` is NaN then set this
1993 /// object to a NaN.
1994 /// * Otherwise if this object and `rhs` have infinite values of
1995 /// differing signs, store the value of the macro `EDOM` into `errno`
1996 /// and set this object to a NaN.
1997 /// * Otherwise if this object and `rhs` have infinite values of the
1998 /// same sign, then do not change this object.
1999 /// * Otherwise if `rhs` has a zero value (positive or negative), do
2000 /// not change this object.
2001 /// * Otherwise if the sum of this object and `rhs` has an absolute
2002 /// value that is larger than `std::numeric_limits<Decimal64>::max()`
2003 /// then store the value of the macro `ERANGE` into `errno` and
2004 /// set this object to infinity with the same sign as that result.
2005 /// * Otherwise set this object to the sum of the number represented by
2006 /// `rhs` and the number represented by this object.
2007 ///
2008 /// Note that this is a floating-point value so this operations may not
2009 /// change the value of this object at all (if the value is large) or it
2010 /// may seem to update it to the value of the `other` (if the original
2011 /// value is small).
2012 ///
2013 /// Note that when `rhs` is a `Decimal128`, this operation is always
2014 /// performed with 128 bits precision to prevent loss of precision of
2015 /// the `rhs` operand (prior to the operation). The result is then
2016 /// rounded back to 64 bits and stored to this object. See IEEE-754
2017 /// 2008, 5.1, first paragraph, second sentence for specification.
2021
2022 /// Add the specified `rhs` to the value of this object as described by
2023 /// IEEE-754, store the result in this object, and return a reference to
2024 /// this object.
2025 ///
2026 /// * If this object is signaling NaN, then store the value of the
2027 /// macro `EDOM` into `errno` and set this object to a NaN.
2028 /// * Otherwise if this object is NaN, then do not change this object.
2029 /// * Otherwise if this object is infinity, then do not change it.
2030 /// * Otherwise if the sum of this object and `rhs` has an absolute
2031 /// value that is larger than `std::numeric_limits<Decimal64>::max()`
2032 /// then store the value of the macro `ERANGE` into `errno` and
2033 /// set this object to infinity with the same sign as that result.
2034 /// * Otherwise set this object to sum of adding `rhs` and the number
2035 /// represented by this object.
2036 ///
2037 /// Note that this is a floating-point value so this operations may not
2038 /// change the value of this object at all (if the value is large) or it
2039 /// may seem to update it to the value of the `other` (if the original
2040 /// value is small).
2041 Decimal_Type64& operator+=(int rhs);
2042 Decimal_Type64& operator+=(unsigned int rhs);
2043 Decimal_Type64& operator+=(long rhs);
2044 Decimal_Type64& operator+=(unsigned long rhs);
2045 Decimal_Type64& operator+=(long long rhs);
2046 Decimal_Type64& operator+=(unsigned long long rhs);
2047
2048 /// Subtract the value of the specified `rhs` from the value of this
2049 /// object as described by IEEE-754, store the result in this object,
2050 /// and return a reference to this object.
2051 ///
2052 /// * If this object is signaling NaN, then store the value of the
2053 /// macro `EDOM` into `errno` and set this object to a NaN.
2054 /// * Otherwise if either of this object or `rhs` is NaN then set this
2055 /// object to a NaN.
2056 /// * Otherwise if this object and `rhs` have infinity value of the
2057 /// same signs, store the value of the macro `EDOM` into `errno`
2058 /// and set this object to a NaN.
2059 /// * Otherwise if this object and the `rhs` have infinite values of
2060 /// differing signs, then do not change this object.
2061 /// * Otherwise if the `rhs` has a zero value (positive or negative),
2062 /// do not change this object.
2063 /// * Otherwise if subtracting the value of the `rhs` object from this
2064 /// results in an absolute value that is larger than
2065 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2066 /// the macro `ERANGE` into `errno` and set this object to infinity
2067 /// with the same sign as that result.
2068 /// * Otherwise set this object to the result of subtracting the value
2069 /// of `rhs` from the value of this object.
2070 ///
2071 /// Note that this is a floating-point value so this operations may not
2072 /// change the value of this object at all (if the value is large) or it
2073 /// may seem to update it to the value of the `other` (if the original
2074 /// value is small).
2075 ///
2076 /// Note that when `rhs` is a `Decimal128`, this operation is always
2077 /// performed with 128 bits precision to prevent loss of precision of
2078 /// the `rhs` operand (prior to the operation). The result is then
2079 /// rounded back to 64 bits and stored to this object. See IEEE-754
2080 /// 2008, 5.1, first paragraph, second sentence for specification.
2084
2085 /// Subtract the specified `rhs` from the value of this object as
2086 /// described by IEEE-754, store the result in this object, and return a
2087 /// reference to this object.
2088 ///
2089 /// * If this object is signaling NaN, then store the value of the
2090 /// macro `EDOM` into `errno` and set this object to a NaN.
2091 /// * Otherwise if this object is NaN, then do not change this object.
2092 /// * Otherwise if this object is infinity, then do not change it.
2093 /// * Otherwise if subtracting `rhs` from this object's value results
2094 /// in an absolute value that is larger than
2095 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2096 /// the macro `ERANGE` into `errno` and set this object to infinity
2097 /// with the same sign as that result.
2098 /// * Otherwise set this object to the result of subtracting `rhs` from
2099 /// the value of this object.
2100 ///
2101 /// Note that this is a floating-point value so this operations may not
2102 /// change the value of this object at all (if the value is large) or it
2103 /// may seem to update it to the value of the `other` (if the original
2104 /// value is small).
2105 Decimal_Type64& operator-=(int rhs);
2106 Decimal_Type64& operator-=(unsigned int rhs);
2107 Decimal_Type64& operator-=(long rhs);
2108 Decimal_Type64& operator-=(unsigned long rhs);
2109 Decimal_Type64& operator-=(long long rhs);
2110 Decimal_Type64& operator-=(unsigned long long rhs);
2111
2112 /// Multiply the value of the specified `rhs` object by the value of
2113 /// this as described by IEEE-754, store the result in this object, and
2114 /// return a reference to this object.
2115 ///
2116 /// * If either of this object or `rhs` is signaling NaN, then store
2117 /// the value of the macro `EDOM` into `errno` and set this object to
2118 /// a NaN.
2119 /// * Otherwise if either of this object or `rhs` is NaN then set this
2120 /// object to a NaN.
2121 /// * Otherwise, if one of this object and `rhs` is zero (positive or
2122 /// negative) and the other is infinity (positive or negative), store
2123 /// the value of the macro `EDOM` into `errno` and set this object to
2124 /// a NaN.
2125 /// * Otherwise, if either this object or `rhs` is positive or negative
2126 /// infinity, set this object to infinity. The sign of this object
2127 /// will be positive if this object and `rhs` had the same sign, and
2128 /// negative otherwise.
2129 /// * Otherwise, if either this object or `rhs` is zero, set this
2130 /// object to zero. The sign of this object will be positive if this
2131 /// object and `rhs` had the same sign, and negative otherwise.
2132 /// * Otherwise if the product of this object and `rhs` has an absolute
2133 /// value that is larger than `std::numeric_limits<Decimal64>::max()`
2134 /// then store the value of the macro `ERANGE` into `errno` and set
2135 /// this object to infinity with the same sign of that result.
2136 /// * Otherwise if the product of this object and `rhs` has an absolute
2137 /// value that is smaller than
2138 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2139 /// the macro `ERANGE` into `errno` and set this object to zero value
2140 /// with the same sign as that result.
2141 /// * Otherwise set this object to the product of the value of `rhs`
2142 /// and the value of this object.
2143 ///
2144 /// Note that when `rhs` is a `Decimal128`, this operation is always
2145 /// performed with 128 bits precision to prevent loss of precision of
2146 /// the `rhs` operand (prior to the operation). The result is then
2147 /// rounded back to 64 bits and stored to this object. See IEEE-754
2148 /// 2008, 5.1, first paragraph, second sentence for specification.
2152
2153 /// Multiply the specified `rhs` by the value of this object as
2154 /// described by IEEE-754, store the result in this object, and return a
2155 /// reference to this object.
2156 ///
2157 /// * If this object is signaling NaN, then store the value of the
2158 /// macro `EDOM` into `errno` and set this object to a NaN.
2159 /// * Otherwise if this object is NaN, then do not change this object.
2160 /// * Otherwise if this object is infinity (positive or negative), and
2161 /// `rhs` is zero, then store the value of the macro `EDOM` into
2162 /// `errno` and set this object to a NaN.
2163 /// * Otherwise if this object is infinity (positive or negative), then
2164 /// do not change it.
2165 /// * Otherwise if `rhs` is zero, then set this object to zero with the
2166 /// same sign as its value had prior to this operation.
2167 /// * Otherwise if the product of `rhs` and the value of this object
2168 /// results in an absolute value that is larger than
2169 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2170 /// the macro `ERANGE` into `errno` and set this object to infinity
2171 /// with the same sign as that result.
2172 /// * Otherwise if the product of `rhs` and the value of this object
2173 /// results in an absolute value that is smaller than
2174 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2175 /// the macro `ERANGE` into `errno` and set this object to zero with
2176 /// the same sign as that result.
2177 Decimal_Type64& operator*=(int rhs);
2178 Decimal_Type64& operator*=(unsigned int rhs);
2179 Decimal_Type64& operator*=(long rhs);
2180 Decimal_Type64& operator*=(unsigned long rhs);
2181 Decimal_Type64& operator*=(long long rhs);
2182 Decimal_Type64& operator*=(unsigned long long rhs);
2183
2184 /// Divide the value of this object by the value of the specified `rhs`
2185 /// as described by IEEE-754, store the result in this object, and
2186 /// return a reference to this object.
2187 ///
2188 /// * If either of this object or `rhs` is signaling NaN, then store
2189 /// the value of the macro `EDOM` into `errno` and set this object to
2190 /// a NaN.
2191 /// * Otherwise if either of this object or `rhs` is NaN then set this
2192 /// object to a NaN.
2193 /// * Otherwise if this object and `rhs` are both infinity (positive or
2194 /// negative) or both zero (positive or negative), then store the
2195 /// value of the macro `EDOM` into `errno` and return a NaN.
2196 /// * Otherwise if `rhs` has a positive zero value, then store the
2197 /// value of the macro `ERANGE` into `errno` and set this object to
2198 /// infinity with the same sign as its original value.
2199 /// * Otherwise if `rhs` has a negative zero value, then store the
2200 /// value of the macro `ERANGE` into `errno` and set this object to
2201 /// infinity with the opposite sign as its original value.
2202 /// * Otherwise if dividing the value of this object by the value of
2203 /// `rhs` results in an absolute value that is larger than
2204 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2205 /// the macro `ERANGE` into `errno` and return infinity with the same
2206 /// sign as that result.
2207 /// * Otherwise if dividing the value of this object by the value of
2208 /// `rhs` results in an absolute value that is smaller than
2209 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2210 /// the macro `ERANGE` into `errno`and return zero with the same sign
2211 /// as that result.
2212 /// * Otherwise set this object to the result of dividing the value of
2213 /// this object by the value of `rhs`.
2214 ///
2215 /// Note that when `rhs` is a `Decimal128`, this operation is always
2216 /// performed with 128 bits precision to prevent loss of precision of
2217 /// the `rhs` operand (prior to the operation). The result is then
2218 /// rounded back to 64 bits and stored to this object. See IEEE-754
2219 /// 2008, 5.1, first paragraph, second sentence for specification.
2223
2224 /// Divide the value of this object by the specified `rhs` as described
2225 /// by IEEE-754, store the result in this object, and return a reference
2226 /// to this object.
2227 ///
2228 /// * If this object is signaling NaN, then store the value of the
2229 /// macro `EDOM` into `errno` and set this object to a NaN.
2230 /// * Otherwise if this object is NaN then set this object to a NaN.
2231 /// * Otherwise if this object is infinity (positive or negative) and
2232 /// `rhs` is positive value then set this object to infinity value
2233 /// with the same sign as its original value.
2234 /// * Otherwise if this object is infinity (positive or negative) and
2235 /// `rhs` is negative value then set this object to infinity value
2236 /// with the opposite sign as its original value.
2237 /// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
2238 /// into `errno` and set this object to infinity with the same sign
2239 /// it had prior to this operation.
2240 /// * Otherwise if dividing the value of this object by the value of
2241 /// `rhs` results in an absolute value that is larger than
2242 /// `std::numeric_limits<Decimal64>::max()` then store the value of
2243 /// the macro `ERANGE` into `errno` and return infinity with the same
2244 /// sign as that result.
2245 /// * Otherwise if dividing the value of this object by the value of
2246 /// `rhs` results in an absolute value that is smaller than
2247 /// `std::numeric_limits<Decimal64>::min()` then store the value of
2248 /// the macro `ERANGE` into `errno`and return zero with the same sign
2249 /// as that result.
2250 /// * Otherwise set this object to the result of dividing the value of
2251 /// this object by the value of `rhs`.
2252 Decimal_Type64& operator/=(int rhs);
2253 Decimal_Type64& operator/=(unsigned int rhs);
2254 Decimal_Type64& operator/=(long rhs);
2255 Decimal_Type64& operator/=(unsigned long rhs);
2256 Decimal_Type64& operator/=(long long rhs);
2257 Decimal_Type64& operator/=(unsigned long long rhs);
2258
2259 /// Return a modifiable pointer to the underlying implementation.
2261
2262 // Aspects
2263
2264 /// Assign to this object the value read from the specified input
2265 /// `stream` using the specified `version` format, and return a
2266 /// reference to `stream`. If `stream` is initially invalid, this
2267 /// operation has no effect. If `version` is not supported, this object
2268 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
2269 /// If `version` is supported but `stream` becomes invalid during this
2270 /// operation, this object has an undefined, but valid, state. Note
2271 /// that no version is read from `stream`. See the `bslx` package-level
2272 /// documentation for more information on BDEX streaming of
2273 /// value-semantic types and containers.
2274 template <class STREAM>
2275 STREAM& bdexStreamIn(STREAM& stream, int version);
2276
2277 // ACCESSORS
2278
2279 /// Return a non-modifiable pointer to the underlying implementation.
2280 const DecimalImpUtil::ValueType64 *data() const;
2281
2282 /// Return the value of the underlying implementation.
2284
2285 // Aspects
2286
2287 /// Write the value of this object, using the specified `version`
2288 /// format, to the specified output `stream`, and return a reference to
2289 /// `stream`. If `stream` is initially invalid, this operation has no
2290 /// effect. If `version` is not supported, `stream` is invalidated, but
2291 /// otherwise unmodified. Note that `version` is not written to
2292 /// `stream`. See the `bslx` package-level documentation for more
2293 /// information on BDEX streaming of value-semantic types and
2294 /// containers.
2295 template <class STREAM>
2296 STREAM& bdexStreamOut(STREAM& stream, int version) const;
2297
2298 /// Write the value of this object to the specified output `stream` in a
2299 /// human-readable format, and return a reference to `stream`.
2300 /// Optionally specify an initial indentation `level`, whose absolute
2301 /// value is incremented recursively for nested objects. If `level` is
2302 /// specified, optionally specify `spacesPerLevel`, whose absolute value
2303 /// indicates the number of spaces per indentation level for this and
2304 /// all of its nested objects. If `level` is negative, suppress
2305 /// indentation of the first line. If `spacesPerLevel` is negative,
2306 /// format the entire output on one line, suppressing all but the
2307 /// initial indentation (as governed by `level`). If `stream` is not
2308 /// valid on entry, this operation has no effect. Note that this
2309 /// human-readable format is not fully specified, and can change without
2310 /// notice.
2311 bsl::ostream& print(bsl::ostream& stream,
2312 int level = 0,
2313 int spacesPerLevel = 4) const;
2314};
2315
2316// FREE OPERATORS
2317
2318/// Return a copy of the specified `value`.
2320
2321/// Return the result of applying the unary - operator to the specified
2322/// `value` as described by IEEE-754. Note that floating-point numbers have
2323/// signed zero, therefore this operation is not the same as `0-value`.
2325
2326/// Apply the prefix ++ operator to the specified `value` and return its
2327/// original value. Note that this is a floating-point value so this
2328/// operations may not change the value of this object at all (if the value
2329/// is large) or it may just set it to 1.0 (if the original value is small).
2331
2332/// Apply the prefix -- operator to the specified `value` and return its
2333/// original value. Note that this is a floating-point value so this
2334/// operations may not change the value of this object at all (if the value
2335/// is large) or it may just set it to -1.0 (if the original value is
2336/// small).
2338
2339/// Add the value of the specified `rhs` to the value of the specified `lhs`
2340/// as described by IEEE-754 and return the result.
2341///
2342/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2343/// the macro `EDOM` into `errno` and return a NaN.
2344/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2345/// * Otherwise if `lhs` and `rhs` are infinities of differing signs, store
2346/// the value of the macro `EDOM` into `errno` and return a NaN.
2347/// * Otherwise if `lhs` and `rhs` are infinities of the same sign then
2348/// return infinity of that sign.
2349/// * Otherwise if `rhs` is zero (positive or negative), return `lhs`.
2350/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
2351/// larger than `std::numeric_limits<Decimal64>::max()` then store the
2352/// value of the macro `ERANGE` into `errno` and set this object to
2353/// infinity with the same sign as that result.
2354/// * Otherwise return the sum of the number represented by `lhs` and the
2355/// number represented by `rhs`.
2359
2360/// Add the specified `rhs` to the value of the specified `lhs` as described
2361/// by IEEE-754 and return the result.
2362///
2363/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2364/// into `errno` and return a NaN.
2365/// * Otherwise if `lhs` object is NaN, then return a NaN.
2366/// * Otherwise if `lhs` is infinity, then return infinity.
2367/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
2368/// larger than `std::numeric_limits<Decimal64>::max()` then store the
2369/// value of the macro `ERANGE` into `errno` and return infinity with the
2370/// same sign as that result.
2371/// * Otherwise return the sum of `rhs` and the number represented by
2372/// `lhs`.
2374Decimal64 operator+(Decimal64 lhs, unsigned int rhs);
2376Decimal64 operator+(Decimal64 lhs, unsigned long rhs);
2377Decimal64 operator+(Decimal64 lhs, long long rhs);
2378Decimal64 operator+(Decimal64 lhs, unsigned long long rhs);
2379
2380/// Add the specified `lhs` to the value of the specified `rhs` as described
2381/// by IEEE-754 and return the result.
2382///
2383/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2384/// into `errno` and return a NaN.
2385/// * Otherwise if `rhs` object is NaN, then return a NaN.
2386/// * Otherwise if `rhs` is infinity, then return infinity.
2387/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
2388/// larger than `std::numeric_limits<Decimal64>::max()` then store the
2389/// value of the macro `ERANGE` into `errno` and return infinity with the
2390/// same sign as that result.
2391/// * Otherwise return the sum of `lhs` and the number represented by
2392/// `rhs`.
2394Decimal64 operator+(unsigned int lhs, Decimal64 rhs);
2396Decimal64 operator+(unsigned long lhs, Decimal64 rhs);
2397Decimal64 operator+(long long lhs, Decimal64 rhs);
2398Decimal64 operator+(unsigned long long lhs, Decimal64 rhs);
2399
2400/// Subtract the value of the specified `rhs` from the value of the
2401/// specified `lhs` as described by IEEE-754 and return the result.
2402///
2403/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2404/// the macro `EDOM` into `errno` and return a NaN.
2405/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2406/// * Otherwise if `lhs` and the `rhs` have infinity values of the same
2407/// sign, store the value of the macro `EDOM` into `errno` and return a
2408/// NaN.
2409/// * Otherwise if `lhs` and the `rhs` have infinity values of differing
2410/// signs, then return `lhs`.
2411/// * Otherwise if the subtracting of `lhs` and `rhs` has an absolute value
2412/// that is larger than `std::numeric_limits<Decimal64>::max()` then
2413/// store the value of the macro `ERANGE` into `errno` and return
2414/// infinity with the same sign as that result.
2415/// * Otherwise return the result of subtracting the value of `rhs`from the
2416/// value of `lhs`.
2420
2421/// Subtract the specified `rhs` from the value of the specified `lhs` as
2422/// described by IEEE-754 and return a reference to this object.
2423///
2424/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2425/// into `errno` and return a NaN.
2426/// * Otherwise if `lhs` is NaN, then return a NaN.
2427/// * Otherwise if `lhs` is infinity, then return infinity.
2428/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
2429/// an absolute value that is larger than
2430/// `std::numeric_limits<Decimal32>::max()` then store the value of the
2431/// macro `ERANGE` into `errno` and return infinity with the same sign as
2432/// that result.
2433/// * Otherwise return the result of subtracting `rhs` from the value of
2434/// `lhs`.
2436Decimal64 operator-(Decimal64 lhs, unsigned int rhs);
2438Decimal64 operator-(Decimal64 lhs, unsigned long rhs);
2439Decimal64 operator-(Decimal64 lhs, long long rhs);
2440Decimal64 operator-(Decimal64 lhs, unsigned long long rhs);
2441
2442/// Subtract the specified `rhs` from the value of the specified `lhs` as
2443/// described by IEEE-754 and return a reference to this object.
2444///
2445/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2446/// into `errno` and return a NaN.
2447/// * Otherwise if `rhs` is NaN, then return a NaN.
2448/// * Otherwise if `rhs` is infinity, then return infinity.
2449/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
2450/// an absolute value that is larger than
2451/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2452/// macro `ERANGE` into `errno` and return infinity with the same sign as
2453/// that result.
2454/// * Otherwise return the result of subtracting the value of `rhs` from
2455/// the number `lhs`.
2457Decimal64 operator-(unsigned int lhs, Decimal64 rhs);
2459Decimal64 operator-(unsigned long lhs, Decimal64 rhs);
2460Decimal64 operator-(long long lhs, Decimal64 rhs);
2461Decimal64 operator-(unsigned long long lhs, Decimal64 rhs);
2462
2463/// Multiply the value of the specified `lhs` object by the value of the
2464/// specified `rhs` as described by IEEE-754 and return the result.
2465///
2466/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2467/// the macro `EDOM` into `errno` and return a NaN.
2468/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2469/// * Otherwise if one of the operands is infinity (positive or negative)
2470/// and the other is zero (positive or negative), then store the value of
2471/// the macro `EDOM` into `errno` and return a NaN.
2472/// * Otherwise if both `lhs` and `rhs` are infinity (positive or
2473/// negative), return infinity. The sign of the returned value will be
2474/// positive if `lhs` and `rhs` have the same sign, and negative
2475/// otherwise.
2476/// * Otherwise, if either `lhs` or `rhs` is zero, return zero. The sign
2477/// of the returned value will be positive if `lhs` and `rhs` have the
2478/// same sign, and negative otherwise.
2479/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
2480/// that is larger than `std::numeric_limits<Decimal64>::max()` then
2481/// store the value of the macro `ERANGE` into `errno` and return an
2482/// infinity with the same sign as that result.
2483/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
2484/// that is smaller than `std::numeric_limits<Decimal64>::min()` then
2485/// store the value of the macro `ERANGE` into `errno` and return zero
2486/// with the same sign as that result.
2487/// * Otherwise return the product of the value of `rhs` and the number
2488/// represented by `rhs`.
2492
2493/// Multiply the specified `rhs` by the value of the specified `lhs` as
2494/// described by IEEE-754, and return the result.
2495///
2496/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2497/// into `errno` and return a NaN.
2498/// * Otherwise if `lhs` is NaN, then return a NaN.
2499/// * Otherwise if `lhs` is infinity (positive or negative), and `rhs` is
2500/// zero, then store the value of the macro `EDOM` into'errno' and return
2501/// a NaN.
2502/// * Otherwise if `lhs` is infinity (positive or negative), then return
2503/// `lhs`.
2504/// * Otherwise if `rhs` is zero, then return zero with the sign of `lhs`.
2505/// * Otherwise if the product of `rhs` and the value of `lhs` results in
2506/// an absolute value that is larger than
2507/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2508/// macro `ERANGE` into `errno` and return infinity with the same sign as
2509/// that result.
2510/// * Otherwise if the product of `rhs` and the value of `lhs` results in
2511/// an absolute value that is smaller than
2512/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2513/// macro `ERANGE` into `errno` and return zero with the same sign as
2514/// that result.
2515/// * Otherwise return the product of the value of `lhs` and value `rhs`.
2517Decimal64 operator*(Decimal64 lhs, unsigned int rhs);
2519Decimal64 operator*(Decimal64 lhs, unsigned long rhs);
2520Decimal64 operator*(Decimal64 lhs, long long rhs);
2521Decimal64 operator*(Decimal64 lhs, unsigned long long rhs);
2522
2523/// Multiply the specified `lhs` by the value of the specified `rhs` as
2524/// described by IEEE-754, and return the result.
2525///
2526/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2527/// into `errno` and return a NaN.
2528/// * Otherwise if `rhs` is NaN, then return a NaN.
2529/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
2530/// zero, then store the value of the macro `EDOM` into'errno' and return
2531/// a NaN.
2532/// * Otherwise if `rhs` is infinity (positive or negative), then return
2533/// `rhs`.
2534/// * Otherwise if `lhs` is zero, then return zero with the sign of `rhs`.
2535/// * Otherwise if the product of `lhs` and the value of `rhs` results in
2536/// an absolute value that is larger than
2537/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2538/// macro `ERANGE` into `errno` and return infinity with the same sign as
2539/// that result.
2540/// * Otherwise if the product of `lhs` and the value of `rhs` results in
2541/// an absolute value that is smaller than
2542/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2543/// macro `ERANGE` into `errno` and return zero with the same sign as
2544/// that result.
2545/// * Otherwise return the product of the value of `lhs` and value `rhs`.
2547Decimal64 operator*(unsigned int lhs, Decimal64 rhs);
2549Decimal64 operator*(unsigned long lhs, Decimal64 rhs);
2550Decimal64 operator*(long long lhs, Decimal64 rhs);
2551Decimal64 operator*(unsigned long long lhs, Decimal64 rhs);
2552
2553/// Divide the value of the specified `lhs` by the value of the specified
2554/// `rhs` as described by IEEE-754, and return the result.
2555///
2556/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
2557/// the macro `EDOM` into `errno` and return a NaN.
2558/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
2559/// * Otherwise if `lhs` and `rhs` are both infinity (positive or negative)
2560/// or both zero (positive or negative) then store the value of the macro
2561/// `EDOM` into `errno` and return a NaN.
2562/// * Otherwise if `lhs` has a normal value and `rhs` has a positive zero
2563/// value, store the value of the macro `ERANGE` into `errno` and return
2564/// infinity with the sign of `lhs`.
2565/// * Otherwise if `lhs` has a normal value and `rhs` has a negative zero
2566/// value, store the value of the macro `ERANGE` into `errno` and return
2567/// infinity with the opposite sign as `lhs`.
2568/// * Otherwise if `lhs` has infinity value and `rhs` has a positive zero
2569/// value, return infinity with the sign of `lhs`.
2570/// * Otherwise if `lhs` has infinity value and `rhs` has a negative zero
2571/// value, return infinity with the opposite sign as `lhs`.
2572/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2573/// results in an absolute value that is larger than
2574/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2575/// macro `ERANGE` into `errno` and return infinity with the same sign as
2576/// that result.
2577/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2578/// results in an absolute value that is smaller than
2579/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2580/// macro `ERANGE` into `errno` and return zero with the same sign as
2581/// that result.
2582/// * Otherwise return the result of dividing the value of `lhs` by the
2583/// value of `rhs`.
2587
2588/// Divide the value of the specified `lhs` by the specified `rhs` as
2589/// described by IEEE-754, and return the result.
2590///
2591/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
2592/// into `errno` and return a NaN.
2593/// * Otherwise if `lhs` is NaN then return a NaN.
2594/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
2595/// positive value then return infinity value with the same sign as its
2596/// original value.
2597/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
2598/// negative value then return infinity value with the opposite sign as
2599/// its original value.
2600/// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
2601/// into `errno` and return infinity with the same sign it had prior to
2602/// this operation.
2603/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2604/// results in an absolute value that is larger than
2605/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2606/// macro `ERANGE` into `errno` and return infinity with the same sign as
2607/// that result.
2608/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2609/// results in an absolute value that is smaller than
2610/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2611/// macro `ERANGE` into `errno` and return zero with the same sign as
2612/// that result.
2613/// * Otherwise return the result of dividing the value of `lhs` by the
2614/// value `rhs`.
2616Decimal64 operator/(Decimal64 lhs, unsigned int rhs);
2618Decimal64 operator/(Decimal64 lhs, unsigned long rhs);
2619Decimal64 operator/(Decimal64 lhs, long long rhs);
2620Decimal64 operator/(Decimal64 lhs, unsigned long long rhs);
2621
2622/// Divide the specified `lhs` by the value of the specified `rhs` as
2623/// described by IEEE-754, and return the result.
2624///
2625/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
2626/// into `errno` and return a NaN.
2627/// * Otherwise if `rhs` is NaN then return a NaN.
2628/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
2629/// zero, store the value of the macro `ERANGE` into `errno` and return a
2630/// NaN.
2631/// * Otherwise if `rhs` is zero (positive or negative), store the value of
2632/// the macro `ERANGE` into `errno` and return infinity with the sign of
2633/// `lhs`.
2634/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2635/// results in an absolute value that is larger than
2636/// `std::numeric_limits<Decimal64>::max()` then store the value of the
2637/// macro `ERANGE` into `errno` and return infinity with the same sign as
2638/// that result.
2639/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
2640/// results in an absolute value that is smaller than
2641/// `std::numeric_limits<Decimal64>::min()` then store the value of the
2642/// macro `ERANGE` into `errno` and return zero with the same sign as
2643/// that result.
2644/// * Otherwise return the result of dividing the value of `lhs` by the
2645/// value of `rhs`. Note that this is a floating-point operation, not
2646/// integer.
2648Decimal64 operator/(unsigned int lhs, Decimal64 rhs);
2650Decimal64 operator/(unsigned long lhs, Decimal64 rhs);
2651Decimal64 operator/(long long lhs, Decimal64 rhs);
2652Decimal64 operator/(unsigned long long lhs, Decimal64 rhs);
2653
2654/// Return `true` if the specified `lhs` and `rhs` have the same value, and
2655/// `false` otherwise. Two `Decimal64` objects have the same value if the
2656/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
2657/// comparison) considers the underlying IEEE representations equal. In
2658/// other words, two `Decimal64` objects have the same value if:
2659///
2660/// * both have a zero value (positive or negative), or
2661/// * both have the same infinity value (both positive or negative), or
2662/// * both have the value of a real number that are equal, even if they are
2663/// represented differently (cohorts have the same value)
2664///
2665/// This operation stores the value of the macro `EDOM` into `errno` if
2666/// either or both operands are signaling NaN.
2667///
2668/// Note that a NaN is never equal to anything, including itself:
2669/// @code
2670/// Decimal64 aNaN = std::numeric_limits<Decimal64>::quiet_NaN();
2671/// assert(!(aNan == aNan));
2672/// @endcode
2673bool operator==(Decimal64 lhs, Decimal64 rhs);
2674
2675/// Return `true` if the specified `lhs` and `rhs` have the same value, and
2676/// `false` otherwise. Two decimal objects have the same value if the
2677/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
2678/// comparison) considers the underlying IEEE representations equal. In
2679/// other words, two decimal objects have the same value if:
2680///
2681/// * both have a zero value (positive or negative), or
2682/// * both have the same infinity value (both positive or negative), or
2683/// * both have the value of a real number that are equal, even if they are
2684/// represented differently (cohorts have the same value)
2685///
2686/// This operation stores the value of the macro `EDOM` into `errno` if
2687/// either or both operands are signaling NaN.
2688bool operator==(Decimal32 lhs, Decimal64 rhs);
2689bool operator==(Decimal64 lhs, Decimal32 rhs);
2690
2691/// Return `true` if the specified `lhs` and `rhs` do not have the same
2692/// value, and `false` otherwise. Two `Decimal64` objects do not have the
2693/// same value if the `compareQuietEqual` operation (IEEE-754 defined,
2694/// non-total ordering comparison) considers the underlying IEEE
2695/// representations not equal. In other words, two `Decimal64` objects do
2696/// not have the same value if:
2697///
2698/// * both are a NaN, or
2699/// * one has zero value (positive or negative) and the other does not, or
2700/// * one has the value of positive infinity and the other does not, or
2701/// * one has the value of negative infinity and the other does not, or
2702/// * both have the value of a real number that are not equal, regardless
2703/// of their representation (cohorts are equal)
2704///
2705/// This operation stores the value of the macro `EDOM` into `errno` if
2706/// either or both operands are signaling NaN.
2707///
2708/// Note that a NaN is never equal to anything, including itself:
2709/// @code
2710/// Decimal64 aNaN = std::numeric_limits<Decimal64>::quiet_NaN();
2711/// assert(aNan != aNan);
2712/// @endcode
2713bool operator!=(Decimal64 lhs, Decimal64 rhs);
2714
2715/// Return `true` if the specified `lhs` and `rhs` do not have the same
2716/// value, and `false` otherwise. Two decimal objects do not have the same
2717/// value if the `compareQuietEqual` operation (IEEE-754 defined, non-total
2718/// ordering comparison) considers the underlying IEEE representations not
2719/// equal. In other words, two decimal objects do not have the same value
2720/// if:
2721///
2722/// * both are NaN, or
2723/// * one has zero value (positive or negative) and the other does not, or
2724/// * one has the value of positive infinity and the other does not, or
2725/// * one has the value of negative infinity and the other does not, or
2726/// * both have the value of a real number that are not equal, regardless
2727/// of their representation (cohorts are equal)
2728///
2729/// This operation stores the value of the macro `EDOM` into `errno` if
2730/// either or both operands are signaling NaN.
2731bool operator!=(Decimal32 lhs, Decimal64 rhs);
2732bool operator!=(Decimal64 lhs, Decimal32 rhs);
2733
2734/// Return `true` if the specified `lhs` has a value less than the specified
2735/// `rhs` and `false` otherwise. The value of a `Decimal64` object `lhs` is
2736/// less than that of an object `rhs` if the `compareQuietLess` operation
2737/// (IEEE-754 defined, non-total ordering comparison) considers the
2738/// underlying IEEE representation of `lhs` to be less than of that of
2739/// `rhs`. In other words, `lhs` is less than `rhs` if:
2740///
2741/// * neither `lhs` nor `rhs` are NaN, or
2742/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
2743/// * `rhs` is zero (positive or negative) and `lhs` negative, or
2744/// * `lhs` is not positive infinity, or
2745/// * `lhs` is negative infinity and `rhs` is not, or
2746/// * `lhs` and `rhs` both represent a real number and the real number of
2747/// `lhs` is less than that of `rhs`
2748///
2749/// This operation stores the value of the macro `EDOM` into `errno` if
2750/// either or both operands are signaling NaN.
2751bool operator<(Decimal64 lhs, Decimal64 rhs);
2752
2753/// Return `true` if the specified `lhs` has a value less than the specified
2754/// `rhs` and `false` otherwise. The value of a decimal object `lhs` is
2755/// less than that of an object `rhs` if the `compareQuietLess` operation
2756/// (IEEE-754 defined, non-total ordering comparison) considers the
2757/// underlying IEEE representation of `lhs` to be less than of that of
2758/// `rhs`. In other words, `lhs` is less than `rhs` if:
2759///
2760/// * neither `lhs` nor `rhs` are NaN, or
2761/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
2762/// * `rhs` is zero (positive or negative) and `lhs` negative, or
2763/// * `lhs` is not positive infinity, or
2764/// * `lhs` is negative infinity and `rhs` is not, or
2765/// * `lhs` and `rhs` both represent a real number and the real number of
2766/// `lhs` is less than that of `rhs`
2767///
2768/// This operation stores the value of the macro `EDOM` into `errno` if
2769/// either or both operands are signaling NaN.
2770bool operator<(Decimal32 lhs, Decimal64 rhs);
2771bool operator<(Decimal64 lhs, Decimal32 rhs);
2772
2773/// Return `true` if the specified `lhs` has a value less than or equal the
2774/// value of the specified `rhs` and `false` otherwise. The value of a
2775/// `Decimal64` object `lhs` is less than or equal to the value of an object
2776/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
2777/// non-total ordering comparison) considers the underlying IEEE
2778/// representation of `lhs` to be less or equal to that of `rhs`. In other
2779/// words, `lhs` is less or equal than `rhs` if:
2780///
2781/// * neither `lhs` nor `rhs` are NaN, or
2782/// * `lhs` and `rhs` are both zero (positive or negative), or
2783/// * both `lhs` and `rhs` are positive infinity, or
2784/// * `lhs` is negative infinity, or
2785/// * `lhs` and `rhs` both represent a real number and the real number of
2786/// `lhs` is less or equal to that of `rhs`
2787///
2788/// This operation stores the value of the macro `EDOM` into `errno` if
2789/// either or both operands are signaling NaN.
2790bool operator<=(Decimal64 lhs, Decimal64 rhs);
2791
2792/// Return `true` if the specified `lhs` has a value less than or equal the
2793/// value of the specified `rhs` and `false` otherwise. The value of a
2794/// decimal object `lhs` is less than or equal to the value of an object
2795/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
2796/// non-total ordering comparison) considers the underlying IEEE
2797/// representation of `lhs` to be less or equal to that of `rhs`. In other
2798/// words, `lhs` is less or equal than `rhs` if:
2799///
2800/// * neither `lhs` nor `rhs` are NaN, or
2801/// * `lhs` and `rhs` are both zero (positive or negative), or
2802/// * both `lhs` and `rhs` are positive infinity, or
2803/// * `lhs` is negative infinity, or
2804/// * `lhs` and `rhs` both represent a real number and the real number of
2805/// `lhs` is less or equal to that of `rhs`
2806///
2807/// This operation stores the value of the macro `EDOM` into `errno` if
2808/// either or both operands are signaling NaN.
2809bool operator<=(Decimal32 lhs, Decimal64 rhs);
2810bool operator<=(Decimal64 lhs, Decimal32 rhs);
2811
2812/// Return `true` if the specified `lhs` has a greater value than the
2813/// specified `rhs` and `false` otherwise. The value of a `Decimal64`
2814/// object `lhs` is greater than that of an object `rhs` if the
2815/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
2816/// comparison) considers the underlying IEEE representation of `lhs` to be
2817/// greater than of that of `rhs`. In other words, `lhs` is greater than
2818/// `rhs` if:
2819///
2820/// * neither `lhs` nor `rhs` are NaN, or
2821/// * `rhs` is zero (positive or negative) and `lhs` positive, or
2822/// * `lhs` is zero (positive or negative) and `rhs` negative, or
2823/// * `lhs` is not negative infinity, or
2824/// * `lhs` is positive infinity and `rhs` is not, or
2825/// * `lhs` and `rhs` both represent a real number and the real number of
2826/// `lhs` is greater than that of `rhs`
2827///
2828/// This operation stores the value of the macro `EDOM` into `errno` if
2829/// either or both operands are signaling NaN.
2830bool operator>(Decimal64 lhs, Decimal64 rhs);
2831
2832/// Return `true` if the specified `lhs` has a greater value than the
2833/// specified `rhs` and `false` otherwise. The value of a decimal object
2834/// `lhs` is greater than that of an object `rhs` if the
2835/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
2836/// comparison) considers the underlying IEEE representation of `lhs` to be
2837/// greater than of that of `rhs`. In other words, `lhs` is greater than
2838/// `rhs` if:
2839///
2840/// * neither `lhs` nor `rhs` are NaN, or
2841/// * `rhs` is zero (positive or negative) and `lhs` positive, or
2842/// * `lhs` is zero (positive or negative) and `rhs` negative, or
2843/// * `lhs` is not negative infinity, or
2844/// * `lhs` is positive infinity and `rhs` is not, or
2845/// * `lhs` and `rhs` both represent a real number and the real number of
2846/// `lhs` is greater than that of `rhs`
2847///
2848/// This operation stores the value of the macro `EDOM` into `errno` if
2849/// either or both operands are signaling NaN.
2850bool operator>(Decimal32 lhs, Decimal64 rhs);
2851bool operator>(Decimal64 lhs, Decimal32 rhs);
2852
2853/// Return `true` if the specified `lhs` has a value greater than or equal
2854/// to the value of the specified `rhs` and `false` otherwise. The value of
2855/// a `Decimal64` object `lhs` is greater or equal to a `Decimal64` object
2856/// `rhs` if the `compareQuietGreaterEqual` operation (IEEE-754 defined,
2857/// non-total ordering comparison ) considers the underlying IEEE
2858/// representation of `lhs` to be greater or equal to that of `rhs`. In
2859/// other words, `lhs` is greater than or equal to `rhs` if:
2860///
2861/// * neither `lhs` nor `rhs` are NaN, or
2862/// * `lhs` and `rhs` are both zero (positive or negative), or
2863/// * both `lhs` and `rhs` are negative infinity, or
2864/// * `lhs` is positive infinity, or
2865/// * `lhs` and `rhs` both represent a real number and the real number of
2866/// `lhs` is greater or equal to that of `rhs`
2867///
2868/// This operation stores the value of the macro `EDOM` into `errno` if
2869/// either or both operands are signaling NaN.
2870bool operator>=(Decimal64 lhs, Decimal64 rhs);
2871
2872/// Return `true` if the specified `lhs` has a value greater than or equal
2873/// to the value of the specified `rhs` and `false` otherwise. The value of
2874/// a decimal object `lhs` is greater or equal to a decimal object `rhs` if
2875/// the `compareQuietGreaterEqual` operation (IEEE-754 defined, non-total
2876/// ordering comparison ) considers the underlying IEEE representation of
2877/// `lhs` to be greater or equal to that of `rhs`. In other words, `lhs` is
2878/// greater than or equal to `rhs` if:
2879///
2880/// * neither `lhs` nor `rhs` are NaN, or
2881/// * `lhs` and `rhs` are both zero (positive or negative), or
2882/// * both `lhs` and `rhs` are negative infinity, or
2883/// * `lhs` is positive infinity, or
2884/// * `lhs` and `rhs` both represent a real number and the real number of
2885/// `lhs` is greater or equal to that of `rhs`
2886///
2887/// This operation stores the value of the macro `EDOM` into `errno` if
2888/// either or both operands are signaling NaN.
2889bool operator>=(Decimal32 lhs, Decimal64 rhs);
2890bool operator>=(Decimal64 lhs, Decimal32 rhs);
2891
2892/// Read, into the specified `object`, from the specified input `stream` an
2893/// IEEE 64 bit decimal floating-point value as described in the IEEE-754
2894/// 2008 standard (5.12 Details of conversions between floating point
2895/// numbers and external character sequences) and return a reference
2896/// providing modifiable access to `stream`. If `stream` contains a Nan
2897/// value, it is unspecified if `object` will receive a quiet or signaling
2898/// `Nan`. If `stream` is not valid on entry `stream.good() == false`, this
2899/// operation has no effect other than setting `stream.fail()` to `true`.
2900/// If eof (end-of-file) is found before any non-whitespace characters
2901/// `stream.fail()` is set to `true` and `object` remains unchanged. If eof
2902/// is detected after some characters have been read (and successfully
2903/// interpreted as part of the textual representation of a floating-point
2904/// value as specified by IEEE-754) then `stream.eof()` is set to true. If
2905/// the first non-whitespace character sequence is not a valid textual
2906/// representation of a floating-point value (e.g., 12e or e12 or 1*2) the
2907/// `stream.fail()` is set to true and `object` will remain unchanged. If a
2908/// real number value is represented by the character sequence but it is a
2909/// large positive or negative value that cannot be stored into `object`
2910/// then store the value of the macro `ERANGE` into `errno` and positive or
2911/// negative infinity is stored into `object`, respectively. If a real
2912/// number value is represented by the character sequence but it is a small
2913/// positive or negative value that cannot be stored into `object` then
2914/// store the value of the macro `ERANGE` into `errno` and positive or
2915/// negative zero is stored into `object`, respectively. If a real number
2916/// value is represented by the character sequence but it cannot be stored
2917/// exactly into `object`, the value is rounded according to the current
2918/// rounding direction (of the environment) and then stored into `object`.
2919///
2920/// NOTE: This method does not yet fully support iostream flags or the
2921/// decimal floating point exception context.
2922template <class CHARTYPE, class TRAITS>
2923bsl::basic_istream<CHARTYPE, TRAITS>&
2924operator>> (bsl::basic_istream<CHARTYPE, TRAITS>& stream, Decimal64& object);
2925
2926/// Write the value of the specified `object` to the specified output
2927/// `stream` in a single line format as described in the IEEE-754 2008
2928/// standard (5.12 Details of conversions between floating point numbers and
2929/// external character sequences), and return a reference providing
2930/// modifiable access to `stream`. If `stream` is not valid on entry, this
2931/// operation has no effect.
2932///
2933/// NOTE: This method does not yet fully support iostream flags or the
2934/// decimal floating point exception context.
2935template <class CHARTYPE, class TRAITS>
2936bsl::basic_ostream<CHARTYPE, TRAITS>&
2937operator<< (bsl::basic_ostream<CHARTYPE, TRAITS>& stream, Decimal64 object);
2938
2939#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
2940 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
2941inline namespace literals {
2942inline namespace DecimalLiterals {
2943/// Produce an object of the indicated return type by parsing the specified
2944/// `str` having the specified `len` excluding the terminating null
2945/// character that represents a floating-point number written in both fixed
2946/// and scientific notations. These user-defined literal suffixes can be
2947/// applied to both numeric and string literals, (i.e., 1.2_d128, "1.2"_d64
2948/// or "inf"_d64). The resulting decimal object is initialized as follows:
2949///
2950/// * If `str` does not represent a floating-point value, then return a
2951/// decimal object of the indicated return type initialized to a NaN.
2952/// * Otherwise if `str` represents infinity (positive or negative), then
2953/// return a decimal object of the indicated return type initialized to
2954/// infinity value with the same sign.
2955/// * Otherwise if `str` represents zero (positive or negative), then
2956/// return a decimal object of the indicated return type initialized to
2957/// zero with the same sign.
2958/// * Otherwise if `str` represents a value that has an absolute value that
2959/// is larger than the maximum value supported by the indicated return
2960/// type, then store the value of the macro `ERANGE` into `errno` and
2961/// return a decimal object of the return type initialized to infinity
2962/// with the same sign.
2963/// * Otherwise if `str` represents a value that has an absolute value that
2964/// is smaller than min value of the indicated return type, then store
2965/// the value of the macro `ERANGE` into `errno` and return a decimal
2966/// object of the return type initialized to zero with the same sign.
2967/// * Otherwise if `str` has a value that is not exactly representable
2968/// using the maximum digit number supported by the indicated return
2969/// type, then return a decimal object of the return type initialized to
2970/// the value represented by `str` rounded according to the rounding
2971/// direction.
2972/// * Otherwise return a decimal object of the indicated return type
2973/// initialized to the decimal value representation of `str`.
2974///
2975/// Note that the parsing follows the rules as specified for the `strtod64`
2976/// function in section 9.6 of the ISO/EIC TR 247128 C Decimal
2977/// Floating-Point Technical Report.
2978///
2979/// Also note that the numeric literal version omits the optional leading
2980/// sign in `str`. For example, if the string is -1.2_d64 then the string
2981/// "1.2" is passed to the one-argument form, not "-1.2", because leading
2982/// signs are operators, not parts of literals. On the other hand, the
2983/// string literal version does not omit leading sign and if the string is
2984/// "-1.2"_d64 then the string "-1.2" is passed to the two-argument form.
2985///
2986/// Also note that the quantum of the resultant value is affected by the
2987/// number of decimal places in `str` string in both numeric and string
2988/// literal formats starting with the most significand digit and cannot
2989/// exceed the maximum number of digits necessary to differentiate all
2990/// values of the indicated return type, for example:
2991///
2992/// `0.015_d64; => 15e-3`
2993/// `1.5_d64; => 15e-1`
2994/// `1.500_d64; => 1500e-3`
2995/// `1.2345678901234567_d64; => 1234567890123458-15`
2996bdldfp::Decimal64 operator "" _d64 (const char *str);
2997bdldfp::Decimal64 operator "" _d64 (const char *str, bsl::size_t len);
2998
2999} // close DecimalLiterals namespace
3000} // close literals namespace
3001#endif
3002
3003// FREE FUNCTIONS
3004
3005/// Pass the specified `object` to the specified `hashAlg`. This function
3006/// integrates with the `bslh` modular hashing system and effectively
3007/// provides a `bsl::hash` specialization for `Decimal64`. Note that two
3008/// objects which have the same value but different representations will
3009/// hash to the same value.
3010template <class HASHALG>
3011void hashAppend(HASHALG& hashAlg, const Decimal64& object);
3012
3013
3014 // =====================
3015 // class Decimal_Type128
3016 // =====================
3017
3018/// This value-semantic class implements the IEEE-754 128 bit decimal
3019/// floating-point format arithmetic type. This class is a standard layout
3020/// type that is `const` thread-safe and exception-neutral.
3021///
3022/// See @ref bdldfp_decimal
3024
3025 private:
3026 // DATA
3028 // The underlying IEEE representation
3029
3030 public:
3031 // CLASS METHODS
3032
3033 // Aspects
3034
3035 static int maxSupportedBdexVersion();
3036 /// Return the maximum valid BDEX format version, as indicated by the
3037 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
3038 /// method. Note that it is highly recommended that `versionSelector`
3039 /// be formatted as "YYYYMMDD", a date representation. Also note that
3040 /// `versionSelector` should be a *compile*-time-chosen value that
3041 /// selects a format version supported by both externalizer and
3042 /// unexternalizer. See the `bslx` package-level documentation for more
3043 /// information on BDEX streaming of value-semantic types and
3044 /// containers.
3045 static int maxSupportedBdexVersion(int versionSelector);
3046
3047 // TRAITS
3050
3051 // CREATORS
3052
3053 /// Create a `Decimal128_Type` object having the value positive zero and
3054 /// the smallest exponent value.
3056
3057 /// Create a `Decimal128_Type` object having the specified `value`.
3059
3060 /// Create a `Decimal128_Type` object having the specified `value`,
3061 /// subject to the conversion rules as defined by IEEE-754:
3062 ///
3063 /// * If `value` is NaN, initialize this object to a NaN.
3064 /// * Otherwise if `value` is infinity, then initialize this object to
3065 /// infinity with the same sign.
3066 /// * Otherwise if `value` is zero, then initialize this object to zero
3067 /// with the same sign.
3068 /// * Otherwise initialize this object to `value`.
3069 Decimal_Type128(Decimal32 value); // IMPLICIT
3070 Decimal_Type128(Decimal64 value); // IMPLICIT
3071
3072 /// Create a `Decimal128_Type` object having the value closest to the
3073 /// specified `other` value. *Warning:* clients requiring a conversion
3074 /// for an exact decimal value should use @ref bdldfp_decimalconvertutil
3075 /// (see *WARNING*: Conversions from `float` and `double`}. This
3076 /// conversion follows the conversion rules as defined by IEEE-754:
3077 ///
3078 explicit Decimal_Type128(float other);
3079 /// * If `value` is NaN, initialize this object to a NaN.
3080 /// * Otherwise if `value` is infinity, then initialize this object to
3081 /// infinity value with the same sign.
3082 /// * Otherwise if `value` has a zero value, then initialize this
3083 /// object to zero with the same sign.
3084 /// * Otherwise initialize this object to `value`.
3085 explicit Decimal_Type128(double other);
3086
3087 /// Create a `Decimal128_Type` object having the value closest to the
3088 /// specified `value` subject to the conversion rules as defined by
3089 /// IEEE-754:
3090 ///
3091 explicit Decimal_Type128(int value);
3092 explicit Decimal_Type128(unsigned int value);
3093 explicit Decimal_Type128(long value);
3094 explicit Decimal_Type128(unsigned long value);
3095 explicit Decimal_Type128(long long value);
3096 /// * If `value` has an absolute value that is larger than
3097 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3098 /// the macro `ERANGE` into `errno` and initialize this object to
3099 /// infinity with the same sign as `other`.
3100 /// * Otherwise if `value` has a value that is not exactly
3101 /// representable using `std::numeric_limits<Decimal128>::max_digit`
3102 /// decimal digits then initialize this object to the value of
3103 /// `value` rounded according to the rounding direction.
3104 /// * Otherwise initialize this object to `value` with exponent 0.
3105 explicit Decimal_Type128(unsigned long long value);
3106
3107 Decimal128_Type(const Decimal128_Type& original) = default;
3108 // Create a 'Decimal128_Type' object that is a copy of the specified
3109 // 'original' as defined by the 'copy' operation of IEEE-754 2008:
3110 //
3111 //: o If 'original' is NaN, initialize this object to a NaN.
3112 //:
3113 //: o Otherwise initialize this object to the value of the 'original'.
3114 //
3115 // Note that since floating-point types may be NaN, and NaNs are
3116 // unordered (do not compare equal even to themselves) it is possible
3117 // that a copy of a decimal will not compare equal to the original;
3118 // however it will behave as the original.
3119
3120 ~Decimal128_Type() = default;
3121 // Destroy this object.
3122
3123 // MANIPULATORS
3125 // Make this object a copy of the specified 'rhs' as defined by the
3126 // 'copy' operation of IEEE-754 2008 and return a reference providing
3127 // modifiable access to this object.
3128 //
3129 //: o If 'rhs' is NaN, set this object to a NaN.
3130 //:
3131 //: o Otherwise set this object to the value of the 'other'.
3132 //
3133 // Note that since floating-point types may be NaN, and NaNs are
3134 // unordered (do not compare equal even to themselves) it is possible
3135 // that, after an assignment, a decimal will not compare equal to the
3136 // original; however it will behave as the original.
3137
3138 /// Add 1.0 to the value of this object and return a reference to it.
3139 /// Note that this is a floating-point value so this operation may not
3140 /// change the value of this object at all (if the value is large) or it
3141 /// may just set it to 1.0 (if the original value is small).
3143
3144 /// Add -1.0 to the value of this object and return a reference to it.
3145 /// Note that this is a floating-point value so this operation may not
3146 /// change the value of this object at all (if the value is large) or it
3147 /// may just set it to -1.0 (if the original value is small).
3149
3150 /// Add the value of the specified `rhs` object to the value of this as
3151 /// described by IEEE-754, store the result in this object, and return a
3152 /// reference to this object.
3153 ///
3154 /// * If either of this object or `rhs` is signaling NaN, then store
3155 /// the value of the macro `EDOM` into `errno` and set this object to
3156 /// a NaN.
3157 /// * Otherwise if either of this object or `rhs` is NaN then set this
3158 /// object to a NaN.
3159 /// * Otherwise if this object and `rhs` have infinity value of
3160 /// differing signs, store the value of the macro `EDOM` into `errno`
3161 /// and set this object to a NaN.
3162 /// * Otherwise if this object and `rhs` have infinite values of the
3163 /// same sign, then do not change this object.
3164 /// * Otherwise if `rhs` has a zero value (positive or negative), do
3165 /// not change this object.
3166 /// * Otherwise if the sum of this object and `rhs` has an absolute
3167 /// value that is larger than
3168 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3169 /// the macro `ERANGE` into `errno` and set this object to infinity
3170 /// with the same sign as that result.
3171 /// * Otherwise set this object to the sum of the number represented by
3172 /// `rhs` and the number represented by this object.
3173 ///
3174 /// Note that this is a floating-point value so this operations may not
3175 /// change the value of this object at all (if the value is large) or it
3176 /// may seem to update it to the value of the `other` (if the original
3177 /// value is small).
3181
3182 /// Add the specified `rhs` to the value of this object as described by
3183 /// IEEE-754, store the result in this object, and return a reference to
3184 /// this object.
3185 ///
3186 /// * If this object is signaling NaN, then store the value of the
3187 /// macro `EDOM` into `errno` and set this object to a NaN.
3188 /// * Otherwise if this object is NaN, then do not change this object.
3189 /// * Otherwise if this object is infinity, then do not change it.
3190 /// * Otherwise if the sum of this object and `rhs` has an absolute
3191 /// value that is larger than
3192 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3193 /// the macro `ERANGE` into `errno` and set this object to infinity
3194 /// with the same sign as that result.
3195 /// * Otherwise set this object to sum of adding `rhs` and the number
3196 /// represented by this object.
3197 ///
3198 /// Note that this is a floating-point value so this operations may not
3199 /// change the value of this object at all (if the value is large) or it
3200 /// may seem to update it to the value of the `other` (if the original
3201 /// value is small).
3202 Decimal_Type128& operator+=(int rhs);
3203 Decimal_Type128& operator+=(unsigned int rhs);
3204 Decimal_Type128& operator+=(long rhs);
3205 Decimal_Type128& operator+=(unsigned long rhs);
3206 Decimal_Type128& operator+=(long long rhs);
3207 Decimal_Type128& operator+=(unsigned long long rhs);
3208
3209 /// Subtract the value of the specified `rhs` from the value of this
3210 /// object as described by IEEE-754, store the result in this object,
3211 /// and return a reference to this object.
3212 ///
3213 /// * If this object is signaling NaN, then store the value of the
3214 /// macro `EDOM` into `errno` and set this object to a NaN.
3215 /// * Otherwise if either of this object or `rhs` is NaN then set this
3216 /// object to a NaN.
3217 /// * Otherwise if this object and `rhs` have infinity value of the
3218 /// same signs, store the value of the macro `EDOM` into `errno`
3219 /// and set this object to a NaN.
3220 /// * Otherwise if this object and the `rhs` have infinite values of
3221 /// differing signs, then do not change this object.
3222 /// * Otherwise if the `rhs` has a zero value (positive or negative),
3223 /// do not change this object.
3224 /// * Otherwise if subtracting the value of the `rhs` object from this
3225 /// results in an absolute value that is larger than
3226 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3227 /// the macro `ERANGE` into `errno` and set this object to infinity
3228 /// with the same sign as that result.
3229 /// * Otherwise set this object to the result of subtracting the value
3230 /// of `rhs` from the value of this object.
3231 ///
3232 /// Note that this is a floating-point value so this operations may not
3233 /// change the value of this object at all (if the value is large) or it
3234 /// may seem to update it to the value of the `other` (if the original
3235 /// value is small).
3239
3240 /// Subtract the specified `rhs` from the value of this object as
3241 /// described by IEEE-754, store the result in this object, and return a
3242 /// reference to this object.
3243 ///
3244 /// * If this object is signaling NaN, then store the value of the
3245 /// macro `EDOM` into `errno` and set this object to a NaN.
3246 /// * Otherwise if this object is NaN, then do not change this object.
3247 /// * Otherwise if this object is infinity, then do not change it.
3248 /// * Otherwise if subtracting `rhs` from this object's value results
3249 /// in an absolute value that is larger than
3250 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3251 /// the macro `ERANGE` into `errno` and set this object to infinity
3252 /// with the same sign as that result.
3253 /// * Otherwise set this object to the result of subtracting `rhs` from
3254 /// the value of this object.
3255 ///
3256 /// 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).
3260 Decimal_Type128& operator-=(int rhs);
3261 Decimal_Type128& operator-=(unsigned int rhs);
3262 Decimal_Type128& operator-=(long rhs);
3263 Decimal_Type128& operator-=(unsigned long rhs);
3264 Decimal_Type128& operator-=(long long rhs);
3265 Decimal_Type128& operator-=(unsigned long long rhs);
3266
3267 /// Multiply the value of the specified `rhs` object by the value of
3268 /// this as described by IEEE-754, store the result in this object, and
3269 /// return a reference to this object.
3270 ///
3271 /// * If either of this object or `rhs` is signaling NaN, then store
3272 /// the value of the macro `EDOM` into `errno` and set this object to
3273 /// a NaN.
3274 /// * Otherwise if either of this object or `rhs` is NaN then set this
3275 /// object to a NaN.
3276 /// * Otherwise, if one of this object and `rhs` is zero (positive or
3277 /// negative) and the other is infinity (positive or negative), store
3278 /// the value of the macro `EDOM` into `errno` and set this object to
3279 /// a NaN.
3280 /// * Otherwise, if either this object or `rhs` is positive or negative
3281 /// infinity, set this object to infinity. The sign of this object
3282 /// will be positive if this object and `rhs` had the same sign, and
3283 /// negative otherwise.
3284 /// * Otherwise, if either this object or `rhs` is zero, set this
3285 /// object to zero. The sign of this object will be positive if this
3286 /// object and `rhs` had the same sign, and negative otherwise.
3287 /// * Otherwise if the product of this object and `rhs` has an absolute
3288 /// value that is larger than
3289 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3290 /// the macro `ERANGE` into `errno` and set this object to infinity
3291 /// with the same sign of that result.
3292 /// * Otherwise if the product of this object and `rhs` has an absolute
3293 /// value that is smaller than
3294 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3295 /// the macro `ERANGE` into `errno` and set this object to zero value
3296 /// with the same sign as that result.
3297 /// * Otherwise set this object to the product of the value of `rhs`
3298 /// and the value of this object.
3302
3303 /// Multiply the specified `rhs` by the value of this object as
3304 /// described by IEEE-754, store the result in this object, and return a
3305 /// reference to this object.
3306 ///
3307 /// * If this object is signaling NaN, then store the value of the
3308 /// macro `EDOM` into `errno` and set this object to a NaN.
3309 /// * Otherwise if this object is NaN, then do not change this object.
3310 /// * Otherwise if this object is infinity (positive or negative), and
3311 /// `rhs` is zero, then store the value of the macro `EDOM` into
3312 /// `errno` and set this object to a NaN.
3313 /// * Otherwise if this object is infinity (positive or negative), then
3314 /// do not change it.
3315 /// * Otherwise if `rhs` is zero, then set this object to zero with the
3316 /// same sign as its value had prior to this operation.
3317 /// * Otherwise if the product of `rhs` and the value of this object
3318 /// results in an absolute value that is larger than
3319 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3320 /// the macro `ERANGE` into `errno` and set this object to infinity
3321 /// with the same sign as that result.
3322 /// * Otherwise if the product of `rhs` and the value of this object
3323 /// results in an absolute value that is smaller than
3324 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3325 /// the macro `ERANGE` into `errno` and set this object to zero with
3326 /// the same sign as that result.
3327 /// * Otherwise set this object to the product of the value of this
3328 /// object and the value `rhs`.
3329 Decimal_Type128& operator*=(int rhs);
3330 Decimal_Type128& operator*=(unsigned int rhs);
3331 Decimal_Type128& operator*=(long rhs);
3332 Decimal_Type128& operator*=(unsigned long rhs);
3333 Decimal_Type128& operator*=(long long rhs);
3334 Decimal_Type128& operator*=(unsigned long long rhs);
3335
3336 /// Divide the value of this object by the value of the specified `rhs`
3337 /// as described by IEEE-754, store the result in this object, and
3338 /// return a reference to this object.
3339 ///
3340 /// * If either of this object or `rhs` is signaling NaN, then store
3341 /// the value of the macro `EDOM` into `errno` and set this object to
3342 /// a NaN.
3343 /// * Otherwise if either of this object or `rhs` is NaN then set this
3344 /// object to a NaN.
3345 /// * Otherwise if this object and `rhs` are both infinity (positive or
3346 /// negative) or both zero (positive or negative) then store the
3347 /// value of the macro `EDOM` into `errno` and return a NaN.
3348 /// * Otherwise if `rhs` has a positive zero value, then store the
3349 /// value of the macro `ERANGE` into `errno` and set this object to
3350 /// infinity with the same sign as its original value.
3351 /// * Otherwise if `rhs` has a negative zero value, then store the
3352 /// value of the macro `ERANGE` into `errno` and set this object to
3353 /// infinity with the opposite sign as its original value.
3354 /// * Otherwise if dividing the value of this object by the value of
3355 /// `rhs` results in an absolute value that is larger than
3356 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3357 /// the macro `ERANGE` into `errno` and return infinity with the same
3358 /// sign as that result.
3359 /// * Otherwise if dividing the value of this object by the value of
3360 /// `rhs` results in an absolute value that is smaller than
3361 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3362 /// the macro `ERANGE` into `errno`and return zero with the same sign
3363 /// as that result.
3364 /// * Otherwise set this object to the result of dividing the value of
3365 /// this object by the value of `rhs`.
3369
3370 /// Divide the value of this object by the specified `rhs` as described
3371 /// by IEEE-754, store the result in this object, and return a reference
3372 /// to this object.
3373 ///
3374 /// * If this object is signaling NaN, then store the value of the
3375 /// macro `EDOM` into `errno` and set this object to a NaN.
3376 /// * Otherwise if this object is NaN then set this object to a NaN.
3377 /// * Otherwise if this object is infinity (positive or negative) and
3378 /// `rhs` is positive value then set this object to infinity value
3379 /// with the same sign as its original value.
3380 /// * Otherwise if this object is infinity (positive or negative) and
3381 /// `rhs` is negative value then set this object to infinity value
3382 /// with the opposite sign as its original value.
3383 /// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
3384 /// into `errno` and set this object to infinity with the same sign
3385 /// it had prior to this operation.
3386 /// * Otherwise if dividing the value of this object by the value of
3387 /// `rhs` results in an absolute value that is larger than
3388 /// `std::numeric_limits<Decimal128>::max()` then store the value of
3389 /// the macro `ERANGE` into `errno` and return infinity with the same
3390 /// sign as that result.
3391 /// * Otherwise if dividing the value of this object by the value of
3392 /// `rhs` results in an absolute value that is smaller than
3393 /// `std::numeric_limits<Decimal128>::min()` then store the value of
3394 /// the macro `ERANGE` into `errno`and return zero with the same sign
3395 /// as that result.
3396 /// * Otherwise set this object to the result of dividing the value of
3397 /// this object by the value of `rhs`.
3398 Decimal_Type128& operator/=(int rhs);
3399 Decimal_Type128& operator/=(unsigned int rhs);
3400 Decimal_Type128& operator/=(long rhs);
3401 Decimal_Type128& operator/=(unsigned long rhs);
3402 Decimal_Type128& operator/=(long long rhs);
3403 Decimal_Type128& operator/=(unsigned long long rhs);
3404
3405 /// Return a modifiable pointer to the underlying implementation.
3407
3408 // Aspects
3409
3410 /// Assign to this object the value read from the specified input
3411 /// `stream` using the specified `version` format, and return a
3412 /// reference to `stream`. If `stream` is initially invalid, this
3413 /// operation has no effect. If `version` is not supported, this object
3414 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
3415 /// If `version` is supported but `stream` becomes invalid during this
3416 /// operation, this object has an undefined, but valid, state. Note
3417 /// that no version is read from `stream`. See the `bslx` package-level
3418 /// documentation for more information on BDEX streaming of
3419 /// value-semantic types and containers.
3420 template <class STREAM>
3421 STREAM& bdexStreamIn(STREAM& stream, int version);
3422
3423 // ACCESSORS
3424
3425 /// Return a non-modifiable pointer to the underlying implementation.
3426 const DecimalImpUtil::ValueType128 *data() const;
3427
3428 /// Return the value of the underlying implementation.
3430
3431 // Aspects
3432
3433 /// Write the value of this object, using the specified `version`
3434 /// format, to the specified output `stream`, and return a reference to
3435 /// `stream`. If `stream` is initially invalid, this operation has no
3436 /// effect. If `version` is not supported, `stream` is invalidated, but
3437 /// otherwise unmodified. Note that `version` is not written to
3438 /// `stream`. See the `bslx` package-level documentation for more
3439 /// information on BDEX streaming of value-semantic types and
3440 /// containers.
3441 template <class STREAM>
3442 STREAM& bdexStreamOut(STREAM& stream, int version) const;
3443};
3444
3445// FREE OPERATORS
3446
3447/// Return a copy of the specified `value` if the value is not negative
3448/// zero, and return positive zero otherwise.
3450
3451/// Return the result of applying the unary - operator to the specified
3452/// `value` as described by IEEE-754. Note that floating-point numbers have
3453/// signed zero, therefore this operation is not the same as `0-value`.
3455
3456/// Apply the prefix ++ operator to the specified `value` and return its
3457/// original value. Note that this is a floating-point value so this
3458/// operations may not change the value of this object at all (if the value
3459/// is large) or it may just set it to 1.0 (if the original value is small).
3461
3462/// Apply the prefix -- operator to the specified `value` and return its
3463/// original value. Note that this is a floating-point value so this
3464/// operations may not change the value of this object at all (if the value
3465/// is large) or it may just set it to -1.0 (if the original value is
3466/// small).
3468
3469/// Add the value of the specified `rhs` to the value of the specified `lhs`
3470/// as described by IEEE-754 and return the result.
3471///
3472/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3473/// the macro `EDOM` into `errno` and return a NaN.
3474/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3475/// * Otherwise if `lhs` and `rhs` are infinities of differing signs, store
3476/// the value of the macro `EDOM` into `errno` and return a NaN.
3477/// * Otherwise if `lhs` and `rhs` are infinities of the same sign then
3478/// return infinity of that sign.
3479/// * Otherwise if `rhs` is zero (positive or negative), return `lhs`.
3480/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
3481/// larger than `std::numeric_limits<Decimal128>::max()` then store the
3482/// value of the macro `ERANGE` into `errno` and set this object to
3483/// infinity with the same sign as that result.
3484/// * Otherwise return the sum of the number represented by `lhs` and the
3485/// number represented by `rhs`.
3491
3492/// Add the specified `rhs` to the value of the specified `lhs` as described
3493/// by IEEE-754 and return the result.
3494///
3495/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3496/// into `errno` and return a NaN.
3497/// * Otherwise if `lhs` object is NaN, then return a NaN.
3498/// * Otherwise if `lhs` is infinity, then return infinity.
3499/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
3500/// larger than `std::numeric_limits<Decimal128>::max()` then store the
3501/// value of the macro `ERANGE` into `errno` and return infinity with the
3502/// same sign as that result.
3503/// * Otherwise return the sum of `rhs` and the number represented by
3504/// `lhs`.
3506Decimal128 operator+(Decimal128 lhs, unsigned int rhs);
3508Decimal128 operator+(Decimal128 lhs, unsigned long rhs);
3509Decimal128 operator+(Decimal128 lhs, long long rhs);
3510Decimal128 operator+(Decimal128 lhs, unsigned long long rhs);
3511
3512/// Add the specified `lhs` to the value of the specified `rhs` as described
3513/// by IEEE-754 and return the result.
3514///
3515/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3516/// into `errno` and return a NaN.
3517/// * Otherwise if `rhs` object is NaN, then return a NaN.
3518/// * Otherwise if `rhs` is infinity, then return infinity.
3519/// * Otherwise if the sum of `lhs` and `rhs` has an absolute value that is
3520/// larger than `std::numeric_limits<Decimal128>::max()` then store the
3521/// value of the macro `ERANGE` into `errno` and return infinity with the
3522/// same sign as that result.
3523/// * Otherwise return the sum of `lhs` and the number represented by
3524/// `rhs`.
3526Decimal128 operator+(unsigned int lhs, Decimal128 rhs);
3528Decimal128 operator+(unsigned long lhs, Decimal128 rhs);
3529Decimal128 operator+(long long lhs, Decimal128 rhs);
3530Decimal128 operator+(unsigned long long lhs, Decimal128 rhs);
3531
3532/// Subtract the value of the specified `rhs` from the value of the
3533/// specified `lhs` as described by IEEE-754 and return the result.
3534///
3535/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3536/// the macro `EDOM` into `errno` and return a NaN.
3537/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3538/// * Otherwise if `lhs` and the `rhs` have infinity values of the same
3539/// sign, store the value of the macro `EDOM` into `errno` and return a
3540/// NaN.
3541/// * Otherwise if `lhs` and the `rhs` have infinity values of differing
3542/// signs, then return `lhs`.
3543/// * Otherwise if the subtracting of `lhs` and `rhs` has an absolute value
3544/// that is larger than `std::numeric_limits<Decimal128>::max()` then
3545/// store the value of the macro `ERANGE` into `errno` and return
3546/// infinity with the same sign as that result.
3547/// * Otherwise return the result of subtracting the value of `rhs`from the
3548/// value of `lhs`.
3554
3555/// Subtract the specified `rhs` from the value of the specified `lhs` as
3556/// described by IEEE-754 and return a reference to this object.
3557///
3558/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3559/// into `errno` and return a NaN.
3560/// * Otherwise if `lhs` is NaN, then return a NaN.
3561/// * Otherwise if `lhs` is infinity, then return infinity.
3562/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
3563/// an absolute value that is larger than
3564/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3565/// macro `ERANGE` into `errno` and return infinity with the same sign as
3566/// that result.
3567/// * Otherwise return the result of subtracting `rhs` from the value of
3568/// `lhs`.
3570Decimal128 operator-(Decimal128 lhs, unsigned int rhs);
3572Decimal128 operator-(Decimal128 lhs, unsigned long rhs);
3573Decimal128 operator-(Decimal128 lhs, long long rhs);
3574Decimal128 operator-(Decimal128 lhs, unsigned long long rhs);
3575
3576/// Subtract the specified `rhs` from the value of the specified `lhs` as
3577/// described by IEEE-754 and return a reference to this object.
3578///
3579/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3580/// into `errno` and return a NaN.
3581/// * Otherwise if `rhs` is NaN, then return a NaN.
3582/// * Otherwise if `rhs` is infinity, then return infinity.
3583/// * Otherwise if subtracting `rhs` from `lhs` object's value results in
3584/// an absolute value that is larger than
3585/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3586/// macro `ERANGE` into `errno` and return infinity with the same sign as
3587/// that result.
3588/// * Otherwise return the result of subtracting the value of `rhs` from
3589/// the number `lhs`.
3591Decimal128 operator-(unsigned int lhs, Decimal128 rhs);
3593Decimal128 operator-(unsigned long lhs, Decimal128 rhs);
3594Decimal128 operator-(long long lhs, Decimal128 rhs);
3595Decimal128 operator-(unsigned long long lhs, Decimal128 rhs);
3596
3597/// Multiply the value of the specified `lhs` object by the value of the
3598/// specified `rhs` as described by IEEE-754 and return the result.
3599///
3600/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3601/// the macro `EDOM` into `errno` and return a NaN.
3602/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3603/// * Otherwise if one of the operands is infinity (positive or negative)
3604/// and the other is zero (positive or negative), then store the value of
3605/// the macro `EDOM` into `errno` and return a NaN.
3606/// * Otherwise if both `lhs` and `rhs` are infinity (positive or
3607/// negative), return infinity. The sign of the returned value will be
3608/// positive if `lhs` and `rhs` have the same sign, and negative
3609/// otherwise.
3610/// * Otherwise, if either `lhs` or `rhs` is zero, return zero. The sign
3611/// of the returned value will be positive if `lhs` and `rhs` have the
3612/// same sign, and negative otherwise.
3613/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
3614/// that is larger than `std::numeric_limits<Decimal128>::max()` then
3615/// store the value of the macro `ERANGE` into `errno` and return an
3616/// infinity with the same sign as that result.
3617/// * Otherwise if the product of `lhs` and `rhs` has an absolute value
3618/// that is smaller than `std::numeric_limits<Decimal128>::min()` then
3619/// store the value of the macro `ERANGE` into `errno` and return zero
3620/// with the same sign as that result.
3621/// * Otherwise return the product of the value of `rhs` and the number
3622/// represented by `rhs`.
3628
3629/// Multiply the specified `rhs` by the value of the specified `lhs` as
3630/// described by IEEE-754, and return the result.
3631///
3632/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3633/// into `errno` and return a NaN.
3634/// * Otherwise if `lhs` is NaN, then return a NaN.
3635/// * Otherwise if `lhs` is infinity (positive or negative), and `rhs` is
3636/// zero, then store the value of the macro `EDOM` into'errno' and return
3637/// a NaN.
3638/// * Otherwise if `lhs` is infinity (positive or negative), then return
3639/// `lhs`.
3640/// * Otherwise if `rhs` is zero, then return zero with the sign of `lhs`.
3641/// * Otherwise if the product of `rhs` and the value of `lhs` results in
3642/// an absolute value that is larger than
3643/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3644/// macro `ERANGE` into `errno` and return infinity with the same sign as
3645/// that result.
3646/// * Otherwise if the product of `rhs` and the value of `lhs` results in
3647/// an absolute value that is smaller than
3648/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3649/// macro `ERANGE` into `errno` and return zero with the same sign as
3650/// that result.
3651/// * Otherwise return the product of the value of `lhs` and value `rhs`.
3653Decimal128 operator*(Decimal128 lhs, unsigned int rhs);
3655Decimal128 operator*(Decimal128 lhs, unsigned long rhs);
3656Decimal128 operator*(Decimal128 lhs, long long rhs);
3657Decimal128 operator*(Decimal128 lhs, unsigned long long rhs);
3658
3659/// Multiply the specified `lhs` by the value of the specified `rhs` as
3660/// described by IEEE-754, and return the result.
3661///
3662/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3663/// into `errno` and return a NaN.
3664/// * Otherwise if `rhs` is NaN, then return a NaN.
3665/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
3666/// zero, then store the value of the macro `EDOM` into'errno' and return
3667/// a NaN.
3668/// * Otherwise if `rhs` is infinity (positive or negative), then return
3669/// `rhs`.
3670/// * Otherwise if `lhs` is zero, then return zero with the sign of `rhs`.
3671/// * Otherwise if the product of `lhs` and the value of `rhs` results in
3672/// an absolute value that is larger than
3673/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3674/// macro `ERANGE` into `errno` and return infinity with the same sign as
3675/// that result.
3676/// * Otherwise if the product of `lhs` and the value of `rhs` results in
3677/// an absolute value that is smaller than
3678/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3679/// macro `ERANGE` into `errno` and return zero with the same sign as
3680/// that result.
3681/// * Otherwise return the product of the value of `lhs` and value `rhs`.
3683Decimal128 operator*(unsigned int lhs, Decimal128 rhs);
3685Decimal128 operator*(unsigned long lhs, Decimal128 rhs);
3686Decimal128 operator*(long long lhs, Decimal128 rhs);
3687Decimal128 operator*(unsigned long long lhs, Decimal128 rhs);
3688
3689/// Divide the value of the specified `lhs` by the value of the specified
3690/// `rhs` as described by IEEE-754, and return the result.
3691///
3692/// * If either of `lhs` or `rhs` is signaling NaN, then store the value of
3693/// the macro `EDOM` into `errno` and return a NaN.
3694/// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
3695/// * Otherwise if `lhs` and `rhs` are both infinity (positive or negative)
3696/// or both zero (positive or negative) then store the value of the macro
3697/// `EDOM` into `errno` and return a NaN.
3698/// * Otherwise if `lhs` has a normal value and `rhs` has a positive zero
3699/// value, store the value of the macro `ERANGE` into `errno` and return
3700/// infinity with the sign of `lhs`.
3701/// * Otherwise if `lhs` has a normal value and `rhs` has a negative zero
3702/// value, store the value of the macro `ERANGE` into `errno` and return
3703/// infinity with the opposite sign as `lhs`.
3704/// * Otherwise if `lhs` has infinity value and `rhs` has a positive zero
3705/// value, return infinity with the sign of `lhs`.
3706/// * Otherwise if `lhs` has infinity value and `rhs` has a negative zero
3707/// value, return infinity with the opposite sign as `lhs`.
3708/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3709/// results in an absolute value that is larger than
3710/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3711/// macro `ERANGE` into `errno` and return infinity with the same sign as
3712/// that result.
3713/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3714/// results in an absolute value that is smaller than
3715/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3716/// macro `ERANGE` into `errno` and return zero with the same sign as
3717/// that result.
3718/// * Otherwise return the result of dividing the value of `lhs` by the
3719/// value of `rhs`.
3725
3726/// Divide the value of the specified `lhs` by the specified `rhs` as
3727/// described by IEEE-754, and return the result.
3728///
3729/// * If `lhs` is signaling NaN, then store the value of the macro `EDOM`
3730/// into `errno` and return a NaN.
3731/// * Otherwise if `lhs` is NaN then return a NaN.
3732/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
3733/// positive value then return infinity value with the same sign as its
3734/// original value.
3735/// * Otherwise if `lhs` is infinity (positive or negative) and `rhs` is
3736/// negative value then return infinity value with the opposite sign as
3737/// its original value.
3738/// * Otherwise if `rhs` is zero, store the value of the macro `ERANGE`
3739/// into `errno` and return infinity with the same sign it had prior to
3740/// this operation.
3741/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3742/// results in an absolute value that is larger than
3743/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3744/// macro `ERANGE` into `errno` and return infinity with the same sign as
3745/// that result.
3746/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3747/// results in an absolute value that is smaller than
3748/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3749/// macro `ERANGE` into `errno` and return zero with the same sign as
3750/// that result.
3751/// * Otherwise return the result of dividing the value of `lhs` by the
3752/// value of `rhs`.
3754Decimal128 operator/(Decimal128 lhs, unsigned int rhs);
3756Decimal128 operator/(Decimal128 lhs, unsigned long rhs);
3757Decimal128 operator/(Decimal128 lhs, long long rhs);
3758Decimal128 operator/(Decimal128 lhs, unsigned long long rhs);
3759
3760/// Divide the specified `lhs` by the value of the specified `rhs` as
3761/// described by IEEE-754, and return the result.
3762///
3763/// * If `rhs` is signaling NaN, then store the value of the macro `EDOM`
3764/// into `errno` and return a NaN.
3765/// * Otherwise if `rhs` is NaN then return a NaN.
3766/// * Otherwise if `rhs` is infinity (positive or negative), and `lhs` is
3767/// zero, store the value of the macro `ERANGE` into `errno` and return a
3768/// NaN.
3769/// * Otherwise if `rhs` is zero (positive or negative), store the value of
3770/// the macro `ERANGE` into `errno` and return infinity with the sign of
3771/// `lhs`.
3772/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3773/// results in an absolute value that is larger than
3774/// `std::numeric_limits<Decimal128>::max()` then store the value of the
3775/// macro `ERANGE` into `errno` and return infinity with the same sign as
3776/// that result.
3777/// * Otherwise if dividing the value of `lhs` by the value of `rhs`
3778/// results in an absolute value that is smaller than
3779/// `std::numeric_limits<Decimal128>::min()` then store the value of the
3780/// macro `ERANGE` into `errno` and return zero with the same sign as
3781/// that result.
3782/// * Otherwise return the result of dividing the value of `lhs` by the
3783/// value of `rhs`. Note that this is a floating-point operation, not
3784/// integer.
3786Decimal128 operator/(unsigned int lhs, Decimal128 rhs);
3788Decimal128 operator/(unsigned long lhs, Decimal128 rhs);
3789Decimal128 operator/(long long lhs, Decimal128 rhs);
3790Decimal128 operator/(unsigned long long lhs, Decimal128 rhs);
3791
3792/// Return `true` if the specified `lhs` and `rhs` have the same value, and
3793/// `false` otherwise. Two `Decimal128` objects have the same value if the
3794/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
3795/// comparison) considers the underlying IEEE representations equal. In
3796/// other words, two `Decimal128` objects have the same value if:
3797///
3798/// * both have a zero value (positive or negative), or
3799/// * both have the same infinity value (both positive or negative), or
3800/// * both have the value of a real number that are equal, even if they are
3801/// represented differently (cohorts have the same value)
3802///
3803/// This operation stores the value of the macro `EDOM` into `errno` if
3804/// either or both operands are signaling NaN.
3805///
3806/// Note that a NaN is never equal to anything, including itself:
3807/// @code
3808/// Decimal128 aNaN = std::numeric_limits<Decimal128>::quiet_NaN();
3809/// assert(!(aNan == aNan));
3810/// @endcode
3811bool operator==(Decimal128 lhs, Decimal128 rhs);
3812
3813/// Return `true` if the specified `lhs` and `rhs` have the same value, and
3814/// `false` otherwise. Two decimal objects have the same value if the
3815/// `compareQuietEqual` operation (IEEE-754 defined, non-total ordering
3816/// comparison) considers the underlying IEEE representations equal. In
3817/// other words, two decimal objects have the same value if:
3818///
3819/// * both have a zero value (positive or negative), or
3820/// * both have the same infinity value (both positive or negative), or
3821/// * both have the value of a real number that are equal, even if they are
3822/// represented differently (cohorts have the same value)
3823///
3824/// This operation stores the value of the macro `EDOM` into `errno` if
3825/// either or both operands are signaling NaN.
3826bool operator==(Decimal32 lhs, Decimal128 rhs);
3827bool operator==(Decimal128 lhs, Decimal32 rhs);
3828bool operator==(Decimal64 lhs, Decimal128 rhs);
3829bool operator==(Decimal128 lhs, Decimal64 rhs);
3830
3831/// Return `true` if the specified `lhs` and `rhs` do not have the same
3832/// value, and `false` otherwise. Two `Decimal128` objects do not have the
3833/// same value if the `compareQuietEqual` operation (IEEE-754 defined,
3834/// non-total ordering comparison) considers the underlying IEEE
3835/// representations not equal. In other words, two `Decimal128` objects do
3836/// not have the same value if:
3837///
3838/// * both are a NaN, or
3839/// * one has zero value (positive or negative) and the other does not, or
3840/// * one has the value of positive infinity and the other does not, or
3841/// * one has the value of negative infinity and the other does not, or
3842/// * both have the value of a real number that are not equal, regardless
3843/// of their representation (cohorts are equal)
3844///
3845/// This operation stores the value of the macro `EDOM` into `errno` if
3846/// either or both operands are signaling NaN.
3847///
3848/// Note that a NaN is never equal to anything, including itself:
3849/// @code
3850/// Decimal128 aNaN = std::numeric_limits<Decimal128>::quiet_NaN();
3851/// assert(aNan != aNan);
3852/// @endcode
3853bool operator!=(Decimal128 lhs, Decimal128 rhs);
3854
3855/// Return `true` if the specified `lhs` and `rhs` do not have the same
3856/// value, and `false` otherwise. Two decimal objects do not have the same
3857/// value if the `compareQuietEqual` operation (IEEE-754 defined, non-total
3858/// ordering comparison) considers the underlying IEEE representations not
3859/// equal. In other words, two decimal objects do not have the same value
3860/// if:
3861///
3862/// * both are NaN, or
3863/// * one has zero value (positive or negative) and the other does not, or
3864/// * one has the value of positive infinity and the other does not, or
3865/// * one has the value of negative infinity and the other does not, or
3866/// * both have the value of a real number that are not equal, regardless
3867/// of their representation (cohorts are equal)
3868///
3869/// This operation stores the value of the macro `EDOM` into `errno` if
3870/// either or both operands are signaling NaN.
3871bool operator!=(Decimal32 lhs, Decimal128 rhs);
3872bool operator!=(Decimal128 lhs, Decimal32 rhs);
3873bool operator!=(Decimal64 lhs, Decimal128 rhs);
3874bool operator!=(Decimal128 lhs, Decimal64 rhs);
3875
3876/// Return `true` if the specified `lhs` has a value less than the specified
3877/// `rhs` and `false` otherwise. The value of a `Decimal128` object `lhs`
3878/// is less than that of an object `rhs` if the `compareQuietLess` operation
3879/// (IEEE-754 defined, non-total ordering comparison) considers the
3880/// underlying IEEE representation of `lhs` to be less than of that of
3881/// `rhs`. In other words, `lhs` is less than `rhs` if:
3882///
3883/// * neither `lhs` nor `rhs` are NaN, or
3884/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
3885/// * `rhs` is zero (positive or negative) and `lhs` negative, or
3886/// * `lhs` is not positive infinity, or
3887/// * `lhs` is negative infinity and `rhs` is not, or
3888/// * `lhs` and `rhs` both represent a real number and the real number of
3889/// `lhs` is less than that of `rhs`
3890///
3891/// This operation stores the value of the macro `EDOM` into `errno` if
3892/// either or both operands are signaling NaN.
3893bool operator<(Decimal128 lhs, Decimal128 rhs);
3894
3895/// Return `true` if the specified `lhs` has a value less than the specified
3896/// `rhs` and `false` otherwise. The value of a decimal object `lhs` is
3897/// less than that of an object `rhs` if the `compareQuietLess` operation
3898/// (IEEE-754 defined, non-total ordering comparison) considers the
3899/// underlying IEEE representation of `lhs` to be less than of that of
3900/// `rhs`. In other words, `lhs` is less than `rhs` if:
3901///
3902/// * neither `lhs` nor `rhs` are NaN, or
3903/// * `lhs` is zero (positive or negative) and `rhs` is positive, or
3904/// * `rhs` is zero (positive or negative) and `lhs` negative, or
3905/// * `lhs` is not positive infinity, or
3906/// * `lhs` is negative infinity and `rhs` is not, or
3907/// * `lhs` and `rhs` both represent a real number and the real number of
3908/// `lhs`is less than that of `rhs`
3909///
3910/// This operation stores the value of the macro `EDOM` into `errno` if
3911/// either or both operands are signaling NaN.
3912bool operator<(Decimal32 lhs, Decimal128 rhs);
3913bool operator<(Decimal128 lhs, Decimal32 rhs);
3914bool operator<(Decimal64 lhs, Decimal128 rhs);
3915bool operator<(Decimal128 lhs, Decimal64 rhs);
3916
3917/// Return `true` if the specified `lhs` has a value less than or equal the
3918/// value of the specified `rhs` and `false` otherwise. The value of a
3919/// `Decimal128` object `lhs` is less than or equal to the value of an
3920/// object `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
3921/// non-total ordering comparison) considers the underlying IEEE
3922/// representation of `lhs` to be less or equal to that of `rhs`. In other
3923/// words, `lhs` is less or equal than `rhs` if:
3924///
3925/// * neither `lhs` nor `rhs` are NaN, or
3926/// * `lhs` and `rhs` are both zero (positive or negative), or
3927/// * both `lhs` and `rhs` are positive infinity, or
3928/// * `lhs` is negative infinity, or
3929/// * `lhs` and `rhs` both represent a real number and the real number of
3930/// `lhs` is less or equal to that of `rhs`
3931///
3932/// This operation stores the value of the macro `EDOM` into `errno` if
3933/// either or both operands are signaling NaN.
3934bool operator<=(Decimal128 lhs, Decimal128 rhs);
3935
3936/// Return `true` if the specified `lhs` has a value less than or equal the
3937/// value of the specified `rhs` and `false` otherwise. The value of a
3938/// decimal object `lhs` is less than or equal to the value of an object
3939/// `rhs` if the `compareQuietLessEqual` operation (IEEE-754 defined,
3940/// non-total ordering comparison) considers the underlying IEEE
3941/// representation of `lhs` to be less or equal to that of `rhs`. In other
3942/// words, `lhs` is less or equal than `rhs` if:
3943///
3944/// * neither `lhs` nor `rhs` are NaN, or
3945/// * `lhs` and `rhs` are both zero (positive or negative), or
3946/// * both `lhs` and `rhs` are positive infinity, or
3947/// * `lhs` is negative infinity, or
3948/// * `lhs` and `rhs` both represent a real number and the real number of
3949/// `lhs` is less or equal to that of `rhs`
3950///
3951/// This operation stores the value of the macro `EDOM` into `errno` if
3952/// either or both operands are signaling NaN.
3953bool operator<=(Decimal32 lhs, Decimal128 rhs);
3954bool operator<=(Decimal128 lhs, Decimal32 rhs);
3955bool operator<=(Decimal64 lhs, Decimal128 rhs);
3956bool operator<=(Decimal128 lhs, Decimal64 rhs);
3957
3958/// Return `true` if the specified `lhs` has a greater value than the
3959/// specified `rhs` and `false` otherwise. The value of a `Decimal128`
3960/// object `lhs` is greater than that of an object `rhs` if the
3961/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
3962/// comparison) considers the underlying IEEE representation of `lhs` to be
3963/// greater than of that of `rhs`. In other words, `lhs` is greater than
3964/// `rhs` if:
3965///
3966/// * neither `lhs` nor `rhs` are NaN, or
3967/// * `rhs` is zero (positive or negative) and `lhs` positive, or
3968/// * `lhs` is zero (positive or negative) and `rhs` negative, or
3969/// * `lhs` is not negative infinity, or
3970/// * `lhs` is positive infinity and `rhs` is not, or
3971/// * `lhs` and `rhs` both represent a real number and the real number of
3972/// `lhs` is greater than that of `rhs`
3973///
3974/// This operation stores the value of the macro `EDOM` into `errno` if
3975/// either or both operands are signaling NaN.
3976bool operator>(Decimal128 lhs, Decimal128 rhs);
3977
3978/// Return `true` if the specified `lhs` has a greater value than the
3979/// specified `rhs` and `false` otherwise. The value of a decimal object
3980/// `lhs` is greater than that of an object `rhs` if the
3981/// `compareQuietGreater` operation (IEEE-754 defined, non-total ordering
3982/// comparison) considers the underlying IEEE representation of `lhs` to be
3983/// greater than of that of `rhs`. In other words, `lhs` is greater than
3984/// `rhs` if:
3985///
3986/// * neither `lhs` nor `rhs` are NaN, or
3987/// * `rhs` is zero (positive or negative) and `lhs` positive, or
3988/// * `lhs` is zero (positive or negative) and `rhs` negative, or
3989/// * `lhs` is not negative infinity, or
3990/// * `lhs` is positive infinity and `rhs` is not, or
3991/// * `lhs` and `rhs` both represent a real number and the real number of
3992/// `lhs` is greater than that of `rhs`
3993///
3994/// This operation stores the value of the macro `EDOM` into `errno` if
3995/// either or both operands are signaling NaN.
3996bool operator>(Decimal32 lhs, Decimal128 rhs);
3997bool operator>(Decimal128 lhs, Decimal32 rhs);
3998bool operator>(Decimal64 lhs, Decimal128 rhs);
3999bool operator>(Decimal128 lhs, Decimal64 rhs);
4000
4001/// Return `true` if the specified `lhs` has a value greater than or equal
4002/// to the value of the specified `rhs` and `false` otherwise. The value of
4003/// a `Decimal128` object `lhs` is greater or equal to a `Decimal128` object
4004/// `rhs` if the `compareQuietGreaterEqual` operation (IEEE-754 defined,
4005/// non-total ordering comparison ) considers the underlying IEEE
4006/// representation of `lhs` to be greater or equal to that of `rhs`. In
4007/// other words, `lhs` is greater than or equal to `rhs` if:
4008///
4009/// * neither `lhs` nor `rhs` are NaN, or
4010/// * `lhs` and `rhs` are both zero (positive or negative), or
4011/// * both `lhs` and `rhs` are negative infinity, or
4012/// * `lhs` is positive infinity, or
4013/// * `lhs` and `rhs` both represent a real number and the real number of
4014/// `lhs` is greater or equal to that of `rhs`
4015///
4016/// This operation stores the value of the macro `EDOM` into `errno` if
4017/// either or both operands are signaling NaN.
4018bool operator>=(Decimal128 lhs, Decimal128 rhs);
4019
4020/// Return `true` if the specified `lhs` has a value greater than or equal
4021/// to the value of the specified `rhs` and `false` otherwise. The value of
4022/// a decimal object `lhs` is greater or equal to a decimal object `rhs` if
4023/// the `compareQuietGreaterEqual` operation (IEEE-754 defined, non-total
4024/// ordering comparison ) considers the underlying IEEE representation of
4025/// `lhs` to be greater or equal to that of `rhs`. In other words, `lhs` is
4026/// greater than or equal to `rhs` if:
4027///
4028/// * neither `lhs` nor `rhs` are NaN, or
4029/// * `lhs` and `rhs` are both zero (positive or negative), or
4030/// * both `lhs` and `rhs` are negative infinity, or
4031/// * `lhs` is positive infinity, or
4032/// * `lhs` and `rhs` both represent a real number and the real number of
4033/// `lhs` is greater or equal to that of `rhs`
4034///
4035/// This operation stores the value of the macro `EDOM` into `errno` if
4036/// either or both operands are signaling NaN.
4037bool operator>=(Decimal32 lhs, Decimal128 rhs);
4038bool operator>=(Decimal128 lhs, Decimal32 rhs);
4039bool operator>=(Decimal64 lhs, Decimal128 rhs);
4040bool operator>=(Decimal128 lhs, Decimal64 rhs);
4041
4042/// Read, into the specified `object`, from the specified input `stream` an
4043/// IEEE 128 bit decimal floating-point value as described in the IEEE-754
4044/// 2008 standard (5.12 Details of conversions between floating point
4045/// numbers and external character sequences) and return a reference
4046/// providing modifiable access to `stream`. If `stream` contains a Nan
4047/// value, it is unspecified if `object` will receive a quiet or signaling
4048/// `Nan`. If `stream` is not valid on entry `stream.good() == false`, this
4049/// operation has no effect other than setting `stream.fail()` to `true`.
4050/// If eof (end-of-file) is found before any non-whitespace characters
4051/// `stream.fail()` is set to `true` and `object` remains unchanged. If eof
4052/// is detected after some characters have been read (and successfully
4053/// interpreted as part of the textual representation of a floating-point
4054/// value as specified by IEEE-754) then `stream.eof()` is set to true. If
4055/// the first non-whitespace character sequence is not a valid textual
4056/// representation of a floating-point value (e.g., 12e or e12 or 1*2) the
4057/// `stream.fail()` is set to true and `object` will remain unchanged. If a
4058/// real number value is represented by the character sequence but it is a
4059/// large positive or negative value that cannot be stored into `object`
4060/// then store the value of the macro `ERANGE` into `errno` and positive or
4061/// negative infinity is stored into `object`, respectively. If a real
4062/// number value is represented by the character sequence but it is a small
4063/// positive or negative value that cannot be stored into `object` then
4064/// store the value of the macro `ERANGE` into `errno` and positive or
4065/// negative zero is stored into `object`, respectively. If a real number
4066/// value is represented by the character sequence but it cannot be stored
4067/// exactly into `object`, the value is rounded according to the current
4068/// rounding direction (of the environment) and then stored into `object`.
4069///
4070/// NOTE: This method does not yet fully support iostream flags or the
4071/// decimal floating point exception context.
4072template <class CHARTYPE, class TRAITS>
4073bsl::basic_istream<CHARTYPE, TRAITS>&
4074operator>> (bsl::basic_istream<CHARTYPE, TRAITS>& stream, Decimal128& object);
4075
4076/// Write the value of the specified `object` to the specified output
4077/// `stream` in a single line format as described in the IEEE-754 2008
4078/// standard (5.12 Details of conversions between floating point numbers and
4079/// external character sequences), and return a reference providing
4080/// modifiable access to `stream`. If `stream` is not valid on entry, this
4081/// operation has no effect.
4082///
4083/// NOTE: This method does not yet fully support iostream flags or the
4084/// decimal floating point exception context.
4085template <class CHARTYPE, class TRAITS>
4086bsl::basic_ostream<CHARTYPE, TRAITS>&
4087operator<< (bsl::basic_ostream<CHARTYPE, TRAITS>& stream, Decimal128 object);
4088
4089#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
4090 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
4091inline namespace literals {
4092inline namespace DecimalLiterals {
4093/// Produce an object of the indicated return type by parsing the specified
4094/// `str` having the specified `len` excluding the terminating null
4095/// character that represents a floating-point number written in both fixed
4096/// and scientific notations. These user-defined literal suffixes can be
4097/// applied to both numeric and string literals, (i.e., 1.2_d128, "1.2"_d128
4098/// or "inf"_d128). The resulting decimal object is initialized as follows:
4099///
4100/// * If `str` does not represent a floating-point value, then return a
4101/// decimal object of the indicated return type initialized to a NaN.
4102/// * Otherwise if `str` represents infinity (positive or negative), then
4103/// return a decimal object of the indicated return type initialized to
4104/// infinity value with the same sign.
4105/// * Otherwise if `str` represents zero (positive or negative), then
4106/// return a decimal object of the indicated return type initialized to
4107/// zero with the same sign.
4108/// * Otherwise if `str` represents a value that has an absolute value that
4109/// is larger than the maximum value supported by the indicated return
4110/// type, then store the value of the macro `ERANGE` into `errno` and
4111/// return a decimal object of the return type initialized to infinity
4112/// with the same sign.
4113/// * Otherwise if `str` represents a value that has an absolute value that
4114/// is smaller than min value of the indicated return type, then store
4115/// the value of the macro `ERANGE` into `errno` and return a decimal
4116/// object of the return type initialized to zero with the same sign.
4117/// * Otherwise if `str` has a value that is not exactly representable
4118/// using the maximum digit number supported by the indicated return
4119/// type, then return a decimal object of the return type initialized to
4120/// the value represented by `str` rounded according to the rounding
4121/// direction.
4122/// * Otherwise return a decimal object of the indicated return type
4123/// initialized to the decimal value representation of `str`.
4124///
4125/// Note that the parsing follows the rules as specified for the `strtod128`
4126/// function in section 9.6 of the ISO/EIC TR 247128 C Decimal
4127/// Floating-Point Technical Report.
4128///
4129/// Also note that the numeric literal version omits the optional leading
4130/// sign in `str`. For example, if the string is -1.2_d128 then the string
4131/// "1.2" is passed to the one-argument form, not "-1.2", because leading
4132/// signs are operators, not parts of literals. On the other hand, the
4133/// string literal version does not omit leading sign and if the string is
4134/// "-1.2"_d128 then the string "-1.2" is passed to the two-argument form.
4135///
4136/// Also note that the quantum of the resultant value is affected by the
4137/// number of decimal places in `str` string in both numeric and string
4138/// literal formats starting with the most significand digit and cannot
4139/// exceed the maximum number of digits necessary to differentiate all
4140/// values of the indicated return type, for example:
4141///
4142/// `0.015_d128; => 15e-3`
4143/// `1.5_d128; => 15e-1`
4144/// `1.500_d128; => 1500e-3`
4145/// '1.2345678901234567890123456789012349_d128;
4146/// => 1234567890123456789012345678901235e-33'
4147bdldfp::Decimal128 operator "" _d128(const char *str);
4148bdldfp::Decimal128 operator "" _d128(const char *str, bsl::size_t len);
4149
4150} // close DecimalLiterals namespace
4151} // close literals namespace
4152#endif
4153
4154// FREE FUNCTIONS
4155
4156/// Pass the specified `object` to the specified `hashAlg`. This function
4157/// integrates with the `bslh` modular hashing system and effectively
4158/// provides a `bsl::hash` specialization for `Decimal128`. Note that two
4159/// objects which have the same value but different representations will
4160/// hash to the same value.
4161template <class HASHALG>
4162void hashAppend(HASHALG& hashAlg, const Decimal128& object);
4163
4164 // MISCELLANEOUS RELATED TYPES
4165
4166 // ===================
4167 // class DecimalNumGet
4168 // ===================
4169
4170/// A facet type (mechanism) used in reading decimal floating-point types.
4171/// Note that this type does not follow BDE conventions because its content
4172/// is dictated by the C++ standard and native standard library
4173/// implementations. See ISO/IEC TR 24733 3.10.2 for details.
4174///
4175/// See @ref bdldfp_decimal
4176template <class CHARTYPE,
4177 class INPUTITERATOR = bsl::istreambuf_iterator<CHARTYPE> >
4178class DecimalNumGet : public bsl::locale::facet {
4179
4180#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
4181 private:
4182 // ACCESSORS
4183 bsl::locale::id& __get_id() const;
4184 // The function __get_id() is a pure virtual function in the Rogue
4185 // Wave implementation of locales. It is in violation with the
4186 // standard. We have to define it as a workaround.
4187#endif
4188
4189 public:
4190 // -dk:TODO make private while making the output operator a friend
4191
4192 // CLASS METHODS
4194 // TBD
4195
4196 public:
4197 // PUBLIC TYPES
4198 static bsl::locale::id id; // The locale identifier
4199
4200 typedef CHARTYPE char_type;
4201 typedef INPUTITERATOR iter_type;
4202
4203 // CREATORS
4204
4205 /// Constructs a `DecimalNumGet` object. Optionally specify starting
4206 /// reference count `refs`, which will default to 0. If `refs` is
4207 /// non-zero, the `DecimalNumGet` object will not be deleted when the
4208 /// last locale referencing it goes out of scope.
4209 explicit DecimalNumGet(bsl::size_t refs = 0);
4210
4211 // ACCESSORS
4212
4213 /// Forward to, and return using the specified `begin`, `end`, `str`,
4214 /// `err`, and `value`, the results of
4215 /// `this->do_get(begin, end, str, err, value)`.
4217 iter_type end,
4218 bsl::ios_base& str,
4219 bsl::ios_base::iostate& err,
4220 Decimal32& value) const;
4222 iter_type end,
4223 bsl::ios_base& str,
4224 bsl::ios_base::iostate& err,
4225 Decimal64& value) const;
4227 iter_type end,
4228 bsl::ios_base& str,
4229 bsl::ios_base::iostate& err,
4230 Decimal128& value) const;
4231
4232 protected:
4233 // CREATORS
4234
4235 /// Destroy this object. Note that the destructor is virtual.
4237
4238 // ACCESSORS
4239
4240 /// Interpret characters from the half-open iterator range denoted by
4241 /// the specified `begin` and `end`, generate a decimal floating-point
4242 /// number and store it into the specified `value`. During conversion
4243 /// the formatting flags of the specified `str` (`str.flags()`) are
4244 /// obeyed; character classifications are determined by the `bsl::ctype`
4245 /// while punctuation characters are determined by the `bsl::numpunct`
4246 /// facet imbued to the `str` stream-base. Use the specified `err` to
4247 /// report back failure or EOF streams states. For further, more
4248 /// detailed information please consult the section
4249 /// [lib.facet.num.get.virtuals] of the C++ Standard. Note that for the
4250 /// conversions to the `Decimal32`, 64 and 128 types the conversion
4251 /// specifiers are %Hg, %Dg and %DDg, respectively. Also note that
4252 /// these (possibly overridden) `do_get` virtual function are used by
4253 /// every formatted C++ stream input operator call (`in >> aDecNumber`).
4255 iter_type end,
4256 bsl::ios_base& str,
4257 bsl::ios_base::iostate& err,
4258 Decimal32& value) const;
4260 iter_type end,
4261 bsl::ios_base& str,
4262 bsl::ios_base::iostate& err,
4263 Decimal64& value) const;
4265 iter_type end,
4266 bsl::ios_base& str,
4267 bsl::ios_base::iostate& err,
4268 Decimal128& value) const;
4269};
4270
4271 // ============================================
4272 // template <class CHARTYPE, bool WCHAR_8_BITS>
4273 // class WideBufferWrapper
4274 // ============================================
4275
4276/// This class provides a wrapper around a buffer of the specified (template
4277/// parameter) `CHARTYPE`. `CHARTYPE` shall be either plain character type
4278/// `char` or wide character type `wchar_t`. The width of `wchar_t` is
4279/// compiler-specific and can be as small as 8 bits. The template parameter
4280/// `WCHAR_8_BITS` shall be `true` if `wchar_t` and `char` widths are the
4281/// same, i.e. 8 bits, and `false` otherwise. This class provides accessors
4282/// to the beginning and the end of the buffer of `CHARTYPE` characters.
4283template <class CHARTYPE, bool WCHAR_8_BITS>
4285
4286 // ========================================================
4287 // template <bool WCHAR_8_BIT>
4288 // class DecimalNumPut_WideBufferWrapper<char, WCHAR_8_BIT>
4289 // ========================================================
4290
4291/// This class is specialization of the template
4292/// `WideBufferWrapper<CHARTYPE, WCHAR_8_BITS>` for `char` type and
4293/// `wchar_t` type which width is 8 bits.
4294template <bool WCHAR_8_BIT>
4295class DecimalNumPut_WideBufferWrapper<char, WCHAR_8_BIT> {
4296
4297 // DATA
4298 const char *d_begin; // pointer to the beginning of plain character buffer
4299 const char *d_end; // pointer to the end of plain character buffer
4300
4301 // NOT IMPLEMENTED
4305
4306 public:
4307 // CREATORS
4308
4309 /// Create a wide buffer wrapper for the specified `buffer` of the
4310 /// specified length `len`.
4311 DecimalNumPut_WideBufferWrapper(const char *buffer,
4312 int len,
4313 const bsl::locale&);
4314
4315 // ACCESSORS
4316
4317 /// Return a pointer to the beginning of the buffer of plain characters
4318 /// provided in this class constructor.
4319 const char *begin() const;
4320
4321 /// Return a pointer to the end of the buffer of plain characters
4322 /// provided in this class constructor.
4323 const char *end() const;
4324};
4325
4326 // =====================================================
4327 // template <>
4328 // class DecimalNumPut_WideBufferWrapper<wchar_t, false>
4329 // =====================================================
4330
4331/// This class is specialization of the template
4332/// `WideBufferWrapper<CHARTYPE, WCHAR_8_BIT>` for `wchar_t` type which
4333/// width exceeds 8 bits.
4334template <>
4335class DecimalNumPut_WideBufferWrapper<wchar_t, false> {
4336
4337 // DATA
4338 wchar_t *d_buffer_p; // Buffer of wide characters
4339 size_t d_len; // Length of the buffer
4340
4341 // NOT IMPLEMENTED
4345
4346 public:
4347 // CREATORS
4348
4349 /// Create a wide buffer wrapper for the specified `buffer` of the
4350 /// specified length `len`. Use the specified locale `loc` to widen
4351 /// character in the buffer into wide characters representation.
4352 inline
4353 DecimalNumPut_WideBufferWrapper(const char *buffer,
4354 int len,
4355 const bsl::locale& loc);
4356
4357 /// Destroy this object.
4359
4360 // ACCESSORS
4361
4362 /// Return a pointer to the beginning of the buffer of wide characters.
4363 const wchar_t *begin() const;
4364
4365 /// Return a pointer to the end the buffer of wide characters.
4366 const wchar_t *end() const;
4367};
4368
4369// ============================================================================
4370// INLINE DEFINITIONS
4371// ============================================================================
4372
4373 // -------------------------------------------
4374 // class DecimalNumPut_WideBufferWrapper<char>
4375 // -------------------------------------------
4376
4377//CREATORS
4378template <bool WCHAR_8_BIT>
4379inline
4381DecimalNumPut_WideBufferWrapper(const char *buffer,
4382 int len,
4383 const bsl::locale&)
4384: d_begin(buffer)
4385, d_end(buffer + len)
4386{
4387 BSLS_ASSERT(buffer);
4388 BSLS_ASSERT(len >= 0);
4389}
4390
4391// ACCESSORS
4392template <bool WCHAR_8_BIT>
4393inline
4395{
4396 return d_begin;
4397}
4398
4399template <bool WCHAR_8_BIT>
4400inline
4402{
4403 return d_end;
4404}
4405
4406 // ----------------------------------------------
4407 // class DecimalNumPut_WideBufferWrapper<wchar_t>
4408 // ----------------------------------------------
4409
4410//CREATORS
4411inline
4413DecimalNumPut_WideBufferWrapper(const char *buffer,
4414 int len,
4415 const bsl::locale& loc)
4416: d_buffer_p(0)
4417, d_len(len)
4418{
4419 BSLS_ASSERT(buffer);
4420 BSLS_ASSERT(len >= 0);
4421
4423
4424 d_buffer_p = (wchar_t *)allocator->allocate(sizeof(wchar_t) * len);
4425
4426 bsl::use_facet<std::ctype<wchar_t> >(loc).widen(buffer,
4427 buffer + len,
4428 d_buffer_p);
4429}
4430
4431inline
4438
4439 // ACCESSORS
4440inline
4442{
4443 return d_buffer_p;
4444}
4445
4446inline
4448{
4449 return d_buffer_p + d_len;
4450}
4451
4452 // ===================
4453 // class DecimalNumPut
4454 // ===================
4455
4456/// A facet type (mechanism) used in writing decimal floating-point types.
4457/// Note that this type does not follow BDE conventions because its content
4458/// is dictated by the C++ standard and native standard library
4459/// implementations. See ISO/IEC TR 24733 3.10.3 for details.
4460///
4461/// See @ref bdldfp_decimal
4462template <class CHARTYPE,
4463 class OUTPUTITERATOR = bsl::ostreambuf_iterator<CHARTYPE> >
4464class DecimalNumPut : public bsl::locale::facet {
4465
4466#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
4467 private:
4468 // ACCESSORS
4469 bsl::locale::id& __get_id() const;
4470 // The function __get_id() is a pure virtual function in the Rogue Wave
4471 // implementation of locales. It is in violation with the standard.
4472 // We have to define it as a workaround.
4473#endif
4474
4475 public:
4476 // -dk:TODO make private while making the output operator a friend
4477
4478 // CLASS METHODS
4480 // TBD
4481
4482 public:
4483 // PUBLIC TYPES
4484 static bsl::locale::id id; // The locale identifier
4485
4486 typedef CHARTYPE char_type;
4487 typedef OUTPUTITERATOR iter_type;
4488
4489 // CREATORS
4490
4491 /// Constructs a `DecimalNumPut` object. Optionally specify starting
4492 /// reference count `refs`, which will default to 0. If `refs` is
4493 /// non-zero, the `DecimalNumPut` object will not be deleted when the
4494 /// last locale referencing it goes out of scope.
4495 explicit DecimalNumPut(bsl::size_t refs = 0);
4496
4497 // ACCESSORS
4498
4499 /// Forward to, and return using the specified `out`, `str`, `fill`, and
4500 /// `value`, the results of `this->do_put(out, str, fill, value)`.
4502 bsl::ios_base& str,
4503 char_type fill,
4504 Decimal32 value) const;
4506 bsl::ios_base& str,
4507 char_type fill,
4508 Decimal64 value) const;
4510 bsl::ios_base& str,
4511 char_type fill,
4512 Decimal128 value) const;
4513
4514 protected:
4515 // CREATORS
4516
4517 /// Destroy this object. Note that the destructor is virtual.
4519
4520 // ACCESSORS
4521
4522 /// Write characters (of @ref char_type ) that represent the specified
4523 /// `value` to the output stream determined by the specified `out`
4524 /// output iterator. Use the `bsl::ctype` and the `bsl::numpunct`
4525 /// facets imbued to the specified stream-base @ref ios_format as well as
4526 /// the formatting flags of the @ref ios_format (`bsl.flags()`) to generate
4527 /// the properly localized output. The specified `fill` character will
4528 /// be used as a placeholder character in padded output. For further,
4529 /// more detailed information please consult the section
4530 /// [lib.facet.num.put.virtuals] of the C++ Standard noting that the
4531 /// length modifiers "H", "D" and "DD" are added to the conversion
4532 /// specifiers of for the types Decimal32, 64 and 128, respectively.
4533 /// Also note that these (possibly overridden) `do_put` virtual function
4534 /// are used by every formatted C++ stream output operator call
4535 /// (`out << aDecNumber`). Note that currently, only the width,
4536 /// capitalization, justification, fixed and scientific formatting flags
4537 /// are supported, and the operators only support code pages that
4538 /// include the ASCII sub-range. Because of potential future
4539 /// improvements to support additional formatting flags, the operations
4540 /// should not be used for serialization.
4542 bsl::ios_base& ios_format,
4543 char_type fill,
4544 Decimal32 value) const;
4546 bsl::ios_base& ios_format,
4547 char_type fill,
4548 Decimal64 value) const;
4550 bsl::ios_base& ios_format,
4551 char_type fill,
4552 Decimal128 value) const;
4553
4554 /// Write characters that represent the specified `value` into a string
4555 /// of the specified @ref char_type , and output the represented decimal
4556 /// number to the specified `out`, adjusting for the formatting flags in
4557 /// the specified @ref ios_format and using the specified `fill` character.
4558 /// Currently, formatting for the formatting flags of justification,
4559 /// width, uppercase, showpos, fixed and scientific are supported.
4560 template <class DECIMAL>
4562 bsl::ios_base& ios_format,
4563 char_type fill,
4564 DECIMAL value) const;
4565};
4566
4567 // =====================================
4568 // class Decimal_StandardNamespaceCanary
4569 // =====================================
4570
4571/// An empty class used for error detection when looking for the original
4572/// name of the standard namespace. Do not use it.
4573///
4574/// See @ref bdldfp_decimal
4577
4578 // =================================================================
4579 // template<...> class faux_numeric_limits<NUMERIC_TYPE, DUMMY_TYPE>
4580 // =================================================================
4581
4582/// This class is used as a base-class for manifest constants in the
4583/// `std::numeric_limits` specializations to overcome a Sun compiler issue.
4584template<class NUMERIC_TYPE, class DUMMY_TYPE = void>
4586
4587 // ===============================================================
4588 // class faux_numeric_limits<Decimal_StandardNamespaceCanary, ...>
4589 // ===============================================================
4590
4591/// Explicit full specialization of the standard "traits" template
4592/// `std::numeric_limits` for the type
4593/// `BloombergLP::bdldfp::Decimal_StandardNamespaceCanary`. Note that this
4594/// specialization is required for technical reasons and it is identical to
4595/// the non-specialized default traits.
4596template<class DUMMY_TYPE>
4598{
4599
4600 public:
4601 // CLASS DATA
4602
4603 /// `BloombergLP::bdldfp::Decimal_StandardNamespaceCanary` is not a
4604 /// numeric type.
4605 static const bool is_specialized = false;
4606};
4607
4608 // ==============================================================
4609 // template<...> class faux_numeric_limits<Decimal32, DUMMY_TYPE>
4610 // ==============================================================
4611
4612template<class DUMMY_TYPE>
4613class faux_numeric_limits<BloombergLP::bdldfp::Decimal32, DUMMY_TYPE> {
4614 // Explicit full specialization of the standard "traits" template
4615 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal32'.
4616
4617 public:
4618 // CLASS DATA
4619
4620 /// The template instance
4621 /// `std::numeric_limits<BloombergLP::bdldfp::Decimal32>` is
4622 /// meaningfully specialized. Also means that
4623 /// `BloombergLP::bdldfp::Decimal32` is a numeric type.
4624 static const bool is_specialized = true;
4625
4626 /// The maximum number of significant digits, in the native (10) radix
4627 /// of the `BloombergLP::bdldfp::Decimal32` type that the type is able
4628 /// to represent. Defined to be 7 by IEEE-754.
4629 static const int digits = 7;
4630
4631 /// The maximum number of significant decimal digits that the
4632 /// `BloombergLP::bdldfp::Decimal32` type is able to represent. Defined
4633 /// to be 7 by IEEE-754.
4634 static const int digits10 = digits;
4635
4636 /// The number of significant decimal digits necessary to uniquely
4637 /// represent the significant digits of any
4638 /// `BloombergLP::bdldfp::Decimal32` value. Note that max_digit10 is
4639 /// the same as digits10 for decimal floating-point values.
4640 static const int max_digits10 = digits;
4641
4642 /// `BloombergLP::bdldfp::Decimal32` is a signed type.
4643 static const bool is_signed = true;
4644
4645 /// `BloombergLP::bdldfp::Decimal32` is not an integer type.
4646 static const bool is_integer = false;
4647
4648 /// `BloombergLP::bdldfp::Decimal32` is not an exact type, i.e.:
4649 /// calculations done on the type are not free of rounding errors. Note
4650 /// that integer and possibly rational types may be exact,
4651 /// floating-point types are never exact.
4652 static const bool is_exact = false;
4653
4654 /// The base for `BloombergLP::bdldfp::Decimal32` is decimal or 10.
4655 static const int radix = 10;
4656
4657 /// The lowest possible negative exponent for the native base of the
4658 /// `BloombergLP::bdldfp::Decimal32` type that does not yet represent a
4659 /// denormal number. Defined to be -95 by IEEE-754.
4660 static const int min_exponent = -95;
4661
4662 /// The lowest possible negative decimal exponent in the
4663 /// `BloombergLP::bdldfp::Decimal32` type that does not yet represent a
4664 /// denormal number. Defined to be -95 by IEEE-754. Note that
4665 /// @ref min_exponent10 is the same as @ref min_exponent for decimal types.
4666 static const int min_exponent10 = min_exponent;
4667
4668 /// The highest possible positive exponent for the native base of the
4669 /// `BloombergLP::bdldfp::Decimal32` type that represents a finite
4670 /// value. Defined to be 96 by IEEE-754.
4671 static const int max_exponent = 96;
4672
4673 /// The highest possible positive decimal exponent of the
4674 /// `BloombergLP::bdldfp::Decimal32` type that represents a finite
4675 /// value. Defined to be 97 by IEEE-754. Note that @ref max_exponent10 is
4676 /// the same as @ref max_exponent for decimal types.
4677 static const int max_exponent10 = max_exponent;
4678
4679 /// `BloombergLP::bdldfp::Decimal32` can represent infinity.
4680 static const bool has_infinity = true;
4681
4682 /// `BloombergLP::bdldfp::Decimal32` can be a non-signaling Not a
4683 /// Number.
4684 static const bool has_quiet_NaN = true;
4685
4686 /// `BloombergLP::bdldfp::Decimal32` can be a signaling Not a Number.
4687 static const bool has_signaling_NaN = true;
4688
4689 /// `BloombergLP::bdldfp::Decimal32` may contain denormal values.
4690 static const std::float_denorm_style has_denorm = std::denorm_present;
4691
4692 /// `BloombergLP::bdldfp::Decimal32` is able to distinguish loss of
4693 /// precision (floating-point underflow) due to denormalization from
4694 /// other causes.
4695 static const bool has_denorm_loss = true;
4696
4697 /// Decimal floating-point types represent a finite set of values.
4698 static const bool is_bounded = true;
4699
4700 /// Decimal floating-point is not covered by the IEC 559 standard.
4701 static const bool is_iec559 = false;
4702
4703 /// Decimal floating-point types do not have modulo representation.
4704 static const bool is_modulo = false;
4705
4706 /// Decimal floating-point types are able to detect if a value is too
4707 /// small to represent as a normalized value before rounding it.
4708 static const bool tinyness_before = true;
4709
4710 /// Decimal floating-point types implement traps to report arithmetic
4711 /// exceptions (required by IEEE-754).
4712 static const bool traps = true;
4713
4714 /// The highest possible precision in the
4715 /// `BloombergLP::bdldfp::Decimal32` type that is large enough to
4716 /// output the smallest non-zero denormalized value in fixed notation.
4717 static const int max_precision = digits10 - 1 + (-min_exponent10);
4718
4719 // Rounding style
4720
4721 /// Decimal floating-point rounding style is defined to be indeterminate
4722 /// by the C and C++ Decimal TRs.
4723 static const std::float_round_style round_style = std::round_indeterminate;
4724};
4725
4726 // ==============================================================
4727 // template<...> class faux_numeric_limits<Decimal64, DUMMY_TYPE>
4728 // ==============================================================
4729
4730template<class DUMMY_TYPE>
4731class faux_numeric_limits<BloombergLP::bdldfp::Decimal64, DUMMY_TYPE> {
4732 // Explicit full specialization of the standard "traits" template
4733 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal64'.
4734
4735 public:
4736 // CLASS DATA
4737
4738 /// The template instance
4739 /// `std::numeric_limits<BloombergLP::bdldfp::Decimal64>` is
4740 /// meaningfully specialized. Also means that
4741 /// `BloombergLP::bdldfp::Decimal64` is a numeric type.
4742 static const bool is_specialized = true;
4743
4744 /// The maximum number of significant digits, in the native (10) radix
4745 /// of the `BloombergLP::bdldfp::Decimal64` type that the type is able
4746 /// to represent. Defined to be 16 by IEEE-754.
4747 static const int digits = 16;
4748
4749 /// The maximum number of significant decimal digits that the
4750 /// `BloombergLP::bdldfp::Decimal64` type is able to represent. Defined
4751 /// to be 16 by IEEE-754.
4752 static const int digits10 = digits;
4753
4754 /// The number of significant decimal digits necessary to uniquely
4755 /// represent the significant digits of any
4756 /// `BloombergLP::bdldfp::Decimal64` value. Note that max_digit10 is
4757 /// the same as digits10 for decimal floating-point values.
4758 static const int max_digits10 = digits;
4759
4760 /// `BloombergLP::bdldfp::Decimal64` is a signed type.
4761 static const bool is_signed = true;
4762
4763 /// `BloombergLP::bdldfp::Decimal64` is not an integer type.
4764 static const bool is_integer = false;
4765
4766 /// `BloombergLP::bdldfp::Decimal64` is not an exact type, i.e.:
4767 /// calculations done on the type are not free of rounding errors. Note
4768 /// that integer and possibly rational types may be exact,
4769 /// floating-point types are never exact.
4770 static const bool is_exact = false;
4771
4772 /// The base for `BloombergLP::bdldfp::Decimal64` is decimal or 10.
4773 static const int radix = 10;
4774
4775 /// The lowest possible negative exponent for the native base of the
4776 /// `BloombergLP::bdldfp::Decimal64` type that does not yet represent a
4777 /// denormal number. Defined to be -383 by IEEE-754.
4778 static const int min_exponent = -383;
4779
4780 /// The lowest possible negative decimal exponent in the
4781 /// `BloombergLP::bdldfp::Decimal64` type that does not yet represent a
4782 /// denormal number. Defined to be -382 by IEEE-754. Note that
4783 /// @ref min_exponent10 is the same as @ref min_exponent for decimal types.
4784 static const int min_exponent10 = min_exponent;
4785
4786 /// The highest possible positive exponent for the native base of the
4787 /// `BloombergLP::bdldfp::Decimal64` type that represents a finite
4788 /// value. Defined to be 384 by IEEE-754.
4789 static const int max_exponent = 384;
4790
4791 /// The highest possible positive decimal exponent of the
4792 /// `BloombergLP::bdldfp::Decimal64` type that represents a finite
4793 /// value. Defined to be 384 by IEEE-754. Note that @ref max_exponent10
4794 /// is the same as @ref max_exponent for decimal types.
4795 static const int max_exponent10 = max_exponent;
4796
4797 /// `BloombergLP::bdldfp::Decimal64` can represent infinity.
4798 static const bool has_infinity = true;
4799
4800 /// `BloombergLP::bdldfp::Decimal64` can be a non-signaling Not a
4801 /// Number.
4802 static const bool has_quiet_NaN = true;
4803
4804 /// `BloombergLP::bdldfp::Decimal64` can be a signaling Not a Number.
4805 static const bool has_signaling_NaN = true;
4806
4807 /// `BloombergLP::bdldfp::Decimal64` may contain denormal values.
4808 static const std::float_denorm_style has_denorm = std::denorm_present;
4809
4810 /// `BloombergLP::bdldfp::Decimal64` is able to distinguish loss of
4811 /// precision (floating-point underflow) due to denormalization from
4812 /// other causes.
4813 static const bool has_denorm_loss = true;
4814
4815 /// Decimal floating-point is not covered by the IEC 559 standard.
4816 static const bool is_iec559 = false;
4817
4818 /// Decimal floating-point types represent a finite set of values.
4819 static const bool is_bounded = true;
4820
4821 /// Decimal floating-point types do not have modulo representation.
4822 static const bool is_modulo = false;
4823
4824 /// Decimal floating-point types implement traps to report arithmetic
4825 /// exceptions (required by IEEE-754).
4826 static const bool traps = true;
4827
4828 /// Decimal floating-point types are able to detect if a value is too
4829 /// small to represent as a normalized value before rounding it.
4830 static const bool tinyness_before = true;
4831
4832 /// The highest possible precision in the
4833 /// `BloombergLP::bdldfp::Decimal64` type that is large enough to
4834 /// output the smallest non-zero denormalized value in fixed notation.
4835 static const int max_precision = digits10 - 1 + (-min_exponent10);
4836
4837 /// Decimal floating-point rounding style is defined to be indeterminate
4838 /// by the C and C++ Decimal TRs.
4839 static const std::float_round_style round_style = std::round_indeterminate;
4840};
4841
4842 // ===============================================================
4843 // template<...> class faux_numeric_limits<Decimal128, DUMMY_TYPE>
4844 // ===============================================================
4845
4846template<class DUMMY_TYPE>
4847class faux_numeric_limits<BloombergLP::bdldfp::Decimal128, DUMMY_TYPE> {
4848 // Explicit full specialization of the standard "traits" template
4849 // 'std::numeric_limits' for the type
4850 // 'BloombergLP::bdldfp::Decimal128'.
4851
4852 public:
4853 // CLASS DATA
4854
4855 /// The template instance
4856 /// `std::numeric_limits<BloombergLP::bdldfp::Decimal128>` is
4857 /// meaningfully specialized. Also means that
4858 /// `BloombergLP::bdldfp::Decimal128` is a numeric type.
4859 static const bool is_specialized = true;
4860
4861 /// The maximum number of significant digits, in the native (10) radix
4862 /// of the `BloombergLP::bdldfp::Decimal128` type that the type is able
4863 /// to represent. Defined to be 34 by IEEE-754.
4864 static const int digits = 34;
4865
4866 /// The maximum number of significant decimal digits that the
4867 /// `BloombergLP::bdldfp::Decimal128` type is able to represent.
4868 /// Defined to be 34 by IEEE-754.
4869 static const int digits10 = digits;
4870
4871 /// The number of significant decimal digits necessary to uniquely
4872 /// represent the significant digits of any
4873 /// `BloombergLP::bdldfp::Decimal128` value. Note that max_digit10 is
4874 /// the same as digits10 for decimal floating-point values.
4875 static const int max_digits10 = digits;
4876
4877 /// `BloombergLP::bdldfp::Decimal128` is a signed type.
4878 static const bool is_signed = true;
4879
4880 /// `BloombergLP::bdldfp::Decimal128` is not an integer type.
4881 static const bool is_integer = false;
4882
4883 /// `BloombergLP::bdldfp::Decimal128` is not an exact type, i.e.:
4884 /// calculations done on the type are not free of rounding errors. Note
4885 /// that integer and possibly rational types may be exact,
4886 /// floating-point types are never exact.
4887 static const bool is_exact = false;
4888
4889 /// The base for `BloombergLP::bdldfp::Decimal128` is decimal or 10.
4890 static const int radix = 10;
4891
4892 /// The lowest possible negative exponent for the native base of the
4893 /// `BloombergLP::bdldfp::Decimal128` type that does not yet represent a
4894 /// denormal number. Defined to be -6143 by IEEE-754.
4895 static const int min_exponent = -6143;
4896
4897 /// The lowest possible negative decimal exponent in the
4898 /// `BloombergLP::bdldfp::Decimal128` type that does not yet represent a
4899 /// denormal number. Defined to be -6142 by IEEE-754. Note that
4900 /// @ref min_exponent10 is the same as @ref min_exponent for decimal types.
4901 static const int min_exponent10 = min_exponent;
4902
4903 /// The highest possible positive exponent for the native base of the
4904 /// `BloombergLP::bdldfp::Decimal128` type that represents a finite
4905 /// value. Defined to be 385 by IEEE-754.
4906 static const int max_exponent = 6144;
4907
4908 /// The highest possible positive decimal exponent of the
4909 /// `BloombergLP::bdldfp::Decimal128` type that represents a finite
4910 /// value. Defined to be 6145 by IEEE-754. Note that @ref max_exponent10
4911 /// is the same as @ref max_exponent for decimal types.
4912 static const int max_exponent10 = max_exponent;
4913
4914 /// `BloombergLP::bdldfp::Decimal128` can represent infinity.
4915 static const bool has_infinity = true;
4916
4917 /// `BloombergLP::bdldfp::Decimal128` can be a non-signaling Not a
4918 /// Number.
4919 static const bool has_quiet_NaN = true;
4920
4921 /// `BloombergLP::bdldfp::Decimal128` can be a signaling Not a Number.
4922 static const bool has_signaling_NaN = true;
4923
4924 /// `BloombergLP::bdldfp::Decimal128` may contain denormal values.
4925 static const std::float_denorm_style has_denorm = std::denorm_present;
4926
4927 /// `BloombergLP::bdldfp::Decimal128` is able to distinguish loss of
4928 /// precision (floating-point underflow) due to denormalization from
4929 /// other causes.
4930 static const bool has_denorm_loss = true;
4931
4932 /// Decimal floating-point is not covered by the IEC 559 standard.
4933 static const bool is_iec559 = false;
4934
4935 /// Decimal floating-point types represent a finite set of values.
4936 static const bool is_bounded = true;
4937
4938 /// Decimal floating-point types do not have modulo representation.
4939 static const bool is_modulo = false;
4940
4941 /// Decimal floating-point types implement traps to report arithmetic
4942 /// exceptions (required by IEEE-754).
4943 static const bool traps = true;
4944
4945 /// Decimal floating-point types are able to detect if a value is too
4946 /// small to represent as a normalized value before rounding it.
4947 static const bool tinyness_before = true;
4948
4949 /// The highest possible precision in the
4950 /// `BloombergLP::bdldfp::Decimal128` type that is large enough to
4951 /// output the smallest non-zero denormalized value in fixed notation.
4952 static const int max_precision = digits10 - 1 + (-min_exponent10);
4953
4954 /// Decimal floating-point rounding style is defined to be indeterminate
4955 /// by the C and C++ Decimal TRs.
4956 static const std::float_round_style round_style = std::round_indeterminate;
4957
4958};
4959
4960 // --------------------------------------------------
4961 // faux_numeric_limits<Decimal32, ...> member storage
4962 // --------------------------------------------------
4963
4964template<class DUMMY_TYPE>
4966
4967template<class DUMMY_TYPE>
4969
4970template<class DUMMY_TYPE>
4972
4973template<class DUMMY_TYPE>
4975
4976template<class DUMMY_TYPE>
4978
4979template<class DUMMY_TYPE>
4981
4982template<class DUMMY_TYPE>
4984
4985template<class DUMMY_TYPE>
4987
4988template<class DUMMY_TYPE>
4990
4991template<class DUMMY_TYPE>
4993
4994template<class DUMMY_TYPE>
4996
4997template<class DUMMY_TYPE>
4999
5000template<class DUMMY_TYPE>
5002
5003template<class DUMMY_TYPE>
5005
5006template<class DUMMY_TYPE>
5008
5009template<class DUMMY_TYPE>
5010const std::float_denorm_style
5012
5013template<class DUMMY_TYPE>
5015
5016template<class DUMMY_TYPE>
5018
5019template<class DUMMY_TYPE>
5021
5022template<class DUMMY_TYPE>
5024
5025template<class DUMMY_TYPE>
5027
5028template<class DUMMY_TYPE>
5030
5031template<class DUMMY_TYPE>
5032const std::float_round_style
5034
5035 // --------------------------------------------------
5036 // faux_numeric_limits<Decimal64, ...> member storage
5037 // --------------------------------------------------
5038
5039template<class DUMMY_TYPE>
5041
5042template<class DUMMY_TYPE>
5044
5045template<class DUMMY_TYPE>
5047
5048template<class DUMMY_TYPE>
5050
5051template<class DUMMY_TYPE>
5053
5054template<class DUMMY_TYPE>
5056
5057template<class DUMMY_TYPE>
5059
5060template<class DUMMY_TYPE>
5062
5063template<class DUMMY_TYPE>
5065
5066template<class DUMMY_TYPE>
5068
5069template<class DUMMY_TYPE>
5071
5072template<class DUMMY_TYPE>
5074
5075template<class DUMMY_TYPE>
5077
5078template<class DUMMY_TYPE>
5080
5081template<class DUMMY_TYPE>
5083
5084template<class DUMMY_TYPE>
5085const std::float_denorm_style
5087
5088template<class DUMMY_TYPE>
5090
5091template<class DUMMY_TYPE>
5093
5094template<class DUMMY_TYPE>
5096
5097template<class DUMMY_TYPE>
5099
5100template<class DUMMY_TYPE>
5102
5103template<class DUMMY_TYPE>
5105
5106template<class DUMMY_TYPE>
5107const std::float_round_style
5109
5110 // ---------------------------------------------------
5111 // faux_numeric_limits<Decimal128, ...> member storage
5112 // ---------------------------------------------------
5113
5114template<class DUMMY_TYPE>
5116
5117template<class DUMMY_TYPE>
5119
5120template<class DUMMY_TYPE>
5122
5123template<class DUMMY_TYPE>
5125
5126template<class DUMMY_TYPE>
5128
5129template<class DUMMY_TYPE>
5131
5132template<class DUMMY_TYPE>
5134
5135template<class DUMMY_TYPE>
5137
5138template<class DUMMY_TYPE>
5140
5141template<class DUMMY_TYPE>
5143
5144template<class DUMMY_TYPE>
5146
5147template<class DUMMY_TYPE>
5149
5150template<class DUMMY_TYPE>
5152
5153template<class DUMMY_TYPE>
5155
5156template<class DUMMY_TYPE>
5158
5159template<class DUMMY_TYPE>
5160const std::float_denorm_style
5162
5163template<class DUMMY_TYPE>
5165
5166template<class DUMMY_TYPE>
5168
5169template<class DUMMY_TYPE>
5171
5172template<class DUMMY_TYPE>
5174
5175template<class DUMMY_TYPE>
5177
5178template<class DUMMY_TYPE>
5180
5181template<class DUMMY_TYPE>
5182const std::float_round_style
5184
5185} // close package namespace
5186
5187
5188namespace std {
5189
5190 // ========================================================================
5191 // template<> class numeric_limits<bdldfp::Decimal_StandardNamespaceCanary>
5192 // ========================================================================
5193
5194/// Explicit full specialization of the standard "traits" template
5195/// `std::numeric_limits` for the type
5196/// `BloombergLP::bdldfp::Decimal_StandardNamespaceCanary`. Note that this
5197/// specialization is required for technical reasons and it is identical to
5198/// the non-specialized default traits.
5199template<>
5200class numeric_limits<BloombergLP::bdldfp::Decimal_StandardNamespaceCanary>
5201 : public BloombergLP::bdldfp::faux_numeric_limits<
5202 BloombergLP::bdldfp::Decimal_StandardNamespaceCanary> {
5203};
5204
5205 // ==================================================
5206 // template<> class numeric_limits<bdldfp::Decimal32>
5207 // ==================================================
5208
5209template<>
5210class numeric_limits<BloombergLP::bdldfp::Decimal32>
5211 : public BloombergLP::bdldfp::faux_numeric_limits<
5212 BloombergLP::bdldfp::Decimal32> {
5213 // Explicit full specialization of the standard "traits" template
5214 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal32'.
5215
5216 public:
5217 // CLASS METHODS
5218
5219 /// Return the smallest positive (also non-zero) number
5220 /// `BloombergLP::bdldfp::Decimal32` can represent (IEEE-754: +1e-95).
5221 static BloombergLP::bdldfp::Decimal32 min() BSLS_KEYWORD_NOEXCEPT;
5222
5223 /// Return the largest number `BloombergLP::bdldfp::Decimal32` can
5224 /// represent (IEEE-754: +9.999999e+96).
5225 static BloombergLP::bdldfp::Decimal32 max() BSLS_KEYWORD_NOEXCEPT;
5226
5227 /// Return the difference between 1 and the smallest value representable
5228 /// by the `BloombergLP::bdldfp::Decimal32` type. (IEEE-754: +1e-6)
5229 static BloombergLP::bdldfp::Decimal32 epsilon() BSLS_KEYWORD_NOEXCEPT;
5230
5231 /// Return the maximum rounding error for the
5232 /// `BloombergLP::bdldfp::Decimal32` type. The actual value returned
5233 /// depends on the current decimal floating point rounding setting.
5234 static BloombergLP::bdldfp::Decimal32 round_error() BSLS_KEYWORD_NOEXCEPT;
5235
5236 /// Return the smallest non-zero denormalized value for the
5237 /// `BloombergLP::bdldfp::Decimal32` type. (IEEE-754: +0.000001E-95)
5238 static BloombergLP::bdldfp::Decimal32 denorm_min() BSLS_KEYWORD_NOEXCEPT;
5239
5240 /// Return the value that represents positive infinity for the
5241 /// `BloombergLP::bdldfp::Decimal32` type.
5242 static BloombergLP::bdldfp::Decimal32 infinity() BSLS_KEYWORD_NOEXCEPT;
5243
5244 /// Return a value that represents non-signaling NaN for the
5245 /// `BloombergLP::bdldfp::Decimal32` type.
5246 static BloombergLP::bdldfp::Decimal32 quiet_NaN() BSLS_KEYWORD_NOEXCEPT;
5247
5248 /// Return a value that represents signaling NaN for the
5249 /// `BloombergLP::bdldfp::Decimal32` type.
5250 static
5251 BloombergLP::bdldfp::Decimal32 signaling_NaN() BSLS_KEYWORD_NOEXCEPT;
5252};
5253
5254 // ==================================================
5255 // template<> class numeric_limits<bdldfp::Decimal64>
5256 // ==================================================
5257
5258template<>
5259class numeric_limits<BloombergLP::bdldfp::Decimal64>
5260 : public BloombergLP::bdldfp::faux_numeric_limits<
5261 BloombergLP::bdldfp::Decimal64> {
5262 // Explicit full specialization of the standard "traits" template
5263 // 'std::numeric_limits' for the type 'BloombergLP::bdldfp::Decimal64'.
5264
5265 public:
5266 // CLASS METHODS
5267
5268 /// Return the smallest positive (also non-zero) number
5269 /// `BloombergLP::bdldfp::Decimal64` can represent (IEEE-754: +1e-383).
5270 static BloombergLP::bdldfp::Decimal64 min() BSLS_KEYWORD_NOEXCEPT;
5271
5272 /// Return the largest number `BloombergLP::bdldfp::Decimal64` can
5273 /// represent (IEEE-754: +9.999999999999999e+384).
5274 static BloombergLP::bdldfp::Decimal64 max() BSLS_KEYWORD_NOEXCEPT;
5275
5276 /// Return the difference between 1 and the smallest value representable
5277 /// by the `BloombergLP::bdldfp::Decimal64` type. (IEEE-754: +1e-15)
5278 static BloombergLP::bdldfp::Decimal64 epsilon() BSLS_KEYWORD_NOEXCEPT;
5279
5280 /// Return the maximum rounding error for the
5281 /// `BloombergLP::bdldfp::Decimal64` type. The actual value returned
5282 /// depends on the current decimal floating point rounding setting.
5283 static BloombergLP::bdldfp::Decimal64 round_error() BSLS_KEYWORD_NOEXCEPT;
5284
5285 /// Return the smallest non-zero denormalized value for the
5286 /// `BloombergLP::bdldfp::Decimal64` type. (IEEE-754:
5287 /// +0.000000000000001e-383)
5288 static BloombergLP::bdldfp::Decimal64 denorm_min() BSLS_KEYWORD_NOEXCEPT;
5289
5290 /// Return the value that represents positive infinity for the
5291 /// `BloombergLP::bdldfp::Decimal64` type.
5292 static BloombergLP::bdldfp::Decimal64 infinity() BSLS_KEYWORD_NOEXCEPT;
5293
5294 /// Return a value that represents non-signaling NaN for the
5295 /// `BloombergLP::bdldfp::Decimal64` type.
5296 static BloombergLP::bdldfp::Decimal64 quiet_NaN() BSLS_KEYWORD_NOEXCEPT;
5297
5298 /// Return a value that represents signaling NaN for the
5299 /// `BloombergLP::bdldfp::Decimal64` type.
5300 static
5301 BloombergLP::bdldfp::Decimal64 signaling_NaN() BSLS_KEYWORD_NOEXCEPT;
5302
5303};
5304
5305 // ===================================================
5306 // template<> class numeric_limits<bdldfp::Decimal128>
5307 // ===================================================
5308
5309template<>
5310class numeric_limits<BloombergLP::bdldfp::Decimal128>
5311 : public BloombergLP::bdldfp::faux_numeric_limits<
5312 BloombergLP::bdldfp::Decimal128> {
5313 // Explicit full specialization of the standard "traits" template
5314 // 'std::numeric_limits' for the type
5315 // 'BloombergLP::bdldfp::Decimal128'.
5316
5317 public:
5318 // CLASS METHODS
5319
5320 /// Return the smallest positive (also non-zero) number
5321 /// `BloombergLP::bdldfp::Decimal128` can represent (IEEE-754:
5322 /// +1e-6143).
5323 static BloombergLP::bdldfp::Decimal128 min() BSLS_KEYWORD_NOEXCEPT;
5324
5325 /// Return the largest number `BloombergLP::bdldfp::Decimal128` can
5326 /// represent (IEEE-754: +9.999999999999999999999999999999999e+6144).
5327 static BloombergLP::bdldfp::Decimal128 max() BSLS_KEYWORD_NOEXCEPT;
5328
5329 /// Return the difference between 1 and the smallest value representable
5330 /// by the `BloombergLP::bdldfp::Decimal128` type. (IEEE-754: +1e-33)
5331 static BloombergLP::bdldfp::Decimal128 epsilon() BSLS_KEYWORD_NOEXCEPT;
5332
5333 /// Return the maximum rounding error for the
5334 /// `BloombergLP::bdldfp::Decimal128` type. The actual value returned
5335 /// depends on the current decimal floating point rounding setting.
5336 static BloombergLP::bdldfp::Decimal128 round_error() BSLS_KEYWORD_NOEXCEPT;
5337
5338 /// Return the smallest non-zero denormalized value for the
5339 /// `BloombergLP::bdldfp::Decimal128` type. (IEEE-754:
5340 /// +0.000000000000000000000000000000001e-6143)
5341 static BloombergLP::bdldfp::Decimal128 denorm_min() BSLS_KEYWORD_NOEXCEPT;
5342
5343 /// Return the value that represents positive infinity for the
5344 /// `BloombergLP::bdldfp::Decimal128` type.
5345 static BloombergLP::bdldfp::Decimal128 infinity() BSLS_KEYWORD_NOEXCEPT;
5346
5347 /// Return a value that represents non-signaling NaN for the
5348 /// `BloombergLP::bdldfp::Decimal128` type.
5349 static BloombergLP::bdldfp::Decimal128 quiet_NaN() BSLS_KEYWORD_NOEXCEPT;
5350
5351 /// Return a value that represents signaling NaN for the
5352 /// `BloombergLP::bdldfp::Decimal128` type.
5353 static
5354 BloombergLP::bdldfp::Decimal128 signaling_NaN() BSLS_KEYWORD_NOEXCEPT;
5355};
5356
5357} // close namespace std
5358
5359// ============================================================================
5360// INLINE DEFINITIONS
5361// ============================================================================
5362
5363
5364namespace bdldfp {
5365
5366 // THE DECIMAL FLOATING-POINT TYPES
5367
5368 // --------------------
5369 // class Decimal_Type32
5370 // --------------------
5371
5372// CLASS METHODS
5373
5374 // Aspects
5375inline
5376int Decimal_Type32::maxSupportedBdexVersion()
5377{
5378 return 1;
5379}
5380
5381inline
5382int Decimal_Type32::maxSupportedBdexVersion(int /* versionSelector */)
5383{
5384 return 1;
5385}
5386
5387// CREATORS
5388inline
5389Decimal_Type32::Decimal_Type32()
5390{
5391 bsl::memset(&d_value, 0, sizeof(d_value));
5392}
5393
5394inline
5395Decimal_Type32::Decimal_Type32(DecimalImpUtil::ValueType32 value)
5396: d_value(value)
5397{
5398}
5399
5400inline
5402: d_value(DecimalImpUtil::convertToDecimal32(*other.data()))
5403{
5404}
5405
5406inline
5408: d_value(DecimalImpUtil::convertToDecimal32(*other.data()))
5409{
5410}
5411
5412inline
5414: d_value(DecimalImpUtil::binaryToDecimal32(other))
5415{
5416}
5417
5418inline
5420: d_value(DecimalImpUtil::binaryToDecimal32(other))
5421{
5422}
5423
5424inline
5426: d_value(DecimalImpUtil::int32ToDecimal32(other))
5427{
5428}
5429
5430inline
5432: d_value(DecimalImpUtil::uint32ToDecimal32(other))
5433{
5434}
5435
5436inline
5438: d_value(DecimalImpUtil::int64ToDecimal32(other))
5439{
5440}
5441
5442inline
5443Decimal_Type32::Decimal_Type32(unsigned long int other)
5444: d_value(DecimalImpUtil::uint64ToDecimal32(other))
5445{
5446}
5447
5448inline
5450: d_value(DecimalImpUtil::int64ToDecimal32(other))
5451{
5452}
5453
5454inline
5455Decimal_Type32::Decimal_Type32(unsigned long long other)
5456: d_value(DecimalImpUtil::uint64ToDecimal32(other))
5457{
5458}
5459
5460// MANIPULATORS
5461
5462 // Incrementation and Decrementation
5463
5465{
5466 return *this += Decimal32(1);
5467}
5468
5470{
5471 return *this -= Decimal32(1);
5472}
5473
5474 // Addition
5475
5477{
5478 this->d_value = DecimalImpUtil::add(this->d_value, rhs.d_value);
5479 return *this;
5480}
5481
5483{
5484 return *this = Decimal32(Decimal64(*this) + rhs);
5485}
5486
5488{
5489 return *this = Decimal32(Decimal128(*this) + rhs);
5490}
5491
5493{
5494 return *this += Decimal64(rhs);
5495}
5496
5498{
5499 return *this += Decimal64(rhs);
5500}
5501
5503{
5504 return *this += Decimal64(rhs);
5505}
5506
5508{
5509 return *this += Decimal64(rhs);
5510}
5511
5513{
5514 return *this += Decimal128(rhs);
5515}
5516
5517inline Decimal_Type32& Decimal_Type32::operator+=(unsigned long long rhs)
5518{
5519 return *this += Decimal128(rhs);
5520}
5521
5522 // Subtraction
5523
5525{
5526 this->d_value = DecimalImpUtil::subtract(this->d_value, rhs.d_value);
5527 return *this;
5528}
5529
5531{
5532 return *this = Decimal32(Decimal64(*this) - rhs);
5533}
5534
5536{
5537 return *this = Decimal32(Decimal128(*this) - rhs);
5538}
5539
5541{
5542 return *this -= Decimal64(rhs);
5543}
5544
5546{
5547 return *this -= Decimal64(rhs);
5548}
5549
5551{
5552 return *this -= Decimal64(rhs);
5553}
5554
5556{
5557 return *this -= Decimal64(rhs);
5558}
5559
5561{
5562 return *this -= Decimal128(rhs);
5563}
5564
5565inline Decimal_Type32& Decimal_Type32::operator-=(unsigned long long rhs)
5566{
5567 return *this -= Decimal128(rhs);
5568}
5569
5570 // Multiplication
5571
5573{
5574 this->d_value = DecimalImpUtil::multiply(this->d_value, rhs.d_value);
5575 return *this;
5576}
5577
5579{
5580 return *this = Decimal32(Decimal64(*this) * rhs);
5581}
5582
5584{
5585 return *this = Decimal32(Decimal128(*this) * rhs);
5586}
5587
5589{
5590 return *this *= Decimal64(rhs);
5591}
5592
5594{
5595 return *this *= Decimal64(rhs);
5596}
5597
5599{
5600 return *this *= Decimal64(rhs);
5601}
5602
5604{
5605 return *this *= Decimal64(rhs);
5606}
5607
5609{
5610 return *this *= Decimal128(rhs);
5611}
5612
5613inline Decimal_Type32& Decimal_Type32::operator*=(unsigned long long rhs)
5614{
5615 return *this *= Decimal128(rhs);
5616}
5617
5618 // Division
5619
5621{
5622 this->d_value = DecimalImpUtil::divide(this->d_value, rhs.d_value);
5623 return *this;
5624}
5625
5627{
5628 return *this = Decimal32(Decimal64(*this) / rhs);
5629}
5630
5632{
5633 return *this = Decimal32(Decimal128(*this) / rhs);
5634}
5635
5637{
5638 return *this /= Decimal64(rhs);
5639}
5640
5642{
5643 return *this /= Decimal64(rhs);
5644}
5645
5647{
5648 return *this /= Decimal64(rhs);
5649}
5650
5652{
5653 return *this /= Decimal64(rhs);
5654}
5655
5657{
5658 return *this /= Decimal128(rhs);
5659}
5660
5661inline Decimal_Type32& Decimal_Type32::operator/=(unsigned long long rhs)
5662{
5663 return *this /= Decimal128(rhs);
5664}
5665
5666
5667inline
5669{
5670 return &d_value;
5671}
5672
5673 // Aspects
5674
5675template <class STREAM>
5676STREAM& Decimal_Type32::bdexStreamIn(STREAM& stream, int version)
5677{
5678 if (stream) {
5679 switch (version) { // switch on the schema version
5680 case 1: {
5682 stream.getUint32(bidVal);
5683
5684 if (stream) {
5685 d_value.d_raw = bidVal;
5686 }
5687 else {
5688 stream.invalidate();
5689 }
5690 } break;
5691 default: {
5692 stream.invalidate(); // unrecognized version number
5693 }
5694 }
5695 }
5696 return stream;
5697}
5698
5699inline
5701{
5702 return &d_value;
5703}
5704
5705inline
5707{
5708 return d_value;
5709}
5710
5711 // Aspects
5712
5713template <class STREAM>
5714STREAM& Decimal_Type32::bdexStreamOut(STREAM& stream, int version) const
5715{
5716 if (stream) {
5717 switch (version) { // switch on the schema version
5718 case 1: {
5719 stream.putUint32(d_value.d_raw);
5720 } break;
5721 default: {
5722 stream.invalidate(); // unrecognized version number
5723 }
5724 }
5725 }
5726 return stream;
5727}
5728
5729 // --------------------
5730 // class Decimal_Type64
5731 // --------------------
5732
5733// CLASS METHODS
5734
5735 // Aspects
5736inline
5738{
5739 return 1;
5740}
5741
5742inline
5743int Decimal_Type64::maxSupportedBdexVersion(int /* versionSelector */)
5744{
5745 return 1;
5746}
5747
5748// CREATORS
5749inline
5751{
5752 bsl::memset(&d_value, 0, sizeof(d_value));
5753}
5754
5755inline
5757: d_value(value)
5758{
5759}
5760
5761inline
5763: d_value(DecimalImpUtil::convertToDecimal64(*other.data()))
5764{
5765}
5766
5767inline
5769: d_value(DecimalImpUtil::convertToDecimal64(*other.data()))
5770{
5771}
5772
5773 // Numerical Conversion Constructors
5774
5775inline
5777: d_value(DecimalImpUtil::binaryToDecimal64(other))
5778{
5779}
5780
5781inline
5783: d_value(DecimalImpUtil::binaryToDecimal64(other))
5784{
5785}
5786
5787 // Integral Conversion Constructors
5788
5789inline
5791: d_value(DecimalImpUtil::int32ToDecimal64(other))
5792{
5793}
5794
5795inline
5797: d_value(DecimalImpUtil::uint32ToDecimal64(other))
5798{
5799}
5800
5801inline
5803: d_value(DecimalImpUtil::int64ToDecimal64(other))
5804{
5805}
5806
5807inline
5809: d_value(DecimalImpUtil::uint64ToDecimal64(other))
5810{
5811}
5812
5813inline
5815: d_value(DecimalImpUtil::int64ToDecimal64(other))
5816{
5817}
5818
5819inline
5820Decimal_Type64::Decimal_Type64(unsigned long long other)
5821: d_value(DecimalImpUtil::uint64ToDecimal64(other))
5822{
5823}
5824
5825
5826// MANIPULATORS
5827
5828 // Incrementation and Decrementation
5829
5831{
5832 return *this += Decimal64(1);
5833}
5834
5836{
5837 return *this -= Decimal64(1);
5838}
5839
5840 // Addition
5841
5843{
5844 return *this += Decimal64(rhs);
5845}
5846
5848{
5849 this->d_value = DecimalImpUtil::add(this->d_value, rhs.d_value);
5850 return *this;
5851}
5852
5854{
5855 return *this = Decimal64(Decimal128(*this) + rhs);
5856}
5857
5859{
5860 return *this += Decimal64(rhs);
5861}
5862
5864{
5865 return *this += Decimal64(rhs);
5866}
5867
5869{
5870 return *this += Decimal64(rhs);
5871}
5872
5874{
5875 return *this += Decimal64(rhs);
5876}
5877
5879{
5880 return *this += Decimal128(rhs);
5881}
5882
5883inline Decimal_Type64& Decimal_Type64::operator+=(unsigned long long rhs)
5884{
5885 return *this += Decimal128(rhs);
5886}
5887
5888 // Subtraction
5889
5891{
5892 return *this -= Decimal64(rhs);
5893}
5894
5896{
5897 this->d_value = DecimalImpUtil::subtract(this->d_value, rhs.d_value);
5898 return *this;
5899}
5900
5902{
5903 return *this = Decimal64(Decimal128(*this) - rhs);
5904}
5905
5907{
5908 return *this -= Decimal64(rhs);
5909}
5910
5912{
5913 return *this -= Decimal64(rhs);
5914}
5915
5917{
5918 return *this -= Decimal64(rhs);
5919}
5920
5922{
5923 return *this -= Decimal64(rhs);
5924}
5925
5927{
5928 return *this -= Decimal128(rhs);
5929}
5930
5931inline Decimal_Type64& Decimal_Type64::operator-=(unsigned long long rhs)
5932{
5933 return *this -= Decimal128(rhs);
5934}
5935
5936 // Multiplication
5937
5939{
5940 return *this *= Decimal64(rhs);
5941}
5942
5944{
5945 this->d_value = DecimalImpUtil::multiply(this->d_value, rhs.d_value);
5946 return *this;
5947}
5948
5950{
5951 return *this = Decimal64(Decimal128(*this) * rhs);
5952}
5953
5955{
5956 return *this *= Decimal64(rhs);
5957}
5958
5960{
5961 return *this *= Decimal64(rhs);
5962}
5963
5965{
5966 return *this *= Decimal64(rhs);
5967}
5968
5970{
5971 return *this *= Decimal64(rhs);
5972}
5973
5975{
5976 return *this *= Decimal128(rhs);
5977}
5978
5979inline Decimal_Type64& Decimal_Type64::operator*=(unsigned long long rhs)
5980{
5981 return *this *= Decimal128(rhs);
5982}
5983
5984 // Division
5985
5987{
5988 return *this /= Decimal64(rhs);
5989}
5990
5992{
5993 this->d_value = DecimalImpUtil::divide(this->d_value, rhs.d_value);
5994 return *this;
5995}
5996
5998{
5999 return *this = Decimal64(Decimal128(*this) / rhs);
6000}
6001
6003{
6004 return *this /= Decimal64(rhs);
6005}
6006
6008{
6009 return *this /= Decimal64(rhs);
6010}
6011
6013{
6014 return *this /= Decimal64(rhs);
6015}
6016
6018{
6019 return *this /= Decimal64(rhs);
6020}
6021
6023{
6024 return *this /= Decimal128(rhs);
6025}
6026
6027inline Decimal_Type64& Decimal_Type64::operator/=(unsigned long long rhs)
6028{
6029 return *this /= Decimal128(rhs);
6030}
6031
6032 // Aspects
6033
6034template <class STREAM>
6035STREAM& Decimal_Type64::bdexStreamIn(STREAM& stream, int version)
6036{
6037 if (stream) {
6038 switch (version) { // switch on the schema version
6039 case 1: {
6041 stream.getUint64(bidVal);
6042
6043 if (stream) {
6044 d_value.d_raw = bidVal;
6045 }
6046 else {
6047 stream.invalidate();
6048 }
6049 } break;
6050 default: {
6051 stream.invalidate(); // unrecognized version number
6052 }
6053 }
6054 }
6055
6056 return stream;
6057}
6058
6059//ACCESSORS
6060
6061 // Internals Accessors
6062
6064{
6065 return &d_value;
6066}
6067
6069{
6070 return &d_value;
6071}
6072
6074{
6075 return d_value;
6076}
6077
6078 // Aspects
6079
6080template <class STREAM>
6081STREAM& Decimal_Type64::bdexStreamOut(STREAM& stream, int version) const
6082{
6083 if (stream) {
6084 switch (version) { // switch on the schema version
6085 case 1: {
6086 stream.putUint64(d_value.d_raw);
6087 } break;
6088 default: {
6089 stream.invalidate(); // unrecognized version number
6090 }
6091 }
6092 }
6093 return stream;
6094}
6095
6096 // ---------------------
6097 // class Decimal_Type128
6098 // ---------------------
6099
6100// CLASS METHODS
6101
6102 // Aspects
6103inline
6105{
6106 return 1;
6107}
6108
6109inline
6110int Decimal_Type128::maxSupportedBdexVersion(int /* versionSelector */)
6111{
6112 return 1;
6113}
6114
6115// CREATORS
6116inline
6118{
6119 bsl::memset(&d_value, 0, sizeof(d_value));
6120}
6121
6122inline
6127
6128inline
6130: d_value(DecimalImpUtil::convertToDecimal128(*value.data()))
6131{
6132}
6133
6134inline
6136: d_value(DecimalImpUtil::convertToDecimal128(*value.data()))
6137{
6138}
6139
6140inline
6142: d_value(DecimalImpUtil::binaryToDecimal128(other))
6143{
6144}
6145
6146inline
6148: d_value(DecimalImpUtil::binaryToDecimal128(other))
6149{
6150}
6151
6152inline
6154: d_value(DecimalImpUtil::int32ToDecimal128(value))
6155{
6156}
6157
6158inline Decimal_Type128::Decimal_Type128(unsigned int value)
6159: d_value(DecimalImpUtil::uint32ToDecimal128(value))
6160{
6161}
6162
6164: d_value(DecimalImpUtil::int64ToDecimal128(value))
6165{
6166}
6167
6168inline Decimal_Type128::Decimal_Type128(unsigned long value)
6169: d_value(DecimalImpUtil::uint64ToDecimal128(value))
6170{
6171}
6172
6174: d_value(DecimalImpUtil::int64ToDecimal128(value))
6175{
6176}
6177
6178inline Decimal_Type128::Decimal_Type128(unsigned long long value)
6179: d_value(DecimalImpUtil::uint64ToDecimal128(value))
6180{
6181}
6182
6183
6184inline
6186{
6187 return *this += Decimal128(1);
6188}
6189
6190inline
6192{
6193 return *this -= Decimal128(1);
6194}
6195
6196 // Addition
6197
6198inline
6200{
6201 return *this += Decimal128(rhs);
6202}
6203
6204inline
6206{
6207 return *this += Decimal128(rhs);
6208}
6209
6210inline
6212{
6213 this->d_value = DecimalImpUtil::add(this->d_value, rhs.d_value);
6214 return *this;
6215}
6216
6217inline
6219{
6220 return *this += Decimal128(rhs);
6221}
6222
6223inline
6225{
6226 return *this += Decimal128(rhs);
6227}
6228
6229inline
6231{
6232 return *this += Decimal128(rhs);
6233}
6234
6235inline
6237{
6238 return *this += Decimal128(rhs);
6239}
6240
6241inline
6243{
6244 return *this += Decimal128(rhs);
6245}
6246
6247inline
6249{
6250 return *this += Decimal128(rhs);
6251}
6252
6253 // Subtraction
6254
6255inline
6257{
6258 return *this -= Decimal128(rhs);
6259}
6260
6261inline
6263{
6264 return *this -= Decimal128(rhs);
6265}
6266
6267inline
6269{
6270 this->d_value = DecimalImpUtil::subtract(this->d_value, rhs.d_value);
6271 return *this;
6272}
6273
6274
6275inline
6277{
6278 return *this -= Decimal128(rhs);
6279}
6280
6281inline
6283{
6284 return *this -= Decimal128(rhs);
6285}
6286
6287inline
6289{
6290 return *this -= Decimal128(rhs);
6291}
6292
6293inline
6295{
6296 return *this -= Decimal128(rhs);
6297}
6298
6299inline
6301{
6302 return *this -= Decimal128(rhs);
6303}
6304
6305inline
6307{
6308 return *this -= Decimal128(rhs);
6309}
6310
6311 // Multiplication
6312
6313inline
6315{
6316 return *this *= Decimal128(rhs);
6317}
6318
6319inline
6321{
6322 return *this *= Decimal128(rhs);
6323}
6324
6325inline
6327{
6328 this->d_value = DecimalImpUtil::multiply(this->d_value, rhs.d_value);
6329 return *this;
6330}
6331
6332
6333inline
6335{
6336 return *this *= Decimal128(rhs);
6337}
6338
6339inline
6341{
6342 return *this *= Decimal128(rhs);
6343}
6344
6345inline
6347{
6348 return *this *= Decimal128(rhs);
6349}
6350
6351inline
6353{
6354 return *this *= Decimal128(rhs);
6355}
6356
6357inline
6359{
6360 return *this *= Decimal128(rhs);
6361}
6362
6363inline
6365{
6366 return *this *= Decimal128(rhs);
6367}
6368
6369 // Division
6370
6371inline
6373{
6374 return *this /= Decimal128(rhs);
6375}
6376
6377inline
6379{
6380 return *this /= Decimal128(rhs);
6381}
6382
6383inline
6385{
6386 this->d_value = DecimalImpUtil::divide(this->d_value, rhs.d_value);
6387 return *this;
6388}
6389
6390
6391inline
6393{
6394 return *this /= Decimal128(rhs);
6395}
6396
6397inline
6399{
6400 return *this /= Decimal128(rhs);
6401}
6402
6403inline
6405{
6406 return *this /= Decimal128(rhs);
6407}
6408
6409inline
6411{
6412 return *this /= Decimal128(rhs);
6413}
6414
6415inline
6417{
6418 return *this /= Decimal128(rhs);
6419}
6420
6421inline
6423{
6424 return *this /= Decimal128(rhs);
6425}
6426
6427 // Internals Accessors
6428
6429inline
6431{
6432 return &d_value;
6433}
6434
6435 // Aspects
6436
6437template <class STREAM>
6438STREAM& Decimal_Type128::bdexStreamIn(STREAM& stream, int version)
6439{
6440 if (stream) {
6441 switch (version) { // switch on the schema version
6442 case 1: {
6444 const int len = sizeof(DecimalStorage::Type128)
6445 / sizeof(unsigned char);
6446
6447 unsigned char *value_p =
6448 reinterpret_cast<unsigned char *>(&bidVal);
6449
6450#ifdef BSLS_PLATFORM_IS_BIG_ENDIAN
6451 for (int i(0); i < len; ++i) {
6452 stream.getUint8(*(value_p + i));
6453 }
6454#elif defined(BSLS_PLATFORM_IS_LITTLE_ENDIAN)
6455 for (int i(len - 1); i >= 0; --i) {
6456 stream.getUint8(*(value_p + i));
6457 }
6458#endif
6459 if (stream) {
6460 d_value.d_raw = bidVal;
6461 }
6462 else {
6463 stream.invalidate();
6464 }
6465 } break;
6466 default: {
6467 stream.invalidate(); // unrecognized version number
6468 }
6469 }
6470 }
6471 return stream;
6472}
6473
6474inline
6476{
6477 return &d_value;
6478}
6479
6480inline
6482{
6483 return d_value;
6484}
6485
6486 // Aspects
6487
6488template <class STREAM>
6489STREAM& Decimal_Type128::bdexStreamOut(STREAM& stream, int version) const
6490{
6491 if (stream) {
6492 switch (version) { // switch on the schema version
6493 case 1: {
6494 const int len = sizeof(DecimalStorage::Type128)
6495 / sizeof(unsigned char);
6496
6497 const unsigned char *value_p =
6498 reinterpret_cast<const unsigned char *>(&d_value.d_raw);
6499
6500#ifdef BSLS_PLATFORM_IS_BIG_ENDIAN
6501 for (int i(0); i < len; ++i) {
6502 stream.putUint8(*(value_p + i));
6503 }
6504#elif defined(BSLS_PLATFORM_IS_LITTLE_ENDIAN)
6505 for (int i(len - 1); i >= 0; --i) {
6506 stream.putUint8(*(value_p + i));
6507 }
6508#endif
6509 } break;
6510 default: {
6511 stream.invalidate(); // unrecognized version number
6512 }
6513 }
6514 }
6515 return stream;
6516}
6517} // close package namespace
6518
6519
6520// FREE OPERATORS
6521
6522inline
6524{
6525 return value;
6526}
6527
6528inline
6530{
6531 return Decimal32(DecimalImpUtil::negate(value.value()));
6532}
6533
6534inline
6536{
6537 bdldfp::Decimal32 result(value);
6538 ++value;
6539 return result;
6540}
6541
6542inline
6544{
6545 bdldfp::Decimal32 result(value);
6546 --value;
6547 return result;
6548}
6549
6550 // Addition
6551
6552inline
6555{
6556 return DecimalImpUtil::add(*lhs.data(), *rhs.data());
6557}
6558
6559inline
6561 int rhs)
6562{
6563 return Decimal32(lhs + Decimal64(rhs));
6564}
6565
6566inline
6568 unsigned int rhs)
6569{
6570 return Decimal32(lhs + Decimal64(rhs));
6571}
6572
6573inline
6575 long rhs)
6576{
6577 return Decimal32(lhs + Decimal64(rhs));
6578}
6579
6580inline
6582 unsigned long rhs)
6583{
6584 return Decimal32(lhs + Decimal64(rhs));
6585}
6586
6587inline
6589 long long rhs)
6590{
6591 return Decimal32(lhs + Decimal128(rhs));
6592}
6593
6594inline
6596 unsigned long long rhs)
6597{
6598 return Decimal32(lhs + Decimal128(rhs));
6599}
6600
6601inline
6604{
6605 return Decimal32(Decimal64(lhs) + rhs);
6606}
6607
6608inline
6609bdldfp::Decimal32 bdldfp::operator+(unsigned int lhs,
6611{
6612 return Decimal32(Decimal64(lhs) + rhs);
6613}
6614
6615inline
6618{
6619 return Decimal32(Decimal64(lhs) + rhs);
6620}
6621
6622inline
6623bdldfp::Decimal32 bdldfp::operator+(unsigned long lhs,
6625{
6626 return Decimal32(Decimal64(lhs) + rhs);
6627}
6628
6629inline
6632{
6633 return Decimal32(Decimal128(lhs) + rhs);
6634}
6635
6636inline
6637bdldfp::Decimal32 bdldfp::operator+(unsigned long long lhs,
6639{
6640 return Decimal32(Decimal128(lhs) + rhs);
6641}
6642
6643
6644 // Subtraction
6645
6646inline
6649{
6650 return DecimalImpUtil::subtract(*lhs.data(), *rhs.data());
6651}
6652
6653inline
6655 int rhs)
6656{
6657 return Decimal32(lhs - Decimal64(rhs));
6658}
6659
6660inline
6662 unsigned int rhs)
6663{
6664 return Decimal32(lhs - Decimal64(rhs));
6665}
6666
6667inline
6669 long rhs)
6670{
6671 return Decimal32(lhs - Decimal64(rhs));
6672}
6673
6674inline
6676 unsigned long rhs)
6677{
6678 return Decimal32(lhs - Decimal64(rhs));
6679}
6680
6681inline
6683 long long rhs)
6684{
6685 return Decimal32(lhs - Decimal128(rhs));
6686}
6687
6688inline
6690 unsigned long long rhs)
6691{
6692 return Decimal32(lhs - Decimal128(rhs));
6693}
6694
6695inline
6698{
6699 return Decimal32(Decimal64(lhs) - rhs);
6700}
6701
6702inline
6703bdldfp::Decimal32 bdldfp::operator-(unsigned int lhs,
6705{
6706 return Decimal32(Decimal64(lhs) - rhs);
6707}
6708
6709inline
6712{
6713 return Decimal32(Decimal64(lhs) - rhs);
6714}
6715
6716inline
6717bdldfp::Decimal32 bdldfp::operator-(unsigned long lhs,
6719{
6720 return Decimal32(Decimal64(lhs) - rhs);
6721}
6722
6723inline
6726{
6727 return Decimal32(Decimal128(lhs) - Decimal64(rhs));
6728}
6729
6730inline
6731bdldfp::Decimal32 bdldfp::operator-(unsigned long long lhs,
6733{
6734 return Decimal32(Decimal128(lhs) - Decimal64(rhs));
6735}
6736
6737 // Multiplication
6738
6741{
6742 return DecimalImpUtil::multiply(*lhs.data(), *rhs.data());
6743}
6744
6745inline
6747 int rhs)
6748{
6749 return Decimal32(lhs * Decimal64(rhs));
6750}
6751
6752inline
6754 unsigned int rhs)
6755{
6756 return Decimal32(lhs * Decimal64(rhs));
6757}
6758
6759inline
6761 long rhs)
6762{
6763 return Decimal32(lhs * Decimal64(rhs));
6764}
6765
6766inline
6768 unsigned long rhs)
6769{
6770 return Decimal32(lhs * Decimal64(rhs));
6771}
6772
6773inline
6775 long long rhs)
6776{
6777 return Decimal32(lhs * Decimal128(rhs));
6778}
6779
6780inline
6782 unsigned long long rhs)
6783{
6784 return Decimal32(lhs * Decimal128(rhs));
6785}
6786
6787inline
6790{
6791 return Decimal32(Decimal64(lhs) * rhs);
6792}
6793
6794inline
6795bdldfp::Decimal32 bdldfp::operator*(unsigned int lhs,
6797{
6798 return Decimal32(Decimal64(lhs) * rhs);
6799}
6800
6801inline
6804{
6805 return Decimal32(Decimal64(lhs) * rhs);
6806}
6807
6808inline
6809bdldfp::Decimal32 bdldfp::operator*(unsigned long lhs,
6811{
6812 return Decimal32(Decimal64(lhs) * rhs);
6813}
6814
6815inline
6818{
6819 return Decimal32(Decimal128(lhs) * rhs);
6820}
6821
6822inline
6823bdldfp::Decimal32 bdldfp::operator*(unsigned long long lhs,
6825{
6826 return Decimal32(Decimal128(lhs) * rhs);
6827}
6828
6829 // Division
6830
6831inline
6834{
6835 return DecimalImpUtil::divide(*lhs.data(), *rhs.data());
6836}
6837
6838inline
6840 int rhs)
6841{
6842 return Decimal32(lhs / Decimal64(rhs));
6843}
6844
6845inline
6847 unsigned int rhs)
6848{
6849 return Decimal32(lhs / Decimal64(rhs));
6850}
6851
6852inline
6854 long rhs)
6855{
6856 return Decimal32(lhs / Decimal64(rhs));
6857}
6858
6859inline
6861 unsigned long rhs)
6862{
6863 return Decimal32(lhs / Decimal64(rhs));
6864}
6865
6866inline
6868 long long rhs)
6869{
6870 return Decimal32(lhs / Decimal128(rhs));
6871}
6872
6873inline
6875 unsigned long long rhs)
6876{
6877 return Decimal32(lhs / Decimal128(rhs));
6878}
6879
6880inline
6883{
6884 return Decimal32(Decimal64(lhs) / rhs);
6885}
6886
6887inline
6888bdldfp::Decimal32 bdldfp::operator/(unsigned int lhs,
6890{
6891 return Decimal32(Decimal64(lhs) / rhs);
6892}
6893
6894inline
6897{
6898 return Decimal32(Decimal64(lhs) / Decimal64(rhs));
6899}
6900
6901inline
6902bdldfp::Decimal32 bdldfp::operator/(unsigned long lhs,
6904{
6905 return Decimal32(Decimal64(lhs) / rhs);
6906}
6907
6908inline
6911{
6912 return Decimal32(Decimal128(lhs) / rhs);
6913}
6914
6915inline
6916bdldfp::Decimal32 bdldfp::operator/(unsigned long long lhs,
6918{
6919 return Decimal32(Decimal128(lhs) / rhs);
6920}
6921
6922
6923inline
6925{
6926 return DecimalImpUtil::equal(*lhs.data(), *rhs.data());
6927}
6928
6929inline
6931{
6932 return DecimalImpUtil::notEqual(*lhs.data(), *rhs.data());
6933}
6934
6935inline
6937{
6938 return DecimalImpUtil::less(*lhs.data(), *rhs.data());
6939}
6940
6941inline
6943{
6944 return DecimalImpUtil::lessEqual(*lhs.data(), *rhs.data());
6945}
6946
6947inline
6949{
6950 return DecimalImpUtil::greater(*lhs.data(), *rhs.data());
6951}
6952
6953inline
6955{
6956 return DecimalImpUtil::greaterEqual(*lhs.data(), *rhs.data());
6957}
6958
6959#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
6960 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
6961inline
6962bdldfp::Decimal32 bdldfp::DecimalLiterals::operator "" _d32(const char *str)
6963{
6964 return DecimalImpUtil::parse32(str);
6965}
6966
6967inline
6968bdldfp::Decimal32 bdldfp::DecimalLiterals::operator "" _d32(
6969 const char *str, bsl::size_t)
6970{
6971 return DecimalImpUtil::parse32(str);
6972}
6973#endif
6974
6975// FREE OPERATORS
6976inline
6978{
6979 return value;
6980}
6981
6982inline
6984{
6985 return DecimalImpUtil::negate(*value.data());
6986}
6987
6988inline
6990{
6991 bdldfp::Decimal64 result(value);
6992 ++value;
6993 return result;
6994}
6995
6996inline
6998{
6999 bdldfp::Decimal64 result(value);
7000 --value;
7001 return result;
7002}
7003
7004 // Addition
7005
7006inline
7009{
7010 return Decimal64(DecimalImpUtil::add(*lhs.data(), *rhs.data()));
7011}
7012
7013inline
7016{
7017 return Decimal64(lhs) + rhs;
7018}
7019
7020inline
7023{
7024 return lhs + Decimal64(rhs);
7025}
7026
7027inline
7029 int rhs)
7030{
7031 return lhs + Decimal64(rhs);
7032}
7033
7034inline
7036 unsigned int rhs)
7037{
7038 return lhs + Decimal64(rhs);
7039}
7040
7041inline
7043 long rhs)
7044{
7045 return lhs + Decimal64(rhs);
7046}
7047
7048inline
7050 unsigned long rhs)
7051{
7052 return lhs + Decimal64(rhs);
7053}
7054
7055inline
7057 long long rhs)
7058{
7059 return Decimal64(lhs + Decimal128(rhs));
7060}
7061
7062inline
7064 unsigned long long rhs)
7065{
7066 return Decimal64(lhs + Decimal128(rhs));
7067}
7068
7069inline
7072{
7073 return Decimal64(lhs) + rhs;
7074}
7075
7076inline
7077bdldfp::Decimal64 bdldfp::operator+(unsigned int lhs,
7079{
7080 return Decimal64(lhs) + rhs;
7081}
7082
7083inline
7086{
7087 return Decimal64(lhs) + rhs;
7088}
7089
7090inline
7091bdldfp::Decimal64 bdldfp::operator+(unsigned long lhs,
7093{
7094 return Decimal64(lhs) + rhs;
7095}
7096
7097inline
7100{
7101 return Decimal64(Decimal128(lhs) + rhs);
7102}
7103
7104inline
7105bdldfp::Decimal64 bdldfp::operator+(unsigned long long lhs,
7107{
7108 return Decimal64(Decimal128(lhs) + rhs);
7109}
7110
7111 // Subtraction
7112
7113inline
7116{
7117 return Decimal64(DecimalImpUtil::subtract(*lhs.data(), *rhs.data()));
7118}
7119
7120inline
7123{
7124 return Decimal64(lhs) - rhs;
7125}
7126
7127inline
7130{
7131 return lhs - Decimal64(rhs);
7132}
7133
7134inline
7136 int rhs)
7137{
7138 return lhs - Decimal64(rhs);
7139}
7140
7141inline
7143 unsigned int rhs)
7144{
7145 return lhs - Decimal64(rhs);
7146}
7147
7148inline
7150 long rhs)
7151{
7152 return lhs - Decimal64(rhs);
7153}
7154
7155inline
7157 unsigned long rhs)
7158{
7159 return lhs - Decimal64(rhs);
7160}
7161
7162inline
7164 long long rhs)
7165{
7166 return Decimal64(lhs - Decimal128(rhs));
7167}
7168
7169inline
7171 unsigned long long rhs)
7172{
7173 return Decimal64(lhs - Decimal128(rhs));
7174}
7175
7176inline
7179{
7180 return Decimal64(lhs) - rhs;
7181}
7182
7183inline
7184bdldfp::Decimal64 bdldfp::operator-(unsigned int lhs,
7186{
7187 return Decimal64(lhs) - rhs;
7188}
7189
7190inline
7193{
7194 return Decimal64(lhs) - rhs;
7195}
7196
7197inline
7198bdldfp::Decimal64 bdldfp::operator-(unsigned long lhs,
7200{
7201 return Decimal64(lhs) - rhs;
7202}
7203
7204inline
7207{
7208 return Decimal64(Decimal128(lhs) - rhs);
7209}
7210
7211inline
7212bdldfp::Decimal64 bdldfp::operator-(unsigned long long lhs,
7214{
7215 return Decimal64(Decimal128(lhs) - rhs);
7216}
7217
7218 // Multiplication
7219
7222{
7223 return Decimal64(DecimalImpUtil::multiply(*lhs.data(), *rhs.data()));
7224}
7225
7228{
7229 return Decimal64(lhs) * rhs;
7230}
7231
7234{
7235 return lhs * Decimal64(rhs);
7236}
7237
7239 int rhs)
7240{
7241 return lhs * Decimal64(rhs);
7242}
7243
7245 unsigned int rhs)
7246{
7247 return lhs * Decimal64(rhs);
7248}
7249
7251 long rhs)
7252{
7253 return lhs * Decimal64(rhs);
7254}
7255
7257 unsigned long rhs)
7258{
7259 return lhs * Decimal64(rhs);
7260}
7261
7263 long long rhs)
7264{
7265 return Decimal64(lhs * Decimal128(rhs));
7266}
7267
7269 unsigned long long rhs)
7270{
7271 return Decimal64(lhs * Decimal128(rhs));
7272}
7273
7276{
7277 return Decimal64(lhs) * rhs;
7278}
7279
7280inline bdldfp::Decimal64 bdldfp::operator*(unsigned int lhs,
7282{
7283 return Decimal64(lhs) * rhs;
7284}
7285
7286inline bdldfp::Decimal64 bdldfp::operator*(long lhs,
7288{
7289 return Decimal64(lhs) * rhs;
7290}
7291
7292inline bdldfp::Decimal64 bdldfp::operator*(unsigned long lhs,
7294{
7295 return Decimal64(lhs) * rhs;
7296}
7297
7298inline bdldfp::Decimal64 bdldfp::operator*(long long lhs,
7300{
7301 return Decimal64(Decimal128(lhs) * rhs);
7302}
7303
7304inline bdldfp::Decimal64 bdldfp::operator*(unsigned long long lhs,
7306{
7307 return Decimal64(Decimal128(lhs) * rhs);
7308}
7309
7310 // Division
7311
7314{
7315 return Decimal64(DecimalImpUtil::divide(*lhs.data(), *rhs.data()));
7316}
7317
7320{
7321 return Decimal64(lhs) / rhs;
7322}
7323
7326{
7327 return lhs / Decimal64(rhs);
7328}
7329
7331 int rhs)
7332{
7333 return lhs / Decimal64(rhs);
7334}
7335
7337 unsigned int rhs)
7338{
7339 return lhs / Decimal64(rhs);
7340}
7341
7343 long rhs)
7344{
7345 return lhs / Decimal64(rhs);
7346}
7347
7349 unsigned long rhs)
7350{
7351 return lhs / Decimal64(rhs);
7352}
7353
7355 long long rhs)
7356{
7357 return Decimal64(lhs / Decimal128(rhs));
7358}
7359
7361 unsigned long long rhs)
7362{
7363 return Decimal64(lhs / Decimal128(rhs));
7364}
7365
7368{
7369 return Decimal64(lhs) / rhs;
7370}
7371
7372inline bdldfp::Decimal64 bdldfp::operator/(unsigned int lhs,
7374{
7375 return Decimal64(lhs) / rhs;
7376}
7377
7378inline bdldfp::Decimal64 bdldfp::operator/(long lhs,
7380{
7381 return Decimal64(lhs) / rhs;
7382}
7383
7384inline bdldfp::Decimal64 bdldfp::operator/(unsigned long lhs,
7386{
7387 return Decimal64(lhs) / rhs;
7388}
7389
7390inline bdldfp::Decimal64 bdldfp::operator/(long long lhs,
7392{
7393 return Decimal64(Decimal128(lhs) / rhs);
7394}
7395
7396inline bdldfp::Decimal64 bdldfp::operator/(unsigned long long lhs,
7398{
7399 return Decimal64(Decimal128(lhs) / rhs);
7400}
7401
7402 // Equality
7403
7405{
7406 return DecimalImpUtil::equal(*lhs.data(), *rhs.data());
7407}
7408
7410{
7411 return Decimal64(lhs) == rhs;
7412}
7413
7415{
7416 return lhs == Decimal64(rhs);
7417}
7418
7419 // Inequality
7420
7422{
7423 return DecimalImpUtil::notEqual(*lhs.data(), *rhs.data());
7424}
7425
7427{
7428 return Decimal64(lhs) != rhs;
7429}
7430
7432{
7433 return lhs != Decimal64(rhs);
7434}
7435
7436 // Less Than
7437
7439{
7440 return DecimalImpUtil::less(*lhs.data(), *rhs.data());
7441}
7442
7444{
7445 return Decimal64(lhs) < rhs;
7446}
7447
7449{
7450 return lhs < Decimal64(rhs);
7451}
7452
7453 // Less Equal
7454
7456{
7457 return DecimalImpUtil::lessEqual(*lhs.data(), *rhs.data());
7458}
7459
7461{
7462 return Decimal64(lhs) <= rhs;
7463}
7464
7466{
7467 return lhs <= Decimal64(rhs);
7468}
7469
7470 // Greater Than
7471
7473{
7474 return DecimalImpUtil::greater(*lhs.data(), *rhs.data());
7475}
7476
7478{
7479 return Decimal64(lhs) > rhs;
7480}
7481
7483{
7484 return lhs > Decimal64(rhs);
7485}
7486
7487 // Greater Equal
7488
7490{
7491 return DecimalImpUtil::greaterEqual(*lhs.data(), *rhs.data());
7492}
7493
7495{
7496 return Decimal64(lhs) >= rhs;
7497}
7498
7500{
7501 return lhs >= Decimal64(rhs);
7502}
7503
7504#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
7505 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
7506inline
7507bdldfp::Decimal64 bdldfp::DecimalLiterals::operator "" _d64(const char *str)
7508{
7509 return DecimalImpUtil::parse64(str);
7510}
7511
7512inline
7513bdldfp::Decimal64 bdldfp::DecimalLiterals::operator "" _d64(
7514 const char *str, bsl::size_t)
7515{
7516 return DecimalImpUtil::parse64(str);
7517}
7518#endif
7519
7520// FREE OPERATORS
7521
7522inline
7524{
7525 return value;
7526}
7527
7528inline
7530{
7531 return Decimal128(DecimalImpUtil::negate(*value.data()));
7532}
7533
7534inline
7536{
7537 Decimal128 result = value;
7538 ++value;
7539 return result;
7540}
7541
7542inline
7544{
7545 Decimal128 result = value;
7546 --value;
7547 return result;
7548}
7549
7550 // Addition
7551
7552inline
7555{
7556 return Decimal128(DecimalImpUtil::add(*lhs.data(), *rhs.data()));
7557}
7558
7559inline
7562{
7563 return Decimal128(lhs) + rhs;
7564}
7565
7566inline
7569{
7570 return lhs + Decimal128(rhs);
7571}
7572
7573inline
7576{
7577 return Decimal128(lhs) + rhs;
7578}
7579
7580inline
7583{
7584 return lhs + Decimal128(rhs);
7585}
7586
7587inline
7589 int rhs)
7590{
7591 return lhs + Decimal128(rhs);
7592}
7593
7594inline
7596 unsigned int rhs)
7597{
7598 return lhs + Decimal128(rhs);
7599}
7600
7601inline
7603 long rhs)
7604{
7605 return lhs + Decimal128(rhs);
7606}
7607
7608inline
7610 unsigned long rhs)
7611{
7612 return lhs + Decimal128(rhs);
7613}
7614
7615inline
7617 long long rhs)
7618{
7619 return lhs + Decimal128(rhs);
7620}
7621
7622inline
7624 unsigned long long rhs)
7625{
7626 return lhs + Decimal128(rhs);
7627}
7628
7629inline
7632{
7633 return Decimal128(lhs) + rhs;
7634}
7635
7636inline
7637bdldfp::Decimal128 bdldfp::operator+(unsigned int lhs,
7639{
7640 return Decimal128(lhs) + rhs;
7641}
7642
7643inline
7646{
7647 return Decimal128(lhs) + rhs;
7648}
7649
7650inline
7651bdldfp::Decimal128 bdldfp::operator+(unsigned long lhs,
7653{
7654 return Decimal128(lhs) + rhs;
7655}
7656
7657inline
7660{
7661 return Decimal128(lhs) + rhs;
7662}
7663
7664inline
7665bdldfp::Decimal128 bdldfp::operator+(unsigned long long lhs,
7667{
7668 return Decimal128(lhs) + rhs;
7669}
7670
7671 // Subtraction
7672
7673inline
7676{
7677 return Decimal128(DecimalImpUtil::subtract(*lhs.data(), *rhs.data()));
7678}
7679
7680inline
7683{
7684 return Decimal128(lhs) - rhs;
7685}
7686
7687inline
7690{
7691 return lhs - Decimal128(rhs);
7692}
7693
7694inline
7697{
7698 return Decimal128(lhs) - rhs;
7699}
7700
7701inline
7704{
7705 return lhs - Decimal128(rhs);
7706}
7707
7708inline
7710 int rhs)
7711{
7712 return lhs - Decimal128(rhs);
7713}
7714
7715inline
7717 unsigned int rhs)
7718{
7719 return lhs - Decimal128(rhs);
7720}
7721
7722inline
7724 long rhs)
7725{
7726 return lhs - Decimal128(rhs);
7727}
7728
7729inline
7731 unsigned long rhs)
7732{
7733 return lhs - Decimal128(rhs);
7734}
7735
7736inline
7738 long long rhs)
7739{
7740 return lhs - Decimal128(rhs);
7741}
7742
7743inline
7745 unsigned long long rhs)
7746{
7747 return lhs - Decimal128(rhs);
7748}
7749
7750inline
7753{
7754 return Decimal128(lhs) - rhs;
7755}
7756
7757inline
7758bdldfp::Decimal128 bdldfp::operator-(unsigned int lhs,
7760{
7761 return Decimal128(lhs) - rhs;
7762}
7763
7764inline
7767{
7768 return Decimal128(lhs) - rhs;
7769}
7770
7771inline
7772bdldfp::Decimal128 bdldfp::operator-(unsigned long lhs,
7774{
7775 return Decimal128(lhs) - rhs;
7776}
7777
7778inline
7781{
7782 return Decimal128(lhs) - rhs;
7783}
7784
7785inline
7786bdldfp::Decimal128 bdldfp::operator-(unsigned long long lhs,
7788{
7789 return Decimal128(lhs) - rhs;
7790}
7791
7792 // Multiplication
7793
7794inline
7797{
7798 return Decimal128(DecimalImpUtil::multiply(*lhs.data(), *rhs.data()));
7799}
7800
7801inline
7804{
7805 return Decimal128(lhs) * rhs;
7806}
7807
7808inline
7811{
7812 return lhs * Decimal128(rhs);
7813}
7814
7815inline
7818{
7819 return Decimal128(lhs) * rhs;
7820}
7821
7822inline
7825{
7826 return lhs * Decimal128(rhs);
7827}
7828
7829inline
7831 int rhs)
7832{
7833 return lhs * Decimal128(rhs);
7834}
7835
7836inline
7838 unsigned int rhs)
7839{
7840 return lhs * Decimal128(rhs);
7841}
7842
7843inline
7845 long rhs)
7846{
7847 return lhs * Decimal128(rhs);
7848}
7849
7850inline
7852 unsigned long rhs)
7853{
7854 return lhs * Decimal128(rhs);
7855}
7856
7857inline
7859 long long rhs)
7860{
7861 return lhs * Decimal128(rhs);
7862}
7863
7864inline
7866 unsigned long long rhs)
7867{
7868 return lhs * Decimal128(rhs);
7869}
7870
7871inline
7874{
7875 return Decimal128(lhs) * rhs;
7876}
7877
7878inline
7879bdldfp::Decimal128 bdldfp::operator*(unsigned int lhs,
7881{
7882 return Decimal128(lhs) * rhs;
7883}
7884
7885inline
7888{
7889 return Decimal128(lhs) * rhs;
7890}
7891
7892inline
7893bdldfp::Decimal128 bdldfp::operator*(unsigned long lhs,
7895{
7896 return Decimal128(lhs) * rhs;
7897}
7898
7899inline
7902{
7903 return Decimal128(lhs) * rhs;
7904}
7905
7906inline
7907bdldfp::Decimal128 bdldfp::operator*(unsigned long long lhs,
7909{
7910 return Decimal128(lhs) * rhs;
7911}
7912
7913 // Division
7914
7915inline
7918{
7919 return Decimal128(DecimalImpUtil::divide(*lhs.data(), *rhs.data()));
7920}
7921
7922inline
7925{
7926 return Decimal128(lhs) / rhs;
7927}
7928
7929inline
7932{
7933 return lhs / Decimal128(rhs);
7934}
7935
7936inline
7939{
7940 return Decimal128(lhs) / rhs;
7941}
7942
7943inline
7946{
7947 return lhs / Decimal128(rhs);
7948}
7949
7950inline
7952 int rhs)
7953{
7954 return lhs / Decimal128(rhs);
7955}
7956
7957inline
7959 unsigned int rhs)
7960{
7961 return lhs / Decimal128(rhs);
7962}
7963
7964inline
7966 long rhs)
7967{
7968 return lhs / Decimal128(rhs);
7969}
7970
7971inline
7973 unsigned long rhs)
7974{
7975 return lhs / Decimal128(rhs);
7976}
7977
7978inline
7980 long long rhs)
7981{
7982 return lhs / Decimal128(rhs);
7983}
7984
7985inline
7987 unsigned long long rhs)
7988{
7989 return lhs / Decimal128(rhs);
7990}
7991
7992inline
7995{
7996 return Decimal128(lhs) / rhs;
7997}
7998
7999inline
8000bdldfp::Decimal128 bdldfp::operator/(unsigned int lhs,
8002{
8003 return Decimal128(lhs) / rhs;
8004}
8005
8006inline
8009{
8010 return Decimal128(lhs) / rhs;
8011}
8012
8013inline
8014bdldfp::Decimal128 bdldfp::operator/(unsigned long lhs,
8016{
8017 return Decimal128(lhs) / rhs;
8018}
8019
8020inline
8023{
8024 return Decimal128(lhs) / rhs;
8025}
8026
8027inline
8028bdldfp::Decimal128 bdldfp::operator/(unsigned long long lhs,
8030{
8031 return Decimal128(lhs) / rhs;
8032}
8033
8034 // Equality
8035
8036inline
8038{
8039 return DecimalImpUtil::equal(*lhs.data(), *rhs.data());
8040}
8041
8042inline
8044{
8045 return Decimal128(lhs) == rhs;
8046}
8047
8048inline
8050{
8051 return lhs == Decimal128(rhs);
8052}
8053
8054inline
8056{
8057 return Decimal128(lhs) == rhs;
8058}
8059
8060inline
8062{
8063 return lhs == Decimal128(rhs);
8064}
8065
8066 // Inequality
8067
8068inline
8070{
8071 return DecimalImpUtil::notEqual(*lhs.data(), *rhs.data());
8072}
8073
8074inline
8076{
8077 return Decimal128(lhs) != rhs;
8078}
8079
8080inline
8082{
8083 return lhs != Decimal128(rhs);
8084}
8085
8086inline
8088{
8089 return Decimal128(lhs) != rhs;
8090}
8091
8092inline
8094{
8095 return lhs != Decimal128(rhs);
8096}
8097
8098 // Less Than
8099
8100inline
8102{
8103 return DecimalImpUtil::less(*lhs.data(), *rhs.data());
8104}
8105
8106inline
8108{
8109 return Decimal128(lhs) < rhs;
8110}
8111
8112inline
8114{
8115 return lhs < Decimal128(rhs);
8116}
8117
8118inline
8120{
8121 return Decimal128(lhs) < rhs;
8122}
8123
8124inline
8126{
8127 return lhs < Decimal128(rhs);
8128}
8129
8130 // Less Equal
8131
8132inline
8134{
8135 return DecimalImpUtil::lessEqual(*lhs.data(), *rhs.data());
8136}
8137
8138inline
8140{
8141 return Decimal128(lhs) <= rhs;
8142}
8143
8144inline
8146{
8147 return lhs <= Decimal128(rhs);
8148}
8149
8150inline
8152{
8153 return Decimal128(lhs) <= rhs;
8154}
8155
8156inline
8158{
8159 return lhs <= Decimal128(rhs);
8160}
8161
8162 // Greater
8163
8164inline
8166{
8167 return DecimalImpUtil::greater(*lhs.data(), *rhs.data());
8168}
8169
8170inline
8172{
8173 return Decimal128(lhs) > rhs;
8174}
8175
8176inline
8178{
8179 return lhs > Decimal128(rhs);
8180}
8181
8182inline
8184{
8185 return Decimal128(lhs) > rhs;
8186}
8187
8188inline
8190{
8191 return lhs > Decimal128(rhs);
8192}
8193
8194 // Greater Equal
8195
8196inline
8198{
8199 return DecimalImpUtil::greaterEqual(*lhs.data(), *rhs.data());
8200}
8201
8202inline
8204{
8205 return Decimal128(lhs) >= rhs;
8206}
8207
8208inline
8210{
8211 return lhs >= Decimal128(rhs);
8212}
8213
8214inline
8216{
8217 return Decimal128(lhs) >= rhs;
8218}
8219
8220inline
8222{
8223 return lhs >= Decimal128(rhs);
8224}
8225
8226#if defined(BSLS_COMPILERFEATURES_SUPPORT_INLINE_NAMESPACE) && \
8227 defined(BSLS_COMPILERFEATURES_SUPPORT_USER_DEFINED_LITERALS)
8228inline
8229bdldfp::Decimal128 bdldfp::DecimalLiterals::operator "" _d128(const char *str)
8230{
8231 return DecimalImpUtil::parse128(str);
8232}
8233
8234inline
8235bdldfp::Decimal128 bdldfp::DecimalLiterals::operator "" _d128(
8236 const char *str, bsl::size_t)
8237{
8238 return DecimalImpUtil::parse128(str);
8239}
8240#endif
8241
8242// FREE FUNCTIONS
8243template <class HASHALG>
8244inline
8245void bdldfp::hashAppend(HASHALG& hashAlg, const bdldfp::Decimal32& object)
8246{
8247 using ::BloombergLP::bslh::hashAppend;
8248
8250 object.value());
8251 hashAlg(&normalizedObject, sizeof(normalizedObject));
8252}
8253
8254template <class HASHALG>
8255inline
8256void bdldfp::hashAppend(HASHALG& hashAlg, const bdldfp::Decimal64& object)
8257{
8258 using ::BloombergLP::bslh::hashAppend;
8259
8261 object.value());
8262
8263 hashAlg(&normalizedObject, sizeof(normalizedObject));
8264}
8265
8266template <class HASHALG>
8267inline
8268void bdldfp::hashAppend(HASHALG& hashAlg, const bdldfp::Decimal128& object)
8269{
8270 using ::BloombergLP::bslh::hashAppend;
8271
8273 object.value());
8274
8275 hashAlg(&normalizedObject, sizeof(normalizedObject));
8276}
8277
8278
8279
8280#endif
8281
8282// ----------------------------------------------------------------------------
8283// Copyright 2014 Bloomberg Finance L.P.
8284//
8285// Licensed under the Apache License, Version 2.0 (the "License");
8286// you may not use this file except in compliance with the License.
8287// You may obtain a copy of the License at
8288//
8289// http://www.apache.org/licenses/LICENSE-2.0
8290//
8291// Unless required by applicable law or agreed to in writing, software
8292// distributed under the License is distributed on an "AS IS" BASIS,
8293// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8294// See the License for the specific language governing permissions and
8295// limitations under the License.
8296// ----------------------------- END-OF-FILE ----------------------------------
8297
8298/** @} */
8299/** @} */
8300/** @} */
Definition bdldfp_decimalimputil.h:238
static ValueType32 normalize(ValueType32 original)
static bool lessEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2758
static ValueType64 parse64(const char *input)
Definition bdldfp_decimalimputil.h:3101
static ValueType32 parse32(const char *input)
Definition bdldfp_decimalimputil.h:3094
static bool notEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2836
static bool less(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2706
Imp::ValueType64 ValueType64
Definition bdldfp_decimalimputil.h:250
static bool greater(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2732
static ValueType32 multiply(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1670
static ValueType32 divide(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1698
Imp::ValueType128 ValueType128
Definition bdldfp_decimalimputil.h:251
static ValueType128 parse128(const char *input)
Definition bdldfp_decimalimputil.h:3108
static ValueType32 subtract(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1644
static bool equal(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2810
static ValueType32 negate(ValueType32 value)
Definition bdldfp_decimalimputil.h:2681
static bool greaterEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2784
static ValueType32 add(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1619
Imp::ValueType32 ValueType32
Definition bdldfp_decimalimputil.h:249
Definition bdldfp_decimal.h:4178
~DecimalNumGet() BSLS_KEYWORD_OVERRIDE
Destroy this object. Note that the destructor is virtual.
INPUTITERATOR iter_type
Definition bdldfp_decimal.h:4201
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:4198
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:4200
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:4284
Definition bdldfp_decimal.h:4464
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:4487
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:4486
~DecimalNumPut() BSLS_KEYWORD_OVERRIDE
Destroy this object. Note that the destructor is virtual.
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:4484
Definition bdldfp_decimal.h:4575
Definition bdldfp_decimal.h:3023
Decimal_Type128 & operator++()
Definition bdldfp_decimal.h:6185
Decimal_Type128 & operator/=(Decimal32 rhs)
Definition bdldfp_decimal.h:6372
Decimal_Type128()
Definition bdldfp_decimal.h:6117
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdldfp_decimal.h:6438
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdldfp_decimal.h:6489
Decimal_Type128 & operator*=(Decimal32 rhs)
Definition bdldfp_decimal.h:6314
Decimal128_Type & operator=(const Decimal128_Type &rhs)=default
static int maxSupportedBdexVersion()
Definition bdldfp_decimal.h:6104
Decimal_Type128 & operator+=(Decimal32 rhs)
Definition bdldfp_decimal.h:6199
Decimal_Type128 & operator--()
Definition bdldfp_decimal.h:6191
DecimalImpUtil::ValueType128 * data()
Return a modifiable pointer to the underlying implementation.
Definition bdldfp_decimal.h:6430
Decimal128_Type(const Decimal128_Type &original)=default
Decimal_Type128 & operator-=(Decimal32 rhs)
Definition bdldfp_decimal.h:6256
DecimalImpUtil::ValueType128 value() const
Return the value of the underlying implementation.
Definition bdldfp_decimal.h:6481
BSLMF_NESTED_TRAIT_DECLARATION(Decimal_Type128, bsl::is_trivially_copyable)
Definition bdldfp_decimal.h:730
Decimal_Type32 & operator-=(Decimal32 rhs)
Definition bdldfp_decimal.h:5524
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdldfp_decimal.h:5676
DecimalImpUtil::ValueType32 * data()
Definition bdldfp_decimal.h:5668
Decimal_Type32 & operator--()
Definition bdldfp_decimal.h:5469
Decimal_Type32()
Definition bdldfp_decimal.h:5389
Decimal32_Type(const Decimal32_Type &original)=default
DecimalImpUtil::ValueType32 value() const
Return the value of the underlying implementation.
Definition bdldfp_decimal.h:5706
Decimal_Type32 & operator++()
Definition bdldfp_decimal.h:5464
Decimal_Type32 & operator+=(Decimal32 rhs)
Definition bdldfp_decimal.h:5476
Decimal32_Type & operator=(const Decimal32_Type &rhs)=default
static int maxSupportedBdexVersion()
Definition bdldfp_decimal.h:5376
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdldfp_decimal.h:5714
Decimal_Type32 & operator*=(Decimal32 rhs)
Definition bdldfp_decimal.h:5572
BSLMF_NESTED_TRAIT_DECLARATION(Decimal_Type32, bsl::is_trivially_copyable)
Decimal_Type32 & operator/=(Decimal32 rhs)
Definition bdldfp_decimal.h:5620
Definition bdldfp_decimal.h:1834
Decimal_Type64 & operator*=(Decimal32 rhs)
Definition bdldfp_decimal.h:5938
Decimal_Type64 & operator+=(Decimal32 rhs)
Definition bdldfp_decimal.h:5842
Decimal_Type64 & operator/=(Decimal32 rhs)
Definition bdldfp_decimal.h:5986
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdldfp_decimal.h:6081
DecimalImpUtil::ValueType64 value() const
Return the value of the underlying implementation.
Definition bdldfp_decimal.h:6073
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdldfp_decimal.h:6035
Decimal64_Type & operator=(const Decimal64_Type &rhs)=default
Decimal_Type64 & operator++()
Definition bdldfp_decimal.h:5830
static int maxSupportedBdexVersion()
Definition bdldfp_decimal.h:5737
BSLMF_NESTED_TRAIT_DECLARATION(Decimal_Type64, bsl::is_trivially_copyable)
Decimal_Type64()
Definition bdldfp_decimal.h:5750
Decimal64_Type(const Decimal64_Type &original)=default
Decimal_Type64 & operator--()
Definition bdldfp_decimal.h:5835
DecimalImpUtil::ValueType64 * data()
Return a modifiable pointer to the underlying implementation.
Definition bdldfp_decimal.h:6063
Decimal_Type64 & operator-=(Decimal32 rhs)
Definition bdldfp_decimal.h:5890
Definition bdldfp_decimal.h:4585
Definition bslma_allocator.h:457
virtual void deallocate(void *address)=0
virtual void * allocate(size_type size)=0
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 BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition bdldfp_decimal.h:712
Decimal_Type128 Decimal128
Definition bdldfp_decimal.h:719
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:714
void hashAppend(HASHALG &hashAlg, const Decimal32 &object)
Decimal32 operator--(Decimal32 &value, int)
Decimal_Type64 Decimal64
Definition bdldfp_decimal.h:715
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 bdlb_printmethods.h:283
Definition bdldfp_decimal.h:5188
BID_UINT128 Type128
Definition bdldfp_decimalstorage.h:84
BID_UINT64 Type64
Definition bdldfp_decimalstorage.h:83
BID_UINT32 Type32
Definition bdldfp_decimalstorage.h:82
Definition bslmf_istriviallycopyable.h:329
static Allocator * allocator(Allocator *basicAllocator=0)
Definition bslma_default.h:897