-3

I'm trying to simplify fractions in binary with this code that checks if the value is even:

int is_even(floatlet value){
  if(value & 1) return 0;
  return 1;
}

And this while loop keeps bit shifting until the value is odd.

while(is_even(numerator) && is_even(denomExp)){
  numerator >>= 1;
  denomExp <<= 1;
}

The while loop goes on an infinite loop. I'm wondering why? We've done test and the is_even function works fine. Thanks!

skaggs
  • 15
  • 4
  • 2
    What is a `floatlet`? What are the types of `numerator` and `denominator`? – chqrlie Jul 02 '15 at 01:48
  • a) 0 is even and so is 0/2 and 0 * 2. b) You haven't bothered to show the declarations or values of numerator and denomExp ... how can you possibly expect anyone to answer your question without those? – Jim Balter Jul 02 '15 at 01:49
  • It's a minature floating point representation of a floating point number in 8 bits. Numerator and denominator are just integers. – skaggs Jul 02 '15 at 01:51
  • P.S. If you care about speed: #define is_even(x) !((x) & 1) – Jim Balter Jul 02 '15 at 01:53
  • 1
    I am not sure what you mean by *minature floating point representation of a floating point number in 8 bits*... your test for evenness may be incorrect. – chqrlie Jul 02 '15 at 01:54
  • @chqrlie It's presumably a mantissa and exponent crammed into 8 bits. Presumably the exponent is in the high bits ... otherwise is_even is indeed wrong. – Jim Balter Jul 02 '15 at 01:58
  • Please post the complete type definition and the complete code. Your question is incomplete without those. – chqrlie Jul 02 '15 at 01:58
  • @JimBalter Firstly, there is no evidence that the compiler doesn't inline that function, meaning there is no evidence that your code would speed anything up. Secondly... – autistic Jul 02 '15 at 07:33
  • @skaggs `value & 1` isn't necessary a test for evenness. If you care about portability, use `value % 2`. [It'll probably be just as fast.](http://stackoverflow.com/a/160935/1989425) – autistic Jul 02 '15 at 07:33
  • @undefinedbehaviour You're right ... that was silly of me. – Jim Balter Jul 02 '15 at 07:50

1 Answers1

1

Your loop is incorrect: you should be shifting demonExp to the right too. It runs indefinitely for numerator=0 and an even denomExp.

If numerator and denomExp are integer types, and the number is just a fraction numerator/denomExp, you can fix the code this way:

while (numerator && is_even(numerator) && is_even(denomExp)) {
    numerator >>= 1;
    denomExp >>= 1;
}

Conversely, if denomExp is the power of 2 by which to divide the numerator, you should increment it instead, and maybe test for overflow:

while (numerator && is_even(numerator)) {
    numerator >>= 1;
    denomExp += 1;
}

You must post the type definition and semantics as well as the complete code in question.

chqrlie
  • 131,814
  • 10
  • 121
  • 189