odds and evens numbers

R

Raquel

Hello, I would like to know if there are some function in some library
in JAVA to know if one number is odd or even.
Thank you
 
C

Chris

Raquel said:
Hello, I would like to know if there are some function in some library
in JAVA to know if one number is odd or even.
Thank you

int myNumber = 3;
if (myNumber & 0x1 > 0) {
// it's odd
} else {
// it's even
}

This only works with integers, not floats or doubles.
 
J

Jae Muzzin

Chris said:
int myNumber = 3;
if (myNumber & 0x1 > 0) {
// it's odd
} else {
// it's even
}

This only works with integers, not floats or doubles.

Wouldn't it be easier to just say:

if(myNumber % 2 ==0)
//even
else
//odd
 
P

Paul Lutus

Chris said:
int myNumber = 3;
if (myNumber & 0x1 > 0) {
// it's odd
} else {
// it's even
}

This only works with integers, not floats or doubles.

And floats and doubles must be converted to integers before an attempt is
made to run this (or the other common) algorithm, unless of course one
doesn't care whether the outcome is correct.
 
J

Jacob

Raquel said:
Hello, I would like to know if there are some function in some library
in JAVA to know if one number is odd or even.

No there is not.

But there should have been; Many programs needs this feature,
and a clear logic is suddenly poluted by the introduction of
bit arithmetics and/or modulus operators.

I'd suggest the following standard methods:

boolean Integer.isOdd()
static boolean Integer.isOdd (int value)
boolean Integer.isEven()
static boolean Integer.isEven (int value)

And ditto for Long.
 
P

Paul Lutus

Jacob said:
No there is not.

But there should have been; Many programs needs this feature,
and a clear logic is suddenly poluted by the introduction of
bit arithmetics and/or modulus operators.

Polluted? In fact, the choice to use these operators in all current
languages is because it takes advantage of the programmer's knowledge of
mathematics and its notation (assuming that is true).
I'd suggest the following standard methods:

boolean Integer.isOdd()
static boolean Integer.isOdd (int value)
boolean Integer.isEven()
static boolean Integer.isEven (int value)

And ditto for Long.

Sorry, this is silly. Many arithmetic operations are assumed to be the
province of the programmer, such as adding and subtracting numbers. Should
we have class members called "multiply(x,y)" and "divide(x,y)" to avoid
having to use "*" and "/"? If not, then by the same token why avoid the
modulo operator and its many uses, like determining if an integer is odd or
even?
 
J

Jacob

Paul said:
Sorry, this is silly. Many arithmetic operations are assumed to be the
province of the programmer, such as adding and subtracting numbers. Should
we have class members called "multiply(x,y)" and "divide(x,y)" to avoid
having to use "*" and "/"? If not, then by the same token why avoid the
modulo operator and its many uses, like determining if an integer is odd or
even?

I am concerned about the readability of the code only.
I am sure every programmer knows what this means:

// Check if value is even
if (value % 2 == 0) ...

Still I always add the comment as shown. Mostly because
I always need to think twice if it is an odd or an even
test (BTW, I am a mathematician, which explains a lot :)

But as I prefer code that comment itself, I would find
this a lot more expressive:

if (Integer.isEven (value)) ...
 
P

Paul Lutus

Jacob said:
I am concerned about the readability of the code only.
I am sure every programmer knows what this means:

// Check if value is even
if (value % 2 == 0) ...

Uhh, not necessarily. Many current programmers without quality math
instruction (surprisingly common) won't necessarily understand it, or see
its advantages over (value & 1 == 0) .
Still I always add the comment as shown. Mostly because
I always need to think twice if it is an odd or an even
test (BTW, I am a mathematician, which explains a lot :)

In any case, the comment is completely appropriate to include in a
maintainable program, regardless of the skills of the originator.
But as I prefer code that comment itself, I would find
this a lot more expressive:

if (Integer.isEven (value)) ...

Yes, but such a method is only a named wrapper for your above example, it
doesn't add anything to the code, nor does it encapsulate anything
significant, and it places a constraint on the datatype for the underlying
operation (it turns out that in Java, v % 2 == 0 can meaningfully be
applied to nearly any data type).

Nevertheless, the argument can be made, and you have made it. :)
 
T

Tor Iver Wilhelmsen

Jacob said:
But there should have been;

Why add the overhead of a method call to an expression that is learned
in Programming 101?
and a clear logic is suddenly poluted by the introduction of
bit arithmetics and/or modulus operators.

Operators are central to programming languages; expressions are
central to the act of programming. Hiding basic expressions below
methods only serves to "Englishify" maths.
boolean Integer.isOdd()
static boolean Integer.isOdd (int value)
boolean Integer.isEven()
static boolean Integer.isEven (int value)

Also:

static int Integer.halve(int value) - dividing by 2 is done so often
it needs a method.

static int Integer.double(int value) - multiplying by two also.
 
T

Thomas Schodt

Jacob said:
Raquel said:
[Is] there some function in some library
in JAVA to know if one number is odd or even.

No there is not.

