дадаваць і выдаляць апошні біт

Я спрабую вызначыць наступнае і папярэдняе цотная колькасць з поразрядными аперацыямі.

Так, напрыклад, для наступнай функцыі:

x    nextEven(x)
1       2
2       2
3       4
4       4

і папярэдні:

x    previousEven(x)
1       0
2       2
3       2
4       4

I had the idea for the nextEven function something like: value = ((value+1)>>1)<<1;

And for the previousEven function something like: value = ((value)>>1)<<1

ёсць лепшы падыход?, без параўнання і ўбачыць, калі значэнне цотныя ці няцотныя.

Дзякуй.

2
Лепшы падыход <�я> з'яўляецца Параўнанне значэнняў, каб убачыць, калі яны цотных або няцотных. Трукі, як гэта можа выглядаць разумным, але яны рэдка. Аптымізацыя для зручнасці чытання першай. Толькі перайсці да аптымізацыі прадукцыйнасці, калі вы вызначылі канкрэтнае вузкае месца. Я ручаюся розніцай паміж параўнаннем/наборам і многобитным-OPS не варта неад'емна марны кода.
дададзена аўтар paxdiablo, крыніца
Лепшы падыход <�я> з'яўляецца Параўнанне значэнняў, каб убачыць, калі яны цотных або няцотных. Трукі, як гэта можа выглядаць разумным, але яны рэдка. Аптымізацыя для зручнасці чытання першай. Толькі перайсці да аптымізацыі прадукцыйнасці, калі вы вызначылі канкрэтнае вузкае месца. Я ручаюся розніцай паміж параўнаннем/наборам і многобитным-OPS не варта неад'емна марны кода.
дададзена аўтар paxdiablo, крыніца

12 адказы

Робячы зрух направа з наступным зрухам налева, каб ачысціць LSB не вельмі эфектыўным.

Я хацеў бы выкарыстаць нешта накшталт:

previous: value &= ~1;
next: value = (value +1) & ~1;

<�Код> ~ 1 можа (і звычайна будзе) быць папярэдне вылічана падчас кампіляцыі, так што папярэдні будзе ў канчатковым выніку ў якасці адзіных пабітава аперацый падчас выканання. кнопку наступны , верагодна, у канчатковым выніку, як дзве аперацыі (павелічэнне, і ), але ўсё роўна павінны быць досыць хутка.

Аб лепшым выпадку вы можаце спадзявацца ад зрухаў у тым, што кампілятар зразумее, што вы проста відавочна LSB, і аптымізаваць яго аб тым, што вы чакалі б гэта вырабляць у любым выпадку.

4
дададзена
Я не думаю, што «папярэдняе значэнне: & = ~ 1;" працы. Калі «значэнне» меў зыходнае значэнне 2, выконваючы «папярэдняе значэнне: & = ~ 1;" б яна застанецца на ўзроўні 2, а не жаданае значэнне 0. Рэкамендуюць замест «папярэдняе: значэнне = (значэнне - 1) & ~ 1;"
дададзена аўтар chux, крыніца
Сяджу выпраўлены.
дададзена аўтар chux, крыніца
@chux: У адпаведнасці з табліцай у пытанні, для ўваходу 2, жаданае «папярэдняя нават» вынік 2.
дададзена аўтар Jerry Coffin, крыніца

Робячы зрух направа з наступным зрухам налева, каб ачысціць LSB не вельмі эфектыўным.

Я хацеў бы выкарыстаць нешта накшталт:

previous: value &= ~1;
next: value = (value +1) & ~1;

<�Код> ~ 1 можа (і звычайна будзе) быць папярэдне вылічана падчас кампіляцыі, так што папярэдні будзе ў канчатковым выніку ў якасці адзіных пабітава аперацый падчас выканання. кнопку наступны , верагодна, у канчатковым выніку, як дзве аперацыі (павелічэнне, і ), але ўсё роўна павінны быць досыць хутка.

Аб лепшым выпадку вы можаце спадзявацца ад зрухаў у тым, што кампілятар зразумее, што вы проста відавочна LSB, і аптымізаваць яго аб тым, што вы чакалі б гэта вырабляць у любым выпадку.

