ReactOS 0.4.16-dev-1019-g2c2cdfd
cfout.cpp File Reference
#include <corecrt_internal_fltintrn.h>
#include <corecrt_internal_big_integer.h>
#include <fenv.h>
#include <string.h>
Include dependency graph for cfout.cpp:

Go to the source code of this file.

Classes

class  anonymous_namespace{cfout.cpp}::fp_control_word_guard
 
class  anonymous_namespace{cfout.cpp}::scoped_fp_state_reset
 

Namespaces

namespace  anonymous_namespace{cfout.cpp}
 

Functions

template<typename FloatingType >
static __forceinline __acrt_has_trailing_digits __cdecl convert_to_fos_high_precision (FloatingType const value, uint32_t const precision, __acrt_precision_style const precision_style, int *const exponent, char *const mantissa_buffer, size_t const mantissa_buffer_count) throw ()
 
__acrt_has_trailing_digits __cdecl __acrt_fltout (_CRT_DOUBLE value, unsigned const precision, __acrt_precision_style const precision_style, STRFLT const flt, char *const result, size_t const result_count)
 

Function Documentation

◆ __acrt_fltout()

__acrt_has_trailing_digits __cdecl __acrt_fltout ( _CRT_DOUBLE  value,
unsigned const  precision,
__acrt_precision_style const  precision_style,
STRFLT const  flt,
char *const  result,
size_t const  result_count 
)

Definition at line 315 of file cfout.cpp.

323{
324 using floating_traits = __acrt_floating_type_traits<double>;
325 using components_type = floating_traits::components_type;
326
327 scoped_fp_state_reset const reset_fp_state;
328
329 components_type& components = reinterpret_cast<components_type&>(value);
330
331 flt->sign = components._sign == 1 ? '-' : ' ';
332 flt->mantissa = result;
333
334 unsigned int float_control;
335 _controlfp_s(&float_control, 0, 0);
336 bool const value_is_zero = components._exponent == 0 && (components._mantissa == 0 || float_control & _DN_FLUSH);
337 if (value_is_zero)
338 {
339 flt->decpt = 0;
340 _ERRCHECK(strcpy_s(result, result_count, "0"));
342 }
343
344 // Handle special cases:
345 __acrt_fp_class const classification = __acrt_fp_classify(value.x);
346 if (classification != __acrt_fp_class::finite)
347 {
348 flt->decpt = 1;
349 }
350
351 switch (classification)
352 {
357 }
358
359 // Make the number positive before we pass it to the digit generator:
360 components._sign = 0;
361
362 // The digit generator produces a truncated sequence of digits. To allow
363 // our caller to correctly round the mantissa, we need to generate an extra
364 // digit.
365 fp_control_word_guard const fpc(_MCW_EM, _MCW_EM);
366 return convert_to_fos_high_precision(value.x, precision + 1, precision_style, &flt->decpt, result, result_count);
367}
static __forceinline __acrt_has_trailing_digits __cdecl convert_to_fos_high_precision(FloatingType const value, uint32_t const precision, __acrt_precision_style const precision_style, int *const exponent, char *const mantissa_buffer, size_t const mantissa_buffer_count)
Definition: cfout.cpp:106
#define _ERRCHECK(e)
__acrt_fp_class __cdecl __acrt_fp_classify(double const &value)
floating_traits::components_type components_type
Definition: cvt.cpp:357
GLenum GLenum GLuint components
Definition: glext.h:9620
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLint GLint * precision
Definition: glext.h:7539
#define _MCW_EM
Definition: float.h:40
#define _DN_FLUSH
Definition: float.h:63
_CRT_MANAGED_FP_DEPRECATE _ACRTIMP errno_t __cdecl _controlfp_s(_Out_opt_ unsigned int *_CurrentState, _In_ unsigned int _NewValue, _In_ unsigned int _Mask)
#define strcpy_s(d, l, s)
Definition: utility.h:200
Definition: pdh_main.c:96

Referenced by _ecvt_s_internal(), _fcvt_internal(), _fcvt_s_internal(), and _gcvt_s_internal().

◆ convert_to_fos_high_precision()

template<typename FloatingType >
static __forceinline __acrt_has_trailing_digits __cdecl convert_to_fos_high_precision ( FloatingType const  value,
uint32_t const  precision,
__acrt_precision_style const  precision_style,
int *const  exponent,
char *const  mantissa_buffer,
size_t const  mantissa_buffer_count 
)
throw (
)
static

