0

I've taken over a project and it uses an enum to flag API calls.

It can filter them by OR'ing the enum values so a previous developer did some bitshifting.

typedef enum {
APICallTimeSeriesSearchTimeSeries   = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo  = (1LL << 2),
APICallTimeSeriesGetSeriesInfo      = (1LL << 3),
....
APICallFavouritesAddNewsFavourite               = (1LL << 79),
APICallFavouritesRemoveNewsFavourite            = (1LL << 80),
APICallFavouritesGetAllFavourites               = (1LL << 81)
} APICallType;

Then we can do things like

filter(APICallTimeSeriesGetTimeSeriesInfo | APICallTimeSeriesGetSeriesInfo | APICallTimeSeriesGetSeriesData);

But recently I notice similar enums mapped to the same value. I dumped the whole enum list like so

NSLog(@"%d",APICallTimeSeriesSearchTimeSeries);
NSLog(@"%d",APICallTimeSeriesGetTimeSeriesInfo);
NSLog(@"%d",APICallTimeSeriesGetSeriesInfo);
NSLog(@"%d",APICallTimeSeriesGetSeriesData);
NSLog(@"%d",APICallFleetSearchVessels);
NSLog(@"%d",APICallFleetGetVesselInfo);
etc.

And we can see the bitshifting in action

2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
2147483648
4294967296
8589934592
17179869184
34359738368
68719476736

The problem is after (1LL << 63) the same values are generated

1152921504606846976 APICallFavouritesAddMarketFavourite = (1LL << 60)
2305843009213693952 APICallFavouritesRemoveMarketFavourite  = (1LL << 61)
4611686018427387904 APICallFavouritesGetFutureFavourites    = (1LL << 62)
-9223372036854775808    APICallFavouritesAddFutureFavourite = (1LL << 63)
-9223372036854775808    APICallFavouritesRemoveFutureFavourite  = (1LL << 64)
-9223372036854775808    APICallFavouritesRemoveVesselFavourite  = (1LL << 65)

etc same value(-9223372036854775808) repeats for all new enums

From this thread Types in objective-c on iPhone

its because -9223372036854775808 is LLONG_MIN

NSLog(@"LLONG_MIN:  %lli", LLONG_MIN);   // signed long long int

I noticed theres a higher value

NSLog(@"LLONG_MAX:  %lli", LLONG_MAX);
NSLog(@"ULLONG_MAX: %llu", ULLONG_MAX);  // unsigned long long int

LLONG_MIN:  -9223372036854775808         
LLONG_MAX:  9223372036854775807          
ULLONG_MAX: 18446744073709551615 

but cant find ULLONG_MIN

How do we fix this?

I tried changing the primitive storage from 1LL to 1ULL but no effect.

FROM:

