ReactOS 0.4.16-dev-852-gcfcc8d8
atoldbl.cpp File Reference
#include <corecrt_internal.h>
#include <corecrt_internal_fltintrn.h>
#include <corecrt_internal_strtox.h>
#include <float.h>
#include <locale.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for atoldbl.cpp:

Go to the source code of this file.

Namespaces

namespace  __crt_strtox
 

Macros

#define _ALLOW_OLD_VALIDATE_MACROS
 
#define PTR_12(x)   ((uint8_t*)(&(x)->ld12))
 
#define MSB_USHORT   ((uint16_t) 0x8000)
 
#define MSB_ULONG   ((uint32_t) 0x80000000)
 
#define TMAX10   5200 /* maximum temporary decimal exponent */
 
#define TMIN10   -5200 /* minimum temporary decimal exponent */
 
#define LD_MAX_EXP_LEN   4 /* maximum number of decimal exponent digits */
 
#define LD_MAX_MAN_LEN   24 /* maximum length of mantissa (decimal)*/
 
#define LD_MAX_MAN_LEN1   25 /* MAX_MAN_LEN+1 */
 
#define LD_BIAS   0x3fff /* exponent bias for long double */
 
#define LD_BIASM1   0x3ffe /* LD_BIAS - 1 */
 
#define LD_MAXEXP   0x7fff /* maximum biased exponent */
 
#define D_BIAS   0x3ff /* exponent bias for double */
 
#define D_BIASM1   0x3fe /* D_BIAS - 1 */
 
#define D_MAXEXP   0x7ff /* maximum biased exponent */
 
#define ALIGN(x)   ((unsigned long _UNALIGNED*)(x))
 
#define U_EXP_12(p)   ((uint16_t *)(PTR_12(p) + 10))
 
#define UL_MANHI_12(p)   ((uint32_t _UNALIGNED*)(PTR_12(p) + 6))
 
#define UL_MANLO_12(p)   ((uint32_t _UNALIGNED*)(PTR_12(p) + 2))
 
#define U_XT_12(p)   ((uint16_t *)(PTR_12(p) ))
 
#define UL_LO_12(p)   ((uint32_t*)(PTR_12(p) ))
 
#define UL_MED_12(p)   ((uint32_t*)(PTR_12(p) + 4))
 
#define UL_HI_12(p)   ((uint32_t*)(PTR_12(p) + 8))
 
#define UCHAR_12(p, i)   ((uint8_t *)( PTR_12(p) + (i)))
 
#define USHORT_12(p, i)   ((uint16_t*)((uint8_t*)PTR_12(p) + (i)))
 
#define ULONG_12(p, i)   ((uint32_t*)((uint8_t*)PTR_12(p) + (i)))
 
#define TEN_BYTE_PART(p)   ((uint8_t *)( PTR_12(p) + 2 ))
 
#define U_EXP_LD(p)   ((uint16_t*)(_PTR_LD(p) + 8))
 
#define UL_MANHI_LD(p)   ((uint32_t*)(_PTR_LD(p) + 4))
 
#define UL_MANLO_LD(p)   ((uint32_t*)(_PTR_LD(p) ))
 
#define U_SHORT4_D(p)   ((uint16_t*)(p) + 3)
 
#define UL_HI_D(p)   ((uint32_t*)(p) + 1)
 
#define UL_LO_D(p)   ((uint32_t*)(p) )
 
#define PUT_INF_12(p, sign)
 
#define PUT_ZERO_12(p)
 
#define ISZERO_12(p)
 
#define PUT_INF_LD(p, sign)
 
#define PUT_ZERO_LD(p)
 
#define ISZERO_LD(p)
 
#define INTRNMAN_LEN   3
 

Typedefs

typedef uint32_tmantissa_t
 

Functions

static __forceinline bool __cdecl add_uint32_carry (uint32_t const x, uint32_t const y, uint32_t *const sum) throw ()
 
static __forceinline void __cdecl add_ld12 (_LDBL12 *const x, _LDBL12 const *const y) throw ()
 
template<uint32_t N>
static __forceinline void __cdecl shl_ld12 (_LDBL12 *const p) throw ()
 
static __forceinline void __cdecl shr_ld12 (_LDBL12 *const p) throw ()
 
static __forceinline void __cdecl multiply_ld12 (_LDBL12 *const px, _LDBL12 const *const py) throw ()
 
static __forceinline void __cdecl multiply_ten_pow_ld12 (_LDBL12 *const pld12, int pow) throw ()
 
static __forceinline void __cdecl multiply_two_pow_ld12 (_LDBL12 *const ld12, int const power) throw ()
 
template<uint32_t N>
static __forceinline void __cdecl multiply_ld12_by (_LDBL12 *) throw ()
 
template<>
__forceinline void __cdecl multiply_ld12_by< 10 > (_LDBL12 *const ld12) throw ()
 
