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