1 /* 2 * percent.c - Take percentage of a number 3 * 4 * Copyright (C) 2006 Theodore Ts'o <tytso (at) 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 */ 18 unsigned int e2p_percent(int percent, unsigned int base) 19 { 20 unsigned int mask = ~((1 << (sizeof(unsigned int) - 1) * 8) - 1); 21 22 if (!percent) 23 return 0; 24 if (100 % percent == 0) 25 return base / (100 / percent); 26 if (mask & base) 27 return (base / 100) * percent; 28 return base * percent / 100; 29 } 30 31 #ifdef DEBUG 32 #include <unistd.h> 33 #include <stdio.h> 34 35 main(int argc, char **argv) 36 { 37 unsigned int base; 38 int percent; 39 char *p; 40 int log_block_size = 0; 41 42 if (argc != 3) { 43 fprintf(stderr, "Usage: %s percent base\n", argv[0]); 44 exit(1); 45 } 46 47 percent = strtoul(argv[1], &p, 0); 48 if (p[0] && p[1]) { 49 fprintf(stderr, "Bad percent: %s\n", argv[1]); 50 exit(1); 51 } 52 53 base = strtoul(argv[2], &p, 0); 54 if (p[0] && p[1]) { 55 fprintf(stderr, "Bad base: %s\n", argv[2]); 56 exit(1); 57 } 58 59 printf("%d percent of %u is %u.\n", percent, base, 60 e2p_percent(percent, base)); 61 62 exit(0); 63 } 64 #endif 65