template<>
__forceinline void __cdecl multiply_ld12_by< 16 > (_LDBL12 *const ld12) throw ()
 
template<uint32_t Base>
static __forceinline void __cdecl convert_mantissa_to_ld12 (uint8_t const *const mantissa, size_t const mantissa_count, _LDBL12 *const ld12) throw ()
 
void __cdecl __crt_strtox::assemble_floating_point_zero (bool const is_negative, _LDBL12 &result) throw ()
 
void __cdecl __crt_strtox::assemble_floating_point_infinity (bool const is_negative, _LDBL12 &result) throw ()
 
void __cdecl __crt_strtox::assemble_floating_point_qnan (bool const is_negative, _LDBL12 &result) throw ()
 
void __cdecl __crt_strtox::assemble_floating_point_snan (bool const is_negative, _LDBL12 &result) throw ()
 
void __cdecl __crt_strtox::assemble_floating_point_ind (_LDBL12 &result) throw ()
 
static SLD_STATUS __cdecl __crt_strtox::common_convert_to_ldbl12 (floating_point_string const &immutable_data, bool const is_hexadecimal, _LDBL12 &result) throw ()
 
SLD_STATUS __cdecl __crt_strtox::convert_decimal_string_to_floating_type (floating_point_string const &data, _LDBL12 &result) throw ()
 
SLD_STATUS __cdecl __crt_strtox::convert_hexadecimal_string_to_floating_type (floating_point_string const &data, _LDBL12 &result) throw ()
 
static int __cdecl transform_into_return_value (SLD_STATUS const status) throw ()
 
static __forceinline bool __cdecl mantissa_has_zero_tail (mantissa_t const mantissa, int const nbit) throw ()
 
static __forceinline bool __cdecl increment_mantissa (mantissa_t const mantissa, int const nbit) throw ()
 
static __forceinline bool __cdecl round_mantissa (mantissa_t const mantissa, int const precision) throw ()
 
static void __cdecl convert_ld12_to_ldouble (_LDBL12 const *const pld12, _LDOUBLE *const result) throw ()
 
int __cdecl _atoldbl_l (_LDOUBLE *const result, char *const string, _locale_t const locale)
 
int __cdecl _atoldbl (_LDOUBLE *const result, char *const string)
 

Variables

static _LDBL12 const ld12_pow10_positive []
 
static _LDBL12 const ld12_pow10_negative []
 

Macro Definition Documentation

◆ _ALLOW_OLD_VALIDATE_MACROS

#define _ALLOW_OLD_VALIDATE_MACROS

Definition at line 9 of file atoldbl.cpp.

◆ ALIGN

#define ALIGN (   x)    ((unsigned long _UNALIGNED*)(x))

Definition at line 49 of file atoldbl.cpp.

◆ D_BIAS

#define D_BIAS   0x3ff /* exponent bias for double */

Definition at line 36 of file atoldbl.cpp.

◆ D_BIASM1

#define D_BIASM1   0x3fe /* D_BIAS - 1 */

Definition at line 37 of file atoldbl.cpp.

◆ D_MAXEXP

#define D_MAXEXP   0x7ff /* maximum biased exponent */

Definition at line 38 of file atoldbl.cpp.

◆ INTRNMAN_LEN

#define INTRNMAN_LEN   3

Definition at line 677 of file atoldbl.cpp.

◆ ISZERO_12

#define ISZERO_12 (   p)
Value:
((*UL_HI_12 (p) & 0x7fffffff) == 0 && \
*UL_MED_12(p) == 0 && \
*UL_LO_12 (p) == 0)
#define UL_MED_12(p)
Definition: atoldbl.cpp:58
#define UL_HI_12(p)
Definition: atoldbl.cpp:59
#define UL_LO_12(p)
Definition: atoldbl.cpp:57
GLfloat GLfloat p
Definition: glext.h:8902

Definition at line 87 of file atoldbl.cpp.

◆ ISZERO_LD

#define ISZERO_LD (   p)
Value:
((*U_EXP_LD (p) & 0x7fff) == 0 && \
*UL_MANHI_LD(p) == 0 && \
*UL_MANLO_LD(p) == 0)
#define U_EXP_LD(p)
Definition: atoldbl.cpp:68
#define UL_MANLO_LD(p)
Definition: atoldbl.cpp:70
#define UL_MANHI_LD(p)
Definition: atoldbl.cpp:69

Definition at line 102 of file atoldbl.cpp.

◆ LD_BIAS

#define LD_BIAS   0x3fff /* exponent bias for long double */

Definition at line 32 of file atoldbl.cpp.

◆ LD_BIASM1

#define LD_BIASM1   0x3ffe /* LD_BIAS - 1 */

Definition at line 33 of file atoldbl.cpp.

◆ LD_MAX_EXP_LEN

#define LD_MAX_EXP_LEN   4 /* maximum number of decimal exponent digits */

