Home | History | Annotate | Download | only in e2p
      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