### Bug Summary

File: | dconv/dprint.cpp
Location: | line 385, column 9
Description: | Value stored to 'bufferSize' is never read

### Annotated Source Code

1 | /******************************************************************************
2 | Copyright (c) 2014 Ryan Juckett
3 | http://www.ryanjuckett.com/
4 |
5 | This software is provided 'as-is', without any express or implied
6 | warranty. In no event will the authors be held liable for any damages
7 | arising from the use of this software.
8 |
9 | Permission is granted to anyone to use this software for any purpose,
10 | including commercial applications, and to alter it and redistribute it
11 | freely, subject to the following restrictions:
12 |
13 | 1. The origin of this software must not be misrepresented; you must not
14 | claim that you wrote the original software. If you use this software
15 | in a product, an acknowledgment in the product documentation would be
16 | appreciated but is not required.
17 |
18 | 2. Altered source versions must be plainly marked as such, and must not be
19 | misrepresented as being the original software.
20 |
21 | 3. This notice may not be removed or altered from any source
22 | distribution.
23 | *******************************************************************************
24 | Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
25 | All rights reserved.
26 |
27 | Redistribution and use in source and binary forms, with or without
28 | modification, are permitted provided that the following conditions
29 | are met:
30 | 1. Redistributions of source code must retain the above copyright
31 | notice, this list of conditions and the following disclaimer.
32 |
33 | 2. Redistributions in binary form must reproduce the above copyright
34 | notice, this list of conditions and the following disclaimer in the
35 | documentation and/or other materials provided with the distribution.
36 |
37 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 |
48 | The origin source code can be obtained from:
49 | http://www.ryanjuckett.com/
50 |
51 | ******************************************************************************/
52 |
53 | #include "clib.h"
54 | #include "dmath.h"
55 | #include "dprint.h"
56 | #include "dragon4.h"
57 | #include <dstandard.h>
58 |
59 | #define memcpyMemCopy MemCopy
60 | #define memmoveMemCopy MemCopy
61 |
62 | //******************************************************************************
63 | // Helper union to decompose a 32-bit IEEE float.
64 | // sign: 1 bit
65 | // exponent: 8 bits
66 | // mantissa: 23 bits
67 | //******************************************************************************
68 | union tFloatUnion32
69 | {
70 | tB IsNegative() const {
71 | return (m_integer >> 31) != 0;
72 | }
73 | tU32 GetExponent() const {
74 | return (m_integer >> 23) & 0xFF;
75 | }
76 | tU32 GetMantissa() const {
77 | return m_integer & 0x7FFFFF;
78 | }
79 |
80 | tF32 m_floatingPoint;
81 | tU32 m_integer;
82 | };
83 |
84 | //******************************************************************************
85 | // Helper union to decompose a 64-bit IEEE float.
86 | // sign: 1 bit
87 | // exponent: 11 bits
88 | // mantissa: 52 bits
89 | //******************************************************************************
90 | union tFloatUnion64
91 | {
92 | tB IsNegative() const {
93 | return (m_integer >> 63) != 0;
94 | }
95 | tU32 GetExponent() const {
96 | return (m_integer >> 52) & 0x7FF;
97 | }
98 | tU64 GetMantissa() const {
99 | return m_integer & 0xFFFFFFFFFFFFFull;
100 | }
101 |
102 | tF64 m_floatingPoint;
103 | tU64 m_integer;
104 | };
105 |
106 | //******************************************************************************
107 | // Outputs the positive number with positional notation: ddddd.dddd
108 | // The output is always NUL terminated and the output length (not including the
109 | // NUL) is returned.
110 | //******************************************************************************
111 | tU32 FormatPositional
112 | (
113 | tC8 * pOutBuffer, // buffer to output into
114 | tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
115 | tU64 mantissa, // value significand
116 | tS32 exponent, // value exponent in base 2
117 | tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
118 | tB hasUnequalMargins, // is the high margin twice as large as the low margin
119 | tS32 precision, // Negative prints as many digits as are needed for a unique
120 | tC8 decimalPoint // Character before the decimals
121 | // number. Positive specifies the maximum number of
122 | // significant digits to print past the decimal point.
123 | )
124 | {
125 | RJ_ASSERT(bufferSize > 0);
126 |
127 | tS32 printExponent;
128 | tU32 numPrintDigits;
129 |
130 | tU32 maxPrintLen = bufferSize - 1;
131 |
132 | if (precision < 0)
133 | {
134 | numPrintDigits = Dragon4( mantissa,
135 | exponent,
136 | mantissaHighBitIdx,
137 | hasUnequalMargins,
138 | CutoffMode_Unique,
139 | 0,
140 | pOutBuffer,
141 | maxPrintLen,
142 | &printExponent );
143 | }
144 | else
145 | {
146 | numPrintDigits = Dragon4( mantissa,
147 | exponent,
148 | mantissaHighBitIdx,
149 | hasUnequalMargins,
150 | CutoffMode_FractionLength,
151 | precision,
152 | pOutBuffer,
153 | maxPrintLen,
154 | &printExponent );
155 | }
156 |
157 | RJ_ASSERT( numPrintDigits > 0 );
158 | RJ_ASSERT( numPrintDigits <= bufferSize );
159 |
160 | // track the number of digits past the decimal point that have been printed
161 | tU32 numFractionDigits = 0;
162 |
163 | // if output has a whole number
164 | if (printExponent >= 0)
165 | {
166 | // leave the whole number at the start of the buffer
167 | tU32 numWholeDigits = printExponent+1;
168 | if (numPrintDigits < numWholeDigits)
169 | {
170 | // don't overflow the buffer
171 | if (numWholeDigits > maxPrintLen)
172 | numWholeDigits = maxPrintLen;
173 |
174 | // add trailing zeros up to the decimal point
175 | for ( ; numPrintDigits < numWholeDigits; ++numPrintDigits )
176 | pOutBuffer[numPrintDigits] = '0';
177 | }
178 | // insert the decimal point prior to the fraction
179 | else if (numPrintDigits > (tU32)numWholeDigits)
180 | {
181 | numFractionDigits = numPrintDigits - numWholeDigits;
182 | tU32 maxFractionDigits = maxPrintLen - numWholeDigits - 1;
183 | if (numFractionDigits > maxFractionDigits)
184 | numFractionDigits = maxFractionDigits;
185 |
186 | memmoveMemCopy(pOutBuffer + numWholeDigits + 1, pOutBuffer + numWholeDigits, numFractionDigits);
187 | pOutBuffer[numWholeDigits] = decimalPoint;
188 | numPrintDigits = numWholeDigits + 1 + numFractionDigits;
189 | }
190 | }
191 | else
192 | {
193 | // shift out the fraction to make room for the leading zeros
194 | if (maxPrintLen > 2)
195 | {
196 | tU32 numFractionZeros = (tU32)-printExponent - 1;
197 | tU32 maxFractionZeros = maxPrintLen - 2;
198 | if (numFractionZeros > maxFractionZeros)
199 | numFractionZeros = maxFractionZeros;
200 |
201 | tU32 digitsStartIdx = 2 + numFractionZeros;
202 |
203 | // shift the significant digits right such that there is room for leading zeros
204 | numFractionDigits = numPrintDigits;
205 | tU32 maxFractionDigits = maxPrintLen - digitsStartIdx;
206 | if (numFractionDigits > maxFractionDigits)
207 | numFractionDigits = maxFractionDigits;
208 |
209 | memmoveMemCopy(pOutBuffer + digitsStartIdx, pOutBuffer, numFractionDigits);
210 |
211 | // insert the leading zeros
212 | for (tU32 i = 2; i < digitsStartIdx; ++i)
213 | pOutBuffer[i] = '0';
214 |
215 | // update the counts
216 | numFractionDigits += numFractionZeros;
217 | numPrintDigits = numFractionDigits;
218 | }
219 |
220 | // add the decimal point
221 | if (maxPrintLen > 1)
222 | {
223 | pOutBuffer[1] = decimalPoint;
224 | numPrintDigits += 1;
225 | }
226 |
227 | // add the initial zero
228 | if (maxPrintLen > 0)
229 | {
230 | pOutBuffer[0] = '0';
231 | numPrintDigits += 1;
232 | }
233 | }
234 |
235 | // add trailing zeros up to precision length
236 | if (precision > (tS32)numFractionDigits && numPrintDigits < maxPrintLen)
237 | {
238 | // add a decimal point if this is the first fractional digit we are printing
239 | if (numFractionDigits == 0)
240 | {
241 | pOutBuffer[numPrintDigits++] = decimalPoint;
242 | }
243 |
244 | // compute the number of trailing zeros needed
245 | tU32 totalDigits = numPrintDigits + (precision - numFractionDigits);
246 | if (totalDigits > maxPrintLen)
247 | totalDigits = maxPrintLen;
248 |
249 | for ( ; numPrintDigits < totalDigits; ++numPrintDigits )
250 | pOutBuffer[numPrintDigits] = '0';
251 | }
252 |
253 | // terminate the buffer
254 | RJ_ASSERT( numPrintDigits <= maxPrintLen );
255 | pOutBuffer[numPrintDigits] = '\0';
256 |
257 | return numPrintDigits;
258 | }
259 |
260 | //******************************************************************************
261 | // Outputs the positive number with scientific notation: d.dddde[sign]ddd
262 | // The output is always NUL terminated and the output length (not including the
263 | // NUL) is returned.
264 | //******************************************************************************
265 | tU32 FormatScientific
266 | (
267 | tC8 * pOutBuffer, // buffer to output into
268 | tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
269 | tU64 mantissa, // value significand
270 | tS32 exponent, // value exponent in base 2
271 | tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
272 | tB hasUnequalMargins, // is the high margin twice as large as the low margin
273 | tS32 precision, // Negative prints as many digits as are needed for a unique
274 | tC8 decimalPoint // Character before the decimals
275 | // number. Positive specifies the maximum number of
276 | // significant digits to print past the decimal point.
277 | )
278 | {
279 | RJ_ASSERT(bufferSize > 0);
280 |
281 | tS32 printExponent;
282 | tU32 numPrintDigits;
283 |
284 | if (precision < 0)
285 | {
286 | numPrintDigits = Dragon4( mantissa,
287 | exponent,
288 | mantissaHighBitIdx,
289 | hasUnequalMargins,
290 | CutoffMode_Unique,
291 | 0,
292 | pOutBuffer,
293 | bufferSize,
294 | &printExponent );
295 | }
296 | else
297 | {
298 | numPrintDigits = Dragon4( mantissa,
299 | exponent,
300 | mantissaHighBitIdx,
301 | hasUnequalMargins,
302 | CutoffMode_TotalLength,
303 | precision + 1,
304 | pOutBuffer,
305 | bufferSize,
306 | &printExponent );
307 | }
308 |
309 | RJ_ASSERT( numPrintDigits > 0 );
310 | RJ_ASSERT( numPrintDigits <= bufferSize );
311 |
312 | tC8 * pCurOut = pOutBuffer;
313 |
314 | // keep the whole number as the first digit
315 | if (bufferSize > 1)
316 | {
317 | pCurOut += 1;
318 | bufferSize -= 1;
319 | }
320 |
321 | // insert the decimal point prior to the fractional number
322 | tU32 numFractionDigits = numPrintDigits-1;
323 | if (numFractionDigits > 0 && bufferSize > 1)
324 | {
325 | tU32 maxFractionDigits = bufferSize-2;
326 | if (numFractionDigits > maxFractionDigits)
327 | numFractionDigits = maxFractionDigits;
328 |
329 | memmoveMemCopy(pCurOut + 1, pCurOut, numFractionDigits);
330 | pCurOut[0] = decimalPoint;
331 | pCurOut += (1 + numFractionDigits);
332 | bufferSize -= (1 + numFractionDigits);
333 | }
334 |
335 | // add trailing zeros up to precision length
336 | if (precision > (tS32)numFractionDigits && bufferSize > 1)
337 | {
338 | // add a decimal point if this is the first fractional digit we are printing
339 | if (numFractionDigits == 0)
340 | {
341 | *pCurOut = decimalPoint;
342 | ++pCurOut;
343 | --bufferSize;
344 | }
345 |
346 | // compute the number of trailing zeros needed
347 | tU32 numZeros = (precision - numFractionDigits);
348 | if (numZeros > bufferSize-1)
349 | numZeros = bufferSize-1;
350 |
351 | for (tC8 * pEnd = pCurOut + numZeros; pCurOut < pEnd; ++pCurOut )
352 | *pCurOut = '0';
353 | }
354 |
355 | // print the exponent into a local buffer and copy into output buffer
356 | if (bufferSize > 1)
357 | {
358 | tC8 exponentBuffer[5];
359 | exponentBuffer[0] = 'e';
360 | if (printExponent >= 0)
361 | {
362 | exponentBuffer[1] = '+';
363 | }
364 | else
365 | {
366 | exponentBuffer[1] = '-';
367 | printExponent = -printExponent;
368 | }
369 |
370 | RJ_ASSERT(printExponent < 1000);
371 | tU32 hundredsPlace = printExponent / 100;
372 | tU32 tensPlace = (printExponent - hundredsPlace*100) / 10;
373 | tU32 onesPlace = (printExponent - hundredsPlace*100 - tensPlace*10);
374 |
375 | exponentBuffer[2] = (tC8)('0' + hundredsPlace);
376 | exponentBuffer[3] = (tC8)('0' + tensPlace);
377 | exponentBuffer[4] = (tC8)('0' + onesPlace);
378 |
379 | // copy the exponent buffer into the output
380 | tU32 maxExponentSize = bufferSize-1;
381 | tU32 exponentSize = (5 < maxExponentSize) ? 5 : maxExponentSize;
382 | memcpyMemCopy( pCurOut, exponentBuffer, exponentSize );
383 |
384 | pCurOut += exponentSize;
385 | bufferSize -= exponentSize;
| Value stored to 'bufferSize' is never read
386 | }
387 |
388 | RJ_ASSERT( bufferSize > 0 );
389 | pCurOut[0] = '\0';
390 |
391 | return pCurOut - pOutBuffer;
392 | }
393 |
394 | //******************************************************************************
395 | // Print a hexadecimal value with a given width.
396 | // The output string is always NUL terminated and the string length (not
397 | // including the NUL) is returned.
398 | //******************************************************************************
399 | static tU32 PrintHex(tC8 * pOutBuffer, tU32 bufferSize, tU64 value, tU32 width)
400 | {
401 | const tC8 digits[] = "0123456789abcdef";
402 |
403 | RJ_ASSERT(bufferSize > 0);
404 |
405 | tU32 maxPrintLen = bufferSize-1;
406 | if (width > maxPrintLen)
407 | width = maxPrintLen;
408 |
409 | tC8 * pCurOut = pOutBuffer;
410 | while (width > 0)
411 | {
412 | --width;
413 |
414 | tU8 digit = (tU8)((value >> 4ull*(tU64)width) & 0xF);
415 | *pCurOut = digits[digit];
416 |
417 | ++pCurOut;
418 | }
419 |
420 | *pCurOut = '\0';
421 | return pCurOut - pOutBuffer;
422 | }
423 |
424 | //******************************************************************************
425 | // Print special case values for infinities and NaNs.
426 | // The output string is always NUL terminated and the string length (not
427 | // including the NUL) is returned.
428 | //******************************************************************************
429 | static tU32 PrintInfNan(tC8 * pOutBuffer, tU32 bufferSize, tU64 mantissa, tU32 mantissaHexWidth)
430 | {
431 | RJ_ASSERT(bufferSize > 0);
432 |
433 | tU32 maxPrintLen = bufferSize-1;
434 |
435 | // Check for infinity
436 | if (mantissa == 0)
437 | {
438 | // copy and make sure the buffer is terminated
439 | tU32 printLen = (3 < maxPrintLen) ? 3 : maxPrintLen;
440 | ::memcpyMemCopy( pOutBuffer, "Inf", printLen );
441 | pOutBuffer[printLen] = '\0';
442 | return printLen;
443 | }
444 | else
445 | {
446 | // copy and make sure the buffer is terminated
447 | tU32 printLen = (3 < maxPrintLen) ? 3 : maxPrintLen;
448 | ::memcpyMemCopy( pOutBuffer, "NaN", printLen );
449 | pOutBuffer[printLen] = '\0';
450 |
451 | // append HEX value
452 | if (maxPrintLen > 3)
453 | printLen += PrintHex(pOutBuffer+3, bufferSize-3, mantissa, mantissaHexWidth);
454 |
455 | return printLen;
456 | }
457 | }
458 |
459 | //******************************************************************************
460 | // Print a 32-bit floating-point number as a decimal string.
461 | // The output string is always NUL terminated and the string length (not
462 | // including the NUL) is returned.
463 | //******************************************************************************
464 | tU32 PrintFloat32
465 | (
466 | tC8 * pOutBuffer, // buffer to output into
467 | tU32 bufferSize, // size of pOutBuffer
468 | tF32 value, // value to print
469 | tPrintFloatFormat format, // format to print with
470 | tS32 precision, // If negative, the minimum number of digits to represent a
471 | tC8 decimalPoint // Character before the decimals
472 | // unique 32-bit floating point value is output. Otherwise,
473 | // this is the number of digits to print past the decimal point.
474 | )
475 | {
476 | if (bufferSize == 0)
477 | return 0;
478 |
479 | if (bufferSize == 1)
480 | {
481 | pOutBuffer[0] = '\0';
482 | return 1;
483 | }
484 |
485 | // deconstruct the floating point value
486 | tFloatUnion32 floatUnion;
487 | floatUnion.m_floatingPoint = value;
488 | tU32 floatExponent = floatUnion.GetExponent();
489 | tU32 floatMantissa = floatUnion.GetMantissa();
490 |
491 | // output the sign
492 | if (floatUnion.IsNegative())
493 | {
494 | pOutBuffer[0] = '-';
495 | ++pOutBuffer;
496 | --bufferSize;
497 | RJ_ASSERT(bufferSize > 0);
498 | }
499 |
500 | // if this is a special value
501 | if (floatExponent == 0xFF)
502 | {
503 | return PrintInfNan(pOutBuffer, bufferSize, floatMantissa, 6);
504 | }
505 | // else this is a number
506 | else
507 | {
508 | // factor the value into its parts
509 | tU32 mantissa;
510 | tS32 exponent;
511 | tU32 mantissaHighBitIdx;
512 | tB hasUnequalMargins;
513 | if (floatExponent != 0)
514 | {
515 | // normalized
516 | // The floating point equation is:
517 | // value = (1 + mantissa/2^23) * 2 ^ (exponent-127)
518 | // We convert the integer equation by factoring a 2^23 out of the exponent
519 | // value = (1 + mantissa/2^23) * 2^23 * 2 ^ (exponent-127-23)
520 | // value = (2^23 + mantissa) * 2 ^ (exponent-127-23)
521 | // Because of the implied 1 in front of the mantissa we have 24 bits of precision.
522 | // m = (2^23 + mantissa)
523 | // e = (exponent-127-23)
524 | mantissa = (1UL << 23) | floatMantissa;
525 | exponent = floatExponent - 127 - 23;
526 | mantissaHighBitIdx = 23;
527 | hasUnequalMargins = (floatExponent != 1) && (floatMantissa == 0);
528 | }
529 | else
530 | {
531 | // denormalized
532 | // The floating point equation is:
533 | // value = (mantissa/2^23) * 2 ^ (1-127)
534 | // We convert the integer equation by factoring a 2^23 out of the exponent
535 | // value = (mantissa/2^23) * 2^23 * 2 ^ (1-127-23)
536 | // value = mantissa * 2 ^ (1-127-23)
537 | // We have up to 23 bits of precision.
538 | // m = (mantissa)
539 | // e = (1-127-23)
540 | mantissa = floatMantissa;
541 | exponent = 1 - 127 - 23;
542 | mantissaHighBitIdx = LogBase2(mantissa);
543 | hasUnequalMargins = false;
544 | }
545 |
546 | // format the value
547 | switch (format)
548 | {
549 | case PrintFloatFormat_Positional:
550 | return FormatPositional( pOutBuffer,
551 | bufferSize,
552 | mantissa,
553 | exponent,
554 | mantissaHighBitIdx,
555 | hasUnequalMargins,
556 | precision,
557 | decimalPoint );
558 |
559 | case PrintFloatFormat_Scientific:
560 | return FormatScientific( pOutBuffer,
561 | bufferSize,
562 | mantissa,
563 | exponent,
564 | mantissaHighBitIdx,
565 | hasUnequalMargins,
566 | precision,
567 | decimalPoint );
568 |
569 | default:
570 | pOutBuffer[0] = '\0';
571 | return 0;
572 | }
573 | }
574 | }
575 |
576 | //******************************************************************************
577 | // Print a 64-bit floating-point number as a decimal string.
578 | // The output string is always NUL terminated and the string length (not
579 | // including the NUL) is returned.
580 | //******************************************************************************
581 | tU32 PrintFloat64
582 | (
583 | tC8 * pOutBuffer, // buffer to output into
584 | tU32 bufferSize, // size of pOutBuffer
585 | tF64 value, // value to print
586 | tPrintFloatFormat format, // format to print with
587 | tS32 precision, // If negative, the minimum number of digits to represent a
588 | tC8 decimalPoint // Character before the decimals
589 | // unique 64-bit floating point value is output. Otherwise,
590 | // this is the number of digits to print past the decimal point.
591 | )
592 | {
593 | if (bufferSize == 0)
594 | return 0;
595 |
596 | if (bufferSize == 1)
597 | {
598 | pOutBuffer[0] = '\0';
599 | return 1;
600 | }
601 |
602 | // deconstruct the floating point value
603 | tFloatUnion64 floatUnion;
604 | floatUnion.m_floatingPoint = value;
605 | tU32 floatExponent = floatUnion.GetExponent();
606 | tU64 floatMantissa = floatUnion.GetMantissa();
607 |
608 | // output the sign
609 | if (floatUnion.IsNegative())
610 | {
611 | pOutBuffer[0] = '-';
612 | ++pOutBuffer;
613 | --bufferSize;
614 | RJ_ASSERT(bufferSize > 0);
615 | }
616 |
617 | // if this is a special value
618 | if (floatExponent == 0x7FF)
619 | {
620 | return PrintInfNan(pOutBuffer, bufferSize, floatMantissa, 13);
621 | }
622 | // else this is a number
623 | else
624 | {
625 | // factor the value into its parts
626 | tU64 mantissa;
627 | tS32 exponent;
628 | tU32 mantissaHighBitIdx;
629 | tB hasUnequalMargins;
630 |
631 | if (floatExponent != 0)
632 | {
633 | // normal
634 | // The floating point equation is:
635 | // value = (1 + mantissa/2^52) * 2 ^ (exponent-1023)
636 | // We convert the integer equation by factoring a 2^52 out of the exponent
637 | // value = (1 + mantissa/2^52) * 2^52 * 2 ^ (exponent-1023-52)
638 | // value = (2^52 + mantissa) * 2 ^ (exponent-1023-52)
639 | // Because of the implied 1 in front of the mantissa we have 53 bits of precision.
640 | // m = (2^52 + mantissa)
641 | // e = (exponent-1023+1-53)
642 | mantissa = (1ull << 52) | floatMantissa;
643 | exponent = floatExponent - 1023 - 52;
644 | mantissaHighBitIdx = 52;
645 | hasUnequalMargins = (floatExponent != 1) && (floatMantissa == 0);
646 | }
647 | else
648 | {
649 | // subnormal
650 | // The floating point equation is:
651 | // value = (mantissa/2^52) * 2 ^ (1-1023)
652 | // We convert the integer equation by factoring a 2^52 out of the exponent
653 | // value = (mantissa/2^52) * 2^52 * 2 ^ (1-1023-52)
654 | // value = mantissa * 2 ^ (1-1023-52)
655 | // We have up to 52 bits of precision.
656 | // m = (mantissa)
657 | // e = (1-1023-52)
658 | mantissa = floatMantissa;
659 | exponent = 1 - 1023 - 52;
660 | mantissaHighBitIdx = LogBase2(mantissa);
661 | hasUnequalMargins = false;
662 | }
663 |
664 | // format the value
665 | switch (format)
666 | {
667 | case PrintFloatFormat_Positional:
668 | return FormatPositional( pOutBuffer,
669 | bufferSize,
670 | mantissa,
671 | exponent,
672 | mantissaHighBitIdx,
673 | hasUnequalMargins,
674 | precision,
675 | decimalPoint );
676 |
677 | case PrintFloatFormat_Scientific:
678 | return FormatScientific( pOutBuffer,
679 | bufferSize,
680 | mantissa,
681 | exponent,
682 | mantissaHighBitIdx,
683 | hasUnequalMargins,
684 | precision,
685 | decimalPoint );
686 |
687 | default:
688 | pOutBuffer[0] = '\0';
689 | return 0;
690 | }
691 | }
692 | }