Definition at line 28 of file atoldbl.cpp.

◆ LD_MAX_MAN_LEN

#define LD_MAX_MAN_LEN   24 /* maximum length of mantissa (decimal)*/

Definition at line 29 of file atoldbl.cpp.

◆ LD_MAX_MAN_LEN1

#define LD_MAX_MAN_LEN1   25 /* MAX_MAN_LEN+1 */

Definition at line 30 of file atoldbl.cpp.

◆ LD_MAXEXP

#define LD_MAXEXP   0x7fff /* maximum biased exponent */

Definition at line 34 of file atoldbl.cpp.

◆ MSB_ULONG

#define MSB_ULONG   ((uint32_t) 0x80000000)

Definition at line 24 of file atoldbl.cpp.

◆ MSB_USHORT

#define MSB_USHORT   ((uint16_t) 0x8000)

Definition at line 23 of file atoldbl.cpp.

◆ PTR_12

#define PTR_12 (   x)    ((uint8_t*)(&(x)->ld12))

Definition at line 21 of file atoldbl.cpp.

◆ PUT_INF_12

#define PUT_INF_12 (   p,
  sign 
)
Value:
*UL_HI_12 (p) = (sign) ? 0xffff8000 : 0x7fff8000; \
*UL_MED_12(p) = 0; \
*UL_LO_12 (p) = 0;
#define sign(x)
Definition: mapdesc.cc:613

Definition at line 77 of file atoldbl.cpp.

◆ PUT_INF_LD

#define PUT_INF_LD (   p,
  sign 
)
Value:
*U_EXP_LD (p) = (sign) ? 0xffff : 0x7fff; \
*UL_MANHI_LD(p) = 0x8000; \
*UL_MANLO_LD(p) = 0;

Definition at line 92 of file atoldbl.cpp.

◆ PUT_ZERO_12

#define PUT_ZERO_12 (   p)
Value:
*UL_HI_12 (p) = 0; \
*UL_MED_12(p) = 0; \
*UL_LO_12 (p) = 0;

Definition at line 82 of file atoldbl.cpp.

◆ PUT_ZERO_LD

#define PUT_ZERO_LD (   p)
Value:
*U_EXP_LD (p) = 0; \
*UL_MANHI_LD(p) = 0; \
*UL_MANLO_LD(p) = 0;

Definition at line 97 of file atoldbl.cpp.

◆ TEN_BYTE_PART

#define TEN_BYTE_PART (   p)    ((uint8_t *)( PTR_12(p) + 2 ))

Definition at line 65 of file atoldbl.cpp.

◆ TMAX10

#define TMAX10   5200 /* maximum temporary decimal exponent */

Definition at line 26 of file atoldbl.cpp.

◆ TMIN10

#define TMIN10   -5200 /* minimum temporary decimal exponent */

Definition at line 27 of file atoldbl.cpp.

◆ U_EXP_12

#define U_EXP_12 (   p)    ((uint16_t *)(PTR_12(p) + 10))

Definition at line 51 of file atoldbl.cpp.

◆ U_EXP_LD

#define U_EXP_LD (   p)    ((uint16_t*)(_PTR_LD(p) + 8))

Definition at line 68 of file atoldbl.cpp.

◆ U_SHORT4_D

#define U_SHORT4_D (   p)    ((uint16_t*)(p) + 3)

Definition at line 73 of file atoldbl.cpp.

◆ U_XT_12

#define U_XT_12 (   p)    ((uint16_t *)(PTR_12(p) ))

Definition at line 54 of file atoldbl.cpp.

◆ UCHAR_12

#define UCHAR_12 (   p,
  i 
)    ((uint8_t *)( PTR_12(p) + (i)))

Definition at line 62 of file atoldbl.cpp.

◆ UL_HI_12

#define UL_HI_12 (   p)    ((uint32_t*)(PTR_12(p) + 8))

Definition at line 59 of file atoldbl.cpp.

◆ UL_HI_D

#define UL_HI_D (   p)    ((uint32_t*)(p) + 1)

Definition at line 74 of file atoldbl.cpp.

◆ UL_LO_12

#define UL_LO_12 (   p)    ((uint32_t*)(PTR_12(p) ))

Definition at line 57 of file atoldbl.cpp.

◆ UL_LO_D

#define UL_LO_D (   p)    ((uint32_t*)(p) )

Definition at line 75 of file atoldbl.cpp.

◆ UL_MANHI_12

#define UL_MANHI_12 (   p)    ((uint32_t _UNALIGNED*)(PTR_12(p) + 6))

Definition at line 52 of file atoldbl.cpp.

◆ UL_MANHI_LD

#define UL_MANHI_LD (   p)    ((uint32_t*)(_PTR_LD(p) + 4))

Definition at line 69 of file atoldbl.cpp.

◆ UL_MANLO_12

#define UL_MANLO_12 (   p)    ((uint32_t _UNALIGNED*)(PTR_12(p) + 2))

