File: price_conv.c

package info (click to toggle)
libgdchart-gd2 0.11.5-10
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 296 kB
  • sloc: ansic: 3,342; makefile: 287
file content (93 lines) | stat: -rw-r--r-- 2,197 bytes parent folder | download | duplicates (7)
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
/* GDCHART 0.10.0dev  PRICE_CONV.C  2 Nov 2000 */
/* Copyright Bruce Verderaime 1998-2004 */

/* 
*  - price as float to a string (ostensibly for printing)
*/

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>

/* ----------------------------------------------------------------- */
/* -- convert a float to a printable string, in form:             -- */
/* --	W N/D                                                     -- */
/* -- where W is whole, N is numerator, D is denominator          -- */
/* -- the frac N/D is one of 2nds, 4,8,16,32,64,128,256ths        -- */
/* -- if cannot convert, return str of the float                  -- */
/* ----------------------------------------------------------------- */

#define EPSILON		((1.0/256.0)/2.0)
#define GET_DEC(x)	( (x) - (float)(int)(x) )

char*
price_to_str( float	price,
			  int	*numorator,
			  int	*demoninator,
			  int	*decimal,
			  char	*fltfmt )			/* printf fmt'ing str */
{
    static char rtn[64];
	int			whole = (int)price;
	float		dec   = GET_DEC( price ),
				numr;
	/* float		pow( double, double ); */

	/* caller doesn't want fractions */
	if( fltfmt )
		{
		sprintf( rtn, fltfmt, price );
		*numorator = *demoninator = *decimal = 0;
		return rtn;
		}

	numr = dec * 256;
	/* check if we have a perfect fration in 256ths */
	{	
		float	rdec = GET_DEC( numr );

		if( rdec < EPSILON )
			;							/* close enough to frac */
		else if( (1-rdec) < EPSILON )	/* just over but close enough */
			++numr;
		else							/* no frac match */
		{
			sprintf( rtn, "%f", price );
			*numorator = *demoninator = *decimal = 0;
			return rtn;
		}
	}

	/* now have numr 256ths */
	/* resolve down */
	if( numr != 0 )
		{
		int	cnt = 8;

		while( (float)(numr)/2.0 == (float)(int)(numr/2) )
			{
			numr /= 2;
			--cnt;
			}

		/* don't want both whole AND numerator to be - */
		if( whole<0 && numr<0.0 )
			numr = -numr;
		*numorator = (int)numr;
		*demoninator = (int)pow(2.0, (float)cnt);
		*decimal = whole;
		sprintf( rtn, "%d %d/%d", whole,
								  (int)numr,
								  *demoninator );
		}
	else
		{
		*numorator = *demoninator = 0;
		*decimal = whole;
		sprintf( rtn, "%d", whole );
		}

    return rtn;
}