Definition at line 106 of file cfout.cpp.

114{
115 using floating_traits = __acrt_floating_type_traits<FloatingType>;
116 using components_type = typename floating_traits::components_type;
117
118 _ASSERTE(mantissa_buffer_count > 0);
119
120 components_type const& value_components = reinterpret_cast<components_type const&>(value);
121
122 // Special handling is required for denormal values: because the implicit
123 // high order bit is a zero, not a one, we need to [1] not set that bit when
124 // we expand the mantissa, and [2] increment the exponent to account for the
125 // extra shift.
126 bool const is_denormal = value_components._exponent == 0;
127
128 uint64_t const mantissa_adjustment = is_denormal
129 ? 0
130 : static_cast<uint64_t>(1) << (floating_traits::mantissa_bits - 1);
131
132 int32_t const exponent_adjustment = is_denormal
133 ? 2
134 : 1;
135
136 // f and e are the unbiased mantissa and exponent, respectively. (Where one-
137 // -letter variable names are used, they match the same variables from the
138 // Burger-Dybvig paper.)
139 uint64_t const f = value_components._mantissa + mantissa_adjustment;
140 int32_t const e =
141 static_cast<int32_t>(value_components._exponent) -
142 floating_traits::exponent_bias -
143 floating_traits::mantissa_bits +
144 exponent_adjustment;
145
146 // k is the decimal exponent, such that the resulting decimal number is of
147 // the form 0.mmmmm * 10^k, where mmmm are the mantissa digits we generate.
148 // Note that the use of log10 here may not give the correct result: it may
149 // be off by one, e.g. as is the case for powers of ten (log10(100) is two,
150 // but the correct value of k for 100 is 3). We detect off-by-one errors
151 // later and correct for them.
152 int32_t k = static_cast<int32_t>(ceil(log10(value)));
153 if (k == INT32_MAX || k == INT32_MIN)
154 {
155 _ASSERTE(("unexpected input value; log10 failed", 0));
156 k = 0;
157 }
158
159 // The floating point number is represented as a fraction, r / s. The
160 // initialization of these two values is as described in the Burger-Dybvig
161 // paper.
163 big_integer s{};
164
165 if (e >= 0)
166 {
167 if (r != make_big_integer_power_of_two(floating_traits::mantissa_bits - 1))
168 {
169 shift_left(r, e + 1); // f * b^e * 2
170 s = make_big_integer(2); // 2
171 }
172 else
173 {
174 shift_left(r, e + 2); // f * b^(e+1) * 2
175 s = make_big_integer(4); // b * 2
176 }
177 }
178 else
179 {
180 if (e == floating_traits::minimum_binary_exponent ||
181 r != make_big_integer_power_of_two(floating_traits::mantissa_bits - 1))
182 {
183 shift_left(r, 1); // f * 2
184 s = make_big_integer_power_of_two(-e + 1); // b^-e * 2
185 }
186 else
187 {
188 shift_left(r, 2); // f * b * 2
189 s = make_big_integer_power_of_two(-e + 2); // b^(-e+1) * 2
190 }
191 }
192
193 if (k >= 0)
194 {
196 }
197 else
198 {
200 }
201
202 char* mantissa_it = mantissa_buffer;
203
204 // Perform a trial digit generation to handle off-by-one errors in the
205 // computation of 'k': There are three possible cases, which we handle
206 // in turn:
207 multiply(r, 10);
208 uint32_t const initial_digit = static_cast<uint32_t>(divide(r, s));
209
210 // If the initial digit was computed as 10, k is too small. We increment k
211 // and adjust s as if it had been computed with the correct k above. We
212 // then treat the digit as a one, which is what it would have been extracted
213 // as had k, r, and s been correct to begin with.
214 if (initial_digit == 10)
215 {
216 ++k;
217 *mantissa_it++ = '1';
218 multiply(s, 10);
219 }
220 // If the initial digit is zero, k is too large. We decrement k and ignore
221 // the zero that we read (the next digit that we read will be the "real"
222 // initial digit.
223 else if (initial_digit == 0)
224 {
225 --k;
226 }
227 // Otherwise, k was correct and the digit we read was the actual initial
228 // digit of the number; just store it.
229 else
230 {
231 *mantissa_it++ = static_cast<char>('0' + initial_digit);
232 }
233
234 *exponent = k; // k is now correct; store it for our caller
235
236 // convert_to_fos_high_precision() generates digits assuming we're formatting with %f
237 // When %e is the format specifier, adding the exponent to the number of required digits
238 // is not needed.
239 uint32_t const required_digits = k >= 0 && precision <= INT_MAX && precision_style == __acrt_precision_style::fixed
240 ? k + precision
241 : precision;
242
243 char* const mantissa_last = mantissa_buffer + __min(mantissa_buffer_count - 1, required_digits);
244
245 // We must track whether there are any non-zero digits that were not written to the mantissa,
246 // since just checking whether 'r' is zero is insufficient for knowing whether there are any
247 // remaining zeros after the generated digits.
248 bool unwritten_nonzero_digits_in_chunk = false;
249 for (;;)
250 {
251 if (mantissa_it == mantissa_last)
252 {
253 break;
254 }
255
256 if (is_zero(r))
257 {
258 break;
259 }
260
261 // To reduce the number of expensive high precision division operations,
262 // we generate multiple digits per iteration. Our quotient type is a
263 // uint32_t, and the largest power of ten representable by a uint32_t is
264 // 10^9, so we generate nine digits per iteration.
265 uint32_t const digits_per_iteration = 9;
266 uint32_t const digits_per_iteration_multiplier = 1000 * 1000 * 1000;
267
268 multiply(r, digits_per_iteration_multiplier);
269 uint32_t quotient = static_cast<uint32_t>(divide(r, s));
270
271 _ASSERTE(quotient < digits_per_iteration_multiplier);
272
273 // Decompose the quotient into its nine component digits by repeatedly
274 // dividing by ten. This generates digits in reverse order.
275 #pragma warning(suppress: 6293) // For-loop counts down from minimum
276 for (uint32_t i = digits_per_iteration - 1; i != static_cast<uint32_t>(-1); --i)
277 {
278 char const d = static_cast<char>('0' + quotient % 10);
279 quotient /= 10;
280
281 // We may not have room in the mantissa buffer for all of the digits.
282 // Ignore the ones for which we do not have room.
283 // Last value in mantissa must be null terminator, account for one place after digit generation.
284 if (static_cast<uint32_t>(mantissa_last - mantissa_it) <= i)
285 {
286 if (d != '0')
287 {
288 unwritten_nonzero_digits_in_chunk = true;
289 }
290
291 continue;
292 }
293
294 mantissa_it[i] = d;
295 }
296
297 mantissa_it += __min(digits_per_iteration, mantissa_last - mantissa_it);
298 }
299
300 *mantissa_it = '\0';
301
302 // To detect whether there are zeros after the generated digits for the purposes of rounding,
303 // we must check whether 'r' is zero, but also whether there were any non-zero numbers that were
304 // not written to the mantissa in the last evaluated chunk.
305 bool const all_zeros_after_chunk = is_zero(r);
306
307 if (all_zeros_after_chunk && !unwritten_nonzero_digits_in_chunk)
308 {
310 }
311
313}
#define _ASSERTE(expr)
Definition: crtdbg.h:114
__int64 exponent
Definition: cvt.cpp:529
INT32 int32_t
Definition: types.h:71
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
double log10(double x)
Definition: freeldr.c:190
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLfloat f
Definition: glext.h:7540
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
_Check_return_ _CRTIMP double __cdecl ceil(_In_ double x)
#define __min(a, b)
Definition: stdlib.h:102
#define INT32_MAX
Definition: intsafe.h:151
#define INT32_MIN
Definition: intsafe.h:124
#define INT_MAX
Definition: intsafe.h:150
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
int k
Definition: mpi.c:3369
__forceinline bool __cdecl is_zero(big_integer const &value)
__forceinline big_integer __cdecl make_big_integer(uint64_t const value)
uint64_t __cdecl divide(big_integer &numerator, big_integer const &denominator)
__forceinline bool __cdecl multiply(big_integer &multiplicand, uint32_t const multiplier)
__forceinline bool __cdecl multiply_by_power_of_ten(big_integer &x, uint32_t const power)
__forceinline bool __cdecl shift_left(big_integer &x, uint32_t const n)
__forceinline big_integer __cdecl make_big_integer_power_of_two(uint32_t const power)
#define const
Definition: zconf.h:233

Referenced by __acrt_fltout().