Definition at line 53 of file atoldbl.cpp.

◆ UL_MANLO_LD

#define UL_MANLO_LD (   p)    ((uint32_t*)(_PTR_LD(p) ))

Definition at line 70 of file atoldbl.cpp.

◆ UL_MED_12

#define UL_MED_12 (   p)    ((uint32_t*)(PTR_12(p) + 4))

Definition at line 58 of file atoldbl.cpp.

◆ ULONG_12

#define ULONG_12 (   p,
  i 
)    ((uint32_t*)((uint8_t*)PTR_12(p) + (i)))

Definition at line 64 of file atoldbl.cpp.

◆ USHORT_12

#define USHORT_12 (   p,
  i 
)    ((uint16_t*)((uint8_t*)PTR_12(p) + (i)))

Definition at line 63 of file atoldbl.cpp.

Typedef Documentation

◆ mantissa_t

typedef uint32_t* mantissa_t

Definition at line 680 of file atoldbl.cpp.

Function Documentation

◆ _atoldbl()

int __cdecl _atoldbl ( _LDOUBLE *const  result,
char *const  string 
)

Definition at line 830 of file atoldbl.cpp.

831{
832 return _atoldbl_l(result, string, nullptr);
833}
int __cdecl _atoldbl_l(_LDOUBLE *const result, char *const string, _locale_t const locale)
Definition: atoldbl.cpp:816
GLuint64EXT * result
Definition: glext.h:11304

◆ _atoldbl_l()

int __cdecl _atoldbl_l ( _LDOUBLE *const  result,
char *const  string,
_locale_t const  locale 
)

Definition at line 816 of file atoldbl.cpp.

817{
818 _LocaleUpdate locale_update(locale);
819
820 _LDBL12 intermediate_result{};
821 SLD_STATUS const conversion_status = parse_floating_point(
822 locale_update.GetLocaleT(),
823 make_c_string_character_source(string, nullptr),
824 &intermediate_result);
825
826 convert_ld12_to_ldouble(&intermediate_result, result);
827 return transform_into_return_value(conversion_status);
828}
static int __cdecl transform_into_return_value(SLD_STATUS const status)
Definition: atoldbl.cpp:666
static void __cdecl convert_ld12_to_ldouble(_LDBL12 const *const pld12, _LDOUBLE *const result)
Definition: atoldbl.cpp:786
Definition: _locale.h:75
c_string_character_source< Character > __cdecl make_c_string_character_source(Character const *const string, EndPointer const end)
SLD_STATUS __cdecl parse_floating_point(_locale_t const locale, CharacterSource source, FloatingType *const result)
Definition: stdlib.h:81

Referenced by _atoldbl().

◆ add_ld12()

static __forceinline void __cdecl add_ld12 ( _LDBL12 *const  x,
_LDBL12 const *const  y 
)
throw (
)
static

Definition at line 189 of file atoldbl.cpp.

190{
192 {
194 {
195 ++*UL_HI_12(x);
196 }
197 }
198
200 {
201 ++*UL_HI_12(x);
202 }
203
204 // Ignore next carry -- assume no overflow will occur
206}
static __forceinline bool __cdecl add_uint32_carry(uint32_t const x, uint32_t const y, uint32_t *const sum)
Definition: atoldbl.cpp:179
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548

Referenced by convert_mantissa_to_ld12(), and multiply_ld12_by< 10 >().

◆ add_uint32_carry()

static __forceinline bool __cdecl add_uint32_carry ( uint32_t const  x,
uint32_t const  y,
uint32_t *const  sum 
)
throw (
)
static

Definition at line 179 of file atoldbl.cpp.

180{
181 uint32_t const r = x + y;
182
183 *sum = r;
184
185 return r < x || r < y; // carry
186}
UINT32 uint32_t
Definition: types.h:75
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35

Referenced by add_ld12(), increment_mantissa(), and multiply_ld12().

◆ convert_ld12_to_ldouble()

static void __cdecl convert_ld12_to_ldouble ( _LDBL12 const *const  pld12,
_LDOUBLE *const  result 
)
throw (
)
static

Definition at line 786 of file atoldbl.cpp.