typedef enum {
APICallTimeSeriesSearchTimeSeries   = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo  = (1LL << 2),
APICallTimeSeriesGetSeriesInfo      = (1LL << 3),
...

TO:

typedef enum {
APICallTimeSeriesSearchTimeSeries               = (1ULL << 1),
APICallTimeSeriesGetTimeSeriesInfo              = (1ULL << 2),
APICallTimeSeriesGetSeriesInfo                  = (1ULL << 3),
...

cheers

4

2 回答 2

1

ULLONG_MIN 为0。ULLONG 表示unsigned long long,即64 位表示的正值。

如果您想要正数和负数,则只能表示可以用相同位宽的无符号类型表示的该组值的一半。这就是 ULLONG_MAX 更大的原因。

于 2012-11-20T22:31:42.493 回答
0

我选择将 APICallType 拆分为另一个枚举。就是这样,或者重新连接一个 3 年的项目,并且必须测试每个 API 调用。

APICallTimeSeriesSearchTimeSeries   = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo  = (1LL << 2),
APICallTimeSeriesGetSeriesInfo      = (1LL << 3),
....
APICallFavouritesAddNewsFavourite               = (1LL << 79),
APICallFavouritesRemoveNewsFavourite            = (1LL << 80),
APICallFavouritesGetAllFavourites               = (1LL << 81)
} APICallType;

变成

typedef enum {
APICallTimeSeriesSearchTimeSeries   = (1LL << 1),
APICallTimeSeriesGetTimeSeriesInfo  = (1LL << 2),
APICallTimeSeriesGetSeriesInfo      = (1LL << 3),
APICallTimeSeriesGetSeriesData      = (1LL << 4),
APICallFleetSearchVessels           = (1LL << 5),
APICallFleetGetVesselInfo           = (1LL << 6),
APICallNewsGetNewsItems             = (1LL << 7),
APICallNewsGetPublicationItems      = (1LL << 8),
APICallPodcastGetPodcastItems       = (1LL << 9),
APICallUserLoginAuthenticateUser    = (1LL << 10),
APICallFFASearchFFARoutes           = (1LL << 11),
APICallFFAGetRouteData              = (1LL << 12),
APICallOwnerSearchOwners            = (1LL << 13),
APICallOwnerGetOwnerFleet           = (1LL << 14),
APICallIndicesSearchIndices         = (1LL << 15),
APICallIndicesGetIndicesData        = (1LL << 16),
APICallEquitiesGetEquitiesData      = (1LL << 17),
APICallEquitiesGetEquityPreviews    = (1LL << 18),
APICallEquitiesSearchBrokingStocks  = (1LL << 19),
APICallEquitiesSearchIndices        = (1LL << 20),
APICallEquitiesSearchCurrencies     = (1LL << 21),
APICallEquitiesGetRelatedNewsItems  = (1LL << 22),
APICallEquitiesGetCurrencyList      = (1LL << 23),
APICallSandPVesselsSearch           = (1LL << 24),
APICallSandPVesselSalesSearch       = (1LL << 25),
APICallSandPGetCommercialData       = (1LL << 26),
APICallSandPGetSimilarSales         = (1LL << 27),
APICallSandPGetFullVesselDetails    = (1LL << 28),
APICallSandPEnquiriesSearch         = (1LL << 29),
APICallTimeSeriesGetCategories                  = (1LL << 30),
APICallTimeSeriesGetShipTypes                   = (1LL << 31),
APICallTimeSeriesGetDataTypes                   = (1LL << 32),
APICallTimeSeriesSearchTimeSeriesWithCategories = (1LL << 33),
APICallHomeGetComments                          = (1LL << 34),
APICallEquitiesGetRelatedNewsItemsWithIds       = (1LL << 35),
APICallEquitiesSearchEquitiesBrokingStocks      = (1LL << 36),
APICallTimeSeriesGetFutureShipTypes             = (1LL << 37),
APICallTimeSeriesGetFutureDataTypes             = (1LL << 38),
APICallTimeSeriesGetOHLCData                    = (1LL << 39),
APICallTimeSeriesGetSeriesDataMaxPoints         = (1LL << 40),
APICallTimeSeriesGetSeriesOHLCDataMaxPoints     = (1LL << 41),
APICallClientSearchClients                      = (1LL << 42),
APICallClientGetClientListForBroker             = (1LL << 43),
APICallClientSearchDivisionsAndDesks            = (1LL << 44),
APICallClientGetDivisionsAndDesks               = (1LL << 45),
APICallClientSaveEmployeeDetails                = (1LL << 46),
APICallTimeSeriesSearchWithSeriesId             = (1LL << 47),
APICallHomeGetCommentsCargo                     = (1LL << 48),
APICallHomeGetCommentsSandP                     = (1LL << 49),
APICallHomeGetCommentsTanker                    = (1LL << 50),
APICallClientGetSandPRoutes                     = (1LL << 51),
APICallClientGetSandP2ndHandValues              = (1LL << 52),
APICallHomeGetCommentsSpecialised               = (1LL << 53),
APICallClientGetSpecialised                     = (1LL << 54),
APICallClientGetGas                             = (1LL << 55),
APICallClientGetGasBunkerPrices                 = (1LL << 56),
APICallFFAGetAllWhiteboardSpreadTypes           = (1LL << 57),
APICallFFAGetWhiteboardSpreadPricesForType      = (1LL << 58),
APICallFavourites                               = (1LL << 59)
/*
APICallFavouritesGetMarketFavourites            = (1LL << 59),
APICallFavouritesAddMarketFavourite             = (1LL << 60),
APICallFavouritesRemoveMarketFavourite          = (1LL << 61),
APICallFavouritesGetFutureFavourites            = (1LL << 62),

//Enum bit shifted greater than 63 will have same value as MAX INT reached
//moved these to 
APICallFavouritesAddFutureFavourite             = (1LL << 63),
APICallFavouritesRemoveFutureFavourite          = (1LL << 64),
APICallFavouritesGetVesselOwnerFavourites       = (1LL << 65),
APICallFavouritesGetVesselFavourites            = (1LL << 66),
APICallFavouritesAddVesselFavourite             = (1LL << 67),
APICallFavouritesRemoveVesselFavourite          = (1LL << 68),
APICallFavouritesGetOwnerFavourites             = (1LL << 69),
APICallFavouritesAddOwnerFavourite              = (1LL << 70),
APICallFavouritesRemoveOwnerFavourite           = (1LL << 71),
APICallFavouritesGetShippingStockFavourites     = (1LL << 72),
APICallFavouritesAddShippingStockFavourite      = (1LL << 73),
APICallFavouritesRemoveShippingStockFavourite   = (1LL << 74),
APICallFavouritesGetIndicieFavourites           = (1LL << 75),
APICallFavouritesAddIndicieFavourite            = (1LL << 76),
APICallFavouritesRemoveIndicieFavourite         = (1LL << 77),
APICallFavouritesGetNewsFavourites              = (1LL << 78),
APICallFavouritesAddNewsFavourite               = (1LL << 79),
APICallFavouritesRemoveNewsFavourite            = (1LL << 80),
APICallFavouritesGetAllFavourites               = (1LL << 81)
*/

} APICallType;

并添加 APICallSubType

typedef enum {

/* for use with APICallType:APICallFavourites */
APICallFavouritesGetMarketFavourites            = (1LL << 1),
APICallFavouritesAddMarketFavourite             = (1LL << 2),
APICallFavouritesRemoveMarketFavourite          = (1LL << 3),

APICallFavouritesGetFutureFavourites            = (1LL << 4),
APICallFavouritesAddFutureFavourite             = (1LL << 5),
APICallFavouritesRemoveFutureFavourite          = (1LL << 6),

APICallFavouritesGetVesselOwnerFavourites       = (1LL << 7),
APICallFavouritesGetVesselFavourites            = (1LL << 8),
APICallFavouritesAddVesselFavourite             = (1LL << 9),
APICallFavouritesRemoveVesselFavourite          = (1LL << 10),

APICallFavouritesGetOwnerFavourites             = (1LL << 11),
APICallFavouritesAddOwnerFavourite              = (1LL << 12),
APICallFavouritesRemoveOwnerFavourite           = (1LL << 13),

APICallFavouritesGetShippingStockFavourites     = (1LL << 14),
APICallFavouritesAddShippingStockFavourite      = (1LL << 15),
APICallFavouritesRemoveShippingStockFavourite   = (1LL << 16),

APICallFavouritesGetIndicieFavourites           = (1LL << 17),
APICallFavouritesAddIndicieFavourite            = (1LL << 18),
APICallFavouritesRemoveIndicieFavourite         = (1LL << 19),

APICallFavouritesGetNewsFavourites              = (1LL << 20),
APICallFavouritesAddNewsFavourite               = (1LL << 21),
APICallFavouritesRemoveNewsFavourite            = (1LL << 22),
APICallFavouritesGetAllFavourites               = (1LL << 23)
//do not go over (1LL << 63) - enum values start at MAX INT after that

} APICallSubType;

并且我在任何地方检查了我必须在之后检查子类型的类型

filter(APICallFavourites);
filterSubType(APICallFavouritesAddVesselFavourite |
              APICallFavouritesRemoveVesselFavourite);

if (responseOfSubType(APICallFavouritesAddVesselFavourite))
{
    NSLog(@"%s APICallFavouritesAddVesselFavourite response not handled", __PRETTY_FUNCTION__);
}

if (responseOfSubType(APICallFavouritesRemoveVesselFavourite))
{
    NSLog(@"%s APICallFavouritesRemoveVesselFavourite response not handled", __PRETTY_FUNCTION__);
}
于 2012-11-21T09:52:06.303 回答