gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: isEqual: and hash in NSDate


From: Adrian Robert
Subject: Re: isEqual: and hash in NSDate
Date: Fri, 22 Jul 2005 15:57:12 -0400


On Jul 22, 2005, at 2:56 PM, Richard Frith-Macdonald wrote:

On 2005-07-22 18:29:31 +0100 Adrian Robert <address@hidden> wrote:

On Jul 22, 2005, at 12:44 PM, Richard Frith-Macdonald wrote:
On 2005-07-22 15:57:03 +0100 Adrian Robert <address@hidden> wrote:
This really seems like a hack (not that it's any worse than the current state :). Couldn't the implementations of -hash and -isEqual be aligned without this loss of information? E.g. something like [warning, sloppy first-attempt code here]:
-isEqual:other
    return abs(selfVal - other->selfVal) < epsilon;
-hash
    return selfVal / epsilon;
(or maybe (selfVal + epsilon/2.0) / epsilon)
No ... each NSDate has to have its own independent hash ... but (following the OpenStep spec) dates are equal if they are within a second of each other. That means that with dates d1, d2, d3 which have offsets from the reference date of 0.0, 0.7 and 1.4 seconds, d1 is eqal to d2 and d2 is equal to d3 but d1 is not equal to d3 ... a rather counterintuitive behavior!
Right, bad.  Thisd could be fixed by changing -isEqual: to simply
return [self hash] == [other hash]

Yes, though the direct instance variable comparison is more efficient.

I don't see anything wrong conceptually with stipulating that dates within some epsilon are isEqual and retrieve the same values as keys in a hash table,

Really?  what value would you use for the hash?

In this example, epsilon is 1 second ...

So d1 and d2 must hash to the same value ... in order for the hash/isEqual test to work for them as dictionary keys (the two equal keys wouldn't be found in the same hash bucket in the dictionary otherwise).

By the same argument d2 and d3 must hash to the same value.
Similarly d3 must hash to the same value as d4 (a date greater than d3 by any value less than epsilon), and so on ... I think you can see that this leads to a single value for hash being required for all possible dates.
The same argument can be used for any non-zero value of epsilon.

I wasn't clear (probably in my own thinking either). You take the hash above of (long)((double)selfVal/epsilon) for the hash, which makes two dates equal if they fall into the same "division-by-epsilon" bucket. This of course violates the "within epsilon of each other are equal" requirement, and in fact you could have two arbitrarily close values that are still not hash-equal. But this same sort of thing happens when you use integers for times anyway and just gets swept under the rug, so I wasn't sure it mattered. Well, anyhow, I'll shut up now.. ;o|


though this might preclude some practical uses. However OS X compatibility seems the better way to go at this point. (While we're on this subject, could we change NSEvent timestamps to be in seconds like OS X (and OpenStep for that matter), instead of milliseconds?)

OS X and OPENSTEP return an NSTimeInterval just like GNUstep ... and they don't round to the second either. The documentatiuon says 'in seconds', but I think this just means that the unit of measurement is the second.

Not rounding, but ([eventB timestamp] - [eventA timestamp] on GNUstep) = 1000x (the value on OS X) for the same time difference. It occasionally affects portability such as when you need to measure the time between two events in user code.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]