790{
791 // This implementation is based on the fact that the _LDBL12 format is
792 // identical to the long double and has 2 extra bytes of mantissa
793 uint16_t exponent = *U_EXP_12(pld12) & static_cast<uint16_t>(0x7fff);
794 uint16_t const sign = *U_EXP_12(pld12) & static_cast<uint16_t>(0x8000);
795
796 uint32_t mantissa[] =
797 {
798 *UL_MANHI_12(pld12),
799 *UL_MANLO_12(pld12),
800 uint32_t ((*U_XT_12(pld12)) << 16)
801 };
802
803 if (round_mantissa(mantissa, 64))
804 {
805 // The MSB of the mantissa is explicit and should be 1
806 // since we had a carry, the mantissa is now 0.
807 mantissa[0] = MSB_ULONG;
808 ++exponent;
809 }
810
811 *UL_MANHI_LD(result) = mantissa[0];
812 *UL_MANLO_LD(result) = mantissa[1];
814}
unsigned short int uint16_t
Definition: acefiex.h:54
#define U_EXP_12(p)
Definition: atoldbl.cpp:51
#define MSB_ULONG
Definition: atoldbl.cpp:24
#define UL_MANHI_12(p)
Definition: atoldbl.cpp:52
#define U_XT_12(p)
Definition: atoldbl.cpp:54
static __forceinline bool __cdecl round_mantissa(mantissa_t const mantissa, int const precision)
Definition: atoldbl.cpp:753
#define UL_MANLO_12(p)
Definition: atoldbl.cpp:53
__int64 exponent
Definition: cvt.cpp:529
#define uint32_t
Definition: nsiface.idl:61

Referenced by _atoldbl_l().

◆ convert_mantissa_to_ld12()

template<uint32_t Base>
static __forceinline void __cdecl convert_mantissa_to_ld12 ( uint8_t const *const  mantissa,
size_t const  mantissa_count,
_LDBL12 *const  ld12 
)
throw (
)
static

Definition at line 495 of file atoldbl.cpp.

500{
501 *UL_LO_12 (ld12) = 0;
502 *UL_MED_12(ld12) = 0;
503 *UL_HI_12 (ld12) = 0;
504
505 uint8_t const* const mantissa_last = mantissa + mantissa_count;
506 for (uint8_t const* it = mantissa; it != mantissa_last; ++it)
507 {
508 multiply_ld12_by<Base>(ld12);
509
510 // Add the new digit into the mantissa:
511 _LDBL12 digit_ld12{};
512 *UL_LO_12 (&digit_ld12) = *it;
513 *UL_MED_12(&digit_ld12) = 0;
514 *UL_HI_12 (&digit_ld12) = 0;
515 add_ld12(ld12, &digit_ld12);
516 }
517
518 uint16_t expn = LD_BIASM1 + 80;
519
520 // Normalize mantissa. First shift word-by-word:
521 while (*UL_HI_12(ld12) == 0)
522 {
523 *UL_HI_12 (ld12) = *UL_MED_12(ld12) >> 16;
524 *UL_MED_12(ld12) = *UL_MED_12(ld12) << 16 | *UL_LO_12(ld12) >> 16;
525 *UL_LO_12 (ld12) <<= 16;
526 expn -= 16;
527 }
528
529 while ((*UL_HI_12(ld12) & MSB_USHORT) == 0)
530 {
531 shl_ld12<1>(ld12);
532 --expn;
533 }
534
535 *U_EXP_12(ld12) = expn;
536}
static __forceinline void __cdecl add_ld12(_LDBL12 *const x, _LDBL12 const *const y)
Definition: atoldbl.cpp:189
#define MSB_USHORT
Definition: atoldbl.cpp:23
#define LD_BIASM1
Definition: atoldbl.cpp:33
BYTE uint8_t
Definition: msvideo1.c:66

◆ increment_mantissa()

static __forceinline bool __cdecl increment_mantissa ( mantissa_t const  mantissa,
int const  nbit 
)
throw (
)
static

Definition at line 721 of file atoldbl.cpp.

722{
723 int nl = nbit / 32;
724 int const nb = 31 - nbit % 32;
725
726 //
727 // |<--- part to be incremented -->|
728 //
729 // ---------------------------------
730 // |... | | ... |
731 // ---------------------------------
732 // ^ ^ ^
733 // | | |<--nb-->
734 // man nl nbit
735 //
736
737 uint32_t const one = static_cast<uint32_t>(1) << nb;
738
739 bool carry = add_uint32_carry(mantissa[nl], one, &mantissa[nl]);
740
741 --nl;
742
743 for (; nl >= 0 && carry; --nl)
744 {
745 carry = add_uint32_carry(mantissa[nl], 1, &mantissa[nl]);
746 }
747
748 return carry;
749}
int one
Definition: sehframes.cpp:28

Referenced by round_mantissa().

◆ mantissa_has_zero_tail()

static __forceinline bool __cdecl mantissa_has_zero_tail ( mantissa_t const  mantissa,
int const  nbit 
)
throw (
)
static

Definition at line 685 of file atoldbl.cpp.

686{
687 int nl = nbit / 32;
688 int const nb = 31 - nbit % 32;
689
690 //
691 // |<---- tail to be checked --->
692 //
693 // -- ------------------------ ----
694 // |... | | ... |
695 // -- ------------------------ ----
696 // ^ ^ ^
697 // | | |<----nb----->
698 // man nl nbit
699 //
700
701 uint32_t const bitmask = ~(UINT32_MAX << nb);
702
703 if (mantissa[nl] & bitmask)
704 return false;
705
706 ++nl;
707
708 for (; nl < INTRNMAN_LEN; ++nl)
709 {
710 if (mantissa[nl])
711 return false;
712 }
713
714 return true;
715}
#define INTRNMAN_LEN
Definition: atoldbl.cpp:677
#define UINT32_MAX
Definition: intsafe.h:153

