I have a problem with the implementations of isEqual: and hash in NSDate.
 
Let's say we have two dates:
 
NSDate *a, *b;
// This is actually a common case if you are doing floating point math to generate dates and get small rounding errors.
a = [NSDate dateWithTimeIntervalSinceReferenceDate:100000.001];
b = [NSDate dateWithTimeIntervalSinceReferenceDate:99999.998];
 
printf("a = %d, b=%d, equal=%d\n", [a hash] , [b hash], [a isEqual:b]);
 
// this code will print a = 100000, b = 99999, equal = 1
 
This breaks the NSDictionary rule that hash of two objects must equal if they are -isEqual:.
 
I propose that we change the implementations to this:
- (unsigned) hash
{
  return (unsigned)([self timeIntervalSinceReferenceDate]+0.5);
}
- (BOOL) isEqual: (id)other
{
  if (other == nil)
    return NO;
  if ([other isKindOfClass: abstractClass]
    && (int)(otherTime(self)+0.5) == (int)(otherTime(other)+0.5) )
    return YES;
  return NO;
}
After my change the program's output changes to:
a = 100000, b = 100000, equal = 1
 
I realize that the dates 100.5 and 100.49 are now not -isEqual:, but you have to draw the line somewhere, and putting it at .000 as the old code was worse.
 
Comments?  I will send a patch, so that no retyping is necessary.
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev

Reply via email to