Objective c 64位NS\U选项位掩码 上下文
我正在使用Objective c 64位NS\U选项位掩码 上下文,objective-c,c,cocoa,enums,bitmask,Objective C,C,Cocoa,Enums,Bitmask,我正在使用NS\u OPTIONS宏创建位掩码。我给它分配了一种类型的NSInteger,因为我是在64位平台上构建的,所以总共有63个“插槽”可供使用(64位减去一位表示符号) 以下是枚举: typedef NS_OPTIONS(NSInteger, LPSVGOPlugin) { LPSVGOPluginNone = 0, LPSVGOPluginCleanupAttrs = 1 &l
NS\u OPTIONS
宏创建位掩码。我给它分配了一种类型的NSInteger
,因为我是在64位平台上构建的,所以总共有63个“插槽”可供使用(64位减去一位表示符号)
以下是枚举:
typedef NS_OPTIONS(NSInteger, LPSVGOPlugin) {
LPSVGOPluginNone = 0,
LPSVGOPluginCleanupAttrs = 1 << 0,
LPSVGOPluginRemoveDoctype = 1 << 1,
LPSVGOPluginRemoveXMLProcInst = 1 << 2,
LPSVGOPluginRemoveComments = 1 << 3,
LPSVGOPluginRemoveMetadata = 1 << 4,
LPSVGOPluginRemoveTitle = 1 << 5,
LPSVGOPluginRemoveDesc = 1 << 6,
LPSVGOPluginRemoveUselessDefs = 1 << 7,
LPSVGOPluginRemoveEditorsNSData = 1 << 8,
LPSVGOPluginRemoveEmptyAttrs = 1 << 9,
LPSVGOPluginRemoveHiddenElems = 1 << 10,
LPSVGOPluginRemoveEmptyText = 1 << 11,
LPSVGOPluginRemoveEmptyContainers = 1 << 12,
LPSVGOPluginRemoveViewBox = 1 << 13,
LPSVGOPluginCleanupEnableBackground = 1 << 14,
LPSVGOPluginMinifyStyles = 1 << 15,
LPSVGOPluginConvertStyleToAttrs = 1 << 16,
LPSVGOPluginConvertColors = 1 << 17,
LPSVGOPluginConvertPathData = 1 << 18,
LPSVGOPluginConvertTransform = 1 << 19,
LPSVGOPluginRemoveUnknownsAndDefaults = 1 << 20,
LPSVGOPluginRemoveNonInheritableGroupAttrs = 1 << 21,
LPSVGOPluginRemoveUselessStrokeAndFill = 1 << 22,
LPSVGOPluginRemoveUnusedNS = 1 << 23,
LPSVGOPluginCleanupIDs = 1 << 24,
LPSVGOPluginCleanupNumericValues = 1 << 25,
LPSVGOPluginMoveElemsAttrsToGroup = 1 << 26,
LPSVGOPluginMoveGroupAttrsToElems = 1 << 27,
LPSVGOPluginCollapseGroups = 1 << 28,
LPSVGOPluginRemoveRasterImages = 1 << 29,
LPSVGOPluginMergePaths = 1 << 30,
LPSVGOPluginConvertShapeToPath = 1 << 31,
LPSVGOPluginSortAttrs = 1 << 32,
LPSVGOPluginTransformsWithOnePath = 1 << 33,
LPSVGOPluginRemoveDimensions = 1 << 34,
LPSVGOPluginRemoveAttrs = 1 << 35,
LPSVGOPluginAddClassesToSVGElement = 1 << 36,
LPSVGOPluginRemoveStyleElement = 1 << 37
};
当我使用以下方法记录defaultPluginMask
的值时:
NSLog(@"maskValue: %li", (long)defaultPluginMask);
结果是-536879137。一旦我从掩码中删除最后添加的掩码(LPSVGOPluginConvertShapeToPath
),我就会得到一个正值:1610604511
关键的是,LPSVGOPluginConvertShapeToPath
左移了31位,这将是32位NSInteger中的最大位位置。但是如果我使用sizeof()
记录defaultPluginMask
的大小,它会将其报告为8个字节,这意味着它应该是64位
我有点(哈!)糊涂了。我犯了一个我看不到的基本错误吗 对于
long
数据类型,C标准规定最小范围要求为-2147483648
到2147483647
,即使用32位
,包括符号位
即使为64位
平台编译,也不能保证long
变量将在64位
上表示。为确保其具有最小的64位
,应使用long
。按照@Olaf的建议,为了精确指定存储大小,可以使用stdint.h
类型(例如int64\u t
)
但上述观察结果似乎不是您案例中问题的根源(如果NSInteger
和long
大小>=8字节)
问题是要移位的值
1
是一个整数文本,适合32位,并将按此方式存储(如果它不适合32位,例如50亿,则将存储在64位)。而1当使用32位或更多位进行移位时,请使用执行该操作的所有工具!非常感谢。如果你把它写下来作为一个正式的答案,并添加一点关于为什么需要ULL的背景知识(我查了一下,但是将来看这个帖子的人会从一个快速的解释中受益),我将把它标记为答案。使用stdint.h
类型和宏。还可以使用inttypes.h
printf
转换说明符<代码>%li
采用长的
,但不能保证长度超过32位。
NSLog(@"maskValue: %li", (long)defaultPluginMask);
-536879137 => ffffffffdfffdfdf - when 1 << 31 is present
1610604511 => 5fffdfdf - when 1 << 31 is removed
printf("%d %d %d %d\n", sizeof(int), sizeof(long), sizeof(long long), sizeof(void*));
// Prints: 4 4 8 8, running on an Windows 64-bit, compiled with gcc from MinGW
long long a[9] = {
1 << 30, // 1073741824 40000000
1LL << 30, // 1073741824 40000000
1 << 31, // -2147483648 ffffffff80000000
1LL << 31, // 2147483648 80000000
1 << 32, // 0 0
1LL << 32, // 4294967296 100000000
1 << 33, // 0 0
1LL << 33, // 8589934592 200000000
5000000000,// 5000000000 12a05f200
};
// Prints of this loop are in the comments above
for (int i = 0; i < 9; i++)
printf("%12lli %16llx\n", a[i], a[i]);
LPSVGOPluginConvertShapeToPath = 1LL << 31,
LPSVGOPluginSortAttrs = 1LL << 32,
LPSVGOPluginTransformsWithOnePath = 1LL << 33,
LPSVGOPluginRemoveDimensions = 1LL << 34,
LPSVGOPluginRemoveAttrs = 1LL << 35,
LPSVGOPluginAddClassesToSVGElement = 1LL << 36,
LPSVGOPluginRemoveStyleElement = 1LL << 37