Referenced by round_mantissa().

◆ multiply_ld12()

static __forceinline void __cdecl multiply_ld12 ( _LDBL12 *const  px,
_LDBL12 const *const  py 
)
throw (
)
static

Definition at line 241 of file atoldbl.cpp.

242{
243 _LDBL12 tempman; // This is actually a 12-byte mantissa, not a 12-byte long double
244 *UL_LO_12 (&tempman) = 0;
245 *UL_MED_12(&tempman) = 0;
246 *UL_HI_12 (&tempman) = 0;
247
248 uint16_t expx = *U_EXP_12(px);
249 uint16_t expy = *U_EXP_12(py);
250
251 uint16_t const sign = (expx ^ expy) & static_cast<uint16_t>(0x8000);
252 expx &= 0x7fff;
253 expy &= 0x7fff;
254 uint16_t expsum = expx + expy;
255
256 if (expx >= LD_MAXEXP ||
257 expy >= LD_MAXEXP ||
258 expsum > LD_MAXEXP + LD_BIASM1)
259 {
260 // Overflow to infinity
261 PUT_INF_12(px, sign);
262 return;
263 }
264
265 if (expsum <= LD_BIASM1 - 63)
266 {
267 // Underflow to zero
268 PUT_ZERO_12(px);
269 return;
270 }
271
272 if (expx == 0)
273 {
274 // If this is a denormal temp real then the mantissa was shifted right
275 // once to set bit 63 to zero.
276 ++expsum; // Correct for this
277
278 if (ISZERO_12(px))
279 {
280 // Put positive sign:
281 *U_EXP_12(px) = 0;
282 return;
283 }
284 }
285
286 if (expy == 0)
287 {
288 ++expsum; // Because arg2 is denormal
289 if (ISZERO_12(py))
290 {
291 PUT_ZERO_12(px);
292 return;
293 }
294 }
295
296 int roffs = 0;
297 for (int i = 0; i < 5; ++i)
298 {
299 int poffs = i << 1;
300 int qoffs = 8;
301 for (int j = 5 - i; j > 0; --j)
302 {
303 bool carry = false;
304
305 uint16_t* const p = USHORT_12(px, poffs);
306 uint16_t* const q = USHORT_12(py, qoffs);
307 uint32_t* const r = ULONG_12(&tempman, roffs);
308 uint32_t const prod = static_cast<uint32_t>(*p) * static_cast<uint32_t>(*q);
309
310 #if defined _M_X64 || defined _M_ARM
311 // handle misalignment problems
312 if (i & 0x1) // i is odd
313 {
314 uint32_t sum = 0;
315 carry = add_uint32_carry(*ALIGN(r), prod, &sum);
316 *ALIGN(r) = sum;
317 }
318 else // i is even
319 {
320 carry = add_uint32_carry(*r, prod, r);
321 }
322 #else
323 carry = add_uint32_carry(*r, prod, r);
324 #endif
325
326 if (carry)
327 {
328 // roffs should be less than 8 in this case
329 ++*USHORT_12(&tempman, roffs + 4);
330 }
331
332 poffs += 2;
333 qoffs -= 2;
334 }
335
336 roffs += 2;
337 }
338
339 expsum -= LD_BIASM1;
340
341 // Normalize
342 while (static_cast<int16_t>(expsum) > 0 && (*UL_HI_12(&tempman) & MSB_ULONG) == 0)
343 {
344 shl_ld12<1>(&tempman);
345 expsum--;
346 }
347
348 if (static_cast<int16_t>(expsum) <= 0)
349 {
350 bool sticky = false;
351
352 expsum--;
353 while (static_cast<int16_t>(expsum) < 0)
354 {
355 if (*U_XT_12(&tempman) & 0x1)
356 sticky = true;
357
358 shr_ld12(&tempman);
359 expsum++;
360 }
361
362 if (sticky)
363 {
364 *U_XT_12(&tempman) |= 0x1;
365 }
366 }
367
368 if (*U_XT_12(&tempman) > 0x8000 || (*UL_LO_12(&tempman) & 0x1ffff) == 0x18000)
369 {
370 // Round up:
371 if (*UL_MANLO_12(&tempman) == UINT32_MAX)
372 {
373 *UL_MANLO_12(&tempman) = 0;
374
375 if (*UL_MANHI_12(&tempman) == UINT32_MAX)
376 {
377 *UL_MANHI_12(&tempman) = 0;
378
379 if (*U_EXP_12(&tempman) == UINT16_MAX)
380 {
381 // 12-byte mantissa overflow:
382 *U_EXP_12(&tempman) = MSB_USHORT;
383 ++expsum;
384 }
385 else
386 {
387 ++*U_EXP_12(&tempman);
388 }
389 }
390 else
391 {
392 ++*UL_MANHI_12(&tempman);
393 }
394 }
395 else
396 {
397 ++*UL_MANLO_12(&tempman);
398 }
399 }
400
401
402 // Check for exponent overflow:
403 if (expsum >= 0x7fff)
404 {
405 PUT_INF_12(px, sign);
406 return;
407 }
408
409 // Put result in px:
410 *U_XT_12 (px) = *USHORT_12(&tempman, 2);
411 *UL_MANLO_12(px) = *UL_MED_12(&tempman);
412 *UL_MANHI_12(px) = *UL_HI_12 (&tempman);
413 *U_EXP_12 (px) = expsum | sign;
414}
#define ISZERO_12(p)
Definition: atoldbl.cpp:87
#define PUT_INF_12(p, sign)
Definition: atoldbl.cpp:77
#define USHORT_12(p, i)
Definition: atoldbl.cpp:63
#define LD_MAXEXP
Definition: atoldbl.cpp:34
#define ULONG_12(p, i)
Definition: atoldbl.cpp:64
#define ALIGN(x)
Definition: atoldbl.cpp:49
static __forceinline void __cdecl shr_ld12(_LDBL12 *const p)
Definition: atoldbl.cpp:230
#define PUT_ZERO_12(p)
Definition: atoldbl.cpp:82
INT16 int16_t
Definition: types.h:70
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define UINT16_MAX
Definition: intsafe.h:148

