summaryrefslogtreecommitdiffstats
path: root/private/crt32/convert/_fptostr.c
blob: 2877168426f51e1be247180432614120e3150822 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/***
*_fptostr.c - workhorse routine for converting floating point to string
*
*	Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
*
*Purpose:
*	Workhorse routine for fcvt, ecvt.
*
*Revision History:
*	09-17-84  DFW	created
*	03-05-90  GJF	Fixed calling type, added #include <cruntime.h>,
*			removed #include <register.h>, fixed copyright. Also,
*			cleaned up the formatting a bit.
*	07-20-90  SBM	Compiles cleanly with -W3 (added #include <string.h>)
*	08-01-90  SBM	Renamed <struct.h> to <fltintrn.h>
*	09-27-90  GJF	New-style function declarator.
*	06-11-92  GDP	Bug fix: Shorten string if leadig (overflow) digit is 1
*	10-09-92  GDP	Backed out last fix for ecvt (printf regressed)
*
*******************************************************************************/

#include <cruntime.h>
#include <string.h>
#include <fltintrn.h>

/***
*void _fptostr(buf, digits, pflt) - workhorse floating point conversion
*
*Purpose:
*	This is the workhorse routine for fcvt, ecvt. Here is where
*	all the digits are put into a buffer and the rounding is
*	performed and indicators of the decimal point position are set. Note,
*	this must not change the mantissa field of pflt since routines which
*	use this routine rely on this being unchanged.
*
*Entry:
*	char *buf - the buffer in which the digits are to be put
*	int digits - the number of digits which are to go into the buffer
*	STRFLT pflt - a pointer to a structure containing information on the
*		floating point value, including a string containing the
*		non-zero significant digits of the mantissa.
*
*Exit:
*	Changes the contents of the buffer and also may increment the decpt
*	field of the structure pointer to by the 'pflt' parameter if overflow
*	occurs during rounding (e.g. 9.999999... gets rounded to 10.000...).
*
*Exceptions:
*
*******************************************************************************/

void _CALLTYPE1 _fptostr (
	char *buf,
	REG4 int digits,
	REG3 STRFLT pflt
	)
{
	REG1 char *pbuf = buf;
	REG2 char *mantissa = pflt->mantissa;

	/* initialize the first digit in the buffer to '0' (NOTE - NOT '\0')
	 * and set the pointer to the second digit of the buffer.  The first
	 * digit is used to handle overflow on rounding (e.g. 9.9999...
	 * becomes 10.000...) which requires a carry into the first digit.
	 */

	*pbuf++ = '0';

	/* Copy the digits of the value into the buffer (with 0 padding)
	 * and insert the terminating null character.
	 */

	while (digits > 0) {
		*pbuf++ = (*mantissa) ? *mantissa++ : (char)'0';
		digits--;
	}
	*pbuf = '\0';

	/* do any rounding which may be needed.  Note - if digits < 0 don't
	 * do any rounding since in this case, the rounding occurs in  a digit
	 * which will not be output beause of the precision requested
	 */

	if (digits >= 0 && *mantissa >= '5') {
		pbuf--;
		while (*pbuf == '9')
			*pbuf-- = '0';
		*pbuf += 1;
	}

	if (*buf == '1') {
		/* the rounding caused overflow into the leading digit (e.g.
		 * 9.999.. went to 10.000...), so increment the decpt position
		 * by 1
		 */
		pflt->decpt++;
	}
	else {
		/* move the entire string to the left one digit to remove the
		 * unused overflow digit.
		 */
		strcpy(buf, buf+1);
	}
}