Age*_*oij 11 cocoa cocoa-touch objective-c
我是Objective-C的新手,我正在寻找处理原始浮点数的最佳方法,并在Objective-C类中实现-hash方法时加倍.在这个问题中,我已经找到了关于isEqual和hash的一些好建议:
但它没有说明如何处理花车和双打.
我最好的尝试:
...
long lat = [[NSNumber numberWithDouble:self.latitude] longValue];
result = prime * result + (int) (lat ^ (lat >>> 32));
...
Run Code Online (Sandbox Code Playgroud)
但我不确定这是正确的方法.有任何想法吗 ?
Jer*_*myP 12
假设Apple的实施-hash
是充分的,有什么问题
result = [[NSNumber numberWithDouble: [self latitude]] hash];
Run Code Online (Sandbox Code Playgroud)
或者使用现代语法
result = [@([self latitude]) hash];
Run Code Online (Sandbox Code Playgroud)
@JeremyP关于使用的建议NSNumber
非常好,但我更深入地了解了这一点.由于CoreFoundation是开源的,我发现如何CFNumber
实现散列函数,这就是我发现的:
将数字拆分为积分和分数部分,对两个部分进行散列并求和.积分部分通过模和散列因子进行散列,小数部分仅通过乘法进行散列.
NSUInteger HashDouble(double value) {
double absolute = ABS(value);
double integral = round(absolute);
double fragment = absolute - integral;
NSUInteger integralHash = 2654435761U * fmod(integral, NSUIntegerMax);
NSUInteger fragmentHash = fragment * NSUIntegerMax;
return integralHash + fragmentHash;
}
Run Code Online (Sandbox Code Playgroud)
来自CoreFoundation的原始源代码评论:
/* For use by NSNumber and CFNumber.
Hashing algorithm for CFNumber:
M = Max CFHashCode (assumed to be unsigned)
For positive integral values: (N * HASHFACTOR) mod M
For negative integral values: ((-N) * HASHFACTOR) mod M
For floating point numbers that are not integral: hash(integral part) + hash(float part * M)
HASHFACTOR is 2654435761, from Knuth's multiplicative method
*/
#define HASHFACTOR 2654435761U
CF_INLINE CFHashCode _CFHashInt(long i) {
return ((i > 0) ? (CFHashCode)(i) : (CFHashCode)(-i)) * HASHFACTOR;
}
CF_INLINE CFHashCode _CFHashDouble(double d) {
double dInt;
if (d < 0) d = -d;
dInt = floor(d+0.5);
CFHashCode integralHash = HASHFACTOR * (CFHashCode)fmod(dInt, (double)ULONG_MAX);
return (CFHashCode)(integralHash + (CFHashCode)((d - dInt) * ULONG_MAX));
}
Run Code Online (Sandbox Code Playgroud)
从文件ForFoundationOnly.h上opensource.apple.com.