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