But there should be; Many programs needs this feature,
and a clear logic is suddenly polluted by the introduction of
bit arithmetics and/or modulus operators.

I'd suggest the following standard methods:

boolean Integer.isOdd()
static boolean Integer.isOdd (int value)
boolean Integer.isEven()
static boolean Integer.isEven (int value)

And ditto for Long.


All of
if ((var&1)==0)
if ((var%2)==0)
if (var.isEven())
would mean the same.

What is this obsession with the value of the least significant
bit of a scalar variable?

In contexts where I would need to know this I would probably need to do
other binary or boolean stuff. Something like isEven() would just throw
my train of thought off the logical track (as I suddently have to
consider semantics instead of logic).


Would both isEven() and isOdd() not be a bit redundant?
You could just use
if (!isEven())


Would you also consider
if (var.isNegative())
preferable over
if (var<0)


I would vote against the introduction of such methods to the primitive
box classes.
OFC you are free to write your own class with static methods for these
operations.
 
J

Jonck van der Kogel

I am concerned about the readability of the code only.
I am sure every programmer knows what this means:

// Check if value is even
if (value % 2 == 0) ...

Still I always add the comment as shown. Mostly because
I always need to think twice if it is an odd or an even
test (BTW, I am a mathematician, which explains a lot :)

But as I prefer code that comment itself, I would find
this a lot more expressive:

if (Integer.isEven (value)) ...

Hi Jacob,
If you prefer that notation a suggestion might be that you write your
own class called, for example, MathUtil and add an isEven and isOdd
method to it (and any other math utility functions you would like).
Then in your code you can import this class and call it as such:
if (MathUtil.isEven(value)) ...

You can make isEven and isOdd polymorphic so it accepts integers,
doubles, singles, etc... as argument.

All the best, Jonck
 
J

Juha Laiho

Thomas Schodt said:
Would both isEven() and isOdd() not be a bit redundant?
You could just use
if (!isEven())

But then, this method only handles issues with numbers divisible by two;
who don't we generalize it to isDivisibleBy(x)?

[ducks; runs, laughing]
 
T

Tom McGlynn

Paul said:
Chris wrote:




And floats and doubles must be converted to integers before an attempt is
made to run this (or the other common) algorithm, unless of course one
doesn't care whether the outcome is correct.

Why??

static boolean isEven(double a) {
return a%2 == 0;
}
static boolean isOdd (double a) {
return Math.abs(a%2) == 1;
}

would seem to work for all doubles. Of course the majority of doubles are
neither even nor odd.

[I was going to say the vast majority, but on reflection that's probably not
true. All very large Java doubles (>~10^17) or floats (>~10^8) are even, so
the fraction of floats/doubles that are even is probably a
good percentage of all of them ~40% at a guess.
The fraction that are odd should be much smaller.]

I could even imagine a use for these kinds of functions,
e.g., if I was dealing with a grid and I needed to
do something special when I happened to land exactly
on a grid point (and do something different on the
odd and even points).

Regardless I think I can manage to code the functions above,
or the more frequently desired integer cases, whenever
I happen to need them.

Regards,
Tom McGlynn
 
P

Paul Lutus

Tom McGlynn wrote:

/ ...

[ P. Lutus said: ]

Because not all floats can be reliably converted into integers without
rounding and other issues creating an unexpected result.
static boolean isEven(double a) {
return a%2 == 0;
}
static boolean isOdd (double a) {
return Math.abs(a%2) == 1;
}

would seem to work for all doubles. Of course the majority of doubles are
neither even nor odd.