4
дададзена
Я не думаю, што «папярэдняе значэнне: & = ~ 1;" працы. Калі «значэнне» меў зыходнае значэнне 2, выконваючы «папярэдняе значэнне: & = ~ 1;" б яна застанецца на ўзроўні 2, а не жаданае значэнне 0. Рэкамендуюць замест «папярэдняе: значэнне = (значэнне - 1) & ~ 1;"
дададзена аўтар chux, крыніца
Сяджу выпраўлены.
дададзена аўтар chux, крыніца
@chux: У адпаведнасці з табліцай у пытанні, для ўваходу 2, жаданае «папярэдняя нават» вынік 2.
дададзена аўтар Jerry Coffin, крыніца

вы маглі б зрабіць нешта накшталт гэтага

за папярэдні нават

unsigned prevev(unsigned x)
{
    return x-(x%2);//bitwise counterpart x-(x&1);
}

для наступнага цотнага

unsigned nxtev(unsigned x)
{
    return (x%2)+x; //bitwise counterpart x+(x&1);
}
3
дададзена
@downvoter чаму downvote? прынамсі пакінуць каментар, калі вы downvoting
дададзена аўтар Koushik Shetty, крыніца

вы маглі б зрабіць нешта накшталт гэтага

за папярэдні нават

unsigned prevev(unsigned x)
{
    return x-(x%2);//bitwise counterpart x-(x&1);
}

для наступнага цотнага

unsigned nxtev(unsigned x)
{
    return (x%2)+x; //bitwise counterpart x+(x&1);
}
3
дададзена
@downvoter чаму downvote? прынамсі пакінуць каментар, калі вы downvoting
дададзена аўтар Koushik Shetty, крыніца

Трукі, як прылада Даф або замена двух зменных з XOR, або распрацоўка наступнага і папярэдняга цотнага ліку з поразрядными аперацый здаюцца разумны, але яны рэдка.

Самае лепшае, што вы можаце зрабіць, як распрацоўшчык, каб аптымізаваць для зручнасці чытання першых і толькі снасть прадукцыйнасці, як толькі вы вызначылі спецыфічны вузкае месца, якое выклікае рэальныя праблемы.

Лепшы код для атрымання папярэдняга цотнай колькасцi (па вашым вызначэнні, дзе папярэдняе цотная колькасць 2 у 2) проста пісаць нешта накшталт:

if ((num % 2) == 1) num--;//num++ for next.

ці (крыху больш прасунуты):

num -= num % 2;           //+= for next.

і дазваляючы вар'яцкія аптымізуюць кампілятары высветліць лепшы зыходны код.

Калі Вы не павінны рабіць гэтыя аперацыі ў мільярды разоў у секунду, чытальнасць заўсёды павінна быць вашай асноўнай задачай.

1
дададзена
@harold, вы выявіце, што цяжка ўбачыць, што адымаючы адно з няцотнай колькасцi дае наступнае нізкае цотная колькасць? І ўсё ж у вас няма праблем з зменным-направа/налева зрух налева? Можа быць, вы працавалі на занадта нізкім узроўні занадта доўга :-)
дададзена аўтар paxdiablo, крыніца
Я згодны з вашай філасофіяй распрацоўніка, але пытацца не спытаў, як гэта зрабіць з пабітава аперацыямі. Так пабітавае рашэнне лепш адказвае на запыт. (Хаця я думаю, што гэта будзе <�я> вельмі </я> стымулюючым, каб стварыць пабітавае адзінае рашэнне.)
дададзена аўтар chux, крыніца
Я лічу, гэта цяжэй зразумець, чым код OPS.
дададзена аўтар harold, крыніца
О не, гэтая частка была проста - але гэта заняло другое месца, перш чым я зразумеў, што гэта тое, што ён робіць. Зрухі былі адразу відавочныя для мяне - падзення МДРА. Але так, я рабіў зборку на працягу апошніх 8 гадоў, і я за захаванне зараз :)
дададзена аўтар harold, крыніца

Трукі, як прылада Даф або замена двух зменных з XOR, або распрацоўка наступнага і папярэдняга цотнага ліку з поразрядными аперацый здаюцца разумны, але яны рэдка.

Самае лепшае, што вы можаце зрабіць, як распрацоўшчык, каб аптымізаваць для зручнасці чытання першых і толькі снасть прадукцыйнасці, як толькі вы вызначылі спецыфічны вузкае месца, якое выклікае рэальныя праблемы.

