ReactOS 0.4.16-dev-852-gcfcc8d8
_fptostr.cpp File Reference
#include <corecrt_internal.h>
#include <corecrt_internal_fltintrn.h>
#include <corecrt_internal_ptd_propagation.h>
#include <fenv.h>
#include <string.h>
#include <stddef.h>
Include dependency graph for _fptostr.cpp:

Go to the source code of this file.

Functions

static bool check_trailing (char const *mantissa_it, __acrt_has_trailing_digits const trailing_digits)
 
static bool should_round_up (char const *const mantissa_base, char const *const mantissa_it, int const sign, __acrt_has_trailing_digits const trailing_digits, __acrt_rounding_mode const rounding_mode)
 
errno_t __cdecl __acrt_fp_strflt_to_string (char *const buffer, size_t const buffer_count, int digits, STRFLT const pflt, __acrt_has_trailing_digits const trailing_digits, __acrt_rounding_mode const rounding_mode, __crt_cached_ptd_host &ptd)
 

Function Documentation

◆ __acrt_fp_strflt_to_string()

errno_t __cdecl __acrt_fp_strflt_to_string ( char *const  buffer,
size_t const  buffer_count,
int  digits,
STRFLT const  pflt,
__acrt_has_trailing_digits const  trailing_digits,
__acrt_rounding_mode const  rounding_mode,
__crt_cached_ptd_host &  ptd 
)

Definition at line 104 of file _fptostr.cpp.

113{
116 buffer[0] = '\0';
117
118 _UCRT_VALIDATE_RETURN_ERRCODE(ptd, buffer_count > static_cast<size_t>((digits > 0 ? digits : 0) + 1), ERANGE);
120
121 char* buffer_it = buffer;
122 char* const mantissa_base = pflt->mantissa;
123 char* mantissa_it = pflt->mantissa;
124
125 // The buffer will contain 'digits' decimal digits plus an optional overflow
126 // digit for the rounding.
127
128 // Initialize the first digit in the buffer to '0' (Note: not '\0') and set
129 // the pointer to the second digit of the buffer. The first digit is used
130 // to handle overflow on rounding (e.g. 9.999... becomes 10.000...), which
131 // requires a carry into the first digit.
132 *buffer_it++ = '0';
133
134 // Copy the digits of the value into the buffer (with '0' padding) and
135 // insert the null terminator:
136 while (digits > 0)
137 {
138 *buffer_it++ = *mantissa_it ? *mantissa_it++ : '0';
139 --digits;
140 }
141
142 *buffer_it = '\0';
143
144 // Do any rounding which may be needed. Note: if digits < 0, we don't do
145 // any rounding because in this case, the rounding occurs in a digit which
146 // will not be output because of the precision requested.
147 if (digits >= 0 && should_round_up(mantissa_base, mantissa_it, pflt->sign, trailing_digits, rounding_mode))
148 {
149 buffer_it--;
150
151 while (*buffer_it == '9')
152 {
153 *buffer_it-- = '0';
154 }
155
156 *buffer_it += 1;
157 }
158
159 if (*buffer == '1')
160 {
161 // The rounding caused overflow into the leading digit (e.g. 9.999...
162 // became 10.000...), so increment the decimal point position by 1:
163 pflt->decpt++;
164 }
165 else
166 {
167 // Move the entire string to the left one digit to remove the unused
168 // overflow digit:
169 memmove(buffer, buffer + 1, strlen(buffer + 1) + 1);
170 }
171
172 return 0;
173}
static bool should_round_up(char const *const mantissa_base, char const *const mantissa_it, int const sign, __acrt_has_trailing_digits const trailing_digits, __acrt_rounding_mode const rounding_mode)
Definition: _fptostr.cpp:43
#define EINVAL
Definition: acclib.h:90
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERANGE
Definition: acclib.h:92
#define _UCRT_VALIDATE_RETURN_ERRCODE(ptd, expr, errorcode)
result_buffer_count char *const _In_ int const _In_ bool const _In_ unsigned const _In_ STRFLT const pflt
Definition: cvt.cpp:116
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
Definition: cvt.cpp:355
_In_ size_t const _In_ int const _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const rounding_mode
Definition: cvt.cpp:223
GLuint buffer
Definition: glext.h:5915
static const int digits[]
Definition: decode.c:71
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
size_t const buffer_count
Definition: xtoa.cpp:36

Referenced by internal_to_string().

◆ check_trailing()

static bool check_trailing ( char const mantissa_it,
__acrt_has_trailing_digits const  trailing_digits 
)
static

Definition at line 23 of file _fptostr.cpp.

24{
25 if (trailing_digits == __acrt_has_trailing_digits::trailing)
26 {
27 return true;
28 }
29
30 while (*mantissa_it == '0')
31 {
32 mantissa_it++;
33 }
34
35 if (*mantissa_it != '\0')
36 {
37 return true;
38 }
39
40 return false;
41}

Referenced by should_round_up().

◆ should_round_up()

static bool should_round_up ( char const *const  mantissa_base,
char const *const  mantissa_it,
int const  sign,
__acrt_has_trailing_digits const  trailing_digits,
__acrt_rounding_mode const  rounding_mode 
)
static

Definition at line 43 of file _fptostr.cpp.

50{
52 {
53 return *mantissa_it >= '5';
54 }
55
56 int const round_mode = fegetround();
57
58 if (round_mode == FE_TONEAREST)
59 {
60 if (*mantissa_it > '5')
61 {
62 return true;
63 }
64
65 if (*mantissa_it < '5')
66 {
67 return false;
68 }
69
70 // If there are trailing digits we are in a scenario like this .5000000001 and should round up
71 if (check_trailing(mantissa_it + 1, trailing_digits))
72 {
73 return true;
74 }
75
76 // At this point, the number is exactly representable and we are rounding 5.
77 // In this case, IEEE 754 states to round towards the nearest even number.
78 // Therefore: if the previous digit is odd, we round up (1.5 -> 2).
79 // if the previous digit is even, we round down (2.5 -> 2).
80
81 // If there is no preceding digit, it is considered zero, so round down.
82 if (mantissa_it == mantissa_base)
83 {
84 return false;
85 }
86
87 // If the previous digit is odd, we should round up to the closest even.
88 return *(mantissa_it - 1) % 2;
89 }
90
91 if (round_mode == FE_UPWARD)
92 {
93 return check_trailing(mantissa_it, trailing_digits) && sign != '-';
94 }
95
96 if (round_mode == FE_DOWNWARD)
97 {
98 return check_trailing(mantissa_it, trailing_digits) && sign == '-';
99 }
100
101 return false;
102}
static bool check_trailing(char const *mantissa_it, __acrt_has_trailing_digits const trailing_digits)
Definition: _fptostr.cpp:23
#define FE_UPWARD
Definition: fenv.h:22
#define FE_TONEAREST
Definition: fenv.h:20
#define FE_DOWNWARD
Definition: fenv.h:21
int __cdecl fegetround(void)
#define sign(x)
Definition: mapdesc.cc:613

Referenced by __acrt_fp_strflt_to_string().