I think that was my point. One would have to accept that the test applied
only to the truncated (not rounded) integer value.
[I was going to say the vast majority, but on reflection that's probably
[not
true. All very large Java doubles (>~10^17) or floats (>~10^8) are even,

Explain? How can a large set of doubles be all declared even based on their
magnitude?
so the fraction of floats/doubles that are even is probably a
good percentage of all of them ~40% at a guess.
The fraction that are odd should be much smaller.]

Again, explain?

(pause) Okay, I think I see what you are saying. Because the double data
type mantissa has about 16 decimal digits, those with a magnitude > roughly
10^16 have trailing zeros in the extended mantissa, therefore they are
even.
 
M

Mark Thornton

Paul said:
Tom McGlynn wrote:

/ ...

[ P. Lutus said: ]



Because not all floats can be reliably converted into integers without
rounding and other issues creating an unexpected result.

static boolean isEven(double a) {
return a%2 == 0;
}
static boolean isOdd (double a) {
return Math.abs(a%2) == 1;
}

would seem to work for all doubles. Of course the majority of doubles are
neither even nor odd.


I think that was my point. One would have to accept that the test applied
only to the truncated (not rounded) integer value.

The tests given by Tom return the correct answer for any double value
(including the special ones) without any conversion to integer. In fact
it is rather difficult to get the correct answer if you do convert to
integer (special handling then required for values out of the integer
range or for non integral values).

Also note that the remainder operator produces an exact result (there is
no rounding required).

Mark
 
P

Paul Lutus

Mark Thornton wrote:

/ ...
The tests given by Tom return the correct answer for any double value
(including the special ones) without any conversion to integer.

The integer conversion is implicit. Obviously carrying out the specified
modulo operation on two floats will produce a floating-point result that is
neither odd nor even. So there is a conversion, in one sense or another,
even if it means testing the remainder against 1.000.
In fact
it is rather difficult to get the correct answer if you do convert to
integer (special handling then required for values out of the integer
range or for non integral values).

I meant truncation of the integer portion of a float. Somewhat less
problematical.
Also note that the remainder operator produces an exact result (there is
no rounding required).

No, that is not consistent with what you said above. Either the modulo
operation produces a floating-point result where appropriate, or there is a
conversion to integer before, during or after the operation.
 
B

Babu Kalakrishnan

Paul said:
No, that is not consistent with what you said above. Either the modulo
operation produces a floating-point result where appropriate, or there is a
conversion to integer before, during or after the operation.

JLS Second edition (§15.17.3) doesn't seem to specify a conversion to integer.

It says :

[cases describing operands involving 0, NaN, Infinity skipped]

"In the remaining cases, where neither an infinity, nor a zero, nor NaN is
involved, the floating-point remainder r from the division of a dividend n by a
divisor d is defined by the mathematical relation r = n - (d.q) where q is an
integer that is negative only if n/d is negative and positive only if n/d is
positive, and whose magnitude is as large as possible without exceeding the
magnitude of the true mathematical quotient of n and d"


BK
 
P

Paul Lutus

Babu said:
Paul said:
No, that is not consistent with what you said above. Either the modulo
operation produces a floating-point result where appropriate, or there is
a conversion to integer before, during or after the operation.

JLS Second edition (§15.17.3) doesn't seem to specify a conversion to
integer.

It says :

[cases describing operands involving 0, NaN, Infinity skipped]

"In the remaining cases, where neither an infinity, nor a zero, nor NaN is
involved, the floating-point remainder r from the division of a dividend n
by a divisor d is defined by the mathematical relation r = n - (d.q) where
q is an integer that is negative only if n/d is negative and positive only
if n/d is positive, and whose magnitude is as large as possible without
exceeding the magnitude of the true mathematical quotient of n and d"

I don't think this directly addresses the issue of applying the modulo
operator to floating-point data types. But that case could be handled
without a conversion to integer by comparing the remainder of n/2 to 0.5
(not 1.0 as I thought earlier). For a floating-point data type that was not
an integer, this would basically determine how close the number was to the
nearest odd or even integer.

It turns out that is apparently what the modulo operator does. Here's some
test code:

import java.text.*;

public class Test {

static String OddEvenTest(double v)
{
return (v >= 0.5)?"Odd":"Even";
}

static public void main(String[] args)
{
for(double v = 0;v < 3;v += 0.1) {
double q = v / 2.0;
double r1 = (q - Math.floor(q)) * 2;
double r2 = v % 2.0;
String sv = new DecimalFormat("0.0").format(v);
System.out.println(sv + "," + OddEvenTest(r1)
+ "," + OddEvenTest(r2));
}
}
}

Output:

0.0,Even,Even
0.1,Even,Even
0.2,Even,Even
0.3,Even,Even
0.4,Even,Even
0.5,Odd,Odd
0.6,Odd,Odd
0.7,Odd,Odd
0.8,Odd,Odd
0.9,Odd,Odd
1.0,Odd,Odd
1.1,Odd,Odd
1.2,Odd,Odd
1.3,Odd,Odd
1.4,Odd,Odd
1.5,Odd,Odd
1.6,Odd,Odd
1.7,Odd,Odd
1.8,Odd,Odd
1.9,Odd,Odd
2.0,Even,Even
2.1,Even,Even
2.2,Even,Even
2.3,Even,Even
2.4,Even,Even
2.5,Odd,Odd
2.6,Odd,Odd
2.7,Odd,Odd
2.8,Odd,Odd
2.9,Odd,Odd

The result is a bit more peculiar than I expected, but it's clear that this
is how the modulo operator is applied to floating-point values.
 
M

Mark Thornton

Paul said:
Mark Thornton wrote:

/ ...




The integer conversion is implicit. Obviously carrying out the specified
modulo operation on two floats will produce a floating-point result that is
neither odd nor even. So there is a conversion, in one sense or another,
even if it means testing the remainder against 1.000.




I meant truncation of the integer portion of a float. Somewhat less
problematical.




No, that is not consistent with what you said above. Either the modulo
operation produces a floating-point result where appropriate, or there is a
conversion to integer before, during or after the operation.

Yes it is. Ignoring the special values, the remainder a%b is always a
member of the set of values exactly representable by a double (assuming
a and b are double values). That is the remainder does not have to be
rounded or truncated to a nearby value.

Thus a%2 will be zero if and only if 'a' an even integer. Similarly
Math.abs(a)%2 will be 1 if and only if 'a' is an odd integer.

Note I could rewrite the tests as

a%2 == 0.0

and

Math.abs(a)%2 == 1.0

this makes it clear that the comparison is done on double values. On
many machines conversion to integer is actually quite slow, so it is
useful to avoid it.

Mark Thornton
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top