2012-11-20 122 views
0

我接手一个项目,它使用一个枚举标志的API调用。的Objective-C的typedef枚举 - 两个枚举映射到相同的价值观

它可以通过对枚举值进行OR运算来过滤它们,所以以前的开发者做了一些移位操作。

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

然后我们可以做的事情一样

filter(APICallTimeSeriesGetTimeSeriesInfo | APICallTimeSeriesGetSeriesInfo | APICallTimeSeriesGetSeriesData); 

但最近我发现映射到相同的值类似枚举。 我甩了整个枚举列表,像这样

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

,我们可以看到在行动bitshifting

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 

之后(1LL < < 63)所产生的问题,相同的价值观

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等值(-9223372036854775808)重复所有新枚举

从这个线程 Types in objective-c on iPhone

其因为-9223372036854775808是LLONG_MIN

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

我那里有注意到一个较高的值

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 

但无法找到ULLONG_MIN

我们如何解决这个问题?

我试图将原始存储从1LL更改为1ULL,但没有效果。

FROM:

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

TO:

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

欢呼声

+1

类型除非你的编译器支持原生128位整数,你可以未定义大于“UINT64_MAX == 2 ** 64 - 1”的枚举。 –

+0

因为您已将位移到了已签名的long变量末尾以外,所以您获得了LLONG_MIN,这意味着它全部为零。将它更改为无符号不会产生任何影响(它只会将它们更改为0而不是LLONG_MIN,它不会购买任何内容)。要么你不得不放弃组合它们的能力,要么将它们分离成代表不同事物的多个不同的枚举。 – Kitsune

+0

是的,我选择了第二条路径。见下文 。干杯 –

回答

1

ULLONG_MIN是0 ULLONG装置无符号长长,即正由64位表示的值。

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

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