BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdldfp_decimalconvertutil_inteldfp.h
Go to the documentation of this file.
1/// @file bdldfp_decimalconvertutil_inteldfp.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdldfp_decimalconvertutil_inteldfp.h -*-C++-*-
8#ifndef INCLUDED_BDLDFP_DECIMALCONVERTUTIL_INTELDFP
9#define INCLUDED_BDLDFP_DECIMALCONVERTUTIL_INTELDFP
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$")
13
14/// @defgroup bdldfp_decimalconvertutil_inteldfp bdldfp_decimalconvertutil_inteldfp
15/// @brief Provide decimal floating-point conversion functions for Intel DFP.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdldfp
19/// @{
20/// @addtogroup bdldfp_decimalconvertutil_inteldfp
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdldfp_decimalconvertutil_inteldfp-purpose"> Purpose</a>
25/// * <a href="#bdldfp_decimalconvertutil_inteldfp-classes"> Classes </a>
26/// * <a href="#bdldfp_decimalconvertutil_inteldfp-description"> Description </a>
27/// * <a href="#bdldfp_decimalconvertutil_inteldfp-usage"> Usage </a>
28/// * <a href="#bdldfp_decimalconvertutil_inteldfp-example-1-tbd"> Example 1: TBD </a>
29///
30/// # Purpose {#bdldfp_decimalconvertutil_inteldfp-purpose}
31/// Provide decimal floating-point conversion functions for Intel DFP.
32///
33/// # Classes {#bdldfp_decimalconvertutil_inteldfp-classes}
34///
35/// - bdldfp::DecimalConvertUtil_IntelDfp: Intel DFP conversion functions
36///
37/// @see bdldfp_decimal, bdldfp_decimalplatform
38///
39/// # Description {#bdldfp_decimalconvertutil_inteldfp-description}
40/// This component provides conversion operations between the
41/// decimal types supplied in this package (`Decimal32`, `Decimal64`,
42/// `Decimal128`) and various alternative representations. Some of the
43/// alternative representations that this component provides conversions for are
44/// IEEE-754 binary floating point (i.e., `float` and `double`) and a network
45/// format (big-endian, Densely Packed Decimal encoding).
46///
47/// ## Usage {#bdldfp_decimalconvertutil_inteldfp-usage}
48///
49///
50/// This section shows the intended use of this component.
51///
52/// ### Example 1: TBD {#bdldfp_decimalconvertutil_inteldfp-example-1-tbd}
53///
54///
55/// @}
56/** @} */
57/** @} */
58
59/** @addtogroup bdl
60 * @{
61 */
62/** @addtogroup bdldfp
63 * @{
64 */
65/** @addtogroup bdldfp_decimalconvertutil_inteldfp
66 * @{
67 */
68
69#include <bdlscm_version.h>
70
72
73#ifdef BDLDFP_DECIMALPLATFORM_INTELDFP
74#include <bdldfp_decimal.h>
78
79#include <bsls_assert.h>
80
81#include <bsl_cstring.h>
82
83
84namespace bdldfp {
85 // =================================
86 // class DecimalConvertUtil_IntelDfp
87 // =================================
88
89/// This `struct` provides a namespace for utility functions that convert
90/// between the decimal floating-point types of @ref bdldfp_decimal and various
91/// other formats.
92///
93/// See @ref bdldfp_decimalconvertutil_inteldfp
94struct DecimalConvertUtil_IntelDfp {
95
96 // Convert to Binary Floating-Point from C++ Decimal TR
97
98 // CLASS METHODS
99
100 // decimalToDouble functions
101
102 static double decimal32ToDouble (Decimal32 decimal);
103 static double decimal64ToDouble (Decimal64 decimal);
104 static double decimal128ToDouble(Decimal128 decimal);
105
106 /// Return a `double` object having the value closest to the value of
107 /// the specified `decimal` object following the conversion rules
108 /// defined by IEEE-754:
109 ///
110 /// * If the `decimal` object is a NaN, return a NaN.
111 /// * Otherwise if `decimal` is positive or negative infinity, return
112 /// infinity of the same sign.
113 /// * Otherwise if `decimal` is positive or negative zero, return zero
114 /// of the same sign.
115 /// * Otherwise if `decimal` object has an absolute value that is
116 /// larger than `std::numeric_limits<double>::max()`, raise the
117 /// "overflow" floating-point exception and return infinity of the
118 /// same sign as `decimal`.
119 /// * Otherwise if `decimal` has an absolute value that is smaller than
120 /// `std::numeric_limits<double>::min()`, raise the "underflow"
121 /// floating-point exception and return zero of the same sign as
122 /// `decimal`.
123 /// * Otherwise if `decimal` has a value that has more significant
124 /// base-10 digits than `std::numeric_limits<double>::digits10`,
125 /// raise the "inexact" floating-point exception, round that value
126 /// according to the *binary* rounding direction setting of the
127 /// floating-point environment, and return the result of that.
128 /// * Otherwise if `decimal` has a significand that cannot be exactly
129 /// represented using binary floating-point, raise the "inexact"
130 /// floating-point exception, roundthat value according to the
131 /// *binary* rounding direction setting of the environment, and
132 /// return the result of that.
133 /// * Otherwise use the exact value of the `other` object for the
134 /// initialization if this object.
135 static double decimalToDouble (Decimal32 decimal);
136 static double decimalToDouble (Decimal64 decimal);
137 static double decimalToDouble (Decimal128 decimal);
138
139 // decimalToFloat functions
140
141 static float decimal32ToFloat (Decimal32 decimal);
142 static float decimal64ToFloat (Decimal64 decimal);
143 static float decimal128ToFloat(Decimal128 decimal);
144
145 /// Return a `float` object having the value closest to the value of the
146 /// specified `decimal` object following the conversion rules defined
147 /// by IEEE-754:
148 ///
149 /// * If the `decimal` object is a NaN, return a NaN.
150 /// * Otherwise if `decimal` is positive or negative infinity, return
151 /// infinity of the same sign.
152 /// * Otherwise if `decimal` is positive or negative zero, return zero
153 /// of the same sign.
154 /// * Otherwise if `decimal` object has an absolute value that is
155 /// larger than `std::numeric_limits<long double>::max()`, raise the
156 /// "overflow" floating-point exception and return infinity of the
157 /// same sign as `decimal`.
158 /// * Otherwise if `decimal` has an absolute value that is smaller than
159 /// `std::numeric_limits<float>::min()`, raise the "underflow"
160 /// floating-point exception and return zero of the same sign as
161 /// `decimal`.
162 /// * Otherwise if `decimal` has a value that has more significant
163 /// base-10 digits than `std::numeric_limits<float>::digits10`,
164 /// raise the "inexact" floating-point exception, round that value
165 /// according to the *binary* rounding direction setting of the
166 /// floating-point environment, and return the result of that.
167 /// * Otherwise if `decimal` has a significand that cannot be exactly
168 /// represented using binary floating-point, raise the "inexact"
169 /// floating-point exception, roundthat value according to the
170 /// *binary* rounding direction setting of the environment, and
171 /// return the result of that.
172 /// * Otherwise use the exact value of the `other` object for the
173 /// initialization if this object.
174 static float decimalToFloat (Decimal32 decimal);
175 static float decimalToFloat (Decimal64 decimal);
176 static float decimalToFloat (Decimal128 decimal);
177
178
179 // decimalToDPD functions
180
181 static void decimal32ToDPD( unsigned char *buffer,
182 Decimal32 decimal);
183 static void decimal64ToDPD( unsigned char *buffer,
184 Decimal64 decimal);
185 static void decimal128ToDPD(unsigned char *buffer,
186 Decimal128 decimal);
187
188 /// Populate the specified `buffer` with the Densely Packed Decimal
189 /// (DPD) representation of the specified `decimal` value. The DPD
190 /// representations of `Decimal32`, `Decimal64`, and `Decimal128`
191 /// require 4, 8, and 16 bytes respectively.
192 ///
193 /// \pre The behavior is undefined unless `buffer` points to a contiguous sequence of at least `sizeof(decimal)` bytes.
194 ///
195 /// \note Note that the DPD representation is
196 /// defined in section 3.5 of IEEE 754-2008.
197 static void decimalToDPD( unsigned char *buffer,
198 Decimal32 decimal);
199 static void decimalToDPD( unsigned char *buffer,
200 Decimal64 decimal);
201 static void decimalToDPD( unsigned char *buffer,
202 Decimal128 decimal);
203
204 // decimalFromDPD functions
205
206 static Decimal32 decimal32FromDPD( const unsigned char *buffer);
207 static Decimal64 decimal64FromDPD( const unsigned char *buffer);
208
209 /// Return the native implementation representation of the value of the
210 /// same size base-10 floating-point value stored in Densely Packed
211 /// Decimal format at the specified `buffer` address.
212 ///
213 /// \pre The behavior is undefined unless `buffer` points to a memory area at least
214 /// `sizeof(decimal)` in size containing a value in DPD format.
215 static Decimal128 decimal128FromDPD(const unsigned char *buffer);
216
217 /// Store, into the specified `decimal`, the native implementation
218 /// representation of the value of the same size base-10 floating point
219 /// value represented in Densely Packed Decimal format, at the specified `buffer` address.
220 ///
221 /// \pre The behavior is undefined unless `buffer` points
222 /// to a memory area at least `sizeof(decimal)` in size containing a
223 /// value in DPD format.
224 static void decimalFromDPD(Decimal32 *decimal,
225 const unsigned char *buffer);
226 static void decimalFromDPD(Decimal64 *decimal,
227 const unsigned char *buffer);
228 static void decimalFromDPD(Decimal128 *decimal,
229 const unsigned char *buffer);
230
231 // decimalToBID functions
232
233 static void decimal32ToBID( unsigned char *buffer,
234 Decimal32 decimal);
235 static void decimal64ToBID( unsigned char *buffer,
236 Decimal64 decimal);
237 static void decimal128ToBID(unsigned char *buffer,
238 Decimal128 decimal);
239
240 /// Populate the specified `buffer` with the Binary Integer Decimal
241 /// (BID) representation of the specified `decimal` value. The BID
242 /// representations of `Decimal32`, `Decimal64`, and `Decimal128`
243 /// require 4, 8, and 16 bytes respectively.
244 ///
245 /// \pre The behavior is undefined unless `buffer` points to a contiguous sequence of at least `sizeof(decimal)` bytes.
246 ///
247 /// \note Note that the BID representation is
248 /// defined in section 3.5 of IEEE 754-2008.
249 static void decimalToBID( unsigned char *buffer,
250 Decimal32 decimal);
251 static void decimalToBID( unsigned char *buffer,
252 Decimal64 decimal);
253 static void decimalToBID( unsigned char *buffer,
254 Decimal128 decimal);
255
256 // decimalFromBID functions
257
258 static Decimal32 decimal32FromBID( const unsigned char *buffer);
259 static Decimal64 decimal64FromBID( const unsigned char *buffer);
260
261 /// Return the native implementation representation of the value of the
262 /// same size base-10 floating-point value stored in Binary Integer
263 /// Decimal format at the specified `buffer` address.
264 ///
265 /// \pre The behavior is undefined unless `buffer` points to a memory area at least
266 /// `sizeof(decimal)` in size containing a value in BID format.
267 static Decimal128 decimal128FromBID(const unsigned char *buffer);
268
269 /// Store, into the specified `decimal`, the native implementation
270 /// representation of the value of the same size base-10 floating point
271 /// value represented in Binary Integer Decimal format, at the specified `buffer` address.
272 ///
273 /// \pre The behavior is undefined unless `buffer` points
274 /// to a memory area at least `sizeof(decimal)` in size containing a
275 /// value in BID format.
276 static void decimalFromBID(Decimal32 *decimal,
277 const unsigned char *buffer);
278 static void decimalFromBID(Decimal64 *decimal,
279 const unsigned char *buffer);
280 static void decimalFromBID(Decimal128 *decimal,
281 const unsigned char *buffer);
282};
283
284// ============================================================================
285// INLINE FUNCTION DEFINITIONS
286// ============================================================================
287
288 // decimalToDouble functions
289
290inline
291double
292DecimalConvertUtil_IntelDfp::decimal32ToDouble(Decimal32 decimal)
293{
294 return decimalToDouble(decimal);
295}
296
297inline
298double
299DecimalConvertUtil_IntelDfp::decimal64ToDouble(Decimal64 decimal)
300{
301 return decimalToDouble(decimal);
302}
303
304inline
305double
306DecimalConvertUtil_IntelDfp::decimal128ToDouble(Decimal128 decimal)
307{
308 return decimalToDouble(decimal);
309}
310
311inline
312double
313DecimalConvertUtil_IntelDfp::decimalToDouble(Decimal32 decimal)
314{
315 _IDEC_flags flags;
316 return __bid32_to_binary64(decimal.data()->d_raw, &flags);
317}
318
319inline
320double
321DecimalConvertUtil_IntelDfp::decimalToDouble(Decimal64 decimal)
322{
323 _IDEC_flags flags;
324 return __bid64_to_binary64(decimal.data()->d_raw, &flags);
325}
326
327inline
328double
329DecimalConvertUtil_IntelDfp::decimalToDouble(Decimal128 decimal)
330{
331 _IDEC_flags flags;
332 return __bid128_to_binary64(decimal.data()->d_raw, &flags);
333}
334
335 // decimalToFloat functions
336
337inline
338float
339DecimalConvertUtil_IntelDfp::decimal32ToFloat(Decimal32 decimal)
340{
341 return decimalToFloat(decimal);
342}
343
344inline float
345DecimalConvertUtil_IntelDfp::decimal64ToFloat(Decimal64 decimal)
346{
347 return decimalToFloat(decimal);
348}
349
350inline float
351DecimalConvertUtil_IntelDfp::decimal128ToFloat(Decimal128 decimal)
352{
353 return decimalToFloat(decimal);
354}
355
356inline
357float
358DecimalConvertUtil_IntelDfp::decimalToFloat(Decimal32 decimal)
359{
360 _IDEC_flags flags;
361 return __bid32_to_binary32(decimal.data()->d_raw, &flags);
362}
363
364inline
365float
366DecimalConvertUtil_IntelDfp::decimalToFloat(Decimal64 decimal)
367{
368 _IDEC_flags flags;
369 return __bid64_to_binary32(decimal.data()->d_raw, &flags);
370}
371
372inline
373float
374DecimalConvertUtil_IntelDfp::decimalToFloat(Decimal128 decimal)
375{
376 _IDEC_flags flags;
377 return __bid128_to_binary32(decimal.data()->d_raw, &flags);
378}
379
380 // decimalToDPD functions
381
382inline
383void DecimalConvertUtil_IntelDfp::decimal32ToDPD(unsigned char *buffer,
384 Decimal32 decimal)
385{
386 decimalToDPD(buffer, decimal);
387}
388
389inline
390void DecimalConvertUtil_IntelDfp::decimal64ToDPD(unsigned char *buffer,
391 Decimal64 decimal)
392{
393 decimalToDPD(buffer, decimal);
394}
395
396inline
397void DecimalConvertUtil_IntelDfp::decimal128ToDPD(unsigned char *buffer,
398 Decimal128 decimal)
399{
400 decimalToDPD(buffer, decimal);
401}
402
403inline
404void DecimalConvertUtil_IntelDfp::decimalToDPD(unsigned char *buffer,
405 Decimal32 decimal)
406{
407 decimal.data()->d_raw = __bid_to_dpd32(decimal.data()->d_raw);
408 bsl::memcpy(buffer, &decimal, sizeof(decimal));
409}
410
411inline
412void DecimalConvertUtil_IntelDfp::decimalToDPD(unsigned char *buffer,
413 Decimal64 decimal)
414{
415 decimal.data()->d_raw = __bid_to_dpd64(decimal.data()->d_raw);
416 bsl::memcpy(buffer, &decimal, sizeof(decimal));
417}
418
419inline
420void DecimalConvertUtil_IntelDfp::decimalToDPD(unsigned char *buffer,
421 Decimal128 decimal)
422{
423 decimal.data()->d_raw = __bid_to_dpd128(decimal.data()->d_raw);
424 bsl::memcpy(buffer, &decimal, sizeof(decimal));
425}
426
427 // decimalFromDPD functions
428
429inline
430Decimal32 DecimalConvertUtil_IntelDfp::decimal32FromDPD(
431 const unsigned char *buffer)
432{
433 BSLS_ASSERT(buffer);
434
436 bsl::memcpy(&value, buffer, sizeof(value));
437 value.d_raw = __bid_dpd_to_bid32(value.d_raw);
438
439 return Decimal32(value);
440}
441
442inline
443Decimal64 DecimalConvertUtil_IntelDfp::decimal64FromDPD(
444 const unsigned char *buffer)
445{
446 BSLS_ASSERT(buffer);
447
449 bsl::memcpy(&value, buffer, sizeof(value));
450 value.d_raw = __bid_dpd_to_bid64(value.d_raw);
451
452 return Decimal64(value);
453}
454
455inline
456Decimal128 DecimalConvertUtil_IntelDfp::decimal128FromDPD(
457 const unsigned char *buffer)
458{
459 BSLS_ASSERT(buffer);
460
462 bsl::memcpy(&value, buffer, sizeof(value));
463 value.d_raw = __bid_dpd_to_bid128(value.d_raw);
464
465 return Decimal128(value);
466}
467
468inline
469void DecimalConvertUtil_IntelDfp::decimalFromDPD(Decimal32 *decimal,
470 const unsigned char *buffer)
471{
472 BSLS_ASSERT(decimal);
473 BSLS_ASSERT(buffer);
474
475 *decimal = decimal32FromDPD(buffer);
476}
477
478inline
479void DecimalConvertUtil_IntelDfp::decimalFromDPD(Decimal64 *decimal,
480 const unsigned char *buffer)
481{
482 BSLS_ASSERT(decimal);
483 BSLS_ASSERT(buffer);
484
485 *decimal = decimal64FromDPD(buffer);
486}
487
488inline
489void DecimalConvertUtil_IntelDfp::decimalFromDPD(Decimal128 *decimal,
490 const unsigned char *buffer)
491{
492 BSLS_ASSERT(decimal);
493 BSLS_ASSERT(buffer);
494
495 *decimal = decimal128FromDPD(buffer);
496}
497
498 // decimalToBID functions
499
500inline
501void
502DecimalConvertUtil_IntelDfp::decimal32ToBID(unsigned char *buffer,
503 Decimal32 decimal)
504{
505 decimalToBID(buffer, decimal);
506}
507
508inline
509void
510DecimalConvertUtil_IntelDfp::decimal64ToBID(unsigned char *buffer,
511 Decimal64 decimal)
512{
513 decimalToBID(buffer, decimal);
514}
515
516inline
517void DecimalConvertUtil_IntelDfp::decimal128ToBID(unsigned char *buffer,
518 Decimal128 decimal)
519{
520 decimalToBID(buffer, decimal);
521}
522
523inline
524void DecimalConvertUtil_IntelDfp::decimalToBID(unsigned char *buffer,
525 Decimal32 decimal)
526{
527 bsl::memcpy(buffer, &decimal, sizeof(decimal));
528}
529
530inline
531void DecimalConvertUtil_IntelDfp::decimalToBID(unsigned char *buffer,
532 Decimal64 decimal)
533{
534 bsl::memcpy(buffer, &decimal, sizeof(decimal));
535}
536
537inline
538void DecimalConvertUtil_IntelDfp::decimalToBID(unsigned char *buffer,
539 Decimal128 decimal)
540{
541 bsl::memcpy(buffer, &decimal, sizeof(decimal));
542}
543
544 // decimalFromBID functions
545
546inline
547Decimal32 DecimalConvertUtil_IntelDfp::decimal32FromBID(
548 const unsigned char *buffer)
549{
550 BSLS_ASSERT(buffer);
551
553 bsl::memcpy(&value, buffer, sizeof(value));
554
555 return Decimal32(value);
556}
557
558inline
559Decimal64 DecimalConvertUtil_IntelDfp::decimal64FromBID(
560 const unsigned char *buffer)
561{
562 BSLS_ASSERT(buffer);
563
565 bsl::memcpy(&value, buffer, sizeof(value));
566
567 return Decimal64(value);
568}
569
570inline
571Decimal128 DecimalConvertUtil_IntelDfp::decimal128FromBID(
572 const unsigned char *buffer)
573{
574 BSLS_ASSERT(buffer);
575
577 bsl::memcpy(&value, buffer, sizeof(value));
578
579 return Decimal128(value);
580}
581
582inline
583void DecimalConvertUtil_IntelDfp::decimalFromBID(Decimal32 *decimal,
584 const unsigned char *buffer)
585{
586 BSLS_ASSERT(decimal);
587 BSLS_ASSERT(buffer);
588
589 *decimal = decimal32FromBID(buffer);
590}
591
592inline
593void DecimalConvertUtil_IntelDfp::decimalFromBID(Decimal64 *decimal,
594 const unsigned char *buffer)
595{
596 BSLS_ASSERT(decimal);
597 BSLS_ASSERT(buffer);
598
599 *decimal = decimal64FromBID(buffer);
600}
601
602inline
603void DecimalConvertUtil_IntelDfp::decimalFromBID(Decimal128 *decimal,
604 const unsigned char *buffer)
605{
606 BSLS_ASSERT(decimal);
607 BSLS_ASSERT(buffer);
608
609 *decimal = decimal128FromBID(buffer);
610}
611
612} // close package namespace
613
614
615#endif
616
617#endif
618
619// ----------------------------------------------------------------------------
620// Copyright 2014 Bloomberg Finance L.P.
621//
622// Licensed under the Apache License, Version 2.0 (the "License");
623// you may not use this file except in compliance with the License.
624// You may obtain a copy of the License at
625//
626// http://www.apache.org/licenses/LICENSE-2.0
627//
628// Unless required by applicable law or agreed to in writing, software
629// distributed under the License is distributed on an "AS IS" BASIS,
630// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
631// See the License for the specific language governing permissions and
632// limitations under the License.
633// ----------------------------- END-OF-FILE ----------------------------------
634
635/** @} */
636/** @} */
637/** @} */
Imp::ValueType64 ValueType64
Definition bdldfp_decimalimputil.h:250
Imp::ValueType128 ValueType128
Definition bdldfp_decimalimputil.h:251
Imp::ValueType32 ValueType32
Definition bdldfp_decimalimputil.h:249
#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
Definition bdldfp_decimal.h:747
Decimal_Type128 Decimal128
Definition bdldfp_decimal.h:754
Decimal_Type32 Decimal32
Definition bdldfp_decimal.h:749
Decimal_Type64 Decimal64
Definition bdldfp_decimal.h:750