Referenced by multiply_ten_pow_ld12(), and multiply_two_pow_ld12().

◆ multiply_ld12_by()

template<uint32_t N>
static __forceinline void __cdecl multiply_ld12_by ( _LDBL12 )
throw (
)
static

◆ multiply_ld12_by< 10 >()

template<>
__forceinline void __cdecl multiply_ld12_by< 10 > ( _LDBL12 *const  ld12)
throw (
)

Definition at line 477 of file atoldbl.cpp.

478{
479 _LDBL12 const original_ld12 = *ld12;
480 shl_ld12<2>(ld12);
481 add_ld12(ld12, &original_ld12);
482 shl_ld12<1>(ld12);
483}

◆ multiply_ld12_by< 16 >()

template<>
__forceinline void __cdecl multiply_ld12_by< 16 > ( _LDBL12 *const  ld12)
throw (
)

Definition at line 486 of file atoldbl.cpp.

487{
488 shl_ld12<4>(ld12);
489}

◆ multiply_ten_pow_ld12()

static __forceinline void __cdecl multiply_ten_pow_ld12 ( _LDBL12 *const  pld12,
int  pow 
)
throw (
)
static

Definition at line 417 of file atoldbl.cpp.

418{
419 if (pow == 0)
420 return;
421
422 _LDBL12 const* pow_10p = ld12_pow10_positive - 8;
423 if (pow < 0)
424 {
425 pow = -pow;
426 pow_10p = ld12_pow10_negative-8;
427 }
428
429 while (pow != 0)
430 {
431 pow_10p += 7;
432 int const last3 = pow & 0x7; // The three least significant bits of pow
433 pow >>= 3;
434
435 if (last3 == 0)
436 continue;
437
438 _LDBL12 const* py = pow_10p + last3;
439
440 _LDBL12 unround;
441
442 // Do an exact 12byte multiplication:
443 if (*U_XT_12(py) >= 0x8000)
444 {
445 // Copy number:
446 unround = *py;
447
448 // Unround adjacent byte:
449 --*UL_MANLO_12(&unround);
450
451 // Point to new operand:
452 py = &unround;
453 }
454
455 multiply_ld12(pld12, py);
456 }
457}
static _LDBL12 const ld12_pow10_positive[]
Definition: atoldbl.cpp:109
static _LDBL12 const ld12_pow10_negative[]
Definition: atoldbl.cpp:142
static __forceinline void __cdecl multiply_ld12(_LDBL12 *const px, _LDBL12 const *const py)
Definition: atoldbl.cpp:241
double pow(double x, double y)
Definition: freeldr.c:178

Referenced by __crt_strtox::common_convert_to_ldbl12().

◆ multiply_two_pow_ld12()

static __forceinline void __cdecl multiply_two_pow_ld12 ( _LDBL12 *const  ld12,
int const  power 
)
throw (
)
static

Definition at line 460 of file atoldbl.cpp.

461{
462 _LDBL12 multiplicand{};
463 *U_XT_12 (&multiplicand) = 0;
464 *UL_MANLO_12(&multiplicand) = 0;
465 *UL_MANHI_12(&multiplicand) = (1u << (sizeof(uint32_t) * CHAR_BIT - 1));
466 *U_EXP_12 (&multiplicand) = static_cast<uint16_t>(power + LD_BIAS);
467
468 multiply_ld12(ld12, &multiplicand);
469}
#define LD_BIAS
Definition: atoldbl.cpp:32
#define CHAR_BIT
Definition: urlcache.c:62
float power
Definition: d3drm.c:3372

