percent.c revision 543547a52a20cb7e69d74921b2f691078fd55d83
16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/*
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * percent.c		- Take percentage of a number
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * Copyright (C) 2006  Theodore Ts'o <tytso@mit.edu>
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * %Begin-Header%
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * This file may be redistributed under the terms of the GNU Library
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * General Public License, version 2.
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * %End-Header%
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "e2p.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <stdlib.h>
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/*
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * We work really hard to calculate this accurately, while avoiding
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) * an overflow.  "Is there a hyphen in anal-retentive?"  :-)
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) */
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)unsigned int e2p_percent(int percent, unsigned int base)
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles){
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	unsigned int mask = ~((1 << (sizeof(unsigned int) - 1) * 8) - 1);
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	if (!percent)
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		return 0;
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	if (100 % percent == 0)
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		return base / (100 / percent);
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	if (mask & base)
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		return (base / 100) * percent;
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	return base * percent / 100;
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#ifdef DEBUG
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <unistd.h>
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include <stdio.h>
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)main(int argc, char **argv)
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles){
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	unsigned int base;
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	int percent;
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	char *p;
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	int log_block_size = 0;
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	if (argc != 3) {
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		fprintf(stderr, "Usage: %s percent base\n", argv[0]);
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		exit(1);
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	}
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)	percent = strtoul(argv[1], &p, 0);
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)	if (p[0] && p[1]) {
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)		fprintf(stderr, "Bad percent: %s\n", argv[1]);
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		exit(1);
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	}
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci	base = strtoul(argv[2], &p, 0);
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	if (p[0] && p[1]) {
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		fprintf(stderr, "Bad base: %s\n", argv[2]);
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)		exit(1);
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	}
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	printf("%d percent of %u is %u.\n", percent, base,
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	       e2p_percent(percent, base));
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)	exit(0);
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)