64-bit mask NS_OPTIONS

Context

I use a macro NS_OPTIONSto create a bit mask. I assigned it a type NSInteger, and since I am building on a 64-bit platform, this should give me 63 slots for work (with 64 bits less than one bit for signing).

Here is the listing:

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
};

The upper value is 37 bits shifted to the left, which is significantly lower than the 63 bits that I should have.


Problem

I create a mask from this listing, for example:

LPSVGOPlugin defaultPluginMask = LPSVGOPluginNone;
        defaultPluginMask = (LPSVGOPluginCleanupAttrs
                               |LPSVGOPluginRemoveDoctype
                               |LPSVGOPluginRemoveXMLProcInst
                               |LPSVGOPluginRemoveComments
                               |LPSVGOPluginRemoveMetadata
                               |LPSVGOPluginRemoveDesc
                               |LPSVGOPluginRemoveUselessDefs
                               |LPSVGOPluginRemoveEditorsNSData
                               |LPSVGOPluginRemoveEmptyAttrs
                               |LPSVGOPluginRemoveHiddenElems
                               |LPSVGOPluginRemoveEmptyText
                               |LPSVGOPluginRemoveEmptyContainers
                               |LPSVGOPluginCleanupEnableBackground
                               |LPSVGOPluginMinifyStyles
                               |LPSVGOPluginConvertStyleToAttrs
                               |LPSVGOPluginConvertColors
                               |LPSVGOPluginConvertPathData
                               |LPSVGOPluginConvertTransform
                               |LPSVGOPluginRemoveUnknownsAndDefaults
                               |LPSVGOPluginRemoveNonInheritableGroupAttrs
                               |LPSVGOPluginRemoveUselessStrokeAndFill
                               |LPSVGOPluginRemoveUnusedNS
                               |LPSVGOPluginCleanupIDs
                               |LPSVGOPluginCleanupNumericValues
                               |LPSVGOPluginMoveElemsAttrsToGroup
                               |LPSVGOPluginMoveGroupAttrsToElems
                               |LPSVGOPluginCollapseGroups
                               |LPSVGOPluginMergePaths
                               |LPSVGOPluginConvertShapeToPath
                               );

When I register a value defaultPluginMaskusing this:

NSLog(@"maskValue: %li", (long)defaultPluginMask);

The result is -536879137. As soon as I remove the last mask ( LPSVGOPluginConvertShapeToPath) from the mask, I get a positive value: 1610604511

, LPSVGOPluginConvertShapeToPath 31 , 32- NSInteger. sizeof() defaultPluginMask, 8 , , 64 .

(!) . , ?

+4
1

long C , -2147483648 2147483647, 32 bits, .

64 bits, , long ​​ 64 bits. , 64 bits, long long. @Olaf, , stdint.h (, int64_t).

, , ( NSInteger long >= 8 ).

, 1 , 32 ( 32 , 5 , 64 ). 1 << 31 32- , 1 , . 64- , ( ).

, , 64 :

 -536879137  =>  ffffffffdfffdfdf   - when 1 << 31 is present
 1610604511  =>          5fffdfdf   - when 1 << 31 is removed

, , "" ( , , 1 << 32 1 << 33, - undefined - , , , 1 << 0 1 << 1).

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]);

: , , :

  • u/u unsigned ( )

  • l/l long

  • ll/ll long long

ll :

LPSVGOPluginConvertShapeToPath              = 1LL << 31,
LPSVGOPluginSortAttrs                       = 1LL << 32,
LPSVGOPluginTransformsWithOnePath           = 1LL << 33,
LPSVGOPluginRemoveDimensions                = 1LL << 34,
LPSVGOPluginRemoveAttrs                     = 1LL << 35,
LPSVGOPluginAddClassesToSVGElement          = 1LL << 36,
LPSVGOPluginRemoveStyleElement              = 1LL << 37
+5

Source: https://habr.com/ru/post/1617329/


All Articles