BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdldfp_decimalimputil.h
Go to the documentation of this file.
1/// @file bdldfp_decimalimputil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdldfp_decimalimputil.h -*-C++-*-
8
9#ifndef INCLUDED_BDLDFP_DECIMALIMPUTIL
10#define INCLUDED_BDLDFP_DECIMALIMPUTIL
11
12#include <bsls_ident.h>
13BSLS_IDENT("$Id$")
14
15/// @defgroup bdldfp_decimalimputil bdldfp_decimalimputil
16/// @brief Provide a unified low-level interface for decimal floating point.
17/// @addtogroup bdl
18/// @{
19/// @addtogroup bdldfp
20/// @{
21/// @addtogroup bdldfp_decimalimputil
22/// @{
23///
24/// <h1> Outline </h1>
25/// * <a href="#bdldfp_decimalimputil-purpose"> Purpose</a>
26/// * <a href="#bdldfp_decimalimputil-classes"> Classes </a>
27/// * <a href="#bdldfp_decimalimputil-description"> Description </a>
28/// * <a href="#bdldfp_decimalimputil-usage"> Usage </a>
29/// * <a href="#bdldfp_decimalimputil-example-1-constructing-a-representation-of-a-value-in-decimal"> Example 1: Constructing a Representation of a Value in Decimal </a>
30/// * <a href="#bdldfp_decimalimputil-example-2-adding-two-decimal-floating-point-values"> Example 2: Adding Two Decimal Floating Point Values </a>
31///
32/// # Purpose {#bdldfp_decimalimputil-purpose}
33/// Provide a unified low-level interface for decimal floating point.
34///
35/// # Classes {#bdldfp_decimalimputil-classes}
36///
37/// - bdldfp::DecimalImpUtil: Unified low-level decimal floating point functions.
38///
39/// @see bdldfp_decimalimputil_inteldfp
40///
41/// # Description {#bdldfp_decimalimputil-description}
42/// This component provides a namespace, `bdldfp::DecimalImpUtil`,
43/// containing primitive utilities used in the implementation of a decimal
44/// floating point type (e.g., see @ref bdldfp_decimal ).
45///
46/// ## Usage {#bdldfp_decimalimputil-usage}
47///
48///
49/// This section shows the intended use of this component.
50///
51/// ### Example 1: Constructing a Representation of a Value in Decimal {#bdldfp_decimalimputil-example-1-constructing-a-representation-of-a-value-in-decimal}
52///
53///
54/// A common requirement for decimal floating point types is to be able to
55/// create a value from independent "coefficient" and "exponent" values, where
56/// the resulting decimal has the value `coefficient * 10 ^ exponent`. In the
57/// following example we use such a `coefficient` and `exponent` to create
58/// `Decimal32`, `Decimal64`, and `Decimal128` values.
59///
60/// First we define values representing the `coefficient` and `exponent` (note
61/// the result should be the value 42.5):
62/// @code
63/// int coefficient = 425; // Yet another name for significand
64/// int exponent = -1;
65/// @endcode
66/// Then we call `makeDecimal32`, `makeDecimal64`, and `makeDecimal128` to
67/// construct a `Decimal32`, `Decimal64`, and `Decimal128` respectively.
68/// @code
69/// bdldfp::DecimalImpUtil::ValueType32 d32 =
70/// bdldfp::DecimalImpUtil::makeDecimalRaw32( coefficient, exponent);
71/// bdldfp::DecimalImpUtil::ValueType64 d64 =
72/// bdldfp::DecimalImpUtil::makeDecimalRaw64( coefficient, exponent);
73/// bdldfp::DecimalImpUtil::ValueType128 d128 =
74/// bdldfp::DecimalImpUtil::makeDecimalRaw128(coefficient, exponent);
75///
76/// ASSERT(bdldfp::DecimalImpUtil::equal(
77/// bdldfp::DecimalImpUtil::binaryToDecimal32( 42.5), d32));
78/// ASSERT(bdldfp::DecimalImpUtil::equal(
79/// bdldfp::DecimalImpUtil::binaryToDecimal64( 42.5), d64));
80/// ASSERT(bdldfp::DecimalImpUtil::equal(
81/// bdldfp::DecimalImpUtil::binaryToDecimal128(42.5), d128));
82/// @endcode
83///
84/// ### Example 2: Adding Two Decimal Floating Point Values {#bdldfp_decimalimputil-example-2-adding-two-decimal-floating-point-values}
85///
86///
87/// Decimal floating point values are frequently used in arithmetic computations
88/// where the precise representation of decimal values is of paramount
89/// importance (for example, financial calculations, as currency is typically
90/// denominated in base-10 decimal values). In the following example we
91/// demonstrate computing the sum of a sequence of security prices, where each
92/// price is held in a `DecimalImpUtil::ValueType64` value.
93///
94/// First, we define the signature of a function that computes the sum of an
95/// array of security prices, and returns that sum as a decimal floating point
96/// value:
97/// @code
98/// /// Return a Decimal Floating Point number representing the arithmetic
99/// /// total of the values specified by `prices` and `numPrices`.
100/// bdldfp::DecimalImpUtil::ValueType64
101/// totalSecurities(bdldfp::DecimalImpUtil::ValueType64 *prices,
102/// int numPrices)
103/// {
104/// @endcode
105/// Then, we create a local variable to hold the intermediate sum, and set it to
106/// 0:
107/// @code
108/// bdldfp::DecimalImpUtil::ValueType64 total;
109/// total = bdldfp::DecimalImpUtil::int32ToDecimal64(0);
110/// @endcode
111/// Next, we loop over the array of `prices` and add each price to the
112/// intermediate `total`:
113/// @code
114/// for (int i = 0; i < numPrices; ++i) {
115/// total = bdldfp::DecimalImpUtil::add(total, prices[i]);
116/// }
117/// @endcode
118/// Now, we return the computed total value of the securities:
119/// @code
120/// return total;
121/// }
122/// @endcode
123/// Notice that `add` is called as a function, and is not an operator overload
124/// for `+`; this is because the `bdldfp::DecimalImpUtil` utility is intended to
125/// be used in the implementation of operator overloads on a more full fledged
126/// type.
127///
128/// Finally, we call the function with some sample data, and check the result:
129/// @code
130/// bdldfp::DecimalImpUtil::ValueType64 data[16];
131///
132/// for (int i = 0; i < 16; ++i) {
133/// data[i] = bdldfp::DecimalImpUtil::int32ToDecimal64(i + 1);
134/// }
135///
136/// bdldfp::DecimalImpUtil::ValueType64 result;
137/// result = totalSecurities(data, 16);
138///
139/// bdldfp::DecimalImpUtil::ValueType64 expected;
140///
141/// expected = bdldfp::DecimalImpUtil::int32ToDecimal64(16);
142///
143/// // Totals of values from 1 to 'x' are '(x * x + x) / 2':
144///
145/// expected = bdldfp::DecimalImpUtil::add(
146/// bdldfp::DecimalImpUtil::multiply(expected, expected),
147/// expected);
148/// expected = bdldfp::DecimalImpUtil::divide(
149/// expected,
150/// bdldfp::DecimalImpUtil::int32ToDecimal64(2));
151///
152/// assert(bdldfp::DecimalImpUtil::equal(expected, result));
153/// @endcode
154/// Notice that arithmetic is unwieldy and hard to visualize. This is by
155/// design, as the DecimalImpUtil and subordinate components are not intended
156/// for public consumption, or direct use in decimal arithmetic.
157/// @}
158/** @} */
159/** @} */
160
161/** @addtogroup bdl
162 * @{
163 */
164/** @addtogroup bdldfp
165 * @{
166 */
167/** @addtogroup bdldfp_decimalimputil
168 * @{
169 */
170
171#include <bdlscm_version.h>
172
178#include <bdldfp_uint128.h>
179
180#include <bslmf_assert.h>
181
182#include <bsls_assert.h>
183#include <bsls_keyword.h>
184#include <bsls_types.h>
185
186#include <bsl_algorithm.h>
187#include <bsl_cmath.h>
188#include <bsl_c_errno.h>
189#include <bsl_iostream.h>
190
191#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
192#include <bsl_c_signal.h> // Formerly transitively included via decContext.h
193#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
194
195#ifdef BDLDFP_DECIMALPLATFORM_SOFTWARE
196
197 // DECIMAL FLOATING-POINT LITERAL EMULATION
198
199
200#define BDLDFP_DECIMALIMPUTIL_DF(lit) \
201 BloombergLP::bdldfp::DecimalImpUtil::parse32( \
202 (BloombergLP::bdldfp::DecimalImpUtil::checkLiteral(lit), #lit))
203
204#define BDLDFP_DECIMALIMPUTIL_DD(lit) \
205 BloombergLP::bdldfp::DecimalImpUtil::parse64( \
206 (BloombergLP::bdldfp::DecimalImpUtil::checkLiteral(lit), #lit))
207
208#define BDLDFP_DECIMALIMPUTIL_DL(lit) \
209 BloombergLP::bdldfp::DecimalImpUtil::parse128( \
210 (BloombergLP::bdldfp::DecimalImpUtil::checkLiteral(lit), #lit))
211
212#elif defined(BDLDFP_DECIMALPLATFORM_C99_TR) || defined( __IBM_DFP__ )
213
214#define BDLDFP_DECIMALIMPUTIL_JOIN_(a,b) a##b
215
216 // Portable decimal floating-point literal support
217
218#define BDLDFP_DECIMALIMPUTIL_DF(lit) BDLDFP_DECIMALIMPUTIL_JOIN_(lit,df)
219
220#define BDLDFP_DECIMALIMPUTIL_DD(lit) BDLDFP_DECIMALIMPUTIL_JOIN_(lit,dd)
221
222#define BDLDFP_DECIMALIMPUTIL_DL(lit) BDLDFP_DECIMALIMPUTIL_JOIN_(lit,dl)
223
224#endif
225
226
227
228namespace bdldfp {
229
230 // ====================
231 // class DecimalImpUtil
232 // ====================
233
234/// This `struct` provides a namespace for utility functions that implement
235/// core decimal floating-poing operations.
236///
237/// See @ref bdldfp_decimalimputil
239
240 private:
241#if defined(BDLDFP_DECIMALPLATFORM_INTELDFP)
242 typedef DecimalImpUtil_IntelDfp Imp;
243#else
244 BDLDFP_DECIMALPLATFORM_COMPILER_ERROR;
245#endif
246
247 public:
248 // TYPES
249 typedef Imp::ValueType32 ValueType32;
250 typedef Imp::ValueType64 ValueType64;
251 typedef Imp::ValueType128 ValueType128;
252
253 enum {
254 // Status flag bitmask for numeric operations.
255
256 k_STATUS_INEXACT = Imp::k_STATUS_INEXACT,
257 k_STATUS_UNDERFLOW = Imp::k_STATUS_UNDERFLOW,
258 k_STATUS_OVERFLOW = Imp::k_STATUS_OVERFLOW
259 };
260
261 // CLASS METHODS
262
263 /// Return a `Decimal64` object that has the specified `significand` and
264 /// `exponent`, rounded according to the current decimal rounding mode,
265 /// if necessary. If an overflow condition occurs, store the value of
266 /// the macro `ERANGE` into `errno` and return infinity with the
267 /// appropriate sign.
268 static ValueType64 makeDecimal64( int significand,
269 int exponent);
270 static ValueType64 makeDecimal64(unsigned int significand,
271 int exponent);
272 static ValueType64 makeDecimal64( long long int significand,
273 int exponent);
274 static ValueType64 makeDecimal64(unsigned long long int significand,
275 int exponent);
276
277 /// Return a `ValueType64` representing infinity. Optionally specify
278 /// whether the infinity `isNegative`. If `isNegative` is `false` or is
279 /// is not supplied, the returned value will be infinity, and negative
280 /// infinity otherwise.
281 static ValueType64 makeInfinity64(bool isNegative = false);
282
283#ifdef BDLDFP_DECIMALPLATFORM_SOFTWARE
284
285 // Literal Checking Functions
286
287 /// This `struct` is a helper type used to generate error messages for
288 /// bad literals.
289 ///
290 /// See @ref bdldfp_decimalimputil
291 struct This_is_not_a_floating_point_literal {};
292
293 /// Generate an error if the specified `t` is bad decimal floating-point.
294 ///
295 /// \note Note that this function is intended for use with
296 /// literals
297 template <class TYPE>
298 static void checkLiteral(const TYPE& t);
299
300 /// Overload to avoid an error when the decimal floating-point literal
301 /// (without the suffix) can be interpreted as a `double` literal.
302 static void checkLiteral(double);
303
304#elif defined(BDLDFP_DECIMALPLATFORM_HARDWARE)
305
306#else
307
308#error Improperly configured decimal floating point platform settings
309
310#endif
311 // classify
312
313 /// Return the integer value that respresents the floating point
314 /// classification of the specified `x` value as follows:
315 ///
316 /// * if `x` is NaN, return FP_NAN;
317 /// * otherwise if `x` is positive or negative infinity, return
318 /// `FP_INFINITE`;
319 /// * otherwise if `x` is a subnormal value, return `FP_SUBNORMAL`
320 /// * otherwise if `x` is a zero value, return `FP_ZERO`
321 /// * otherwise return `FP_NORMAL`
322 ///
323 ///
324 /// \note Note that the mention `FP_XXX` constants are C99 standard macros and
325 /// they are defined in the math.h (cmath) standard header. On systems
326 /// that fail to define those standard macros we define the in this
327 /// component as public macros.
328 static int classify(ValueType32 x);
329 static int classify(ValueType64 x);
330 static int classify(ValueType128 x);
331
332
333 // normalize
334
335 /// Return a `ValueTypeXX` number having the value as the specified
336 /// 'original, but with the significand, that can not be divided by ten,
337 /// and appropriate exponent.
338 ///
339 /// * Any representations of zero value (either positive or negative)
340 /// are normalized to positive zero having null significand and
341 /// exponent.
342 /// * Any NaN values (either signaling or quiet) are normalized to
343 /// quiet NaN.
344 /// * Normalized non-zero value has the same sign as the original one.
348
349 // Quantum functions
350
351 /// Return a number equal to the specified `value` (except for possible
352 /// rounding) having the exponent equal to the exponent of the specified
353 /// `exponent`. Rounding may occur when the exponent is greater than
354 /// the quantum of `value`. E.g., `quantize(147e-2_d32, 1e-1_d32)`
355 /// yields `15e-1_d32`. In the opposite direction, if `exponent` is
356 /// sufficiently less than the quantum of `value`, it may not be
357 /// possible to construct the requested result, and if so, `NaN` is
358 /// returned. E.g., `quantize(1234567e0_d32, 1e-1_d32)` returns `NaN`.
359 static ValueType32 quantize(ValueType32 value, ValueType32 exponent);
360 static ValueType64 quantize(ValueType64 value, ValueType64 exponent);
361 static ValueType128 quantize(ValueType128 value, ValueType128 exponent);
362
363 /// Return a number equal to the specified `value` (except for possible
364 /// rounding) having the specified `exponent`. Rounding may occur when
365 /// `exponent` is greater than the quantum of `value`. E.g.,
366 /// `quantize(147e-2_d32, -1)` yields `15e-1_d32`. In the opposite
367 /// direction, if `exponent` is sufficiently less than the quantum of
368 /// `value`, it may not be possible to construct the requested result,
369 /// and if so, `NaN` is returned. E.g., `quantize(1234567e0_d32, -1)`
370 /// returns `NaN`. Behavior is undefined unless the `exponent`
371 /// satisfies the following conditions
372 /// * for `Decimal32` type: `-101 <= exponent <= 90`
373 /// * for `Decimal64` type: `-398 <= exponent <= 369`
374 /// * for `Decimal128` type: `-6176 <= exponent <= 6111`
375 static ValueType32 quantize(ValueType32 value, int exponent);
376 static ValueType64 quantize(ValueType64 value, int exponent);
377 static ValueType128 quantize(ValueType128 value, int exponent);
378
379 /// If a floating-point number equal to the specified `y` and having the
380 /// specified `exponent` can be constructed, set that value into the
381 /// specified `x` and return 0. Otherwise, or if `y` is NaN or
382 /// infinity, leave the contents of `x` unchanged and return a non-zero value.
383 ///
384 /// \pre The behavior is undefined unless `exponent` satisfies the
385 /// following conditions
386 /// * for `Decimal32` type: `-101 <= exponent <= 90`
387 /// * for `Decimal64` type: `-398 <= exponent <= 369`
388 /// * for `Decimal128` type: `-6176 <= exponent <= 6111`
389 ///
390 /// Example:
391 /// `Decimal32 x;`
392 /// `BSLS_ASSERT(0 == quantizeEqual(&x, 123e+3_d32, 2);`
393 /// `BSLS_ASSERT(1230e+2_d32 == x);`
394 /// `BSLS_ASSERT(0 != quantizeEqual(&x, 123e+3_d32, -2);`
395 /// `BSLS_ASSERT(1230e+2_d32 == x);`
396 static int quantizeEqual(ValueType32 *x, ValueType32 y, int exponent);
397 static int quantizeEqual(ValueType64 *x, ValueType64 y, int exponent);
398 static int quantizeEqual(ValueType128 *x, ValueType128 y, int exponent);
399
400 /// Return `true` if the specified `x` and `y` values have the same
401 /// quantum exponents, and `false` otherwise. If both arguments are NaN
402 /// or both arguments are infinity, they have the same quantum exponents.
403 ///
404 /// \note Note that if exactly one operand is NaN or exactly one
405 /// operand is infinity, they do not have the same quantum exponents.
406 static bool sameQuantum(ValueType32 x, ValueType32 y);
407 static bool sameQuantum(ValueType64 x, ValueType64 y);
408 static bool sameQuantum(ValueType128 x, ValueType128 y);
409
410 // compose and decompose
411
412 /// Decompose the specified decimal `value` into the components of
413 /// the decimal floating-point format and load the result into the
414 /// specified `sign`, `significand` and `exponent` such that
415 /// `value` is equal to `sign * significand * (10 ** exponent)`.
416 /// The special values infinity and NaNs are decomposed to `sign`,
417 /// `exponent` and `significand` parts, even though they don't have
418 /// their normal meaning (except `sign`). That is those specific values
419 /// cannot be restored using these parts, unlike the finite ones.
420 /// Return the integer value that represents the floating point
421 /// classification of the specified `value` as follows:
422 ///
423 /// * if `value` is NaN, return FP_NAN;
424 /// * if `value` is infinity, return `FP_INFINITE`;
425 /// * if `value` is a subnormal value, return `FP_SUBNORMAL`;
426 /// * if `value` is a zero value, return `FP_ZERO`;
427 /// * otherwise return `FP_NORMAL`.
428 ///
429 ///
430 /// \note Note that a decomposed representation may not be unique,
431 /// for example 10 can be represented as either `10 * (10 ** 0)`
432 /// or `1 * (10 ** 1)`. The returned `significand` and `exponent`
433 /// reflect the encoded representation of `value` (i.e., they
434 /// reflect the `quantum` of `value`).
435 static int decompose(int *sign,
436 unsigned int *significand,
437 int *exponent,
438 ValueType32 value);
439 static int decompose(int *sign,
440 bsls::Types::Uint64 *significand,
441 int *exponent,
442 ValueType64 value);
443 static int decompose(int *sign,
444 Uint128 *significand,
445 int *exponent,
446 ValueType128 value);
447
448 // Format functions
449
450 static int format(char *buffer,
451 int length,
452 ValueType32 value,
453 const DecimalFormatConfig& cfg);
454
455 static int format(char *buffer,
456 int length,
457 ValueType64 value,
458 const DecimalFormatConfig& cfg);
459
460 /// Format the specified `value`, according to the parameters in the
461 /// specified `cfg`. Place the output in the buffer designated by the
462 /// specified `buffer` and `length`, and return the length of the
463 /// formatted value. If there is insufficient room in the buffer, its
464 /// contents will be left in an unspecified state, with the returned
465 /// value indicating the necessary size. This function does not write
466 /// a terminating null character. If `length` is not positive, `buffer`
467 /// is permitted to be null. This can be used to determine the
468 /// necessary buffer size. See the
469 /// @ref bdldfp_decimalformatconfig-attributes section for information on
470 /// the configuration attributes.
471 ///
472 ///
473 /// \note Note that for some combinations of `value` and precision provided by
474 /// `cfg` object, the number being written must first be rounded to
475 /// fewer digits than it initially contains. The number written must be
476 /// as close as possible to the initial value given the constraints on
477 /// precision. The rounding should be done as "round-half-up", i.e.,
478 /// round up in magnitude when the first of the discarded digits is
479 /// between 5 and 9.
480 ///
481 /// Also note that if the configuration format attribute `style` is
482 /// `e_NATURAL` then all significand digits of the `value` are output in
483 /// the buffer regardless of the value specified in configuration's
484 /// `precision` attribute.
485 static int format(char *buffer,
486 int length,
487 ValueType128 value,
488 const DecimalFormatConfig& cfg);
489
490 // Integer construction
491
492 static ValueType32 int32ToDecimal32( int value);
493 static ValueType32 uint32ToDecimal32(unsigned int value);
494 static ValueType32 int64ToDecimal32( long long int value);
495
496 /// Return a `Decimal32` object having the value closest to the
497 /// specified `value` following the conversion rules as defined by
498 /// IEEE-754:
499 ///
500 /// * If `value` is zero then initialize this object to a zero with an
501 /// unspecified sign and an unspecified exponent.
502 /// * Otherwise if `value` has a value that is not exactly
503 /// representable using `std::numeric_limits<Decimal32>::max_digit`
504 /// decimal digits then return a decimal value initialized to the
505 /// value of `value` rounded according to the rounding direction.
506 /// * Otherwise initialize this object to the value of the `value`.
507 ///
508 /// The exponent 0 (quantum 1e-6) is preferred during conversion unless
509 /// it would cause unnecessary loss of precision.
510 static ValueType32 uint64ToDecimal32(unsigned long long int value);
511
512 static ValueType64 int32ToDecimal64( int value);
513 static ValueType64 uint32ToDecimal64(unsigned int value);
514 static ValueType64 int64ToDecimal64( long long int value);
515
516 /// Return a `Decimal64` object having the value closest to the
517 /// specified `value` following the conversion rules as defined by
518 /// IEEE-754:
519 ///
520 /// * If `value` is zero then initialize this object to a zero with an
521 /// unspecified sign and an unspecified exponent.
522 /// * Otherwise if `value` has a value that is not exactly
523 /// representable using `std::numeric_limits<Decimal64>::max_digit`
524 /// decimal digits then return a decimal value initialized to the
525 /// value of `value` rounded according to the rounding direction.
526 /// * Otherwise initialize this object to the value of the `value`.
527 ///
528 /// The exponent 0 (quantum 1e-15) is preferred during conversion unless
529 /// it would cause unnecessary loss of precision.
530 static ValueType64 uint64ToDecimal64(unsigned long long int value);
531
532 static ValueType128 int32ToDecimal128( int value);
533 static ValueType128 uint32ToDecimal128(unsigned int value);
534 static ValueType128 int64ToDecimal128( long long int value);
535
536 /// Return a `Decimal128` object having the value closest to the
537 /// specified `value` subject to the conversion rules as defined by
538 /// IEEE-754:
539 ///
540 /// * If `value` is zero then initialize this object to a zero with an
541 /// unspecified sign and an unspecified exponent.
542 /// * Otherwise if `value` has a value that is not exactly
543 /// representable using `std::numeric_limits<Decimal128>::max_digit`
544 /// decimal digits then return a decimal value initialized to the
545 /// value of `value` rounded according to the rounding direction.
546 /// * Otherwise initialize this object to `value`.
547 ///
548 /// The exponent 0 (quantum 1e-33) is preferred during conversion unless
549 /// it would cause unnecessary loss of precision.
550 static ValueType128 uint64ToDecimal128(unsigned long long int value);
551
552 // Arithmetic
553
554 // Addition functions
555
556 /// Add the value of the specified `rhs` to the value of the specified
557 /// `lhs` as described by IEEE-754 and return the result.
558 ///
559 /// * If either of `lhs` or `rhs` is signaling NaN, then store the
560 /// value of the macro `EDOM` into `errno` and return a NaN.
561 /// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
562 /// * Otherwise if `lhs` and `rhs` are infinities of differing signs,
563 /// store the value of the macro `EDOM` into `errno` and return a
564 /// NaN.
565 /// * Otherwise if `lhs` and `rhs` are infinities of the same sign then
566 /// return infinity of that sign.
567 /// * Otherwise if `rhs` is zero (positive or negative), return `lhs`.
568 /// * Otherwise if the sum of `lhs` and `rhs` has an absolute value
569 /// that is larger than the maximum value supported by the indicated
570 /// result type then store the value of the macro `ERANGE` into
571 /// `errno` and return infinity with the same sign as that result.
572 /// * Otherwise return the sum of the number represented by `lhs` and
573 /// the number represented by `rhs`.
574 static ValueType32 add(ValueType32 lhs, ValueType32 rhs);
575 static ValueType64 add(ValueType64 lhs, ValueType64 rhs);
576 static ValueType128 add(ValueType128 lhs, ValueType128 rhs);
577
578 // Subtraction functions
579
580 /// Subtract the value of the specified `rhs` from the value of the
581 /// specified `lhs` as described by IEEE-754 and return the result.
582 ///
583 /// * If either of `lhs` or `rhs` is signaling NaN, then store the
584 /// value of the macro `EDOM` into `errno` and return a NaN.
585 /// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
586 /// * Otherwise if `lhs` and the `rhs` have infinity values of the same
587 /// sign, store the value of the macro `EDOM` into `errno` and return
588 /// a NaN.
589 /// * Otherwise if `lhs` and the `rhs` have infinity values of
590 /// differing signs, then return `lhs`.
591 /// * Otherwise if `rhs` has a zero value (positive or negative), then
592 /// return `lhs`.
593 /// * Otherwise if the subtracting of `lhs` and `rhs` has an absolute
594 /// value that is larger than the maximum value supported by the
595 /// indicated result type then store the value of the macro `ERANGE`
596 /// into `errno` and return infinity with the same sign as that
597 /// result.
598 /// * Otherwise return the result of subtracting the value of `rhs`
599 /// from the value of `lhs`.
603
604 // Multiplication functions
605
606 /// Multiply the value of the specified `lhs` object by the value of the
607 /// specified `rhs` as described by IEEE-754 and return the result.
608 ///
609 /// * If either of `lhs` or `rhs` is signaling NaN, then store the
610 /// value of the macro `EDOM` into `errno` and return a NaN.
611 /// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
612 /// * Otherwise if one of the operands is infinity (positive or
613 /// negative) and the other is zero (positive or negative), then
614 /// store the value of the macro `EDOM` into `errno` and return a
615 /// NaN.
616 /// * Otherwise if both `lhs` and `rhs` are infinity (positive or
617 /// negative), return infinity. The sign of the returned value will
618 /// be positive if `lhs` and `rhs` have the same sign, and negative
619 /// otherwise.
620 /// * Otherwise, if either `lhs` or `rhs` is zero, return zero. The
621 /// sign of the returned value will be positive if `lhs` and `rhs`
622 /// have the same sign, and negative otherwise.
623 /// * Otherwise if the product of `lhs` and `rhs` has an absolute value
624 /// that is larger than the maximum value of the indicated result
625 /// type then store the value of the macro `ERANGE` into `errno` and
626 /// return infinity with the same sign as that result.
627 /// * Otherwise if the product of `lhs` and `rhs` has an absolute value
628 /// that is smaller than min value of the indicated result type then
629 /// store the value of the macro `ERANGE` into `errno` and return
630 /// zero with the same sign as that result.
631 /// * Otherwise return the product of the value of `rhs` and the number
632 /// represented by `rhs`.
636
637 // Division functions
638
639 /// Divide the value of the specified `lhs` by the value of the
640 /// specified `rhs` as described by IEEE-754, and return the result.
641 ///
642 /// * If either of `lhs` or `rhs` is signaling NaN, then store the
643 /// value of the macro `EDOM` into `errno` and return a NaN.
644 /// * Otherwise if either of `lhs` or `rhs` is NaN, return a NaN.
645 /// * Otherwise if `lhs` and `rhs` are both infinity (positive or
646 /// negative) or both zero (positive or negative) then store the
647 /// value of the macro `EDOM` into `errno` and return a NaN.
648 /// * Otherwise if `lhs` has a normal value and `rhs` has a positive
649 /// zero value, store the value of the macro `ERANGE` into `errno`
650 /// and return infinity with the sign of `lhs`.
651 /// * Otherwise if `lhs` has a normal value and `rhs` has a negative
652 /// zero value, store the value of the macro `ERANGE` into `errno`
653 /// and return infinity with the opposite sign as `lhs`.
654 /// * Otherwise if dividing the value of `lhs` by the value of `rhs`
655 /// results in an absolute value that is larger than the maximum
656 /// value supported by the result type then store the value of the
657 /// macro `ERANGE` into `errno` and return infinity with the same
658 /// sign as that result.
659 /// * Otherwise if dividing the value of `lhs` by the value of `rhs`
660 /// results in an absolute value that is smaller than min value
661 /// supported by the indicated result type then store the value of
662 /// the macro `ERANGE` into `errno`and return zero with the same sign
663 /// as that result.
664 /// * Otherwise return the result of dividing the value of `lhs` by the
665 /// value of `rhs`.
666 static ValueType32 divide(ValueType32 lhs, ValueType32 rhs);
667 static ValueType64 divide(ValueType64 lhs, ValueType64 rhs);
669
670 // Math functions
671
672 /// Return a decimal value with the magnitude of the specifed `x` and
673 /// the sign of the specified `y`. If `x` is NaN, then NaN with the
674 /// sign of `y` is returned.
675 ///
676 /// Examples: `copysign( 5.0, -2.0)` ==> -5.0;
677 /// `copysign(-5.0, -2.0)` ==> -5.0
681
682 /// Return `e` (Euler's number, 2.7182818) raised to the specified power
683 /// `x`.
684 ///
685 /// Special value handling:
686 /// * If `x` is +/-0, 1 is returned.
687 /// * If `x` is negative infinity, +0 is returned.
688 /// * If `x` is +infinity, +infinity is returned.
689 /// * If `x` is quiet NaN, quiet NaN is returned.
690 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
691 /// the macro `EDOM` is stored into `errno`.
692 /// * If `x` is finite, but the result value is outside the range of
693 /// the return type, store the value of the macro `ERANGE` into
694 /// `errno` and +infinity value is returned.
695 static ValueType32 exp(ValueType32 x);
696 static ValueType64 exp(ValueType64 x);
697 static ValueType128 exp(ValueType128 x);
698
699 /// Return the natural (base `e`) logarithm of the specified `x`.
700 ///
701 /// Special value handling:
702 /// * If `x` is +/-0, -infinity is returned and the value of the macro
703 /// `ERANGE` is stored into `errno`.
704 /// * If `x` is 1, +0 is returned.
705 /// * If `x` is negative, quiet NaN is returned and the value of the
706 /// macro `EDOM` is stored into `errno`.
707 /// * If `x` is +infinity, +infinity is returned.
708 /// * If `x` is quiet NaN, quiet NaN is returned.
709 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
710 /// the macro `EDOM` is stored into `errno`.
711 static ValueType32 log(ValueType32 x);
712 static ValueType64 log(ValueType64 x);
713 static ValueType128 log(ValueType128 x);
714
715 /// Return the FLT_RADIX-based logarithm (i.e., base 10) of the absolute
716 /// value of the specified `x`.
717 ///
718 /// Special value handling:
719 /// * If `x` is +/-0, -infinity is returned and the value of the macro
720 /// `ERANGE` is stored into `errno`.
721 /// * If `x` is 1, +0 is returned.
722 /// * If `x` is +/-infinity, +infinity is returned.
723 /// * If `x` is quiet NaN, quiet NaN is returned.
724 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
725 /// the macro `EDOM` is stored into `errno`.
726 ///
727 /// Examples: `logB( 10.0)` ==> 1.0;
728 /// `logB(-100.0)` ==> 2.0
729 static ValueType32 logB(ValueType32 x);
730 static ValueType64 logB(ValueType64 x);
732
733 /// Return the common (base-10) logarithm of the specified `x`.
734 ///
735 /// Special value handling:
736 /// * If `x` is +/-0, -infinity is returned and the value of the macro
737 /// `ERANGE` is stored into `errno`.
738 /// * If `x` is 1, +0 is returned.
739 /// * If `x` is negative, quiet NaN is returned and the value of the
740 /// macro `EDOM` is stored into `errno`.
741 /// * If `x` is +infinity, +infinity is returned.
742 /// * If `x` is quiet NaN, quiet NaN is returned.
743 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
744 /// the macro `EDOM` is stored into `errno`.
745 static ValueType32 log10(ValueType32 x);
746 static ValueType64 log10(ValueType64 x);
748
749 /// Return the remainder of the division of the specified `x` by the
750 /// specified `y`. The returned value has the same sign as `x` and is
751 /// less than `y` in magnitude.
752 ///
753 /// Special value handling:
754 /// * If either argument is quiet NaN, quiet NaN is returned.
755 /// * If either argument is signaling NaN, quiet NaN is returned, and
756 /// the value of the macro `EDOM` is stored into `errno`.
757 /// * If `x` is +/-infnity and `y` is not NaN, quiet NaN is returned
758 /// and the value of the macro `EDOM` is stored into `errno`.
759 /// * If `x` is +/-0 and `y` is not zero, +/-0 is returned.
760 /// * If `y` is +/-0, quite NaN is returned and the value of the macro
761 /// `EDOM` is stored into `errno`.
762 /// * If `x` is finite and `y` is +/-infnity, `x` is returned.
766
767 /// Return the remainder of the division of the specified `x` by the
768 /// specified `y`. The remainder of the division operation `x/y`
769 /// calculated by this function is exactly the value `x - n*y`, where
770 /// `n` s the integral value nearest the exact value `x/y`. When
771 /// `|n - x/y| == 0.5`, the value `n` is chosen to be even.
772 ///
773 /// \note Note that in contrast to `DecimalImpUtil::fmod()`, the returned value is not
774 /// guaranteed to have the same sign as `x`.
775 ///
776 /// Special value handling:
777 /// * The current rounding mode has no effect.
778 /// * If either argument is quiet NaN, quiet NaN is returned.
779 /// * If either argument is signaling NaN, quiet NaN is returned, and
780 /// the value of the macro `EDOM` is stored into `errno`.
781 /// * If `y` is +/-0, quiet NaN is returned and the value of the macro
782 /// `EDOM` is stored into `errno`.
783 /// * If `x` is +/-infnity and `y` is not NaN, quiet NaN is returned
784 /// and the value of the macro `EDOM` is stored into `errno`.
785 /// * If `x` is finite and `y` is +/-infnity, `x` is returned.
789
790 static long int lrint(ValueType32 x);
791 static long int lrint(ValueType64 x);
792 static long int lrint(ValueType128 x);
793
794 /// Return an integer value nearest to the specified `x`. Round `x`
795 /// using the current rounding mode. If `x` is +/-infnity, NaN (either
796 /// signaling or quiet) or the rounded value is outside the range of the
797 /// return type, store the value of the macro `EDOM` into `errno` and
798 /// return implementation-defined value.
799 static long long int llrint(ValueType32 x);
800 static long long int llrint(ValueType64 x);
801 static long long int llrint(ValueType128 x);
802
806
807 /// Return the next representable value of the specified `from` in the
808 /// direction of the specified `to`.
809 ///
810 /// Special value handling:
811 /// * If `from` equals `to`, `to` is returned.
812 /// * If either argument is quiet NaN, quiet NaN is returned.
813 /// * If either argument is signaling NaN, quiet NaN is returned and
814 /// the value of the macro `EDOM` is stored into `errno`.
815 /// * If `from` is finite, but the expected result is infinity,
816 /// infinity is returned and the value of the macro `ERANGE` is
817 /// stored into `errno`.
818 /// * If `from` does not equal `to` and the result is subnormal or
819 /// zero, the value of the macro `ERANGE` is stored into `errno`.
823
824 /// Return the value of the specified `base` raised to the power of the
825 /// specified `exp`.
826 ///
827 /// Special value handling:
828 /// * If `base` is finite and negative and `exp` is finite and
829 /// non-integer, quiet NaN is returned and the value of the macro
830 /// `EDOM` is stored into `errno`.
831 /// * If the mathematical result of this function is infinity or
832 /// undefined or a range error due to overflow occurs, infinity is
833 /// returned and the value of the macro `ERANGE` is stored into
834 /// `errno`.
835 /// * If a range error occurs due to underflow, the correct result
836 /// (after rounding) is returned and the value of the macro `ERANGE`
837 /// is stored into `errno`.
838 /// * If either argument is signaling NaN, quiet NaN is returned and
839 /// the value of the macro `EDOM` is stored into `errno`.
840 static ValueType32 pow(ValueType32 base, ValueType32 exp);
841 static ValueType64 pow(ValueType64 base, ValueType64 exp);
842 static ValueType128 pow(ValueType128 base, ValueType128 exp);
843
844 /// Return the smallest integral value that is not less than the
845 /// specified `x`.
846 ///
847 /// Special value handling:
848 /// * if `x` is quiet NaN, quiet NaN is returned.
849 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
850 /// the macro `EDOM` is stored into `errno`.
851 /// * if `x` is +/-infinity or +/-0, it is returned unmodified.
852 ///
853 /// Examples: `ceil(0.5)` ==> 1.0; `ceil(-0.5)` ==> 0.0
854 static ValueType32 ceil(ValueType32 x);
855 static ValueType64 ceil(ValueType64 x);
857
858 /// Return the largest integral value that is not greater than the
859 /// specified `x`.
860 ///
861 /// Special value handling:
862 /// * if `x` is quiet NaN, quiet NaN is returned.
863 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
864 /// the macro `EDOM` is stored into `errno`.
865 /// * if `x` is +/-infinity or +/-0, it is returned unmodified.
866 ///
867 /// Examples: `floor(0.5)` ==> 0.0; `floor(-0.5)` ==> -1.0
868 static ValueType32 floor(ValueType32 x);
869 static ValueType64 floor(ValueType64 x);
871
872 /// Return the integral value nearest to the specified `x`. Round
873 /// halfway cases away from zero, regardless of the current decimal
874 /// floating point rounding mode.
875 ///
876 /// Special value handling:
877 /// * if `x` is quiet NaN, quiet NaN is returned.
878 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
879 /// the macro `EDOM` is stored into `errno`.
880 /// * if `x` is +/-infinity or +/-0, it is returned unmodified.
881 ///
882 /// Examples: `round(0.5)` ==> 1.0; `round(-0.5)` ==> -1.0
883 static ValueType32 round(ValueType32 x);
884 static ValueType64 round(ValueType64 x);
886
887 /// Return the integral value nearest to the specified `x`. Round
888 /// halfway cases away from zero, regardless of the current decimal
889 /// floating point rounding mode.
890 ///
891 /// Special value handling:
892 /// * if `x` is NaN (either quiet or signaling), quiet NaN is returned
893 /// and the value of the macro `EDOM` is stored into `errno`.
894 /// * if `x` is +/-infinity, quite NaN is returned and the value of the
895 /// macro `EDOM` is stored into `errno`.
896 /// * If the result of the rounding is outside the range of the return
897 /// type, the macro `EDOM` is stored into `errno`.
898 ///
899 /// Examples: `lround(0.5)` ==> 1.0; `lround(-0.5)` ==> -1.0
900 static long int lround(ValueType32 x);
901 static long int lround(ValueType64 x);
902 static long int lround(ValueType128 x);
903
904 /// Return the specified `x` value rounded to the specified `precision`.
905 /// Round halfway cases away from zero, regardless of the current
906 /// decimal floating point rounding mode. If `x` is integral, positive
907 /// zero, negative zero, NaN, or infinity then return `x` itself.
908 ///
909 /// Examples: `round(3.14159, 3)` ==> 3.142
910 static ValueType32 round(ValueType32 x, unsigned int precision);
911 static ValueType64 round(ValueType64 x, unsigned int precision);
912 static ValueType128 round(ValueType128 x, unsigned int precision);
913
914
915 /// Return the nearest integral value that is not greater in absolute
916 /// value than the specified `x`.
917 ///
918 /// Special value handling:
919 /// * if `x` is quiet NaN, quiet NaN is returned.
920 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
921 /// the macro `EDOM` is stored into `errno`.
922 /// * if `x` is +/-infinity or +/-0, it is returned unmodified.
923 ///
924 /// Examples: `trunc(0.5)` ==> 0.0; `trunc(-0.5)` ==> 0.0
925 static ValueType32 trunc(ValueType32 x);
926 static ValueType64 trunc(ValueType64 x);
928
929 /// Return, using the specified `x`, `y`, and `z`, the value of the
930 /// expression `x * y + z`, rounded as one ternary operation according
931 /// to the current decimal floating point rounding mode.
932 ///
933 /// Special value handling:
934 /// * If `x` or `y` are quiet NaN, quiet NaN is returned.
935 /// * If any argument is signaling NaN, quiet NaN is returned and the
936 /// value of the macro `EDOM` is stored into `errno`.
937 /// * If `x*y` is an exact infinity and `z` is infinity with the
938 /// opposite sign, quiet NaN is returned and the value of the macro
939 /// `EDOM` is stored into `errno`.
940 /// * If `x` is zero and `y` is infinite or if `x` is infinite and `y`
941 /// is zero, and `z` is not a NaN, then quiet NaN is returned and the
942 /// value of the macro `EDOM` is stored into `errno`.
943 /// * If `x` is zero and `y` is infinite or if `x` is infinite and `y`
944 /// is zero, and `z` is NaN, then quiet NaN is returned.
948
949 /// Return the absolute value of the specified `x`.
950 ///
951 /// Special value handling:
952 /// * if `x` is NaN (either signaling or quiet), quiet NaN is returned.
953 /// * if `x` is +/-infinity or +/-0, it is returned unmodified.
954 static ValueType32 fabs(ValueType32 x);
955 static ValueType64 fabs(ValueType64 x);
957
958 /// Return the square root of the specified `x`.
959 ///
960 /// Special value handling:
961 /// * If `x` is quiet NaN, quiet NaN is returned.
962 /// * If `x` is signaling NaN, quiet NaN is returned and the value of
963 /// the macro `EDOM` is stored into `errno`.
964 /// * If `x` is less than -0, quiet NaN is returned and the value of
965 /// the macro `EDOM` is stored into `errno`.
966 /// * If `x` is +/-infinity or +/-0, it is returned unmodified.
967 static ValueType32 sqrt(ValueType32 x);
968 static ValueType64 sqrt(ValueType64 x);
970
971 // Negation functions
972
973 /// Return the result of applying the unary negation (`-`) operator to the specified `value` as described by IEEE-754.
974 ///
975 /// \note Note that decimal
976 /// floating point representations can encode signed zero values, thus
977 /// negating 0 results in -0 and negating -0 results in 0.
978 static ValueType32 negate(ValueType32 value);
979 static ValueType64 negate(ValueType64 value);
980 static ValueType128 negate(ValueType128 value);
981
982 // Comparison functions
983
984 // Less Than functions
985
986 /// Return `true` if the specified `lhs` has a value less than the
987 /// specified `rhs` and `false` otherwise. The value of a `Decimal64`
988 /// object `lhs` is less than that of an object `rhs` if the
989 /// `compareQuietLess` operation (IEEE-754 defined, non-total ordering
990 /// comparison) considers the underlying IEEE representation of `lhs` to
991 /// be less than of that of `rhs`. In other words, `lhs` is less than
992 /// `rhs` if:
993 ///
994 /// * neither `lhs` nor `rhs` are NaN, or
995 /// * `lhs` is zero (positive or negative) and `rhs` is positive, or
996 /// * `rhs` is zero (positive or negative) and `lhs` negative, or
997 /// * `lhs` is not positive infinity, or
998 /// * `lhs` is negative infinity and `rhs` is not, or
999 /// * `lhs` and `rhs` both represent a real number and the real number
1000 /// of `lhs` is less than that of `rhs`
1001 ///
1002 /// If either or both operands are signaling NaN, store the value of the
1003 /// macro `EDOM` into `errno` and return `false`.
1004 static bool less(ValueType32 lhs, ValueType32 rhs);
1005 static bool less(ValueType64 lhs, ValueType64 rhs);
1006 static bool less(ValueType128 lhs, ValueType128 rhs);
1007
1008 // Greater Than functions
1009
1010 /// Return `true` if the specified `lhs` has a greater value than the
1011 /// specified `rhs` and `false` otherwise. The value of a `Decimal64`
1012 /// object `lhs` is greater than that of an object `rhs` if the
1013 /// `compareQuietGreater` operation (IEEE-754 defined, non-total
1014 /// ordering comparison) considers the underlying IEEE representation of
1015 /// `lhs` to be greater than of that of `rhs`. In other words, `lhs` is
1016 /// greater than `rhs` if:
1017 ///
1018 /// * neither `lhs` nor `rhs` are NaN, or
1019 /// * `rhs` is zero (positive or negative) and `lhs` positive, or
1020 /// * `lhs` is zero (positive or negative) and `rhs` negative, or
1021 /// * `lhs` is not negative infinity, or
1022 /// * `lhs` is positive infinity and `rhs` is not, or
1023 /// * `lhs` and `rhs` both represent a real number and the real number
1024 /// of `lhs` is greater than that of `rhs`
1025 ///
1026 /// If either or both operands are signaling NaN, store the value of the
1027 /// macro `EDOM` into `errno` and return `false`.
1028 static bool greater(ValueType32 lhs, ValueType32 rhs);
1029 static bool greater(ValueType64 lhs, ValueType64 rhs);
1030 static bool greater(ValueType128 lhs, ValueType128 rhs);
1031
1032 // Less Or Equal functions
1033
1034 /// Return `true` if the specified `lhs` has a value less than or equal
1035 /// the value of the specified `rhs` and `false` otherwise. The value
1036 /// of a `Decimal64` object `lhs` is less than or equal to the value of
1037 /// an object `rhs` if the `compareQuietLessEqual` operation (IEEE-754
1038 /// defined, non-total ordering comparison) considers the underlying
1039 /// IEEE representation of `lhs` to be less or equal to that of `rhs`.
1040 /// In other words, `lhs` is less or equal than `rhs` if:
1041 ///
1042 /// * neither `lhs` nor `rhs` are NaN, or
1043 /// * `lhs` and `rhs` are both zero (positive or negative), or
1044 /// * both `lhs` and `rhs` are positive infinity, or
1045 /// * `lhs` is negative infinity, or
1046 /// * `lhs` and `rhs` both represent a real number and the real number
1047 /// of `lhs` is less or equal to that of `rhs`
1048 ///
1049 /// If either or both operands are signaling NaN, store the value of the
1050 /// macro `EDOM` into `errno` and return `false`.
1051 static bool lessEqual(ValueType32 lhs, ValueType32 rhs);
1052 static bool lessEqual(ValueType64 lhs, ValueType64 rhs);
1053 static bool lessEqual(ValueType128 lhs, ValueType128 rhs);
1054
1055 // Greater Or Equal functions
1056
1057 /// Return `true` if the specified `lhs` has a value greater than or
1058 /// equal to the value of the specified `rhs` and `false` otherwise.
1059 /// The value of a `Decimal64` object `lhs` is greater or equal to a
1060 /// `Decimal64` object `rhs` if the `compareQuietGreaterEqual` operation
1061 /// (IEEE-754 defined, non-total ordering comparison ) considers the
1062 /// underlying IEEE representation of `lhs` to be greater or equal to
1063 /// that of `rhs`. In other words, `lhs` is greater than or equal to
1064 /// `rhs` if:
1065 ///
1066 /// * neither `lhs` nor `rhs` are NaN, or
1067 /// * `lhs` and `rhs` are both zero (positive or negative), or
1068 /// * both `lhs` and `rhs` are negative infinity, or
1069 /// * `lhs` is positive infinity, or
1070 /// * `lhs` and `rhs` both represent a real number and the real number
1071 /// of `lhs` is greater or equal to that of `rhs`
1072 ///
1073 /// If either or both operands are signaling NaN, store the value of the
1074 /// macro `EDOM` into `errno` and return `false`.
1075 static bool greaterEqual(ValueType32 lhs, ValueType32 rhs);
1076 static bool greaterEqual(ValueType64 lhs, ValueType64 rhs);
1077 static bool greaterEqual(ValueType128 lhs, ValueType128 rhs);
1078
1079 // Equality functions
1080
1081 /// Return `true` if the specified `lhs` and `rhs` have the same value,
1082 /// and `false` otherwise. Two decimal objects have the same value if
1083 /// the `compareQuietEqual` operation (IEEE-754 defined, non-total
1084 /// ordering comparison) considers the underlying IEEE representations
1085 /// equal. In other words, two decimal objects have the same value if:
1086 ///
1087 /// * both have a zero value (positive or negative), or
1088 /// * both have the same infinity value (both positive or negative), or
1089 /// * both have the value of a real number that are equal, even if they
1090 /// are represented differently (cohorts have the same value)
1091 ///
1092 /// If either or both operands are signaling NaN, store the value of the
1093 /// macro `EDOM` into `errno` and return `false`.
1094 static bool equal(ValueType32 lhs, ValueType32 rhs);
1095 static bool equal(ValueType64 lhs, ValueType64 rhs);
1096 static bool equal(ValueType128 lhs, ValueType128 rhs);
1097
1098 // Inequality functions
1099
1100 /// Return `false` if the specified `lhs` and `rhs` have the same value,
1101 /// and `true` otherwise. Two decimal objects have the same value if
1102 /// the `compareQuietEqual` operation (IEEE-754 defined, non-total
1103 /// ordering comparison) considers the underlying IEEE representations
1104 /// equal. In other words, two decimal objects have the same value if:
1105 ///
1106 /// * both have a zero value (positive or negative), or
1107 /// * both have the same infinity value (both positive or negative), or
1108 /// * both have the value of a real number that are equal, even if they
1109 /// are represented differently (cohorts have the same value)
1110 ///
1111 /// If either or both operands are signaling NaN, store the value of the
1112 /// macro `EDOM` into `errno` and return `false`.
1113 static bool notEqual(ValueType32 lhs, ValueType32 rhs);
1114 static bool notEqual(ValueType64 lhs, ValueType64 rhs);
1115 static bool notEqual(ValueType128 lhs, ValueType128 rhs);
1116
1117 // Inter-type Conversion functions
1118
1119 static ValueType32 convertToDecimal32 (const ValueType64& input);
1120 static ValueType32 convertToDecimal32 (const ValueType128& input);
1121 static ValueType64 convertToDecimal64 (const ValueType32& input);
1122 static ValueType64 convertToDecimal64 (const ValueType128& input);
1123
1124 /// Convert the specified `input` to the closest value of the indicated
1125 /// result type following the conversion rules as defined by IEEE-754:
1126 ///
1127 /// * If `input` is signaling NaN, store the value of the macro `EDOM`
1128 /// into `errno` and return signaling NaN value.
1129 /// * If `input` is NaN, return NaN value.
1130 /// * Otherwise if `input` is infinity (positive or negative), then
1131 /// return infinity with the same sign.
1132 /// * Otherwise if `input` is zero (positive or negative), then
1133 /// return zero with the same sign.
1134 /// * Otherwise if `input` has an absolute value that is larger than
1135 /// maximum or is smaller than minimum value supported by the result
1136 /// type, store the value of the macro `ERANGE` into `errno` and
1137 /// return infinity or zero with the same sign respectively.
1138 /// * Otherwise if `input` has a value that is not exactly
1139 /// representable using maximum digit number supported by the
1140 /// indicated result type then return the `input` rounded according
1141 /// to the rounding direction.
1142 /// * Otherwise return `input` value of the result type.
1143 static ValueType128 convertToDecimal128(const ValueType32& input);
1144 static ValueType128 convertToDecimal128(const ValueType64& input);
1145
1146 // Binary floating point conversion functions
1147
1148 /// Create a `Decimal32` object having the value closest to the
1149 /// specified `value` following the conversion rules as defined by
1150 /// IEEE-754:
1151 ///
1152 /// * If `value` is signaling NaN, store the value of the macro `EDOM`
1153 /// into `errno` and return signaling NaN value.
1154 /// * Otherwise if `value` is NaN, return a NaN.
1155 /// * Otherwise if `value` is infinity (positive or negative), then
1156 /// return an object equal to infinity with the same sign.
1157 /// * Otherwise if `value` is a zero value, then return an object equal
1158 /// to zero with the same sign.
1159 /// * Otherwise if `value` has an absolute value that is larger than
1160 /// `std::numeric_limits<Decimal32>::max()` then store the value of
1161 /// the macro `ERANGE` into `errno` and return infinity with the same
1162 /// sign as `value`.
1163 /// * Otherwise if `value` has an absolute value that is smaller than
1164 /// `std::numeric_limits<Decimal32>::min()` then store the value of
1165 /// the macro `ERANGE` into `errno` and return a zero with the same
1166 /// sign as `value`.
1167 /// * Otherwise if `value` needs more than
1168 /// `std::numeric_limits<Decimal32>::max_digit` significant decimal
1169 /// digits to represent then return the `value` rounded according to
1170 /// the rounding direction.
1171 /// * Otherwise return a `Decimal32` object representing `value`.
1172 static ValueType32 binaryToDecimal32( float value);
1173 static ValueType32 binaryToDecimal32( double value);
1174
1175 /// Create a `Decimal64` object having the value closest to the
1176 /// specified `value` following the conversion rules as defined by
1177 /// IEEE-754:
1178 ///
1179 /// * If `value` is signaling NaN, store the value of the macro `EDOM`
1180 /// into `errno` and return signaling NaN value.
1181 /// * Otherwise if `value` is NaN, return a NaN.
1182 /// * Otherwise if `value` is infinity (positive or negative), then
1183 /// return an object equal to infinity with the same sign.
1184 /// * Otherwise if `value` is a zero value, then return an object equal
1185 /// to zero with the same sign.
1186 /// * Otherwise if `value` needs more than
1187 /// `std::numeric_limits<Decimal64>::max_digit` significant decimal
1188 /// digits to represent then return the `value` rounded according to
1189 /// the rounding direction.
1190 /// * Otherwise return a `Decimal64` object representing `value`.
1191 static ValueType64 binaryToDecimal64( float value);
1192 static ValueType64 binaryToDecimal64( double value);
1193
1194 /// Create a `Decimal128` object having the value closest to the
1195 /// specified `value` following the conversion rules as defined by
1196 /// IEEE-754:
1197 ///
1198 /// * If `value` is signaling NaN, store the value of the macro `EDOM`
1199 /// into `errno` and return signaling NaN value.
1200 /// * Otherwise if `value` is NaN, return a NaN.
1201 /// * Otherwise if `value` is infinity (positive or negative), then
1202 /// return an object equal to infinity with the same sign.
1203 /// * Otherwise if `value` is a zero value, then return an object equal
1204 /// to zero with the same sign.
1205 /// * Otherwise if `value` has an absolute value that is larger than
1206 /// `std::numeric_limits<Decimal128>::max()` then store the value of
1207 /// the macro `ERANGE` into `errno` and return infinity with the same
1208 /// sign as `value`.
1209 /// * Otherwise if `value` has an absolute value that is smaller than
1210 /// `std::numeric_limits<Decimal128>::min()` then store the value of
1211 /// the macro `ERANGE` into `errno` and return a zero with the same
1212 /// sign as `value`.
1213 /// * Otherwise if `value` needs more than
1214 /// `std::numeric_limits<Decimal128>::max_digit` significant decimal
1215 /// digits to represent then return the `value` rounded according to
1216 /// the rounding direction.
1217 /// * Otherwise return a `Decimal128` object representing `value`.
1218 static ValueType128 binaryToDecimal128( float value);
1219 static ValueType128 binaryToDecimal128( double value);
1220
1221 // makeDecimalRaw functions
1222
1223 /// Create a `ValueType32` object representing a decimal floating point
1224 /// number consisting of the specified `significand` and `exponent`,
1225 /// with the sign given by `significand`.
1226 ///
1227 /// \pre The behavior is undefined unless `abs(significand) <= 9,999,999` and `-101 <= exponent <= 90`.
1228 static ValueType32 makeDecimalRaw32(int significand, int exponent);
1229
1230 /// Create a `ValueType64` object representing a decimal floating point
1231 /// number consisting of the specified `significand` and `exponent`,
1232 /// with the sign given by `significand`.
1233 ///
1234 /// \pre The behavior is undefined unless `abs(significand) <= 9,999,999,999,999,999` and
1235 /// `-398 <= exponent <= 369`.
1236 static ValueType64 makeDecimalRaw64(unsigned long long int significand,
1237 int exponent);
1238 static ValueType64 makeDecimalRaw64( long long int significand,
1239 int exponent);
1240 static ValueType64 makeDecimalRaw64(unsigned int significand,
1241 int exponent);
1242 static ValueType64 makeDecimalRaw64( int significand,
1243 int exponent);
1244
1245 /// Create a `ValueType128` object representing a decimal floating point
1246 /// number consisting of the specified `significand` and `exponent`,
1247 /// with the sign given by `significand`.
1248 ///
1249 /// \pre The behavior is undefined unless `-6176 <= exponent <= 6111`.
1250 static ValueType128 makeDecimalRaw128(unsigned long long int significand,
1251 int exponent);
1252 static ValueType128 makeDecimalRaw128( long long int significand,
1253 int exponent);
1254 static ValueType128 makeDecimalRaw128(unsigned int significand,
1255 int exponent);
1256 static ValueType128 makeDecimalRaw128( int significand,
1257 int exponent);
1258
1259 // ScaleB functions
1260
1261 /// Return the result of multiplying the specified `value` by ten raised
1262 /// to the specified `exponent`. The quantum of `value` is scaled
1263 /// according to IEEE 754's `scaleB` operations.
1264 ///
1265 /// Special value handling:
1266 /// * If `value` is quiet NaN, quiet NaN is returned.
1267 /// * If `value` is signaling NaN, quiet NaN is returned and the value
1268 /// of the macro `EDOM` is stored into `errno`.
1269 /// * If `x` is infinite, then infinity is returned.
1270 /// * If a range error due to overflow occurs, infinity is returned and
1271 ///: the value of the macro `ERANGE` is stored into `errno`.
1272 static ValueType32 scaleB(ValueType32 value, int exponent);
1273 static ValueType64 scaleB(ValueType64 value, int exponent);
1274 static ValueType128 scaleB(ValueType128 value, int exponent);
1275
1276 // Parsing functions
1277
1278 static ValueType32 parse32( const char *input);
1279 static ValueType64 parse64( const char *input);
1280 static ValueType128 parse128(const char *input);
1281 static ValueType32 parse32( const char *input, unsigned int *status);
1282 static ValueType64 parse64( const char *input, unsigned int *status);
1283
1284 /// Produce an object of the indicated return type by parsing the
1285 /// specified `input` string that represents a floating-point number
1286 /// (written in either fixed or scientific notation). Optionally
1287 /// specify `status` in which to load a bit mask of additional status
1288 /// information. The resulting decimal object is initialized as follows:
1289 ///
1290 /// * If `input` does not represent a floating-point value, then return
1291 /// a decimal object of the indicated return type initialized to a
1292 /// NaN.
1293 /// * Otherwise if `input` represents infinity (positive or negative),
1294 /// as case-insensitive "Inf" or "Infinity" string, then return a
1295 /// decimal object of the indicated return type initialized to
1296 /// infinity value with the same sign.
1297 /// * Otherwise if `input` represents zero (positive or negative), then
1298 /// return a decimal object of the indicated return type initialized
1299 /// to zero with the same sign.
1300 /// * Otherwise if `str` represents a value that has an absolute value
1301 /// that is larger than `std::numeric_limits<Decimal32>::max()` then
1302 /// store the value of the macro `ERANGE` into `errno` and return a
1303 /// decimal object of the indicated return type initialized to
1304 /// infinity with the same sign.
1305 /// * Otherwise if `input` represents a value that has an absolute
1306 /// value that is smaller than
1307 /// `std::numeric_limits<Decimal32>::min()`, then store the value of
1308 /// the macro `ERANGE` into `errno` and return a decimal object of
1309 /// the indicated return type initialized to zero with the same sign.
1310 /// * Otherwise if `input` has a value that is not exactly
1311 /// representable using `std::numeric_limits<Decimal32>::max_digit`
1312 /// decimal digits then return a decimal object of the indicated
1313 /// return type initialized to the value represented by `input`
1314 /// rounded according to the rounding direction.
1315 /// * Otherwise return a decimal object of the indicated return type
1316 /// initialized to the decimal value representation of `input`.
1317 ///
1318 /// The `*status`, if supplied, mest be 0, and may be loaded with a bit
1319 /// mask of `k_STATUS_INEXACT`, `k_STATUS_UNDERFLOW`, and
1320 /// `k_STATUS_OVERFLOW` indicating wether the conversion from text was
1321 /// inexact, underflowed, or overflowed (or some combination) respectively.
1322 ///
1323 /// \pre The behavior is undefined unless `*status` (if
1324 /// supplied) is 0.
1325 ///
1326 ///
1327 /// \note Note that the parsing follows the rules as specified for the
1328 /// `strtod32` function in section 9.6 of the ISO/EIC TR 24732 C Decimal
1329 /// Floating-Point Technical Report.
1330 ///
1331 /// Also note that the quanta of the resultant value is determined by
1332 /// the number of decimal places starting with the most significand
1333 /// digit in `input` string and cannot exceed the maximum number of
1334 /// digits necessary to differentiate all values of the indicated return
1335 /// type, for example:
1336 ///
1337 /// @code
1338 /// 'parse32("0.015") => 15e-3'
1339 /// 'parse32("1.5") => 15e-1'
1340 /// 'parse32("1.500") => 1500e-3'
1341 /// 'parse32("1.2345678) => 1234568e-6'
1342 /// @endcode
1343 static ValueType128 parse128(const char *input, unsigned int *status);
1344
1345 // Densely Packed Conversion Functions
1346
1347 /// Return a `ValueTypeXX` representing the specified `dpd`, which is
1348 /// currently in Densely Packed Decimal (DPD) format. This format is
1349 /// compatible with the IBM compiler's native type.
1353
1354 /// Return a `DecimalStorage::TypeXX` representing the specified `value`
1355 /// in Densely Packed Decimal (DPD) format. This format is compatible
1356 /// with the IBM compiler's native type.
1360
1361 // Binary Integral Conversion Functions
1362
1363 /// Return a `ValueTypeXX` representing the specified `bid`, which is
1364 /// currently in Binary Integral Decimal (BID) format. This format is
1365 /// compatible with the Intel DFP implementation type.
1369
1370 /// Return a `DecimalStorage::TypeXX` representing the specified
1371 /// `value` in Binary Integral Decimal (BID) format. This format is
1372 /// compatible with the Intel DFP implementation type.
1373 static
1375 static
1377 static
1379
1380 // Functions returning special values
1381
1382 /// Return the smallest positive normalized number `ValueType32` can
1383 /// represent (IEEE-754: +1e-95).
1384 static
1386
1387 /// Return the largest number `ValueType32` can represent (IEEE-754:
1388 /// +9.999999e+96).
1389 static
1391
1392 /// Return the difference between the least representable value of type
1393 /// `ValueType32` greater than 1 and 1 (IEEE-754: +1e-6).
1394 static
1396
1397 /// Return the maximum rounding error for the `ValueType32` type. The
1398 /// actual value returned depends on the current decimal floating point
1399 /// rounding setting.
1400 static
1402
1403 /// Return the smallest positive denormalized value for the
1404 /// `ValueType32` type (IEEE-754: +0.000001e-95).
1405 static
1407
1408 /// Return the value that represents positive infinity for the
1409 /// `ValueType32` type.
1410 static
1412
1413 /// Return a value that represents non-signaling NaN for the
1414 /// `ValueType32` type.
1415 static
1417
1418 /// Return a value that represents signaling NaN for the `ValueType32`
1419 /// type.
1420 static
1422
1423 /// Return the smallest positive normalized number `ValueType64` can
1424 /// represent (IEEE-754: +1e-383).
1425 static
1427
1428 /// Return the largest number `ValueType64` can represent (IEEE-754:
1429 /// +9.999999999999999e+384).
1430 static
1432
1433 /// Return the difference between the least representable value of type
1434 /// `ValueType64` greater than 1 and 1 (IEEE-754: +1e-15).
1435 static
1437
1438 /// Return the maximum rounding error for the `ValueType64` type. The
1439 /// actual value returned depends on the current decimal floating point
1440 /// rounding setting.
1441 static
1443
1444 /// Return the smallest positive denormalized value for the
1445 /// `ValueType64` type (IEEE-754: +0.000000000000001e-383).
1446 static
1448
1449 /// Return the value that represents positive infinity for the
1450 /// `ValueType64` type.
1451 static
1453
1454 /// Return a value that represents non-signaling NaN for the
1455 /// `ValueType64` type.
1456 static
1458
1459 /// Return a value that represents signaling NaN for the `ValueType64`
1460 /// type.
1461 static
1463
1464 /// Return the smallest positive normalized number `ValueType128` can
1465 /// represent (IEEE-754: +1e-6143).
1466 static
1468
1469 /// Return the largest number `ValueType128` can represent (IEEE-754:
1470 /// +9.999999999999999999999999999999999e+6144).
1471 static
1473
1474 /// Return the difference between the least representable value of type
1475 /// `ValueType128` greater than 1 and 1 (IEEE-754: +1e-33).
1476 static
1478
1479 /// Return the maximum rounding error for the `ValueType128` type. The
1480 /// actual value returned depends on the current decimal floating point
1481 /// rounding setting.
1482 static
1484
1485 /// Return the smallest positive denormalized value for the
1486 /// `ValueType128` type (IEEE-754:
1487 /// +0.000000000000000000000000000000001e-6143).
1488 static
1490
1491 /// Return the value that represents positive infinity for the
1492 /// `ValueType128` type.
1493 static
1495
1496 /// Return a value that represents non-signaling NaN for the
1497 /// `ValueType128` type.
1498 static
1500
1501 /// Return a value that represents signaling NaN for the `ValueType128`
1502 /// type.
1503 static
1505};
1506
1507// ============================================================================
1508// INLINE DEFINITIONS
1509// ============================================================================
1510
1511 // --------------------
1512 // class DecimalImpUtil
1513 // --------------------
1514
1515#ifdef BDLDFP_DECIMALPLATFORM_SOFTWARE
1516
1517template <class TYPE>
1518inline
1519void DecimalImpUtil::checkLiteral(const TYPE& t)
1520{
1521 (void)static_cast<This_is_not_a_floating_point_literal>(t);
1522}
1523
1524inline
1525void DecimalImpUtil::checkLiteral(double)
1526{
1527}
1528#endif
1529
1530
1531// CLASS METHODS
1532
1533 // Integer construction
1534
1535inline
1537{
1538 return Imp::int32ToDecimal32(value);
1539}
1540
1541inline
1543{
1544 return Imp::int32ToDecimal64(value);
1545}
1546
1547inline
1549{
1550 return Imp::int32ToDecimal128(value);
1551}
1552
1553
1554inline
1557{
1558 return Imp::uint32ToDecimal32(value);
1559}
1560
1561inline
1564{
1565 return Imp::uint32ToDecimal64(value);
1566}
1567
1568inline
1571{
1572 return Imp::uint32ToDecimal128(value);
1573}
1574
1575
1576inline
1579{
1580 return Imp::int64ToDecimal32(value);
1581}
1582
1583inline
1586{
1587 return Imp::int64ToDecimal64(value);
1588}
1589
1590inline
1593{
1594 return Imp::int64ToDecimal128(value);
1595}
1596
1597
1598inline
1600DecimalImpUtil::uint64ToDecimal32(unsigned long long int value)
1601{
1602 return Imp::uint64ToDecimal32(value);
1603}
1604
1605inline
1607DecimalImpUtil::uint64ToDecimal64(unsigned long long int value)
1608{
1609 return Imp::uint64ToDecimal64(value);
1610}
1611
1612inline
1614DecimalImpUtil::uint64ToDecimal128(unsigned long long int value)
1615{
1616 return Imp::uint64ToDecimal128(value);
1617}
1618
1619 // Arithmetic
1620
1621 // Addition Functions
1622
1623inline
1627{
1628 return Imp::add(lhs, rhs);
1629}
1630
1631inline
1635{
1636 return Imp::add(lhs, rhs);
1637}
1638
1642{
1643 return Imp::add(lhs, rhs);
1644}
1645
1646 // Subtraction Functions
1647
1648inline
1652{
1653 return Imp::subtract(lhs, rhs);
1654}
1655
1656inline
1660{
1661 return Imp::subtract(lhs, rhs);
1662}
1663
1664inline
1668{
1669 return Imp::subtract(lhs, rhs);
1670}
1671
1672 // Multiplication Functions
1673
1674inline
1678{
1679 return Imp::multiply(lhs, rhs);
1680}
1681
1682inline
1686{
1687 return Imp::multiply(lhs, rhs);
1688}
1689
1690inline
1694{
1695 return Imp::multiply(lhs, rhs);
1696}
1697
1698 // Division Functions
1699
1700 // Division Functions
1701
1702inline
1706{
1707 return Imp::divide(lhs, rhs);
1708}
1709
1710inline
1714{
1715 return Imp::divide(lhs, rhs);
1716}
1717
1718inline
1722{
1723 return Imp::divide(lhs, rhs);
1724}
1725
1726inline
1728 ValueType32 exponent)
1729{
1731 _IDEC_flags flags(0);
1732 retval.d_raw = __bid32_quantize(value.d_raw,
1733 exponent.d_raw,
1734 &flags);
1735 return retval;
1736}
1737
1738inline
1740 ValueType64 exponent)
1741{
1743 _IDEC_flags flags(0);
1744 retval.d_raw = __bid64_quantize(value.d_raw,
1745 exponent.d_raw,
1746 &flags);
1747 return retval;
1748}
1749
1750inline
1752 ValueType128 exponent)
1753{
1755 _IDEC_flags flags(0);
1756 retval.d_raw = __bid128_quantize(value.d_raw,
1757 exponent.d_raw,
1758 &flags);
1759 return retval;
1760}
1761
1762inline
1764 int exponent)
1765{
1766 BSLS_ASSERT(-101 <= exponent);
1767 BSLS_ASSERT( exponent <= 90);
1768
1771 1,
1772 exponent);
1773 _IDEC_flags flags(0);
1774 retval.d_raw = __bid32_quantize(value.d_raw, exp.d_raw, &flags);
1775 return retval;
1776}
1777
1778inline
1780 int exponent)
1781{
1782 BSLS_ASSERT(-398 <= exponent);
1783 BSLS_ASSERT( exponent <= 369);
1784
1787 1,
1788 exponent);
1789 _IDEC_flags flags(0);
1790 retval.d_raw = __bid64_quantize(value.d_raw, exp.d_raw, &flags);
1791 return retval;
1792}
1793
1794inline
1796 int exponent)
1797{
1798 BSLS_ASSERT(-6176 <= exponent);
1799 BSLS_ASSERT( exponent <= 6111);
1800
1803 1,
1804 exponent);
1805 _IDEC_flags flags(0);
1806 retval.d_raw = __bid128_quantize(value.d_raw, exp.d_raw, &flags);
1807 return retval;
1808}
1809
1810inline
1812{
1813 BSLS_ASSERT(x);
1814 BSLS_ASSERT(-101 <= exponent);
1815 BSLS_ASSERT( exponent <= 90);
1816
1819 1,
1820 exponent);
1821 _IDEC_flags flags(0);
1822 retval.d_raw = __bid32_quantize(y.d_raw, exp.d_raw, &flags);
1823 if (DecimalImpUtil::equal(retval, y)) {
1824 *x = retval;
1825 return 0;
1826 }
1827 return -1;
1828}
1829
1830inline
1832{
1833 BSLS_ASSERT(x);
1834 BSLS_ASSERT(-398 <= exponent);
1835 BSLS_ASSERT( exponent <= 369);
1838 1,
1839 exponent);
1840 _IDEC_flags flags(0);
1841 retval.d_raw = __bid64_quantize(y.d_raw, exp.d_raw, &flags);
1842 if (DecimalImpUtil::equal(retval, y)) {
1843 *x = retval;
1844 return 0;
1845 }
1846 return -1;
1847}
1848
1849inline
1851{
1852 BSLS_ASSERT(x);
1853 BSLS_ASSERT(-6176 <= exponent);
1854 BSLS_ASSERT( exponent <= 6111);
1855
1858 1,
1859 exponent);
1860 _IDEC_flags flags(0);
1861 retval.d_raw = __bid128_quantize(y.d_raw, exp.d_raw, &flags);
1862 if (DecimalImpUtil::equal(retval, y)) {
1863 *x = retval;
1864 return 0;
1865 }
1866 return -1;
1867}
1868
1869inline
1871{
1872 return __bid32_sameQuantum(x.d_raw, y.d_raw);
1873}
1874
1875inline
1877{
1878 return __bid64_sameQuantum(x.d_raw, y.d_raw);
1879}
1880
1881inline
1883{
1884 return __bid128_sameQuantum(x.d_raw, y.d_raw);
1885}
1886
1887
1888 // Math functions
1889
1890inline
1892{
1893 _IDEC_flags flags(0);
1894 long int ret = __bid32_lrint(x.d_raw, &flags);
1895 if (BID_INVALID_EXCEPTION & flags) {
1896 errno = EDOM;
1897 }
1898 return ret;
1899}
1900
1901inline
1903{
1904 _IDEC_flags flags(0);
1905 long int ret = __bid64_lrint(x.d_raw, &flags);
1906 if (BID_INVALID_EXCEPTION & flags) {
1907 errno = EDOM;
1908 }
1909 return ret;
1910}
1911
1912inline
1914{
1915 _IDEC_flags flags(0);
1916 long int ret = __bid128_lrint(x.d_raw, &flags);
1917 if (BID_INVALID_EXCEPTION & flags) {
1918 errno = EDOM;
1919 }
1920 return ret;
1921}
1922
1923inline
1925{
1926 _IDEC_flags flags(0);
1927 long long int ret = __bid32_llrint(x.d_raw, &flags);
1928 if (BID_INVALID_EXCEPTION & flags) {
1929 errno = EDOM;
1930 }
1931 return ret;
1932}
1933
1934inline
1936{
1937 _IDEC_flags flags(0);
1938 long long int ret = __bid64_llrint(x.d_raw, &flags);
1939 if (BID_INVALID_EXCEPTION & flags) {
1940 errno = EDOM;
1941 }
1942 return ret;
1943}
1944
1945inline
1947{
1948 _IDEC_flags flags(0);
1949 long long int ret = __bid128_llrint(x.d_raw, &flags);
1950 if (BID_INVALID_EXCEPTION & flags) {
1951 errno = EDOM;
1952 }
1953 return ret;
1954}
1955
1956inline
1959{
1961 _IDEC_flags flags(0);
1962 retval.d_raw = __bid32_nextafter(x.d_raw, y.d_raw, &flags);
1963 if (BID_OVERFLOW_EXCEPTION & flags ||
1964 BID_UNDERFLOW_EXCEPTION & flags)
1965 {
1966 errno = ERANGE;
1967 }
1968 if (BID_INVALID_EXCEPTION & flags) {
1969 errno = EDOM;
1970 }
1971 return retval;
1972}
1973
1974inline
1977{
1979 _IDEC_flags flags(0);
1980 retval.d_raw = __bid64_nextafter(x.d_raw, y.d_raw, &flags);
1981 if (BID_OVERFLOW_EXCEPTION & flags ||
1982 BID_UNDERFLOW_EXCEPTION & flags)
1983 {
1984 errno = ERANGE;
1985 }
1986 if (BID_INVALID_EXCEPTION & flags) {
1987 errno = EDOM;
1988 }
1989 return retval;
1990}
1991
1992inline
1995{
1997 _IDEC_flags flags(0);
1998 retval.d_raw = __bid128_nextafter(x.d_raw, y.d_raw, &flags);
1999 if (BID_OVERFLOW_EXCEPTION & flags ||
2000 BID_UNDERFLOW_EXCEPTION & flags)
2001 {
2002 errno = ERANGE;
2003 }
2004 if (BID_INVALID_EXCEPTION & flags) {
2005 errno = EDOM;
2006 }
2007 return retval;
2008}
2009
2010inline
2013{
2015 _IDEC_flags flags(0);
2016 retval.d_raw = __bid32_nexttoward(x.d_raw, y.d_raw, &flags);
2017 if (BID_OVERFLOW_EXCEPTION & flags ||
2018 BID_UNDERFLOW_EXCEPTION & flags)
2019 {
2020 errno = ERANGE;
2021 }
2022 if (BID_INVALID_EXCEPTION & flags) {
2023 errno = EDOM;
2024 }
2025 return retval;
2026}
2027
2028inline
2031{
2033 _IDEC_flags flags(0);
2034 retval.d_raw = __bid64_nexttoward(x.d_raw, y.d_raw, &flags);
2035 if (BID_OVERFLOW_EXCEPTION & flags ||
2036 BID_UNDERFLOW_EXCEPTION & flags)
2037 {
2038 errno = ERANGE;
2039 }
2040 if (BID_INVALID_EXCEPTION & flags) {
2041 errno = EDOM;
2042 }
2043 return retval;
2044}
2045
2046inline
2049{
2051 _IDEC_flags flags(0);
2052 retval.d_raw = __bid128_nexttoward(x.d_raw, y.d_raw, &flags);
2053 if (BID_OVERFLOW_EXCEPTION & flags ||
2054 BID_UNDERFLOW_EXCEPTION & flags)
2055 {
2056 errno = ERANGE;
2057 }
2058 if (BID_INVALID_EXCEPTION & flags) {
2059 errno = EDOM;
2060 }
2061 return retval;
2062}
2063
2064inline
2067{
2069 _IDEC_flags flags(0);
2070 retval.d_raw = __bid32_pow(base.d_raw, exp.d_raw, &flags);
2071 if (BID_OVERFLOW_EXCEPTION & flags ||
2072 BID_UNDERFLOW_EXCEPTION & flags ||
2073 BID_ZERO_DIVIDE_EXCEPTION & flags)
2074 {
2075 errno = ERANGE;
2076 }
2077 if (BID_INVALID_EXCEPTION & flags) {
2078 errno = EDOM;
2079 }
2080 return retval;
2081}
2082
2083inline
2086{
2088 _IDEC_flags flags(0);
2089 retval.d_raw = __bid64_pow(base.d_raw, exp.d_raw, &flags);
2090 if (BID_OVERFLOW_EXCEPTION & flags ||
2091 BID_UNDERFLOW_EXCEPTION & flags ||
2092 BID_ZERO_DIVIDE_EXCEPTION & flags)
2093 {
2094 errno = ERANGE;
2095 }
2096 if (BID_INVALID_EXCEPTION & flags) {
2097 errno = EDOM;
2098 }
2099
2100 return retval;
2101}
2102
2103inline
2106{
2108 _IDEC_flags flags(0);
2109 retval.d_raw = __bid128_pow(base.d_raw, exp.d_raw, &flags);
2110 if (BID_OVERFLOW_EXCEPTION & flags ||
2111 BID_UNDERFLOW_EXCEPTION & flags ||
2112 BID_ZERO_DIVIDE_EXCEPTION & flags)
2113 {
2114 errno = ERANGE;
2115 }
2116 if (BID_INVALID_EXCEPTION & flags) {
2117 errno = EDOM;
2118 }
2119 return retval;
2120}
2121
2122inline
2124{
2126 _IDEC_flags flags(0);
2127 retval.d_raw = __bid32_round_integral_positive(x.d_raw, &flags);
2128 if (BID_INVALID_EXCEPTION & flags) {
2129 errno = EDOM;
2130 }
2131 return retval;
2132}
2133
2134inline
2136{
2138 _IDEC_flags flags(0);
2139 retval.d_raw = __bid64_round_integral_positive(x.d_raw, &flags);
2140 if (BID_INVALID_EXCEPTION & flags) {
2141 errno = EDOM;
2142 }
2143 return retval;
2144}
2145
2146inline
2148{
2150 _IDEC_flags flags(0);
2151 retval.d_raw = __bid128_round_integral_positive(x.d_raw, &flags);
2152 if (BID_INVALID_EXCEPTION & flags) {
2153 errno = EDOM;
2154 }
2155 return retval;
2156
2157}
2158
2159inline
2161{
2163 _IDEC_flags flags(0);
2164 retval.d_raw = __bid32_round_integral_negative(x.d_raw, &flags);
2165 if (BID_INVALID_EXCEPTION & flags) {
2166 errno = EDOM;
2167 }
2168 return retval;
2169}
2170
2171inline
2173{
2175 _IDEC_flags flags(0);
2176 retval.d_raw = __bid64_round_integral_negative(x.d_raw, &flags);
2177 if (BID_INVALID_EXCEPTION & flags) {
2178 errno = EDOM;
2179 }
2180 return retval;
2181}
2182
2183inline
2185{
2187 _IDEC_flags flags(0);
2188 retval.d_raw = __bid128_round_integral_negative(x.d_raw, &flags);
2189 if (BID_INVALID_EXCEPTION & flags) {
2190 errno = EDOM;
2191 }
2192 return retval;
2193}
2194
2195inline
2197{
2199 _IDEC_flags flags(0);
2200 retval.d_raw = __bid32_round_integral_nearest_away(x.d_raw, &flags);
2201 if (BID_INVALID_EXCEPTION & flags) {
2202 errno = EDOM;
2203 }
2204 return retval;
2205}
2206
2207inline
2209{
2211 _IDEC_flags flags(0);
2212 retval.d_raw = __bid64_round_integral_nearest_away(x.d_raw, &flags);
2213 if (BID_INVALID_EXCEPTION & flags) {
2214 errno = EDOM;
2215 }
2216 return retval;
2217}
2218
2219inline
2221{
2223 _IDEC_flags flags(0);
2224 retval.d_raw = __bid128_round_integral_nearest_away(x.d_raw, &flags);
2225 if (BID_INVALID_EXCEPTION & flags) {
2226 errno = EDOM;
2227 }
2228 return retval;
2229}
2230
2231inline
2233{
2234 _IDEC_flags flags(0);
2235 long int rv = __bid32_lround(x.d_raw, &flags);
2236 if (BID_INVALID_EXCEPTION & flags) {
2237 errno = EDOM;
2238 }
2239 return rv;
2240}
2241
2242inline
2244{
2245 _IDEC_flags flags(0);
2246 long int rv = __bid64_lround(x.d_raw, &flags);
2247 if (BID_INVALID_EXCEPTION & flags) {
2248 errno = EDOM;
2249 }
2250 return rv;
2251}
2252
2253inline
2255{
2256 _IDEC_flags flags(0);
2257 long int rv = __bid128_lround(x.d_raw, &flags);
2258 if (BID_INVALID_EXCEPTION & flags) {
2259 errno = EDOM;
2260 }
2261 return rv;
2262}
2263
2264inline
2266{
2268 _IDEC_flags flags(0);
2269 retval.d_raw = __bid32_round_integral_zero(x.d_raw, &flags);
2270 if (BID_INVALID_EXCEPTION & flags) {
2271 errno = EDOM;
2272 }
2273 return retval;
2274}
2275
2276inline
2278{
2280 _IDEC_flags flags(0);
2281 retval.d_raw = __bid64_round_integral_zero(x.d_raw, &flags);
2282 if (BID_INVALID_EXCEPTION & flags) {
2283 errno = EDOM;
2284 }
2285 return retval;
2286}
2287
2288inline
2290{
2292 _IDEC_flags flags(0);
2293 retval.d_raw = __bid128_round_integral_zero(x.d_raw, &flags);
2294 if (BID_INVALID_EXCEPTION & flags) {
2295 errno = EDOM;
2296 }
2297 return retval;
2298}
2299
2300
2301inline
2303{
2304 ValueType32 rv;
2305 _IDEC_flags flags(0);
2306 rv.d_raw = __bid32_fma(x.d_raw, y.d_raw, z.d_raw, &flags);
2307 if (BID_INVALID_EXCEPTION & flags) {
2308 errno = EDOM;
2309 }
2310 return rv;
2311}
2312
2313inline
2315{
2316 ValueType64 rv;
2317 _IDEC_flags flags(0);
2318 rv.d_raw = __bid64_fma(x.d_raw, y.d_raw, z.d_raw, &flags);
2319 if (BID_INVALID_EXCEPTION & flags) {
2320 errno = EDOM;
2321 }
2322 return rv;
2323}
2324
2325inline
2327{
2328 ValueType128 rv;
2329 _IDEC_flags flags(0);
2330 rv.d_raw = __bid128_fma(x.d_raw, y.d_raw, z.d_raw, &flags);
2331 if (BID_INVALID_EXCEPTION & flags) {
2332 errno = EDOM;
2333 }
2334 return rv;
2335}
2336 // Selecting, converting functions
2337
2338inline
2340{
2341 ValueType32 rv;
2342 rv.d_raw = __bid32_abs(value.d_raw);
2343 return rv;
2344}
2345
2346inline
2348{
2349 ValueType64 rv;
2350 rv.d_raw = __bid64_abs(value.d_raw);
2351 return rv;
2352}
2353
2354inline
2356{
2357 ValueType128 rv;
2358 rv.d_raw = __bid128_abs(value.d_raw);
2359 return rv;
2360}
2361
2362inline
2364{
2365 ValueType32 rv;
2366 _IDEC_flags flags(0);
2367 rv.d_raw = __bid32_sqrt(value.d_raw, &flags);
2368 if (BID_INVALID_EXCEPTION & flags) {
2369 errno = EDOM;
2370 }
2371 return rv;
2372}
2373
2374inline
2376{
2377 ValueType64 rv;
2378 _IDEC_flags flags(0);
2379 rv.d_raw = __bid64_sqrt(value.d_raw, &flags);
2380 if (BID_INVALID_EXCEPTION & flags) {
2381 errno = EDOM;
2382 }
2383 return rv;
2384}
2385
2386inline
2388{
2389 ValueType128 rv;
2390 _IDEC_flags flags(0);
2391 rv.d_raw = __bid128_sqrt(value.d_raw, &flags);
2392 if (BID_INVALID_EXCEPTION & flags) {
2393 errno = EDOM;
2394 }
2395 return rv;
2396}
2397
2398inline
2400 ValueType32 y)
2401{
2402 ValueType32 rv;
2403 rv.d_raw = __bid32_copySign(x.d_raw, y.d_raw);
2404 return rv;
2405}
2406
2407inline
2409 ValueType64 y)
2410{
2411 ValueType64 rv;
2412 rv.d_raw = __bid64_copySign(x.d_raw, y.d_raw);
2413 return rv;
2414}
2415
2416inline
2418 ValueType128 y)
2419{
2420 ValueType128 rv;
2421 rv.d_raw = __bid128_copySign(x.d_raw, y.d_raw);
2422 return rv;
2423}
2424
2425inline
2427{
2428 ValueType32 rv;
2429 _IDEC_flags flags(0);
2430 rv.d_raw = __bid32_exp(value.d_raw, &flags);
2431 if (BID_INVALID_EXCEPTION & flags) {
2432 errno = EDOM;
2433 }
2434 if (BID_OVERFLOW_EXCEPTION & flags) {
2435 errno = ERANGE;
2436 }
2437 return rv;
2438}
2439
2440inline
2442{
2443 ValueType64 rv;
2444 _IDEC_flags flags(0);
2445 rv.d_raw = __bid64_exp(value.d_raw, &flags);
2446 if (BID_INVALID_EXCEPTION & flags) {
2447 errno = EDOM;
2448 }
2449 if (BID_OVERFLOW_EXCEPTION & flags) {
2450 errno = ERANGE;
2451 }
2452 return rv;
2453}
2454
2455inline
2457{
2458 ValueType128 rv;
2459 _IDEC_flags flags(0);
2460 rv.d_raw = __bid128_exp(value.d_raw, &flags);
2461 if (BID_INVALID_EXCEPTION & flags) {
2462 errno = EDOM;
2463 }
2464 if (BID_OVERFLOW_EXCEPTION & flags) {
2465 errno = ERANGE;
2466 }
2467 return rv;
2468}
2469
2470inline
2472{
2473 ValueType32 rv;
2474 _IDEC_flags flags(0);
2475 rv.d_raw = __bid32_log(value.d_raw, &flags);
2476 if (BID_INVALID_EXCEPTION & flags) {
2477 errno = EDOM;
2478 }
2479 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2480 errno = ERANGE;
2481 }
2482 return rv;
2483}
2484
2485inline
2487{
2488 ValueType64 rv;
2489 _IDEC_flags flags(0);
2490 rv.d_raw = __bid64_log(value.d_raw, &flags);
2491 if (BID_INVALID_EXCEPTION & flags) {
2492 errno = EDOM;
2493 }
2494 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2495 errno = ERANGE;
2496 }
2497 return rv;
2498}
2499
2500inline
2502{
2503 ValueType128 rv;
2504 _IDEC_flags flags(0);
2505 rv.d_raw = __bid128_log(value.d_raw, &flags);
2506 if (BID_INVALID_EXCEPTION & flags) {
2507 errno = EDOM;
2508 }
2509 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2510 errno = ERANGE;
2511 }
2512 return rv;
2513}
2514
2515inline
2517{
2518 ValueType32 rv;
2519 _IDEC_flags flags(0);
2520 rv.d_raw = __bid32_logb(value.d_raw, &flags);
2521 if (BID_INVALID_EXCEPTION & flags) {
2522 errno = EDOM;
2523 }
2524 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2525 errno = ERANGE;
2526 }
2527 return rv;
2528}
2529
2530inline
2532{
2533 ValueType64 rv;
2534 _IDEC_flags flags(0);
2535 rv.d_raw = __bid64_logb(value.d_raw, &flags);
2536 if (BID_INVALID_EXCEPTION & flags) {
2537 errno = EDOM;
2538 }
2539 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2540 errno = ERANGE;
2541 }
2542 return rv;
2543}
2544
2545inline
2547{
2548 ValueType128 rv;
2549 _IDEC_flags flags(0);
2550 rv.d_raw = __bid128_logb(value.d_raw, &flags);
2551 if (BID_INVALID_EXCEPTION & flags) {
2552 errno = EDOM;
2553 }
2554 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2555 errno = ERANGE;
2556 }
2557 return rv;
2558}
2559
2560inline
2562{
2563 ValueType32 rv;
2564 _IDEC_flags flags(0);
2565 rv.d_raw = __bid32_log10(value.d_raw, &flags);
2566 if (BID_INVALID_EXCEPTION & flags) {
2567 errno = EDOM;
2568 }
2569 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2570 errno = ERANGE;
2571 }
2572 return rv;
2573}
2574
2575inline
2577{
2578 ValueType64 rv;
2579 _IDEC_flags flags(0);
2580 rv.d_raw = __bid64_log10(value.d_raw, &flags);
2581 if (BID_INVALID_EXCEPTION & flags) {
2582 errno = EDOM;
2583 }
2584 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2585 errno = ERANGE;
2586 }
2587 return rv;
2588}
2589
2590inline
2592{
2593 ValueType128 rv;
2594 _IDEC_flags flags(0);
2595 rv.d_raw = __bid128_log10(value.d_raw, &flags);
2596 if (BID_INVALID_EXCEPTION & flags) {
2597 errno = EDOM;
2598 }
2599 if (BID_ZERO_DIVIDE_EXCEPTION & flags) {
2600 errno = ERANGE;
2601 }
2602 return rv;
2603}
2604
2605inline
2607 ValueType32 y)
2608{
2609 ValueType32 rv;
2610 _IDEC_flags flags(0);
2611 rv.d_raw = __bid32_fmod(x.d_raw, y.d_raw, &flags);
2612 if (BID_INVALID_EXCEPTION & flags) {
2613 errno = EDOM;
2614 }
2615 return rv;
2616}
2617
2618inline
2620 ValueType64 y)
2621{
2622 ValueType64 rv;
2623 _IDEC_flags flags(0);
2624 rv.d_raw = __bid64_fmod(x.d_raw, y.d_raw, &flags);
2625 if (BID_INVALID_EXCEPTION & flags) {
2626 errno = EDOM;
2627 }
2628 return rv;
2629}
2630
2631inline
2633 ValueType128 y)
2634{
2635 ValueType128 rv;
2636 _IDEC_flags flags(0);
2637 rv.d_raw = __bid128_fmod(x.d_raw, y.d_raw, &flags);
2638 if (BID_INVALID_EXCEPTION & flags) {
2639 errno = EDOM;
2640 }
2641 return rv;
2642}
2643
2644inline
2646 ValueType32 y)
2647{
2648 ValueType32 rv;
2649 _IDEC_flags flags(0);
2650 rv.d_raw = __bid32_rem(x.d_raw, y.d_raw, &flags);
2651 if (BID_INVALID_EXCEPTION & flags) {
2652 errno = EDOM;
2653 }
2654 return rv;
2655}
2656
2657inline
2659 ValueType64 y)
2660{
2661 ValueType64 rv;
2662 _IDEC_flags flags(0);
2663 rv.d_raw = __bid64_rem(x.d_raw, y.d_raw, &flags);
2664 if (BID_INVALID_EXCEPTION & flags) {
2665 errno = EDOM;
2666 }
2667 return rv;
2668}
2669
2670inline
2672 ValueType128 y)
2673{
2674 ValueType128 rv;
2675 _IDEC_flags flags(0);
2676 rv.d_raw = __bid128_rem(x.d_raw, y.d_raw, &flags);
2677 if (BID_INVALID_EXCEPTION & flags) {
2678 errno = EDOM;
2679 }
2680 return rv;
2681}
2682
2683 // Negation Functions
2684
2685inline
2688{
2689 return Imp::negate(value);
2690}
2691
2692inline
2695{
2696 return Imp::negate(value);
2697}
2698
2699inline
2702{
2703 return Imp::negate(value);
2704}
2705
2706 // Comparison
2707
2708 // Less Than Functions
2709
2710inline
2711bool
2714{
2715 return Imp::less(lhs, rhs);
2716}
2717
2718inline
2719bool
2722{
2723 return Imp::less(lhs, rhs);
2724}
2725
2726inline
2727bool
2730{
2731 return Imp::less(lhs, rhs);
2732}
2733
2734 // Greater Than Functions
2735
2736inline
2737bool
2740{
2741 return Imp::greater(lhs, rhs);
2742}
2743
2744inline
2745bool
2748{
2749 return Imp::greater(lhs, rhs);
2750}
2751
2752inline
2753bool
2756{
2757 return Imp::greater(lhs, rhs);
2758}
2759
2760 // Less Or Equal Functions
2761
2762inline
2763bool
2766{
2767 return Imp::lessEqual(lhs, rhs);
2768}
2769
2770inline
2771bool
2774{
2775 return Imp::lessEqual(lhs, rhs);
2776}
2777
2778inline
2779bool
2782{
2783 return Imp::lessEqual(lhs, rhs);
2784}
2785
2786 // Greater Or Equal Functions
2787
2788inline
2789bool
2792{
2793 return Imp::greaterEqual(lhs, rhs);
2794}
2795
2796inline
2797bool
2800{
2801 return Imp::greaterEqual(lhs, rhs);
2802}
2803
2804inline
2805bool
2808{
2809 return Imp::greaterEqual(lhs, rhs);
2810}
2811
2812 // Equality Functions
2813
2814inline
2815bool
2818{
2819 return Imp::equal(lhs, rhs);
2820}
2821
2822inline
2823bool
2826{
2827 return Imp::equal(lhs, rhs);
2828}
2829
2830inline
2831bool
2834{
2835 return Imp::equal(lhs, rhs);
2836}
2837
2838 // Inequality Functions
2839
2840inline
2841bool
2844{
2845 return Imp::notEqual(lhs, rhs);
2846}
2847
2848inline
2849bool
2852{
2853 return Imp::notEqual(lhs, rhs);
2854}
2855
2856inline
2857bool
2860{
2861 return Imp::notEqual(lhs, rhs);
2862}
2863
2864 // Inter-type Conversion functions
2865
2866inline
2869{
2870 return Imp::convertToDecimal32(input);
2871}
2872
2873inline
2876{
2877 return Imp::convertToDecimal32(input);
2878}
2879
2880inline
2883{
2884 return Imp::convertToDecimal64(input);
2885}
2886
2887inline
2890{
2891 return Imp::convertToDecimal64(input);
2892}
2893
2894inline
2897{
2898 return Imp::convertToDecimal128(input);
2899}
2900
2901inline
2904{
2905 return Imp::convertToDecimal128(input);
2906}
2907
2908 // Binary floating point conversion functions
2909
2910inline
2913{
2914 return Imp::binaryToDecimal32(value);
2915}
2916
2917inline
2920{
2921 return Imp::binaryToDecimal32(value);
2922}
2923
2924inline
2927{
2928 return Imp::binaryToDecimal64(value);
2929}
2930
2931inline
2934{
2935 return Imp::binaryToDecimal64(value);
2936}
2937
2938inline
2941{
2942 return Imp::binaryToDecimal128(value);
2943}
2944
2945inline
2948{
2949 return Imp::binaryToDecimal128(value);
2950}
2951
2952 // makeDecimalRaw Functions
2953
2954inline
2956DecimalImpUtil::makeDecimalRaw32(int significand, int exponent)
2957{
2958 BSLS_ASSERT(-101 <= exponent);
2959 BSLS_ASSERT( exponent <= 90);
2960 BSLS_ASSERT(bsl::max(significand, -significand) <= 9999999);
2961 return Imp::makeDecimalRaw32(significand, exponent);
2962}
2963
2964
2965inline
2967DecimalImpUtil::makeDecimalRaw64(unsigned long long significand, int exponent)
2968{
2969 BSLS_ASSERT(-398 <= exponent);
2970 BSLS_ASSERT( exponent <= 369);
2971 BSLS_ASSERT(significand <= 9999999999999999LL);
2972
2973 return Imp::makeDecimalRaw64(significand, exponent);
2974}
2975
2976inline
2978DecimalImpUtil::makeDecimalRaw64(long long significand, int exponent)
2979{
2980 BSLS_ASSERT(-398 <= exponent);
2981 BSLS_ASSERT( exponent <= 369);
2982 BSLS_ASSERT(std::max(significand, -significand) <= 9999999999999999LL);
2983
2984 return Imp::makeDecimalRaw64(significand, exponent);
2985}
2986
2987inline
2989DecimalImpUtil::makeDecimalRaw64(unsigned int significand, int exponent)
2990{
2991 BSLS_ASSERT(-398 <= exponent);
2992 BSLS_ASSERT( exponent <= 369);
2993
2994 return Imp::makeDecimalRaw64(significand, exponent);
2995}
2996
2997inline
2999DecimalImpUtil::makeDecimalRaw64(int significand, int exponent)
3000{
3001 BSLS_ASSERT(-398 <= exponent);
3002 BSLS_ASSERT( exponent <= 369);
3003 return Imp::makeDecimalRaw64(significand, exponent);
3004}
3005
3006
3007inline
3009DecimalImpUtil::makeDecimalRaw128(unsigned long long significand, int exponent)
3010{
3011 BSLS_ASSERT(-6176 <= exponent);
3012 BSLS_ASSERT( exponent <= 6111);
3013
3014 return Imp::makeDecimalRaw128(significand, exponent);
3015}
3016
3017inline
3019DecimalImpUtil::makeDecimalRaw128(long long significand, int exponent)
3020{
3021 BSLS_ASSERT(-6176 <= exponent);
3022 BSLS_ASSERT( exponent <= 6111);
3023
3024 return Imp::makeDecimalRaw128(significand, exponent);
3025}
3026
3027inline
3029DecimalImpUtil::makeDecimalRaw128(unsigned int significand, int exponent)
3030{
3031 BSLS_ASSERT(-6176 <= exponent);
3032 BSLS_ASSERT( exponent <= 6111);
3033
3034 return Imp::makeDecimalRaw128(significand, exponent);
3035}
3036
3037inline
3039DecimalImpUtil::makeDecimalRaw128(int significand, int exponent)
3040{
3041 BSLS_ASSERT(-6176 <= exponent);
3042 BSLS_ASSERT( exponent <= 6111);
3043
3044 return Imp::makeDecimalRaw128(significand, exponent);
3045}
3046
3047 // IEEE Scale B Functions
3048
3049inline
3052{
3053 ValueType32 result;
3054 _IDEC_flags flags(0);
3055 result.d_raw = __bid32_scalbn(value.d_raw, exponent, &flags);
3056 if (BID_INVALID_EXCEPTION & flags) {
3057 errno = EDOM;
3058 }
3059 if (BID_OVERFLOW_EXCEPTION & flags) {
3060 errno = ERANGE;
3061 }
3062 return result;
3063}
3064
3065inline
3068{
3069 ValueType64 result;
3070 _IDEC_flags flags(0);
3071 result.d_raw = __bid64_scalbn(value.d_raw, exponent, &flags);
3072 if (BID_INVALID_EXCEPTION & flags) {
3073 errno = EDOM;
3074 }
3075 if (BID_OVERFLOW_EXCEPTION & flags) {
3076 errno = ERANGE;
3077 }
3078 return result;
3079}
3080
3081inline
3084{
3085 ValueType128 result;
3086 _IDEC_flags flags(0);
3087 result.d_raw = __bid128_scalbn(value.d_raw, exponent, &flags);
3088 if (BID_INVALID_EXCEPTION & flags) {
3089 errno = EDOM;
3090 }
3091 if (BID_OVERFLOW_EXCEPTION & flags) {
3092 errno = ERANGE;
3093 }
3094 return result;
3095}
3096 // Parsing functions
3097
3098inline
3100DecimalImpUtil::parse32(const char *input)
3101{
3102 return Imp::parse32(input);
3103}
3104
3105inline
3107DecimalImpUtil::parse64(const char *input)
3108{
3109 return Imp::parse64(input);
3110}
3111
3112inline
3115{
3116 return Imp::parse128(input);
3117}
3118
3119inline
3121DecimalImpUtil::parse32(const char *input, unsigned int *status)
3122{
3123 BSLS_ASSERT(0 == *status);
3124 return Imp::parse32(input, status);
3125}
3126
3127inline
3129DecimalImpUtil::parse64(const char *input, unsigned int *status)
3130{
3131 BSLS_ASSERT(0 == *status);
3132 return Imp::parse64(input, status);
3133}
3134
3135inline
3137DecimalImpUtil::parse128(const char *input, unsigned int *status)
3138{
3139 BSLS_ASSERT(0 == *status);
3140 return Imp::parse128(input, status);
3141}
3142
3143 // Densely Packed Conversion Functions
3144inline
3147{
3148 return Imp::convertDPDtoBID(dpd);
3149}
3150
3151inline
3154{
3155 return Imp::convertDPDtoBID(dpd);
3156}
3157
3158inline
3161{
3162 return Imp::convertDPDtoBID(dpd);
3163}
3164
3165inline
3168{
3169 return Imp::convertBIDtoDPD(value);
3170}
3171
3172inline
3175{
3176 return Imp::convertBIDtoDPD(value);
3177}
3178
3179inline
3182{
3183 return Imp::convertBIDtoDPD(value);
3184}
3185 // Binary Integral Conversion Functions
3186
3187inline
3190{
3191 return Imp::convertFromBID(bid);
3192}
3193
3194inline
3197{
3198 return Imp::convertFromBID(bid);
3199}
3200
3201inline
3204{
3205 return Imp::convertFromBID(bid);
3206}
3207
3208inline
3211{
3212 return Imp::convertToBID(value);
3213}
3214
3215inline
3218{
3219 return Imp::convertToBID(value);
3220}
3221
3222inline
3225{
3226 return Imp::convertToBID(value);
3227}
3228
3229} // close package namespace
3230
3231
3232#endif
3233
3234// ----------------------------------------------------------------------------
3235// Copyright 2014 Bloomberg Finance L.P.
3236//
3237// Licensed under the Apache License, Version 2.0 (the "License");
3238// you may not use this file except in compliance with the License.
3239// You may obtain a copy of the License at
3240//
3241// http://www.apache.org/licenses/LICENSE-2.0
3242//
3243// Unless required by applicable law or agreed to in writing, software
3244// distributed under the License is distributed on an "AS IS" BASIS,
3245// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3246// See the License for the specific language governing permissions and
3247// limitations under the License.
3248// ----------------------------- END-OF-FILE ----------------------------------
3249
3250/** @} */
3251/** @} */
3252/** @} */
Definition bdldfp_decimalformatconfig.h:120
Definition bdldfp_decimalimputil.h:238
static ValueType32 min32() BSLS_KEYWORD_NOEXCEPT
static ValueType32 remainder(ValueType32 x, ValueType32 y)
Definition bdldfp_decimalimputil.h:2645
static ValueType32 trunc(ValueType32 x)
Definition bdldfp_decimalimputil.h:2265
static ValueType64 makeDecimal64(long long int significand, int exponent)
static ValueType32 log(ValueType32 x)
Definition bdldfp_decimalimputil.h:2471
static ValueType128 roundError128() BSLS_KEYWORD_NOEXCEPT
static ValueType128 int32ToDecimal128(int value)
Definition bdldfp_decimalimputil.h:1548
static ValueType64 convertToDecimal64(const ValueType32 &input)
Definition bdldfp_decimalimputil.h:2882
static ValueType128 denormMin128() BSLS_KEYWORD_NOEXCEPT
static ValueType32 normalize(ValueType32 original)
static bool lessEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2764
static ValueType128 makeDecimalRaw128(unsigned long long int significand, int exponent)
static ValueType32 fma(ValueType32 x, ValueType32 y, ValueType32 z)
Definition bdldfp_decimalimputil.h:2302
static ValueType64 max64() BSLS_KEYWORD_NOEXCEPT
static ValueType128 convertToDecimal128(const ValueType32 &input)
Definition bdldfp_decimalimputil.h:2896
static ValueType32 scaleB(ValueType32 value, int exponent)
Definition bdldfp_decimalimputil.h:3051
static ValueType32 signalingNaN32() BSLS_KEYWORD_NOEXCEPT
static ValueType64 epsilon64() BSLS_KEYWORD_NOEXCEPT
static ValueType32 pow(ValueType32 base, ValueType32 exp)
Definition bdldfp_decimalimputil.h:2066
static ValueType64 roundError64() BSLS_KEYWORD_NOEXCEPT
static ValueType64 parse64(const char *input)
Definition bdldfp_decimalimputil.h:3107
static ValueType128 max128() BSLS_KEYWORD_NOEXCEPT
static ValueType32 binaryToDecimal32(float value)
Definition bdldfp_decimalimputil.h:2912
static int format(char *buffer, int length, ValueType64 value, const DecimalFormatConfig &cfg)
static int decompose(int *sign, Uint128 *significand, int *exponent, ValueType128 value)
static long long int llrint(ValueType32 x)
Definition bdldfp_decimalimputil.h:1924
static ValueType64 infinity64() BSLS_KEYWORD_NOEXCEPT
static ValueType128 infinity128() BSLS_KEYWORD_NOEXCEPT
static ValueType32 parse32(const char *input)
Definition bdldfp_decimalimputil.h:3100
static bool notEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2842
static ValueType32 floor(ValueType32 x)
Definition bdldfp_decimalimputil.h:2160
static ValueType32 copySign(ValueType32 x, ValueType32 y)
Definition bdldfp_decimalimputil.h:2399
static ValueType32 convertDPDtoBID(DecimalStorage::Type32 dpd)
Definition bdldfp_decimalimputil.h:3146
static bool less(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2712
Imp::ValueType64 ValueType64
Definition bdldfp_decimalimputil.h:250
static ValueType32 round(ValueType32 x)
Definition bdldfp_decimalimputil.h:2196
static ValueType32 uint32ToDecimal32(unsigned int value)
Definition bdldfp_decimalimputil.h:1556
static bool greater(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2738
static ValueType32 fabs(ValueType32 x)
Definition bdldfp_decimalimputil.h:2339
static ValueType32 fmod(ValueType32 x, ValueType32 y)
Definition bdldfp_decimalimputil.h:2606
static ValueType32 log10(ValueType32 x)
Definition bdldfp_decimalimputil.h:2561
static ValueType64 makeDecimalRaw64(long long int significand, int exponent)
static ValueType32 multiply(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1676
static ValueType32 convertFromBID(DecimalStorage::Type32 bid)
Definition bdldfp_decimalimputil.h:3189
static ValueType32 divide(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1704
static int decompose(int *sign, bsls::Types::Uint64 *significand, int *exponent, ValueType64 value)
static ValueType64 min64() BSLS_KEYWORD_NOEXCEPT
static ValueType32 epsilon32() BSLS_KEYWORD_NOEXCEPT
static ValueType32 roundError32() BSLS_KEYWORD_NOEXCEPT
static int decompose(int *sign, unsigned int *significand, int *exponent, ValueType32 value)
static ValueType64 normalize(ValueType64 original)
Imp::ValueType128 ValueType128
Definition bdldfp_decimalimputil.h:251
static ValueType32 makeDecimalRaw32(int significand, int exponent)
Definition bdldfp_decimalimputil.h:2956
static ValueType32 logB(ValueType32 x)
Definition bdldfp_decimalimputil.h:2516
static DecimalStorage::Type32 convertToBID(ValueType32 value)
Definition bdldfp_decimalimputil.h:3210
static int format(char *buffer, int length, ValueType32 value, const DecimalFormatConfig &cfg)
static ValueType64 makeDecimal64(int significand, int exponent)
static long int lround(ValueType32 x)
Definition bdldfp_decimalimputil.h:2232
static ValueType32 convertToDecimal32(const ValueType64 &input)
Definition bdldfp_decimalimputil.h:2868
static ValueType128 parse128(const char *input)
Definition bdldfp_decimalimputil.h:3114
static ValueType128 epsilon128() BSLS_KEYWORD_NOEXCEPT
static ValueType64 int64ToDecimal64(long long int value)
Definition bdldfp_decimalimputil.h:1585
static ValueType32 denormMin32() BSLS_KEYWORD_NOEXCEPT
static ValueType64 binaryToDecimal64(float value)
Definition bdldfp_decimalimputil.h:2926
static ValueType32 quantize(ValueType32 value, ValueType32 exponent)
Definition bdldfp_decimalimputil.h:1727
static int classify(ValueType64 x)
static ValueType32 subtract(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1650
static ValueType128 uint32ToDecimal128(unsigned int value)
Definition bdldfp_decimalimputil.h:1570
static ValueType64 quietNaN64() BSLS_KEYWORD_NOEXCEPT
static ValueType32 sqrt(ValueType32 x)
Definition bdldfp_decimalimputil.h:2363
static ValueType64 round(ValueType64 x, unsigned int precision)
static int quantizeEqual(ValueType32 *x, ValueType32 y, int exponent)
Definition bdldfp_decimalimputil.h:1811
static ValueType128 quietNaN128() BSLS_KEYWORD_NOEXCEPT
static ValueType128 signalingNaN128() BSLS_KEYWORD_NOEXCEPT
@ k_STATUS_UNDERFLOW
Definition bdldfp_decimalimputil.h:257
@ k_STATUS_INEXACT
Definition bdldfp_decimalimputil.h:256
@ k_STATUS_OVERFLOW
Definition bdldfp_decimalimputil.h:258
static bool equal(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2816
static ValueType32 uint64ToDecimal32(unsigned long long int value)
Definition bdldfp_decimalimputil.h:1600
static ValueType64 makeDecimalRaw64(unsigned long long int significand, int exponent)
static int classify(ValueType32 x)
static ValueType128 binaryToDecimal128(float value)
Definition bdldfp_decimalimputil.h:2940
static ValueType64 uint32ToDecimal64(unsigned int value)
Definition bdldfp_decimalimputil.h:1563
static ValueType128 round(ValueType128 x, unsigned int precision)
static ValueType32 round(ValueType32 x, unsigned int precision)
static ValueType32 nexttoward(ValueType32 from, ValueType128 to)
Definition bdldfp_decimalimputil.h:2012
static int classify(ValueType128 x)
static ValueType32 quietNaN32() BSLS_KEYWORD_NOEXCEPT
static ValueType64 makeInfinity64(bool isNegative=false)
static ValueType32 int64ToDecimal32(long long int value)
Definition bdldfp_decimalimputil.h:1578
static ValueType32 nextafter(ValueType32 from, ValueType32 to)
Definition bdldfp_decimalimputil.h:1958
static ValueType32 exp(ValueType32 x)
Definition bdldfp_decimalimputil.h:2426
static ValueType64 int32ToDecimal64(int value)
Definition bdldfp_decimalimputil.h:1542
static ValueType128 normalize(ValueType128 original)
static ValueType32 negate(ValueType32 value)
Definition bdldfp_decimalimputil.h:2687
static ValueType128 makeDecimalRaw128(long long int significand, int exponent)
static ValueType64 makeDecimal64(unsigned int significand, int exponent)
static bool greaterEqual(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:2790
static ValueType32 infinity32() BSLS_KEYWORD_NOEXCEPT
static ValueType32 int32ToDecimal32(int value)
Definition bdldfp_decimalimputil.h:1536
static long int lrint(ValueType32 x)
Definition bdldfp_decimalimputil.h:1891
static ValueType32 max32() BSLS_KEYWORD_NOEXCEPT
static ValueType32 add(ValueType32 lhs, ValueType32 rhs)
Definition bdldfp_decimalimputil.h:1625
static ValueType64 uint64ToDecimal64(unsigned long long int value)
Definition bdldfp_decimalimputil.h:1607
static ValueType128 min128() BSLS_KEYWORD_NOEXCEPT
static DecimalStorage::Type32 convertBIDtoDPD(ValueType32 value)
Definition bdldfp_decimalimputil.h:3167
static ValueType128 uint64ToDecimal128(unsigned long long int value)
Definition bdldfp_decimalimputil.h:1614
static int format(char *buffer, int length, ValueType128 value, const DecimalFormatConfig &cfg)
static ValueType128 int64ToDecimal128(long long int value)
Definition bdldfp_decimalimputil.h:1592
Imp::ValueType32 ValueType32
Definition bdldfp_decimalimputil.h:249
static bool sameQuantum(ValueType32 x, ValueType32 y)
Definition bdldfp_decimalimputil.h:1870
static ValueType64 denormMin64() BSLS_KEYWORD_NOEXCEPT
static ValueType32 ceil(ValueType32 x)
Definition bdldfp_decimalimputil.h:2123
static ValueType64 makeDecimal64(unsigned long long int significand, int exponent)
static ValueType64 signalingNaN64() BSLS_KEYWORD_NOEXCEPT
Definition bdldfp_uint128.h:175
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
Definition bdldfp_decimal.h:747
BID_UINT128 Type128
Definition bdldfp_decimalstorage.h:86
BID_UINT64 Type64
Definition bdldfp_decimalstorage.h:85
BID_UINT32 Type32
Definition bdldfp_decimalstorage.h:84
unsigned long long Uint64
Definition bsls_types.h:139