Re: Requesting help again... as a beginner....
- Posted by DerekParnell (admin) May 24, 2009
- 967 views
if remainder(a, 2) != 0 then puts(1,"\nThat is an odd number.") end if
Bits twiddling is neater and faster:
if and_bits(a, 1) then ...
jiri
Yes, but needs more explanation for a newcomer.
The remainder() idea just works on the premise that odd numbers always have a remainder of 1 when divided by 2. However, dividing is often slower than most other arithmetic operations.
The bit twiddling idea works by knowing that the way that computers store numbers in memory. All numbers are just a set of bits (ones and zeros). In Euphoria, whole numbers use a set of 31-bits and the number of combinations that these have means that it can easily store all the whole numbers from -1,073,741,824 to +1,073,741,823. However, every odd number always has the 31st bit set to 1 and even numbers always have this set to 0. The and_bits() function does a binary 'and' operation on every bit in the two sets of bits supplied in its parameters. An 'and' operation simply returns 0 if either bit is a zero, and returns a 1 if both bits are 1.
So testing for oddness using and_bits(a, 1) is just this ...
31-bits in 'a' = xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 31-bits in 1 = 000 0000 0000 0000 0000 0000 0000 0000 0001Where the 'x' is either 1 or 0. Because all but the 31st bit in '1' is zero, the results for anding these are also zero. But with that last bit, if 'a' is odd then its last bit is 1 otherwise 0 (even). So odd numbers 'and' 1 and 1 ==> 1, and even numbers 'and' 0 and 1 ==> 0.
Therefore, and_bits(a,1) for odd numbers always returns 1 and 0 for even numbers, and this is a lot faster than doing a division.
As this comes up frequently, I'll add it as a standard function to the math.e library for v4. The inlining feature should ensure that this will not have a function call overhead.