正确处理 32/64 位

Posted

技术标签:

【中文标题】正确处理 32/64 位【英文标题】:Handle 32/64bit correctly 【发布时间】:2014-02-24 23:48:54 【问题描述】:

我创建了两个应用程序,分别称为服务器和客户端。这两个应用程序的 xcode 项目都使用公共子项目。这些应用程序专为特定客户设计,可在 ios7/iPad 上运行

为了进行测试,我正在编译服务器应用程序并在 iPad 3 上运行它。客户端应用程序在 Air 上运行。当我为 iPad3 编译时,Xcode 会抛出一堆警告,因为 NSInteger/NSUInteger 类型是 32 位的,而我正在使用的逻辑(在本例中为格式为 %lu 的 NSString)正在抱怨(因为它是为 64 位编写的)

但更麻烦的是,我使用 NSKeyArchiving 将数据从一台 iPad 打包发送到另一台 iPad - 如果存储在这些类型中的数据超过 32 位,我猜我会遇到问题。

看起来我需要标准化另一种基本类型,例如 UInt32 而不是 NSUInteger - 这是正确的方法吗?还有其他提示吗?

编辑: 这是一个例子:

+ (NSUInteger)nextTransactionNumber

    static int64_t currentTransactionNumber = 0;
    OSAtomicIncrement64(&currentTransactionNumber);
    return currentTransactionNumber;

这对于 64 位编译得很好,但在返回 32 位时会感到悲哀。那我用 Uint32 更好吗?

【问题讨论】:

您应该能够通过将 (long) 放在整数前面来解决这个问题——免费桥接在大多数情况下会消除 32 位问题。 如果有任何数据在机器之间发送,即使是不必要的,最好标准化大小(uint32_t、uint64_t)和字节顺序(使用 ntohl、ntohs 等)。 【参考方案1】:

NSNumber 是一个不错的选择。

您可以对其进行序列化、反序列化、打印,而不会出现 32/64 位问题(除非您计划处理超过 40 亿的数字)。

NSNumber *number = @1000U;

打印出来:

NSString *string = [NSString stringWithFormat:@"%@", number];

计算:

NSUInteger value = [number unsignedIntegerValue];

存档:

- (void)encodeWithCoder:(NSCoder *)encoder 
    // …
    [encoder encodeObject:self.number forKey:@"number"];


- (id)initWithCoder:(NSCoder *)decoder 
    self = [super init];
    if (self) 
        // …
        _number = [decoder decodeObjectForKey:@"number"];
    
    return self;

【讨论】:

感谢@Jeffery,我确实在我的应用程序的其他地方使用了它,但不是专门使用它 - 更喜欢使用 encodeInt64。您是否建议在整个过程中使用 NSNumber 抽象是一种更好的模式? @300baud 那么NSNumber、NSInteger、CGFloat等都支持64位和32位。我只是使用它们来防止任何性能影响。一个很好的问题是:***.com/questions/4445173/… @300baud NSNumber 为您完成所有关于存储和持久化的工作。如果您需要一个对象来保存一个数字,这是一个很好的选择。 @nlee918 premature optimization is the root of all evil —Knuth

以上是关于正确处理 32/64 位的主要内容,如果未能解决你的问题,请参考以下文章

CF662CBinary Table 按位处理

数字千分位处理,number.js

[TJOI2017]异或和

一个非常简陋的基于LFSR和Feistel网络的加解密运算,有位处理。C

正确处理 32/64 位

32位和64位的区别