Referenced by __crt_strtox::common_convert_to_ldbl12().

◆ round_mantissa()

static __forceinline bool __cdecl round_mantissa ( mantissa_t const  mantissa,
int const  precision 
)
throw (
)
static

Definition at line 753 of file atoldbl.cpp.

754{
755 // The order of the n'th bit is n-1, since the first bit is bit 0
756 // therefore decrement precision to get the order of the last bit
757 // to be kept
758
759 int const nbit = precision - 1;
760
761 int const rndbit = nbit + 1;
762
763 int const nl = rndbit / 32;
764 int const nb = 31 - rndbit % 32;
765
766 // Get value of round bit
767 uint32_t const rndmask = static_cast<uint32_t>(1) << nb;
768
769 bool retval = false;
770 if ((mantissa[nl] & rndmask) && !mantissa_has_zero_tail(mantissa, rndbit))
771 {
772 // round up
773 retval = increment_mantissa(mantissa, nbit);
774 }
775
776 // Fill rest of mantissa with zeroes
777 mantissa[nl] &= UINT32_MAX << nb;
778 for (int i = nl + 1; i < INTRNMAN_LEN; ++i)
779 {
780 mantissa[i] = 0;
781 }
782
783 return retval;
784}
static __forceinline bool __cdecl mantissa_has_zero_tail(mantissa_t const mantissa, int const nbit)
Definition: atoldbl.cpp:685
static __forceinline bool __cdecl increment_mantissa(mantissa_t const mantissa, int const nbit)
Definition: atoldbl.cpp:721
GLenum GLint GLint * precision
Definition: glext.h:7539
int retval
Definition: wcstombs.cpp:91

Referenced by convert_ld12_to_ldouble().

◆ shl_ld12()

template<uint32_t N>
static __forceinline void __cdecl shl_ld12 ( _LDBL12 *const  p)
throw (
)
static

Definition at line 210 of file atoldbl.cpp.

211{
212 uint32_t const total_bits{sizeof(uint32_t) * CHAR_BIT};
213 uint32_t const msb_bits{N};
214 uint32_t const lsb_bits{total_bits - N};
215
216 static_assert(msb_bits <= total_bits, "shift too large");
217
218 uint32_t const lsb_mask{(1 << (lsb_bits - 1)) - 1};
219 uint32_t const msb_mask{static_cast<uint32_t>(-1) ^ lsb_mask};
220
221 uint32_t const lo_carry {(*UL_LO_12 (p) & msb_mask) >> lsb_bits};
222 uint32_t const med_carry{(*UL_MED_12(p) & msb_mask) >> lsb_bits};
223
224 *UL_LO_12 (p) = (*UL_LO_12 (p) << msb_bits);
225 *UL_MED_12(p) = (*UL_MED_12(p) << msb_bits) | lo_carry;
226 *UL_HI_12 (p) = (*UL_HI_12 (p) << msb_bits) | med_carry;
227}
#define N
Definition: crc32.c:57

◆ shr_ld12()

static __forceinline void __cdecl shr_ld12 ( _LDBL12 *const  p)
throw (
)
static

Definition at line 230 of file atoldbl.cpp.

231{
232 uint32_t const c2 = *UL_HI_12 (p) & 0x1 ? MSB_ULONG : 0;
233 uint32_t const c1 = *UL_MED_12(p) & 0x1 ? MSB_ULONG : 0;
234
235 *UL_HI_12 (p) >>= 1;
236 *UL_MED_12(p) = *UL_MED_12(p) >> 1 | c2;
237 *UL_LO_12 (p) = *UL_LO_12 (p) >> 1 | c1;
238}

Referenced by multiply_ld12().

◆ transform_into_return_value()

static int __cdecl transform_into_return_value ( SLD_STATUS const  status)
throw (
)
static

Definition at line 666 of file atoldbl.cpp.

667{
668 switch (status)
669 {
670 case SLD_OVERFLOW: return _OVERFLOW;
671 case SLD_UNDERFLOW: return _UNDERFLOW;
672 default: return 0;
673 }
674}
#define _UNDERFLOW
Definition: math.h:42
#define _OVERFLOW
Definition: math.h:41
Definition: ps.c:97

Referenced by _atoldbl_l().

Variable Documentation

◆ ld12_pow10_negative

_LDBL12 const ld12_pow10_negative[]
static

Definition at line 142 of file atoldbl.cpp.

Referenced by multiply_ten_pow_ld12().

◆ ld12_pow10_positive

_LDBL12 const ld12_pow10_positive[]
static

Definition at line 109 of file atoldbl.cpp.

Referenced by multiply_ten_pow_ld12().