Лепшы код для атрымання папярэдняга цотнай колькасцi (па вашым вызначэнні, дзе папярэдняе цотная колькасць 2 у 2) проста пісаць нешта накшталт:

if ((num % 2) == 1) num--;//num++ for next.

ці (крыху больш прасунуты):

num -= num % 2;           //+= for next.

і дазваляючы вар'яцкія аптымізуюць кампілятары высветліць лепшы зыходны код.

Калі Вы не павінны рабіць гэтыя аперацыі ў мільярды разоў у секунду, чытальнасць заўсёды павінна быць вашай асноўнай задачай.

1
дададзена
@harold, вы выявіце, што цяжка ўбачыць, што адымаючы адно з няцотнай колькасцi дае наступнае нізкае цотная колькасць? І ўсё ж у вас няма праблем з зменным-направа/налева зрух налева? Можа быць, вы працавалі на занадта нізкім узроўні занадта доўга :-)
дададзена аўтар paxdiablo, крыніца
Я згодны з вашай філасофіяй распрацоўніка, але пытацца не спытаў, як гэта зрабіць з пабітава аперацыямі. Так пабітавае рашэнне лепш адказвае на запыт. (Хаця я думаю, што гэта будзе <�я> вельмі </я> стымулюючым, каб стварыць пабітавае адзінае рашэнне.)
дададзена аўтар chux, крыніца
О не, гэтая частка была проста - але гэта заняло другое месца, перш чым я зразумеў, што гэта тое, што ён робіць. Зрухі былі адразу відавочныя для мяне - падзення МДРА. Але так, я рабіў зборку на працягу апошніх 8 гадоў, і я за захаванне зараз :)
дададзена аўтар harold, крыніца
Я лічу, гэта цяжэй зразумець, чым код OPS.
дададзена аўтар harold, крыніца

Say you're using unsigned ints, previous even (matching your values - we could argue about whether previous even of 2 should be 0 etc) is simply x & ~1u. Next even is previous even of x + 1.

1
дададзена

Say you're using unsigned ints, previous even (matching your values - we could argue about whether previous even of 2 should be 0 etc) is simply x & ~1u. Next even is previous even of x + 1.

1
дададзена

Previous even number:
For previous even number I prefer Jerry Coffin's answer

// Get previous even number
unsigned prevEven(unsigned no)
{
    return (no & ~1);
}

Next even number:
I try to use only bitwise operator's but still i use one unary minus(-) operator to get next number.

// Get next even number
unsigned nextEven(unsigned no)
{
    return (no & 1) ? (-(~no)) : no ;
}

<�Моцны> Праца Метаду nextEven ():

  • If number is even return the same number,
    if no is even it's LSB is 0 otherwise 1
    Get LSB of number => number & 1
  • If number is odd return the number + 1,
    Add 1 to number => -(~number)
1
дададзена

Previous even number:
For previous even number I prefer Jerry Coffin's answer

// Get previous even number
unsigned prevEven(unsigned no)
{
    return (no & ~1);
}

Next even number:
I try to use only bitwise operator's but still i use one unary minus(-) operator to get next number.

// Get next even number
unsigned nextEven(unsigned no)
{
    return (no & 1) ? (-(~no)) : no ;
}

<�Моцны> Праца Метаду nextEven ():

  • If number is even return the same number,
    if no is even it's LSB is 0 otherwise 1
    Get LSB of number => number & 1
  • If number is odd return the number + 1,
    Add 1 to number => -(~number)
1
дададзена
unsigned int previous(unsigned int x)
{
    return x & 0xfffffffe;
}

unsigned int next(unsigned int x)
{
   return previous(x + 2);
}
0
дададзена
вы мяркуючы непадпісаным Int 32 біт. замест таго, каб выкарыстоўваць ~ 1 для гэтага магічнага ліку you'l быць бяспечнымі :)
дададзена аўтар Koushik Shetty, крыніца
unsigned int previous(unsigned int x)
{
    return x & 0xfffffffe;
}

unsigned int next(unsigned int x)
{
   return previous(x + 2);
}
0
дададзена
вы мяркуючы непадпісаным Int 32 біт. замест таго, каб выкарыстоўваць ~ 1 для гэтага магічнага ліку you'l быць бяспечнымі :)
дададзена аўтар Koushik Shetty, крыніца