When you know a thing, to hold that you know it, and when you do not know a thing, to allow that you do not know it - this is knowledge. -Confucius-

The gift of fantasy has meant more to me than my talent for absorbing positive knowledge. -Albert Einstein-

Science investigates religion interprets. Science gives man knowledge which is power religion gives man wisdom which is control. -Martin Luther King, Jr.-

Those who have knowledge, don't predict. Those who predict, don't have knowledge. -Lao Tzu-

Our treasure lies in the beehive of our knowledge. We are perpetually on the way thither, being by nature winged insects and honey gatherers of the mind. -Friedrich Nietzsche-

Thursday, February 18, 2016

Why it's bad to use floting point numbers for equality or condition checking ?




Most of the suggestions are to avoid floating-point numbers from equality checking or in condition checking. Because small errors in the rightmost decimal places are likely to arise when calculations are performed on floating-point numbers, And two float or double values (float and double are also different) rarely are exactly equal.

assume ,
double oneThird = 1.0 / 3.0;
double x = oneThird + oneThird + oneThird;

actually expected result is x to be equal to 1. But it probably doesn't. Because the first assignment statement stores an approximation of 1/3 in to oneThird, which is likely to be 0.3333333 (But actually it's 0.33333.....)
So the second statement stores something like 0.9999999 in to x.
So the computer will compare x with 1 and it recognize it as a mismatch. so eventually it will yield false.

Some interesting code snippets are listed below.

double a = 0.9999999999999999999;
if (1 == a) {
    System.out.println("1 equals to 0.9999999999999999999");
} else {
    System.out.println("1 does not equals to 0.9999999999999999999");
}
// prints "1 equals to 0.9999999999999999999"
float x = 1.1f;
double y = 1.1;
if (x != y) {
    System.out.println("1.1f and 1.1 does not match");
}
// prints "1.1f and 1.1 does not match"
double oneThird = 1.0 / 3.0;
double one = oneThird + oneThird + oneThird;
if(1.0000000000000000001 == one){
    System.out.println("1.0000000000000000001 equals to one");
} else {
    System.out.println("1.0000000000000000001 does not equals to one");
}
// prints "1.0000000000000000001 equals to one"
double a1 = 1.0/3.0;
double a2 = 0.333333;
if(a1 == a2){
    // programmer might think this will be the case !!!
    System.out.println("1.0/3.0 is equal to 0.33333");
}else{
    System.out.println("1.0/3.0 is not equal to 0.33333");
}
// prints "1.0/3.0 is not equal to 0.33333"
So how can we avoid this. Instead of checking for equality, we can test for near equality. one famous way to do this is to compute the difference between the numbers and see whether the result is less than some maximum allowable difference.
double EPSILON = 1.0e-7;
if (Math.abs(1 - a) < EPSILON) {
    System.out.println("yes");
} else {
    System.out.println("no");
}
// prints "yes"
Some interesting articles about this area are listed below.
0.999...
Why do so many people reject proofs that 0.999999... = 1?
Relational operators with floating point types
What Every Computer Scientist Should Know About Floating-Point Arithmetic ?
Comparing floating point numbers
Comparing Floating Point Numbers - by Random ASCII
Doubles are not floats, so don’t compare them
Why not use Double or Float to represent currency?

Thursday, February 11, 2016

When we need to override equals and hashcode methods in Java ?



If a class does not implement the 'equals' and 'hashcode' methods, the default implementation which inherited from the Object class will be used.

equals:

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). can be called as reference equality.

The default implementation is something like below,
public boolean equals(Object object) {
    return this == object;
}

hashCode:

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)
The default implementation is something like below,
public int hashCode() {
    return VMMemoryManager.getIdentityHashCode(this);
}
Consider the sample class Dog.

class Dog{
 String name;
 int age;
 
 public Dog(String name, int age) {
  super();
  this.name = name;
  this.age = age;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 } 
}

Let's initialize some objects from it.
Dog d1 = new Dog("tim",10);
Dog d2 = new Dog("tim",10);
Dog d3 = d1; // point it to the d1, so d3 will be referencing to the same object as d1.

if(d1.equals(d2)){
    System.out.println("yes");
}else{
    System.out.println("no");
}
/* this code block will print 'no' since d1 and d2 are not pointing to the same object, though we feel like both should be equal since attributes of that object are the same.
*/

if(d3.equals(d1)){
    System.out.println("yes");
}else{
    System.out.println("no");
}
// prints 'yes' because d3 and d1 are pointing to the same object.   
So what will happen when using collections framework,
HashMap map = new HashMap<>();
map.put(d1, "dog1");
map.put(d2, "dog2");
map.put(d3, "dog3");
   
System.out.println(map.size()); // prints '2' because d1 and d3 are considered as a single object since equals method will verify them as the same object
System.out.println(map.get(d2)); // prints 'dog2'
System.out.println(map.get(new Dog("tim",10))); // prints 'null'
   /* 'new Dog("tim",10)' has a new reference, it's a newly created object, though it has the attributes same as the other Dog instances. Since it's reference is different we can't use it as a Key in the map. If we want to retreat a value, we need that exact object we set as key. so when using the collections we need to overide the equals and hashcode methods properly*/

As we can see default equals method implementation provides 'reference equality'. But most of the cases we would normally override equals to implement "value equality" - where two distinct objects are deemed equal, usually by virtue of having equal field values themselves. The exact meaning of equality will depend on the design - the two objects could still be distinguishable in other ways, for example.

If you override equals, you should also override hashCode to be consistent with equals, such that if a.equals(b) is true, then a.hashCode() == b.hashCode(). This will allow instances of your class to be used as keys in hash-based collections (e.g. HashMap) so that you can look up a value, based on a key which is EQUAL to the original one(not the original one), rather than having to use a reference to the exact original key object.