Reputation: 113
(all are declared as ints, none are initialized to anything beforehand. I have included math.h and am compiling with -lm)
cachesize = atoi(argv[1]);
blocksize = atoi(argv[3]);
setnumber = (cachesize/blocksize);
printf("setnumber: %d\n", setnumber);
setbits = (log(setnumber))/(log(2));
printf("sbits: %d\n", setbits);
when given cachesize as 1024 and blocksize as 16 the output is as follows:
setnumber: 64
sbits: 5
but log(64)/log(2) = 6 !
It works correctly when given cachesize 512 and blocksize 32. I can't seem to win.
I'm really hoping that it's a stupid mistake on my part, and I'd be grateful if anyone could point out what it is! Thank you!
PS: I posted this in Yahoo Answers first but that was probably silly. Won't be doing that again.
Upvotes: 1
Views: 1044
Reputation: 106127
What's happening is that neither log(2)
or log(setnumber)
are exactly representable as floating-point numbers, and their rounding errors are conspiring to cause their quotient to round down to something just smaller than 6
, which then truncates to 5
when you convert to integer.
Using log2( )
will solve this problem on some platforms that have a good-quality math library, but the C standard does not actually guarantee anything about the accuracy of log( )
or log2( )
(indeed, some platforms just implement log2( )
as log( )/log(2)
, so it may give you the same problem you're having now).
You want to use the ilogb( )
function, which returns the exponent of its argument as a signed integer value.
setbits = ilogb(setnumber);
This has the added benefit of being quite a bit faster on some platforms.
(Admittedly, this use ilogb
is not portable to systems that use non-radix-2 floating-point, but that's a much smaller concern then platforms that just have shoddy math libraries)
Upvotes: 1
Reputation: 284786
log returns a double. You should round instead of truncate. However, you can use log2 here.
Upvotes: 5