1

(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.

0

2 Answers 2

5

log returns a double. You should round instead of truncate. However, you can use log2 here.

Sign up to request clarification or add additional context in comments.

5 Comments

In addition, there is a log2() function to directly get base 2 logarithms, instead of doing that division yourself.
You posted that a second before I added that, Carl. :)
I read that log2 requires "-std=c99" and I'm lazy with my makefiles. If I have another question in the same program but unrelated to this problem should I post it here or make a whole new question?
@DuffDuff: Questions on unrelated issues should be posted separately. That said, the answer is probably CFLAGS += -std=c99
Hahaha, that is NOT what I was going to ask, but thank you. =D
1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.