percent.c revision a8862d9e90d0d94761ba28dbbf9674308fd7d7c0
1/*
2 * percent.c		- Take percentage of a number
3 *
4 * Copyright (C) 2006  Theodore Ts'o <tytso@mit.edu>
5 *
6 * This file can be redistributed under the terms of the GNU Library General
7 * Public License
8 */
9
10#include "e2p.h"
11
12#include <stdlib.h>
13
14/*
15 * We work really hard to calculate this accurately, while avoiding
16 * an overflow.  "Is there a hyphen in anal-retentive?"  :-)
17 */
18unsigned int e2p_percent(int percent, unsigned int base)
19{
20	unsigned int mask = ~((1 << (sizeof(unsigned int) - 1) * 8) - 1);
21
22	if (100 % percent == 0)
23		return base / (100 / percent);
24	if (mask & base)
25		return (base / 100) * percent;
26	return base * percent / 100;
27}
28
29#ifdef DEBUG
30#include <unistd.h>
31#include <stdio.h>
32
33main(int argc, char **argv)
34{
35	unsigned int base;
36	int percent;
37	char *p;
38	int log_block_size = 0;
39
40	if (argc != 3) {
41		fprintf(stderr, "Usage: %s percent base\n", argv[0]);
42		exit(1);
43	}
44
45	percent = strtoul(argv[1], &p, 0);
46	if (p[0] && p[1]) {
47		fprintf(stderr, "Bad percent: %s\n", argv[1]);
48		exit(1);
49	}
50
51	base = strtoul(argv[2], &p, 0);
52	if (p[0] && p[1]) {
53		fprintf(stderr, "Bad base: %s\n", argv[2]);
54		exit(1);
55	}
56
57	printf("%d percent of %u is %u.\n", percent, base,
58	       e2p_percent(percent, base));
59
60	exit(0);
61}
62#endif
63