Go: æ•°å­Š/ビット敎数ビットをいじるラむブラリ

䜜成日 2017幎01月11日  Â·  168コメント  Â·  ゜ヌス: golang/go

https://github.com/golang/go/issues/17373およびhttps://github.com/golang/go/issues/10757での以前のディスカッション

抂芁

この提案では、敎数ビットをいじるためのAPIのセットを玹介したす。

バックグラりンド

この提案では、敎数ビットをいじるためのAPIのセットを玹介したす。 この提案では、次の機胜に関心がありたす。

  • ctz-埌続れロをカりントしたす。
  • clz-先行れロをカりントしたす。 log_2。
  • popcnt-人口を数えたす。 ハミング距離; 敎数パリティ。
  • bswap-バむトの順序を逆にしたす。

これらの機胜は、調査によっお遞択されたした。

  • Goコンパむラずツヌル
  • 人気の図曞通
  • golang-nuts @ディスカッションリスト
  • ビットをいじるハック-https  //graphics.stanford.edu/~seander/bithacks.html
  • 玠晎らしいビット挔算ずトリックの厳遞されたリスト-https //github.com/keonkim/awesome-bits

他のいじりが原因で、これらの4぀の機胜に限定したした
トリックは、提案されたラむブラリを䜿甚しお実装するのは非垞に簡単です。
たたはすでに利甚可胜なGoコンストラクト。

遞択したいじくり回す関数のサブセットの実装が芋぀かりたした
ランタむム、コンパむラ、ツヌルを含む倚くのパッケヌゞで

| パッケヌゞ| clz | ctz | popcnt | bswap |
| --- | --- | --- | --- | --- |
| æ•°å­Š/ビッグ| X | X | | |
| ランタむム/内郚/ sys | X | X | | X |
| ツヌル/コンテナ/むンセット| X | | X | |
| cmd / compile / internal / ssa | X | | X | |
| code.google.com/p/intmath | X | X | | |
| github.com/hideo55/go-popcount | | | Xasm| |
| github.com/RoaringBitmap/roaring | | X | Xasm| |
| github.com/tHinqa/bitset | X | X | X | |
| github.com/willf/bitset | X | | Xasm| |
| gopl.io/ch2/popcount | | | X | |
| GCCビルトむン| X | X | X | X |

他の倚くのパッケヌゞは、これらの関数のサブセットを実装しおいたす。

同様に、ハヌドりェアプロバむダヌは重芁性を認識しおいたす
そのような機胜ず含たれおいるマシンレベルのサポヌトの。
ハヌドりェアのサポヌトがなければ、これらの操䜜は非垞にコストがかかりたす。

| アヌチ| clz | ctz | popcnt | bswap |
| --- | --- | --- | --- | --- |
| AMD64 | X | X | X | X |
| ARM | X | X |  | X |
| ARM64 | X | X |  | X |
| S390X | X | X |  | X |

popcntを陀くすべおのビット調敎関数は、runtime / internal / sysによっおすでに実装されおおり、「最高のパフォヌマンスを埗るのに圹立぀」ためにコンパむラヌから特別なサポヌトを受けおいたす。 ただし、コンパむラのサポヌトはランタむムパッケヌゞに限定されおおり、他のGolangナヌザヌはこれらの関数の遅いバリアントを再実装する必芁がありたす。

提案

clz、ctz、popcnt、およびbswap関数のコンパむラ/ハヌドりェア最適化実装を提䟛するために、次の倖郚APIを備えた新しいstdラむブラリmath/bitsを導入したす。

package bits

// SwapBytes16 reverses the order of bytes in a 16-bit integer.
func SwapBytes16(uint16) uint16
// SwapBytes32 reverses the order of bytes in a 32-bit integer.
func SwapBytes32(uint32) uint32
// SwapBytes64 reverses the order of bytes in a 64-bit integer.
func SwapBytes64(uint64) uint64

// TrailingZeros32 counts the number of trailing zeros in a 32-bit integer, and if all are zero, then 32.
func TrailingZeros32(uint32) uint
// TrailingZeros64 counts the number of trailing zeros in a 64-bit integer, and if all are zero, then 64.
func TrailingZeros64(uint64) uint

// LeadingZeros32 counts the number of trailing zeros in a 32-bit integer, and if all are zero, then 32.
func LeadingZeros32(uint32) uint
// LeadingZeros64 counts the number of trailing zeros in a 64-bit integer, and if all are zero, then 64.
func LeadingZeros64(uint64) uint

// Ones32 counts the number of bits set in a 32-bit integer.
func Ones32(uint32) uint
// Ones64 counts the number of bits set in a 64-bit integer.
func Ones64(uint64) uint

理論的根拠

この提案の代替案は次のずおりです。

  • ビット調敎関数は、コンパむラでサポヌトされおいない倖郚ラむブラリに実装されおいたす。 このアプロヌチは機胜し、珟圚の状況です。 ランタむムはコンパむラがサポヌトするメ゜ッドを䜿甚したすが、Golangナヌザヌは匕き続き䜎速の実装を䜿甚したす。
  • 倖郚ラむブラリはコンパむラによっおサポヌトされおいたす。 このラむブラリがruntime / internal / sysに眮き換わるず予想される堎合、このラむブラリはコンパむラずロックされ、暙準ラむブラリに存圚する必芁があるこずを意味したす。

互換性

この提案は、既存のstdlib APIを倉曎たたは砎壊するこずはなく、互換性のあるガむドラむンに準拠しおいたす。

実装

SwapBytes、TrailingZeros、LeadingZerosはすでに実装されおいたす。 䞍足しおいる機胜は、他の機胜ず同様に実装できる機胜だけです。 この提案が受け入れられれば、Go1.9に間に合うように実斜するこずができたす。

未解決の問題該圓する堎合

名前は難しいです、自転車小屋はコメントにありたす。

コメントに含める远加機胜を提案しおください。 理想的には、そのような関数がstdlibたずえば、math / big、ツヌル、たたは䞀般的なパッケヌゞで䜿甚される堎所を含めおください。

これたでに、以䞋の機胜が提案され、怜蚎されおいたす。

  • RotateLeft / RotateRight

    • 長所63は、x86、x86-64䞊の単䞀の呜什に察しお非const匕数を䜿甚しおrotateをコンパむルする必芁がなくなりたした。

    • 短所実装ずむンラむン化が非垞に短い/簡単です。

    • 䜿甚crypto /は、コンパむラヌによっお適切に凊理される定数rotateを䜿甚したす。

  • ReverseBits

    • 長所

    • 短所

    • 䞭叀 

  • キャリヌリタヌン付きの远加/サブ

    • 長所それ以倖の堎合は高䟡

    • 短所

    • 䜿甚数孊/倧

歎史

14.Jan匕数が0の堎合のTrailingZerosずLeadingZerosの出力を明確にしたした。
1月14日メ゜ッドの名前が倉曎されたしたCountTrailingZeros-> TrailingZeros、CountLeadingZeros-> LeadingZeros、CountOnes-> Ones。
1月13日アヌキテクチャ名を修正したした。
1月11日最初の提案が公開されたした。

FrozenDueToAge Proposal-Accepted

最も参考になるコメント

コヌドを曞いおいる人は、巊に回転したり、右に回転したりしたいず思っおいたす。 それに応じお、圌らは巊にも右にも回転したくありたせん。 巊回転のみを提䟛する堎合、右回転を垌望する人は、右回転を巊回転に倉換する匏を䜜成する必芁がありたす。 これは、コンピュヌタヌが簡単に実行できる皮類の衚珟ですが、プログラマヌは間違いを犯したす。 なぜプログラマヌに自分で曞かせるのでしょうか

党おのコメント168件

@brtzsnrおそらく、提案プロセスのステップで抂説されおいるように、このドキュメントを提案リポゞトリに送信する必芁があり

テンプレヌトに続いおすでにマヌクダりンされおいるため、CLにコピヌアンドペヌストしおファむルdesign / 18616-bit-twiddling.mdたたはその他を䜜成するのは簡単です。

@cespare from https://github.com/golang/proposal 「䜜成者がデザむンドキュメントを䜜成したい堎合は、䜜成できたす」。 デザむンドキュメントずしおスタヌトしたしたが、提出したいずいう気持ちが匷ければ倧䞈倫です。

私はこれで倧䞈倫だず思いたす、それは倚くのアルゎリズムラむブラリで䜿甚される十分に䞀般的な機胜であり、数孊/ビットは適切な堎所のようです。

1぀には、math / bigはnlz== clzも実装したす。

名前に぀いおは、おそらくいく぀かの自転車の脱萜がありたす。 私は、関数が䜕をするかよりも、䜕を返すかを蚀う方が奜きです。 これにより、名前が短くなる可胜性がありたす。 䟋えば

bits.TrailingZeros64(x)ではなくbits.CountTrailingZeros64(x)

などなど。

提案はかなり明確で最小限のようです-蚭蚈ドキュメントはやり過ぎのようです。 珟時点ではCLの方が適切だず思いたす。

これは、APIず基本的な実装を備えたCLです。蚭蚈ドキュメントの代わりに議論するためです。この提案を受け入れるかどうかを決定する必芁がありたす。

@brtzsnrはすでに蚭蚈ドキュメントを䜜成しおいたす。これは問題の説明にあり、テンプレヌトに埓いたす。 これらのドキュメントをすべお1か所にたずめるこずには䜕らかの䟡倀があるず思いたした。

ハヌドりェアサポヌトテヌブルにリストされおいる最埌のアヌチは「BSWAP」です-タむプミス

これを曞いおくれおありがずう。

ctzおよびclzのdoc文字列は、0が枡されたずきの結果を指定する必芁がありたす。

たた、CountTrailingZeros32よりもTrailingZeros32の方が奜きです。 Ctz32にも満足しおいたす。 それは簡朔で、ほずんどの人に銎染みがあり、残りの人は簡単にグヌグルで怜玢できたす。

提案しおくれおありがずう。
指瀺だけに焊点を合わせるのではなく、おそらく䜿甚にも焊点を合わせたいず付け加えたいず思いたす。 たずえば、 @ dr2chaseは、コンパむラ/アセンブラにいく぀かのlog2関数があるこずを䞀床芋぀けたした。 CLZに近いですが、同じではありたせん。 このような機胜は、おそらくビットをいじるパッケヌゞにも含たれおいるはずです。 たた、これらの指瀺に関係のない䟿利な機胜も含たれおいる可胜性がありたす。

によっお定矩されたすべおのビットをいじるプリミティブのパッケヌゞを提䟛するのはどうですか
ハッカヌの喜び

パッケヌゞを蚭蚈する際に、機胜かどうかを考慮する必芁はありたせん。
内圚化するこずもしないこずもできたす。 最適化は埌で行うこずができたす。 あれは、
䜎レベルの実装に高レベルのパッケヌゞを制埡させないでください
むンタヌフェヌス。 たずえそれらのいく぀かができないずしおも、私たちは良いパッケヌゞむンタヌフェヌスを望んでいたす
単䞀の呜什にマップされたす。

@minux 、幞いなこずに、これたでに必芁だったすべおのビット調敎関数は、たさにこの提案に含たれおいるものです。

Hacker's Delightに埓うこずには、名前に぀いお議論する時間を無駄にする必芁がないずいう利点がありたす。

以䞋を远加したいず思いたす。

ReverseBitsuint32およびuint64の堎合
RotateLeft / Right2シフトでむンラむン展開できたすが、コンパむラヌ
シフト範囲の問題により、垞に倉換を実行できるずは限りたせん

たぶん、加算ず枛算の2぀の結果圢匏もありたすか 䟋えば

func AddUint32x、y、carryin uint32carryout、sum uint32//キャリヌむンマスト
0たたは1になりたす。
そしお、uint64に぀いおも同様です。

そしおSqrtInt。

私の提案の倚くは単䞀の呜什で実装するこずはできたせんが、
それがポむントです私たちは単なるものではなく、ちょっずいじるパッケヌゞが欲しいのです
intrisicsパッケヌゞ。 ハヌドりェアが高レベルのパッケヌゞを制限しないようにしおください
むンタヌフェヌス。

関連しお、加算/乗算がオヌバヌフロヌするかどうかをチェックする関数。

関連するデヌタポむントより高速なcgoのために提出されたさたざたな問題がありたす。 そのような䟋の1぀提案16051では、bsr / ctz / etcの高速実装ずいう事実。 goを曞いおいる人々がcgoを䜿いたがっおいる䞀連のナヌスケヌスでうたくいけば欠けおいるず蚀われたかもしれたせん。

@aclementsは2016幎7月1日にコメントしたした

@eloff 、サポヌトされおいる堎合は組み蟌み関数ずしおコンパむルされるpopcountやbsrなどの関数を远加するためのいく぀かの議論がありたした私の知る限り具䜓的な提案はありたせんがmath.Sqrtは今日です。 1.7では、ランタむムでこれを詊しおいたす。これにより、amd64SSAでctz組み蟌みが䜿甚できるようになりたす。 明らかに、それは党䜓的な問題を解決するわけではありたせんが、オヌバヌヘッドの少ないコンテキストでcgoを䜿甚するもう1぀の理由がありたす。

パフォヌマンスのおかげで倚くの人私も含めおが行きたがっおいるので、この珟圚のちょっずしたいじりの提案のようなものが圹立぀でしょう。 はい、cgoも1.8で高速になりたした。これも玠晎らしいこずです。

RotateLeft / Right2シフトでむンラむン展開できたすが、コンパむラヌ
シフト範囲の問題により、垞に倉換を実行できるずは限りたせん

@minux䜕が問題なのか詳しく

@brtzsnr Minuxが蚀及しおいるのは、 (x << k) | (x >> (64-k))を曞くずき、 0 <= k < 64を䜿甚しおいるこずはわかっおいるが、コンパむラヌはあなたの心を読み取るこずができず、明らかにそうではないずいうこずだず思いたす。コヌドから導き出すこずができたす。 機胜があれば

func leftRot(x uint64, k uint) uint64 {
   k &= 63
   return (x << k) | (x >> (64-k))
}

次に、63を介しおコンパむラヌがkの範囲が制限されおいるこずを認識しおいるこずを確認できたす。
したがっお、コンパむラが入力が制限されおいるこずを蚌明できない堎合は、远加のANDが必芁です。 これは、回転アセンブリをたったく生成しないよりも優れおいたす。

金には、2017幎1月13日午前10時37分PMで、キヌス・ランドヌル[email protected]
曞きたした

@brtzsnr https://github.com/brtzsnrMinuxが参照しおいるものだず思いたす
toは、x << kず曞くずきです。 x >>64-k、0を䜿甚しおいるこずがわかりたす
<= k <64ですが、コンパむラはあなたの心を読み取るこずができず、明らかにそうではありたせん
コヌドから導き出すこずができたす。 機胜があれば

func leftRotx uint64、k uintuint64 {
k= 63
リタヌンx << k| x >>64-k
}

次に、63を介しおコンパむラが範囲を認識しおいるこずを確認できたす。
kのは有界です。
したがっお、コンパむラが入力が制限されおいるこずを蚌明できない堎合は、远加の必芁がありたす
ず。 これは、回転アセンブリをたったく生成しないよりも優れおいたす。

右。 RotateLeft関数ずRotateRight関数を定矩するず、正匏に
å·Š/右kビットを回転する関数を定矩したすkが䜕であるかに関係なく。 これは
シフト挔算の定矩方法ず同様です。 そしおこの定矩も
実際の回転呜什にうたくマッピングされたすシフトずは異なり、
盎感的な定矩では、特定のアヌキテクチャを比范する必芁がありたす。

blosc圧瞮ラむブラリで䜿甚されるバむトおよびビットのシャッフルおよびシャッフル解陀関数はどうですか スラむドシャッフルはスラむド17から始たりたす。 これらの機胜は、SSE2 / AVX2で高速化できたす。

23:24時金、2017幎1月13日には、opennota [email protected]は曞きたした

bloscで䜿甚されるバむトおよびビットシャッフル関数はどうですか
https://github.com/Blosc/c-blosc圧瞮ラむブラリ スラむド
http://www.slideshare.net/PyData/blosc-py-data-2014 シャッフル
スラむド17から始たりたす。 これらの機胜は、SSE2 / AVX2で高速化できたす。

SIMDはより倧きな問題であり、このパッケヌゞの範囲倖です。 これは

17373。

珟圚提案されおいる関数には、最適よりもはるかに倧きく、䞍釣り合いに高䟡なGoネむティブ実装がありたす。 䞀方、rotateは、コンパむラが認識できる方法でむンラむンで簡単に蚘述できたす。

@minuxず他のすべおの人䞀定でない数の回転ビットで巊/右回転が䜿甚される堎所を知っおいたすか たずえば、crypto / sha256はrotateを䜿甚したすが、ビット数は䞀定です。

回転は、コンパむラが認識できる方法でむンラむンで簡単に蚘述できたす。

コンパむラの内郚に粟通しおいる人にずっおは簡単です。 それを数孊/ビットパッケヌゞに入れるず、誰にずっおも簡単になりたす。

回転ビットの数が䞀定でない堎合に、巊/右回転が䜿甚される堎所を知っおいたすか

9337の䟋を次に瀺したす。

https://play.golang.org/p/rmDG7MR5F9

各呌び出しでは、毎回䞀定数のロヌテヌションされたビットですが、関数自䜓は珟圚むンラむン化されおいないため、ロヌテヌション呜什なしでコンパむルされたす。 æ•°å­Š/ビットラむブラリ関数は間違いなくここで圹立ちたす。

土では、2017幎1月14日午前5時05分AMで、アレクサンドルMoşoi [email protected]
曞きたした

珟圚提案されおいる関数には、はるかに倧きなGoネむティブ実装がありたす
最適よりも䞍釣り合いに高䟡です。 䞀方、回転したす
コンパむラが認識できる方法でむンラむンで曞くのは簡単です。

この問題で䜕床も匷調したように、これは正しい方法ではありたせん
Goパッケヌゞを蚭蚈したす。 基盀ずなるハヌドりェアずの結び぀きが匷すぎたす。 私たちが䜕を
wantは、䞀般的に圹立぀ちょっずした調敎パッケヌゞです。 どうにか
関数を単䞀の呜什に拡匵できる限り、関係ありたせん
APIむンタヌフェヌスはよく知られおおり、䞀般的に䟿利です。

@minux https://github.com/minuxそしお他のみんな知っおいたすか
å·Š/右回転は、䞀定数の回転ビットで䜿甚されたすか
たずえば、crypto / sha256はrotateを䜿甚したすが、ビット数は䞀定です。

実際の問題では、回転のビット数が䞀定であっおも、
コンパむラはそれを芋るこずができないかもしれたせん。 シフトカりントが保存されおいる堎合など
配列内、たたはルヌプカりンタヌ内に非衚瀺、あるいはむンラむン化されおいない呌び出し元
関数。

可倉数の回転を䜿甚する簡単な䟋の1぀は、興味深いものです。
popcountの実装
// https://play.golang.org/p/ctNRXsBt0z

func RotateRight(x, k uint32) uint32
func Popcount(x uint32) int {
    var v uint32
    for i := v - v; i < 32; i++ {
        v += RotateRight(x, i)
    }
    return int(-int32(v))
}

@josharian rotがむンラむン化されおいない堎合、この䟋は悪いむンラむン化決定のように芋えたす。 あなたはずしお関数を蚘述しようずしたしたfunc rot(x, n)の代わりにrot = func(x, n) 

@minux 同意したす。 APIを特定の呜什セットに結び付けようずはしおいたせん。 ハヌドりェアのサポヌトは玠晎らしいボヌナスです。 私の䞻な焊点は、コンテキストを理解するために実際のコヌドおもちゃのコヌドではないでの䜿甚法を芋぀けるこずです。最良の眲名は䜕であり、誰もが奜きな機胜を提䟛するこずがどれほど重芁かです。 私たちが今これを適切に行わなければ、互換性の玄束は埌で私たちを噛みたす。

䟋キャリヌリタヌン付きの远加の眲名は䜕である必芁がありたすか Add(x, y uint64) (c, s uint64)  math/bigを芋るず、おそらくAdd(x, y uintptr) (c, s uintptr)も必芁です。

rotがむンラむン化されおいない堎合、この䟋は悪いむンラむン化決定のように芋えたす。

はい。 これは、むンラむン化に぀いお䞍平を蚀うバグの䞀郚です。 :)

関数をrot = funcx、nではなくfunc rotx、nずしお蚘述しようずしたしたか

それは私のコヌドではありたせん-そしおそれは芁点の䞀郚です。 そしおずにかく、それは合理的なコヌドです。

暗号化アルゎリズムで安党に䜿甚できるように、rotate関数ずbyte-swap関数が定数時間の操䜜であるこずをパッケヌゞのドキュメントで保蚌するず䟿利です。 おそらく他の機胜に぀いおも考える必芁がありたす。

朚では、2017幎1月19日11:50で、マむケル・Munday [email protected]
曞きたした

パッケヌゞのドキュメントで
ロヌテヌトおよびバむトスワップ関数は定数時間操䜜であるため、
暗号アルゎリズムで安党に䜿甚できたす。 おそらく䜕かを考える
他の機胜にも。

バむトスワップの簡単な実装は定数時間ですが、基瀎ずなるのは
アヌキテクチャは可倉シフト呜什を提䟛したせん、それは難しいでしょう
䞀定時間のロヌテヌションの実装を保蚌したす。 おそらくGoは実行されたせん
しかし、それらのアヌキテクチャでは。

ずは蚀うものの、根底にあるずいう無芖できない可胜性もありたす
マむクロアヌキテクチャはマルチサむクルシフタヌを䜿甚しおおり、保蚌はできたせん
これらの実装では䞀定の時間がロヌテヌションしたす。

厳密な䞀定時間が必芁な堎合、おそらく唯䞀の方法は曞き蟌みアセンブリです
そしおその堎合でも、それはすべおが䜿甚されおいるずいう匷い仮定をしたす
呜什自䜓は䞀定の時間であり、暗黙的に
マむクロアヌキテクチャ。

私はそのような保蚌の必芁性を理解しおいたすが、実際にはそれを超えおいたす
私たちのコントロヌル。

@minuxに同意する傟向がありたす。 䞀定時間の暗号プリミティブが必芁な堎合、それらは暗号/埮劙に存圚する必芁がありたす。 crypto / subtleは、それらの実装が怜蚌されおいるプラ​​ットフォヌム䞊の数孊/ビットに簡単にリダむレクトできたす。 遅いが䞀定時間の実装が必芁な堎合は、他のこずを行うこずができたす。

これはやる䟡倀があるようです。 @griesemerず@ randall77に向けお出発したす。 次のステップは、通垞の堎所にチェックむンされた蚭蚈ドキュメントのようです䞊のスケッチは衚瀺されおいたす。

この提案を進めるこずができるようになったので、APIの詳现に぀いお合意する必芁がありたす。 私が珟時点で芋おいる質問

  • どの関数を含めるか
  • 凊理するタむプ uint64 、 uint32のみ、たたはuint64 、 uint32 、 uint16 、 uint8 、たたはuintptr 
  • 眲名の詳现䟋 TrailingZeroesxx(x uintxx) uint 、xx = 64、32など、vs TrailingZeroes(x uint64, size uint) uint 、サむズは64、32などのいずれか-埌者の堎合、APIが小さくなり、それでも実装に関しおは十分に高速です
  • いく぀かの名前の自転車の脱萜私は「ハッカヌの喜び」ずいう甚語が奜きですが、それを綎る方が適切かもしれたせん
  • このパッケヌゞには数孊/ビットよりも良い堎所がありたすか

@brtzsnrこの取り組みの先頭に立ち続けたすか 最初の蚭蚈を採甚しおこの号で繰り返したい堎合、たたは専甚の蚭蚈ドキュメントを蚭定したい堎合は問題ありたせん。 たたは、これを手に取っお前に進めるこずもできたす。 私はこれが1.9フェヌズの間に入るのを芋るのが奜きです。

個人的には、スペルアりトされたxx名の方が奜きですbits.TrailingZeroesuint64x、32は、bits.TrailingZeroes32x、imoよりも扱いにくく、読みにくく、その呜名スキヌムはプラットフォヌム倉数サむズで機胜したすuintptrがより簡単になりたすxx = Ptr。

たた、たずえば、最初のリリヌスにuint8を含めなかったが、埌で远加した堎合は、さらに明確になりたす。突然、8を远加する䞀連の曎新されたドキュメントコメントの代わりに、倚くの新しいxx = 8関数がありたす。芋逃しがちなリリヌスドキュメントのメモずずもに、有効なサむズのリストに移動したす。

スペルアりトされた名前が䜿甚されおいる堎合、間違ったスペルを怜玢した堎合に怜玢ペヌゞ内たたは怜玢゚ンゞン経由で正芏名を簡単に芋぀けられるように、ハッカヌの喜びの甚語を「別名」ずしお説明に含める必芁があるず思いたす。 。

æ•°å­Š/ビットは玠晎らしい堎所だず思いたす—それはビットを䜿った数孊です。

SwapBytes{16,32,64}は、 sync/atomicよりもSwapBytes(..., bitSize uint) sync/atomic関数ずの敎合性が高いこずに泚意しおください。

がstrconvパッケヌゞを䜿甚しParseInt(..., bitSize int)パタヌンを、間のより関連があるbitsおよびatomicであるよりも、 strconv 。

SwapBytesuint64、size uintが気に入らない3぀の理由

  1. サむズがコンパむル時定数でない堎合に䜿甚する可胜性がありたす
    少なくずも珟圚のコンパむラに、
  2. 倚くの型倉換が必芁です。 最初にuint32をに倉換したす
    uint64、そしおそれを元に戻す。
  3. 将来のゞェネリックのためにゞェネリック名SwapBytesを予玄する必芁がありたす
    関数のバヌゞョンGoがゞェネリックスのサポヌトを取埗したずき。

@griesemerロバヌト、提案を匕き継いでください。 この提案を1か月以内に進める時間はありたすが、それたでは進展が止たらないはずです。

フォヌムの眲名には明確な奜みがあるようです。

func fffNN(x uintNN) uint

どのNNをサポヌトするかを開いたたたにしたす。 継続的な議論のために、NN = 64に焊点を圓おたしょう。 必芁に応じお残りのタむプを远加するのは簡単ですuintptrを含む。

これにより、 @ brtzsnrによる元の提案ず次の関数およびさたざたなタむプのそれぞれのバリ゚ヌションに加えお、その間に人々が提案したものに盎接戻るこずができたす。

// LeadingZeros64 returns the number of leading zero bits in x.
// The result is 64 if x == 0.
func LeadingZeros64(x uint64) uint

// TrailingZeros64 returns the number of trailing zero bits in x.
// The result is 64 if x == 0.
func TrailingZeros64(x uint64) uint

// Ones64 returns the number of bits set in x.
func Ones64(x uint64) uint

// RotateLeft64 returns the value of x rotated left by n%64 bits.
func RotateLeft64(x uint64, n uint) uint64

// RotateRight64 returns the value of x rotated right by n%64 bits.
func RotateRight64(x uint64, n uint) uint64

スワップ関数のセットもあるかもしれたせん。 個人的に私はこれらに぀いお懐疑的です1SwapBitsは必芁ありたせんでした。そしお、SwapBytesのほずんどの䜿甚は、必芁がないずきに゚ンディアンを認識するコヌドによるものです。 コメント

// SwapBits64 reverses the order of the bits in x.
func SwapBits64(x uint64) uint64

// SwapBytes64 reverses the order of the bytes in x.
func SwapBytes64(x uint64) uint64

次に、敎数挔算のセットが存圚する可胜性がありたす。 それらの䞀郚Log2などがこのパッケヌゞの他の関数に近い可胜性があるため、これらはこのパッケヌゞにのみ含たれたす。 これらの機胜は他の堎所にある可胜性がありたす。 おそらく、パッケヌゞ名bitsを調敎する必芁がありたす。 コメント

// Log2 returns the integer binary logarithm of x.
// The result is the integer n for which 2^n <= x < 2^(n+1).
// If x == 0, the result is -1.
func Log2(x uint64) int

// Sqrt returns the integer square root of x.
// The result is the value n such that n^2 <= x < (n+1)^2.
func Sqrt(x uint64) uint64

最埌に、 @ minuxはAddUint32などの操䜜を提案したした。正しく指定するのは難しいず思うのでそしおもっず倚様性があるので、今はそれらを省略したす。 埌でそれらに戻るこずができたす。 䞊蚘に぀いおいく぀かのコンセンサスを埗たしょう。

質問

  • 関数名に぀いお䜕か意芋はありたすか
  • 敎数挔算に぀いお䜕か意芋はありたすか
  • パッケヌゞ名/堎所に぀いおのご意芋はありたすか

長い関数名がいいです。 Goは、関数名の省略圢を回避したす。 コメントには、パッケヌゞをそのように怜玢しおいる人のニックネヌム "nlz"、 "ntz"などを付けるこずができたす。

@griesemer 、メッセヌゞにタむプミスがあるようです。 コメントが関数のシグネチャず䞀臎したせん。

私は圧瞮アプリケヌションでSwapBitsを䜿甚しおいたす。 そうは蚀っおも、䞻芁なアヌキテクチャはビット反転を効率的に行う機胜を提䟛したすか 私は自分のコヌドで行うこずを蚈画しおいたした

v := bits.SwapBytes64(v)
v = (v&0xaaaaaaaaaaaaaaaa)>>1 | (v&0x5555555555555555)<<1
v = (v&0xcccccccccccccccc)>>2 | (v&0x3333333333333333)<<2
v = (v&0xf0f0f0f0f0f0f0f0)>>4 | (v&0x0f0f0f0f0f0f0f0f)<<4

@ bradfitz 、 @ dsnet 眲名を曎新したしたタむプミスを修正したした。 たた、曎新された質問人々はショヌトカットの明瀺的な名前を奜みたす。

ビットスワッピングのネむティブサポヌトがない限り、私はSwapBitsを陀倖するこずに投祚したす。 ビットが各バむト内でのみ亀換されるのか、uint64党䜓で亀換されるのかは、名前だけでは少しあいたいになる可胜性がありたす。

呜什の可甚性のみに基づいお䜕かを陀倖するのはなぜですか リバヌスビット
FFTで泚目すべき甚途がありたす。

リバヌスビット呜什の可甚性に関する質問に答えるにはarm has has
RBIT呜什。

@griesemer次のような関数の型眲名に関する限り

func Ones64(x uint64) uint
func RotateLeft64(x uint64, n uint) uint64

RotateLeftNなどは、簡単に内圚化するために必芁なため可胜な堎合、たたはそれがドメむンであるずいう理由だけで、uintを取りたすか 匷い技術的ニヌズがない堎合は、負の倀が意味をなさない堎合でも、intを取埗するためのより匷力な前䟋がありたす。 匷い技術的ニヌズがある堎合、それらは芏則性のための適切なNのuintNである必芁がありたすか

OnesNずその同類は、そうでない限りintを返す必芁がありたす。そうしないず、これらの挔算を他のビット挔算ず組み合わせるこずができたす。その堎合、適切なNに察しおuintNを返す必芁がありたす。

@jimmyfrascheそれはドメむンだからです。 CPUは気にしたせん。 䜕かがintであるかuintであるかは、比范を陀くほずんどの操䜜には関係ありたせん。 ずはいえ、それをintにするず、決しお負ではない結果、負であっおはならない匕数、たたは負の堎合に䜕をすべきか回転の匕数を指定する必芁がありたす。 その堎合、1回の回転で逃げるこずができるかもしれたせん。

intを䜿甚するず䜜業が簡単になるずは思いたせん。 適切に蚭蚈されおいる堎合、uintはuintに流れmath / bigの堎合、倉換は必芁ありたせん。 ただし、倉換が必芁な堎合でも、CPUコストの点では無料になりたす読みやすさの点ではありたせんが。

しかし、そうでなければ説埗力のある議論を聞いたり芋たりするこずができおうれしいです。

回転ビット数は、特定のサむズなしでuintである必芁がありたす。
蚀語のシフト挔算子。

intを䜿甚しない理由は、かどうかがあいたいになるためです。
RotateRight-2ビットはRotateLeft2ビットず同じです。

@minux Rotate(x, n)がxをn mod 64ビットで回転するように定矩されおいる堎合、あいたいさはありたせん。巊に10ビット回転するこずは、右に64-10 = 54ビット回転するこずず同じです。たたはint匕数を蚱可する堎合-10ビット正の倀は巊に回転するこずを意味するず仮定。 -10 mod 64 = 54。おそらく、CPU呜什を䜿甚しおも無料で効果が埗られたす。 たずえば、32ビットx86 ROL / ROR呜什は、すでにCLレゞスタの䞋䜍5ビットのみを調べおおり、32ビットロヌテヌションに察しおmod32を効果的に実行しおいたす。

唯䞀の本圓の議論は、stdlibの残りの郚分ずの芏則性です。 uintが非垞に理にかなっおいる堎所はたくさんありたすが、代わりにintが䜿甚されたす。

math / bigは泚目に倀する䟋倖なので、これが別のものであるこずに問題はありたせんが、考慮すべき点がありたす。

@minuxは、実装のあいたいさではなく、コヌドを読んだりデバッグしたりする人にずっおのあいたいさを意味しおいるず

パッケヌゞの名前がす​​でにbitsず呌ばれおいる堎合、bits.SwapBitsには実際にビットサフィックスを付けお名前を付ける必芁がありたすか ビットスワップはどうですか

もう1぀のアむデアは、bits.SwapBytesではなくbits.SwapNv uint64、n intです。ここで、nは、スワップのためにグルヌプ化するビット数を衚したす。 n = 1の堎合、ビットが逆になり、n = 8の堎合、バむトが亀換されたす。 1぀の利点は、bits.SwapBytesが存圚する必芁がなくなったこずです。ただし、他のnの倀が必芁になるこずは䞀床も芋たこずがありたせんが、他の人が同意しない可胜性がありたす。

䞊でLeadingZeros64 、 TrailingZeros64 、 Ones64すべおのLGTM。

眲名されたロヌテヌション金額を持぀単䞀のRotate64は魅力的です。 ほずんどの回転も䞀定量で行われるため、これが組み蟌みになる堎合、個別の右/巊関数を䜿甚しないこずによる実行時のコストは発生したせん。

ビット/バむトのシャッフル/スワッピング/リバヌスに぀いおは匷い意芋はありたせん。 ビットを逆にするために、 bits.Reverse64はより良い名前のようです。 そしおおそらくbits.ReverseBytes64  Swap64は少し䞍明瞭だず思いたす。 Swap64にグルヌプサむズをずらせるこずの魅力はわかりたすが、グルヌプサむズが64を均等に分割しない堎合の動䜜はどうなりたすか 重芁なグルヌプサむズが1ず8だけの堎合は、それらに別々の関数を䞎える方が簡単です。 たた、ある皮の䞀般的なビットフィヌルド操䜜の方が優れおいるのではないかず思いたす。おそらく、arm64およびamd64BMI2の呜什を参考にしおください。

敎数の数孊関数がこのパッケヌゞに含たれおいるずは思いたせん。 それらは、実装でビット関数を䜿甚できるパッケヌゞ数孊に属しおいるように芋えたす。 関連しお、なぜfunc Sqrt(x uint64) uint32  uint64を返す代わりにではないのですか

AddUint32ず友達は耇雑ですが、最終的には再蚪したいず思いたす。 他のこずに加えお、 MulUint64はHMULぞのアクセスを提䟛したす。HMULは、超ミニマリストのRISC-VISAでさえ呜什ずしお提䟛されたす。 しかし、はい、最初に䜕かを取埗したしょう。 埌でい぀でも拡匵できたす。

bitsは明らかに正しいパッケヌゞ名のようです。 むンポヌトパスはmath/bitsではなくbitsである必芁があるず蚀いたくなりたすが、私は匷く感じたせん。

ビットは明らかに正しいパッケヌゞ名のようです。 むンポヌトパスは数孊/ビットではなくビットだけである必芁があるず蚀いたくなりたすが、私は匷く感じおいたせん。

IMO、それがbitsだけだった堎合、パッケヌゞのドキュメントを読たずにパッケヌゞbytesいくらか䌌おいるず思いたす。 ぀たり、ビットを操䜜する関数に加えお、バむトストリヌムずの間でビットを読み曞きするためのReaderずWriterが芋぀かるず思いたす。 math/bitsするず、ステヌトレス関数のセットだけがより明確になりたす。

ビットストリヌム甚にリヌダヌ/ラむタヌを远加するこずは提案しおいたせん

眲名された回転量を持぀単䞀のRotate64は魅力的です。 ほずんどの回転も䞀定量で行われるため、これが組み蟌みになる堎合、個別の右/巊関数を䜿甚しないこずによる実行時のコストは発生したせん。

å·Š/右回転を1぀のRotateに組み合わせるこずで、パッケヌゞAPIを少し小さくするず䟿利なこずがわかりたすが、 nパラメヌタヌを効果的に文曞化するこずもできたす。次のこずを瀺したす。

  • 負のnは、巊回転になりたす
  • れロnは倉曎されたせん
  • 正のnは、右回転になりたす

私には、远加されたメンタルずドキュメントのオヌバヌヘッドは、2぀を1぀のRotate結合するこずを正圓化するようには思えたせん。 明瀺的なRotateLeftずRotateRight  nはuintず、より盎感的になりたす。

@mdlayher nビットワヌドを巊にkビット回転させるこずは、nkビットを右に回転させるこずず同じであるこずに

その䞊、ハヌドりェアx86などは、kが䞀定でない堎合でも、これを自動的に実行したす。

@griesemer 、 Rotate欠点は、どちらの方向が正であるかがわからないこずです。 Rotate32(1, 1) 2たたは0x80000000に等しいですか たずえば、それを䜿甚するコヌドを読んでいた堎合、結果は2になるず予想されたすが、 @ mdlayherは0x80000000になるず予想しおいるようです。 䞀方、 RotateLeftずRotateRightは、笊号付きたたは笊号なしの匕数を取るかどうかに関係なく、明確な名前です。  @minuxには、RotateRight by-2がRotateLeft2ず等しいかどうかがあいたいであるこずに同意したせん。これらは明らかに私ず同等のようであり、他にどのように指定できるかわかりたせん。

RotateLeft64ず呌ばれる関数を1぀だけ持ち、負の倀を䜿甚しお右に回転するこずで修正できる

持っおいる少し奇劙に思えるものの@josharianは、私は、同意RotateLeftもせずにRotateRight 。 回転が蚈算される堎合、笊号付き回転を持぀こずの䞀貫性は朜圚的に䟡倀があるように芋えたすが、䞀定の回転の堎合、「負の2ビットを冗談で巊に回転する」よりも「2ビット右に回転する」ずいうコヌドを読みたいず思いたす。

ドキュメントでこれを修正する際の問題は、ドキュメントが関数を呌び出すコヌドの読みやすさを助けないこずです。

コヌドを曞いおいる人は、巊に回転したり、右に回転したりしたいず思っおいたす。 それに応じお、圌らは巊にも右にも回転したくありたせん。 巊回転のみを提䟛する堎合、右回転を垌望する人は、右回転を巊回転に倉換する匏を䜜成する必芁がありたす。 これは、コンピュヌタヌが簡単に実行できる皮類の衚珟ですが、プログラマヌは間違いを犯したす。 なぜプログラマヌに自分で曞かせるのでしょうか

私は確信しおいたす。

@ aclements @ ianlancetaylorポむントを取埗したした。 ずはいえ、RotateLeft / Rightの実装は、おそらく、rotateの1぀の実装を呌び出すだけです。

名前のアむデアは、眲名名ではなくパッケヌゞ名にタむプを入れるこずです。 bits64.Onesではなくbits.Ones64 。

@btracey 、私はそこに少し口の䞭に投げたした。 :) flag64.Intたたはmath64.Floatfrombitsたたはsort64.Floatsたたはatomic64.StoreIntはありたせん。

@ bradfitzgolang.org/x/image/math/f64ずgolang.org/x/image/math/f32は存圚したすが

私はatomicを前䟋ずしお考えおいたせんでしたありがたいこずに、私の通垞のGoの䜿甚法ではありたせん。 他の䟋は、パッケヌゞが倚くの異なるタむプに察しお繰り返される関数のセットよりも倧きいため、異なりたす。

bits64にアクセスしお衚瀺するず、ドキュメントが芋やすくなりたすたずえば、godocで。
Ones LeadingZeros TrailingZeros

bitsに行っお芋る代わりに
Ones8 Ones16 Ones32 Ones64 LeadingZeros8 ...

@iand 、それもかなりグロスです。 32ず64は、Aff、Mat、およびVecの既存のすべおの数倀接尟蟞に芋栄えがよくなかったず思いたす。 それでも、それは通垞のGoスタむルではなく䟋倖だず思いたす。

Goには、pkg64.fooではなくpkg.foo64呜名スタむルを䜿甚するずいうかなり匷力な前䟋がありたす。

n個のタむプがある堎合、パッケヌゞAPIはn倍倧きくなりたすが、APIの耇雑さはそうではありたせん。 これを解決するためのより良いアプロヌチは、ドキュメントず、godocなどのツヌルを介しおAPIがどのように提瀺されるかを介するこずです。 たずえば、次の代わりに

// TrailingZeros16 returns the number of trailing zero bits in x.
// The result is 16 if x == 0.
func TrailingZeros16(x uint16) uint

// TrailingZeros32 returns the number of trailing zero bits in x.
// The result is 32 if x == 0.
func TrailingZeros32(x uint32) uint

// TrailingZeros64 returns the number of trailing zero bits in x.
// The result is 64 if x == 0.
func TrailingZeros64(x uint64) uint

APIを芋るず明らかに粟神的なオヌバヌヘッドが远加されるため、次のように衚すこずができたす。

// TrailingZerosN returns the number of trailing zero bits in a uintN value x for N = 16, 32, 64.
// The result is N if x == 0.
func TrailingZeros16(x uint16) uint
func TrailingZeros32(x uint32) uint
func TrailingZeros64(x uint64) uint

godocは、その意味で類䌌しおいる関数に぀いお賢く、単䞀のdoc文字列を持぀グルヌプずしおそれらを提瀺するこずができたす。 これは他のパッケヌゞでも圹立ちたす。

芁玄するず、提案された呜名スキヌムは問題なく、Goの䌝統にあるように思われたす。 プレれンテヌションの問題は、他の堎所で議論できる別の質問です。

パッケヌゞ名にビットサむズを入れるず+1。

bits64.Log2はbits.Log264よりも読みやすくなっおいたすLog2はそこに属しおいるず思いたす-そしおパッケヌゞの呜名はそれを排陀する良い理由ではありたせん

結局、それはスカラヌタむプによっお「パラメヌタ化」された各タむプの同じAPIであるため、関数がタむプ間で同じ名前を持っおいる堎合、コヌドは別々のパッケヌゞでリファクタリングするのが簡単です-むンポヌトパスを倉曎するだけです単語党䜓の眮換はgofmt -rを䜿甚するず簡単ですが、カスタムサフィックス倉換はより厄介です。

関数名のビットサむズの接尟蟞は慣甚的なものである可胜性があるずいう@griesmeyerに同意したすが、タむプに䟝存しない重芁なコヌドがパッケヌゞに含たれおいる堎合にのみ、それだけの䟡倀があるず思いたす。

゚ンコヌディング/バむナリから遊びを盗み、関連する事前定矩されたタむプを受け入れるメ゜ッドを持぀Uint64、Uint32、...ずいう名前の倉数を䜜成するこずができたす。

ビット.Uint64.RightShift
ビット.Uint8。リバヌス
bits.Uintptr.Log2
..。

@griesemerどのようにそれらをグルヌプ化する方法を知っおいるでしょうか ドキュメント内で実際の名前の代わりに関数名がNで終わる1぀のドキュメント文字列で、䞍䞀臎に䞀臎するドキュメント文字列のない関数間で共通のプレフィックスを芋぀けたすか それはどのように䞀般化されたすか 非垞に少数のパッケヌゞを提䟛するのは耇雑な特殊なケヌスのようです。

@rogpeppeそれは

@nerdatmathこれは、゚ンコヌディング/バむナリの堎合のように、口語的な意味では同じむンタヌフェむスを持ちたすが、Goの意味ではないため、わずかに異なりたすどちらもbinary.ByteOrderを実装したす。したがっお、倉数は名前空間甚になりたす。そしお、godocは、型が゚クスポヌトされない限り、どのメ゜ッドも取埗したせん7823。これは別の方法で面倒です。

サむズの接尟蟞は問題ありたせんが、党䜓ずしお、個別のパッケヌゞを䜿甚したいず思いたす。 しかし、このコメントを超えおそれをプッシュするこずをわざわざするのに十分ではありたせん。

@nerdatmathがvarsの堎合、それらは倉曎可胜であり bits.Uint64 = bits.Uint8実行できたす、コンパむラヌがそれらを組み蟌み関数ずしお扱うのを防ぎたす。これは、パッケヌゞの少なくずも䞀郚の動機の1぀でした。

倉数が゚クスポヌトされおいないタむプであり、状態がない堎合゚クスポヌトされおいない空の構造䜓、倉数は実際には倉曎できたせん。 しかし、共通のむンタヌフェヌスがなければ、godoc今日はひどいものになるでしょう。 それが答えなら修正可胜です。

ただし、すべおが耇数のパッケヌゞを䜿甚するこずになった堎合でも、それを保蚌するのに十分な繰り返しずボリュヌムがある堎合は、少なくずも「X / bits / int64s」、「X / bits / ints」、「X /」のようにパッケヌゞに名前を付けおください。 「゚ラヌ」、「文字列」、「バむト」に䞀臎する「ビット/ int32s」。 ただ倚くのパッケヌゞ爆発のようです。

耇数のタむプ固有のパッケヌゞぞのパスに進むべきではないず思いたす。単䞀のパッケヌゞビットを持぀こずは単玔であり、Goラむブラリ内のパッケヌゞの数を増やすこずはありたせん。

Ones64ずTrailingZeroes64は良い名前ではないず思いたす。 圌らは圌らがカりントを返すこずを知らせたせん。 プレフィックスCountを远加するず、名前がさらに長くなりたす。 私のプログラムでは、これらの関数は倧きな匏に埋め蟌たれおいるこずが倚いため、関数名を短くするず読みやすくなりたす。 「Hacker'sDelight」ずいう本の名前を䜿甚したしたが、IntelアセンブラヌのニヌモニックであるPopcnt64、Tzcnt64、およびLzcnt64に埓うこずをお勧めしたす。 名前は短く、䞀貫したパタヌンに埓い、カりントが返され、すでに確立されおいるこずを通知したす。

通垞、Goのカりントは、カりントが負になるこずはない堎合でも、intずしお返されたす。 代衚的な䟋は組み蟌み関数lenですが、Read、Write、Printfなどはすべお敎数も返したす。 カりントにuint倀を䜿甚するこずは非垞に驚くべきこずであり、int倀を返すこずをお勧めしたす。

衚蚘を乱甚するためにmath / bits /int64s.Onesずmath / bits.Ones64のどちらかを遞択する堎合は、単䞀のパッケヌゞを䜿甚するこずをお勧めしたす。 サむズで分割するよりも、パッケヌゞ識別子にビットを含めるこずが重芁です。 パッケヌゞ識別子にビットがあるず、コヌドが読みやすくなりたす。これは、パッケヌゞのドキュメントでの繰り返しの小さな䞍䟿よりも重芁です。

@ulikunitzビットを倚甚するコヌドでは、い぀でもctz := bits.TrailingZeroes64などを実行できたす。 これは、グロヌバルに自己文曞化された名前ず、耇雑なコヌドのロヌカルにコンパクトな名前のバランスを取りたす。 反察の倉換であるcountTrailingZeroes := bits.Ctz64は、優れたグロヌバルプロパティがすでに倱われおいるため、あたり圹に立ちたせん。

私はめったにビットレベルのものをいじりたせん。 考えなければならなかったのは䜕幎も前のこずなので、毎回このようなものをたくさん調べなければならないので、ハッカヌの喜び/ asmスタむルの名前はすべお腹立たしいほど䞍可解です。 必芁なものを芋぀けおプログラミングに戻るこずができるように、それが䜕をしたかを蚀っただけです。

私は@ulikunitzに同意し

init() instead of initialize(), 
func instead of function
os instead of operatingsystem
proc instead of process
chan instead of channel

さらに、私はそのビットに挑戊したす。TrailingZeroes64は自己文曞化です。 れロが末尟にあるずはどういう意味ですか 自己文曞化プロパティは、ナヌザヌが最初に文曞化のセマンティクスに぀いお䜕かを知っおいるこずを前提ずしお存圚したす。 䞀貫性を保぀ためにHacker'sDelightを䜿甚しおいない堎合は、RotateRight64ずRotateLeft64に䞀臎するようにZeroesRight64ずZeroesLeft64ず呌んでみたせんか

明確にするために、私はそれを䜿甚するずきはい぀でも最初にすべきこずは短い゚むリアスを䜜成するこずであり、䞎えられた名前を決しお䜿甚しおはならないこずを意味する぀もりはありたせんでした。 ぀たり、繰り返し䜿甚しおいる堎合は、コヌドの可読性が向䞊すれば、゚むリアスを䜜成できたす。

たずえば、strings.HasSuffixを呌び出す堎合、1回たたは2回呌び出すため、ほずんどの堎合、指定された名前を䜿甚したすが、1回限りのETLスクリプトなどで時々䜿甚したす。最終的にはそれを束ず呌ぶこずになりたすので、 ends := strings.HasSuffixを実行したす。これは短く、コヌドが明確になりたす。 ゚むリアスの定矩がすぐ近くにあるので問題ありたせん。

非垞に䞀般的なものには、省略名で十分です。 倚くの非プログラマヌはOSの意味を知っおいたす。 Goを知らなくおも、コヌドを読んでいる人は誰でも、funcが関数の略であるこずに気付くでしょう。 チャンネルはGoの基本であり、広く䜿甚されおいるので、chanは問題ありたせん。 ビット関数が極端に䞀般的になるこずは決しおありたせん。

TrailingZeroesは、抂念に慣れおいない堎合、䜕が起こっおいるのかを正確に䌝えるこずができない堎合がありたすが、少なくずも倧たかに蚀っお、Ctzよりもはるかに優れたアむデアを提䟛したす。

@jimmyfrasche https://github.com/golang/go/issues/18616#issuecomment -275828661に぀いおgo / docは、名前がすべおで始たる同じファむル内の連続する䞀連の関数を認識するのは非垞に簡単です。同じ接頭蟞があり、数字のシヌケンスである接尟蟞や、接頭蟞に察しお「短い」単語である可胜性がありたす。 これらの関数の最初の関数だけがドキュメント文字列を持ち、䞀臎するプレフィックスを持぀他の関数は持っおいないずいう事実ず組み合わせたす。 これは、より䞀般的な蚭定で非垞にうたく機胜するず思いたす。 そうは蚀っおも、この提案を乗っ取らないように、他の堎所でこれに぀いお話し合いたしょう。

参考たでに、 go/doc倉曎に぀いお話し合い、その䌚話をこれずは別にするために18858を䜜成したした。

@mdlayherそれをしおくれおありがずう。

@rogpeppeパッケヌゞ名にサむズを入れるのは

@ulikunitz私は通垞、短い名前に最初に投祚した人の1人です。 特にロヌカルコンテキストおよび非垞に頻繁に䜿甚される名前のグロヌバルコンテキストで。 しかし、ここにはパッケヌゞAPIがあり、少なくずも私の経隓では関数はクラむアントに広く衚瀺されたせん。 たずえば、math / big makeはLeadingZeros、Log2などを䜿甚したすが、それは1぀か2぀の呌び出しにすぎたせん。 長い説明的な名前でも倧䞈倫だず思いたす。議論から刀断するず、コメントの倧郚分はそれを支持しおいたす。 関数を頻繁に呌び出す堎合は、短い名前の関数でラップする方が安䟡です。 远加の通話はむンラむン化されたす。 FWIW、Intelのニヌモニックも玠晎らしいものではなく、「カりント」cntに重点が眮かれおいるため、埩号化する必芁のある2文字が残りたす。

Log2の2は必芁ないこずに同意したす。 bits.Logは、2の底を意味したす。

bits.Log64SGTM。

@griesemer私のカットオフセンテンスは、おそらく䞍噚甚な線集のアヌティファクトでした。 取り倖したずころです。

@griesemer名前の自転車の脱萜を続ける䟡倀があるかどうか

@ulikunitzここでのフィヌドバックの倧郚分は、ショヌトカットではない明確な関数名を支持しおいるず思いたす。

@ulikunitz 、さらに

パッケヌゞbigは、LeadingZerosではなくnlzを内郚的に䜿甚したす。

内郚のプラむベヌトな゚クスポヌトされおいない名前は、ここでは圱響を䞎えたせん。

重芁なのは、パブリックAPIの䞀貫性ず暙準的な感觊です。

バむクシェディングは煩わしいかもしれたせんが、私たちが氞遠にそれらに固執するずきは名前が重芁です。

CLhttps  //golang.org/cl/36315はこの問題に぀いお蚀及しおいたす。

レビュヌ甚の初期郚分的にテスト枈みAPI予備実装ありずしおhttps://go-review.googlesource.com/#/c/36315/をアップロヌドしたした蚭蚈ドキュメントの代わりに。

APIが正しいこずを確認しおいるので、今のずころAPIbits.goに぀いおのみコメントしおください。 マむナヌな問題タむプミスなどに぀いおは、CLにコメントしおください。 デザむンの問題に぀いおは、この問題に぀いおコメントしおください。 むンタヌフェむスに満足するたで、CLを曎新し続けたす。

具䜓的には、実装に぀いお心配する必芁はありたせん。 これは基本的なものであり、郚分的にしかテストされおいたせん。 APIに満足したら、実装を簡単に拡匵できたす。

@griesemer倧䞈倫だず思いたすが、それが圹立぀堎合は、テスト付きのCLZアセンブリの実装がありたすhttps://github.com/ericlagergren/decimal/tree/ba42df4f517084ca27f8017acfaeb69629a090fb/internal/arith盗む/いじる/䜕でも。

@ericlagergrenリンクをありがずう。 APIが萜ち着き、あらゆる堎所でテストが実斜されたら、実装の最適化を開始できたす。 私はこれを心に留めおおきたす。 ありがずう。

@griesemer 、提案されたAPIドキュメントは、同じプレフィックスで敎数のサフィックスを持぀関数を適切にドキュメント化できるgo / docに䟝存しおいるようです。

1.9より前にもそれに取り組む蚈画はありたすか

18858、぀たり

@mdlayherそれは理想的です。 ただし、APIには圱響せず、「唯䞀の」ドキュメントに圱響するため、目を芋匵るものにはなりたせん今埌も䞋䜍互換性を維持する必芁がありたす。

@ griesemer @ bradfitz関数名に関する自分の立堎を再考するために時間を費やしおいたす。 名前を遞択する重芁な目的は、APIを䜿甚したコヌドの可読性である必芁がありたす。

次のコヌドは確かに理解しやすいです

n := bits.LeadingZeros64(x)

Ones64xの明確さに぀いおはただ少し疑問がありたすが、LeadingZerosおよびTrailingZerosず䞀臎しおいたす。 だから私は自分の䞻匵を䌑たせ、珟圚の提案を支持したす。 実隓ずしお、テストケヌスを含むパッケヌゞの実隓的な玔粋なGo実装に既存のコヌドを䜿甚したした。

リポゞトリ https 
ドキュメント https 

スワップ関数のセットもあるかもしれたせん[...] SwapBytesのほずんどの䜿甚は、あるべきではないずきに゚ンディアンを認識するコヌドによるものです。 コメント

このため、 SwapBytes APIから陀倖したいず思いたす。 binary/encoding.BigEndianよりも単玔であるたたは高速であるず想定されるため、人々が移怍性のない方法でそれを䜿い始めるのではないかず心配しおいたす。

このため、SwapBytesをAPIから陀倖したいず思いたす。 binary / encoding.BigEndianよりも単玔であるたたは高速であるず想定されるため、人々が移怍性のない方法でそれを䜿い始めるのではないかず心配しおいたす。

@mundaymこれらのルヌチンはこれたでに内圚化される予定ですか SwapBytes64をBSWAPずしお盎接コンパむルさせるず、䞍適切に䜿甚する人よりも倚くなる可胜性がありたす、imo。

バむナリ/゚ンコヌディングよりも単玔であるたたは高速であるず想定されるため、人々が移怍性のない方法でそれを䜿い始めるのではないかず心配しおいたす。BigEndian

ReverseBytes䜿甚は、マシンがデヌタをメモリに配眮する方法で䜎レベルのデヌタにアクセスするunsafeず組み合わせお䜿甚​​した堎合にのみ、移怍性がないず思いたす。 ただし、 encoding.{Little,Big}Endian.Xをそのように䜿甚するず、移怍性がなくなりたす。 ReverseBytesが圧瞮で䜿甚されるのを楜しみにしおいたすが、含たれおいなかったら悲しいです。

@ericlagergren

これらのルヌチンはこれたでに内圚化されるのでしょうか

はい、バむト反転を実行するencoding/binaryの関数は、コンパむラヌによっお認識され、敎列されおいないデヌタをサポヌトするプラットフォヌムで単䞀の呜什 BSWAP に最適化されおいるたたは最適化できるコヌドパタヌンを䜿甚したすアクセス䟋386、amd64、s390x、ppc64leなど。

SwapBytes64をBSWAPずしお盎接コンパむルさせるず、䞍適切に䜿甚しおいる人々よりも重芁になる可胜性がありたす。

私は反察する傟向がありたす。 ゚ンディアンを認識しないコヌドではSwapBytesが合法的に䜿甚されおいる可胜性がありたすが、正しく䜿甚されるよりも頻繁に誀甚されるず思われたす。

runtime / internal / sysは、埌続れロずバむトスワップのGo、アセンブリ、およびコンパむラ組み蟌みバヌゞョンをすでに最適化しおいるため、これらの実装を再利甚できるこずに泚意しおください。

@dsnet興味深いこずに、䜕か具䜓的なこずを考えおいたすか

@aclementsバむトスワップ組み蟌み関数がランタむムのどこで䜿甚されおいるか知っおいたすか テスト以倖の甚途は芋぀かりたせんでした。

@ mundaym 、AFAIKランタむムでは䜿甚されたせん。 内郚APIにそれほど泚意を払う必芁はないので、簡単だったので、ctzを远加するずきに远加しただけだず思いたす。 ポップカりントはより良い遞択だったでしょう。

すべお今のずころAPIに集䞭しおください。 CLでの実装は、これらの関数を実際に䜿甚しおテストできるようにする、単玔で遅い実装です。 APIに満足したら、実装を調敎できたす。

泚 uint32たたはuint64ず同じサむズであるこずが保蚌されおいないため、おそらくuintptrバヌゞョンを含める必芁がありたす。 uintは垞にuint32たたはuint64いずれかであるこずに泚意しおください。 意芋は 埌で䜿甚したすか 良い名前は䜕でしょうか  LeadingZerosPtr 。

今すぐuintptrを実行する必芁がありたす。そうしないず、math / bigはそれを䜿甚できたせん。 接尟蟞Ptr SGTM。 uintも実行する必芁があるず思いたす。そうしないず、倉換なしの呌び出しを行うために、すべおの呌び出しコヌドでintサむズの条件コヌドを蚘述する必芁がありたす。 呜名のアむデアはありたせん。

uintptrのPtr、uintのサフィックスなし。 Ones、Ones8、Ones16、Ones32、Ones64、OnesPtrなど。

ここでは少数掟かもしれたせんが、uintptrを䜿甚する関数を远加するこずには反察です。
math / bigは、最初からuint32 / uint64を䜿甚する必芁がありたした。 実際、私は
すべおのアヌキテクチャにuint64を䜿甚し、最適化は
コンパむラ。

問題はこれです
math / bigは、最適なパフォヌマンスを埗るためにネむティブワヌドサむズを䜿甚したいず考えおいたす。
ただし、近い間、uintptrは正しい遞択ではありたせん。
ポむンタのサむズがず同じサむズであるずいう保蚌はありたせん
ネむティブワヌドサむズ。
代衚的な䟋はamd64p32であり、mips64p32ず
mips64p32leは埌で、64ビットMIPSホストではるかに人気がありたす。

私は確かにそのような䜿甚法をこれ以䞊奚励したくありたせん。 uintptrが最も
アヌキテクチャニュヌトラル敎数ではなく、ポむンタ甚。

ただし、1぀の解決策は、APIに型゚むリアスを導入するこずですおそらくそれ
ブランドタむプである必芁がありたす、これは議論の䜙地がありたす。
タむプWord = uint32 //たたは64ビットアヌキテクチャではuint64
//おそらくWordのようないく぀かの理想的な定数も提䟛する必芁がありたす
ビット数、マスクなど。

次に、Wordを取埗するために、型接頭蟞のない関数を導入したす。

実際、math / bitが2぀の結果を提䟛する堎合、add、sub、mul、
div; math / bigは、アヌキテクチャ固有のアセンブリなしで曞き盎すこずができたす。

math / big exports type Word uintptr 。 それは間違いだったかもしれないず私は同意したすが、互換性にはそれが残っおいるこずが必芁だず思いたす。 したがっお、math / bitsを䜿甚しおmath / bigを実装する堎合は、uintptrAPIが必芁です。

少し話題から倖れおいたすが、ネむティブの笊号なしワヌドサむズは単なる無意味ではありたせんか その堎合、uintの接尟蟞がないのはほが正しいようです。

単䞀のタむプであるWordがアヌキテクチャヌごずに異なるこずは望たしくありたせん。 これは、呌び出し元ずドキュメントに倚くの耇雑さをもたらすようです。 既存のタむプに固執するこずは、あなたがそれを単に䜿うこずができるこずを意味したす。 アヌキテクチャ間で型が異なるずいうこずは、その型を䞭心にすべおのコヌドを蚭蚈するか、ビルドタグで保護されたファむルに倚数のアダプタを含めるこずを意味したす。

FWIW、math / bigの実装では、uint32 / 64ベヌスのビットAPIを匕き続き䜿甚できたす関数のuintptrバヌゞョンがない堎合。

@minux私は2぀の結果のadd、sub、mul、divに反察しおいたせんが、2番目のステップでそれを実行したしょう。 ただし、適切なパフォヌマンスが必芁な堎合は、アセンブリコヌドが必芁です。 しかし、私はコンパむラヌによっお他の方法で玍埗できおうれしいです...

uintバヌゞョンずuintptrバヌゞョンをAPIに远加したした。 CLを芋おコメントしおください。 しかし、機胜の急増にはあたり満足しおいたせん。

@josharianネむティブuintは、64ビットマシンでも32ビット倀になる堎合がありたす。 保蚌はありたせん。 uintptrはマシンのワヌドサむズも保蚌しないこずを私は理解しおいたす。 しかし圓時、振り返っおみるず間違っおいたずしおも、それはより賢明な遞択のように思われたした。 おそらく、本圓にWordタむプが必芁です。

uintptr関数の唯䞀の正圓な必芁性がmath / bigをサポヌトするこずである堎合、おそらくmath / bitsの実装は内郚パッケヌゞに入れるこずができたす。math/ bigでuintptrのものだけを䜿甚し、残りを公開したす。

@ jimmyfrasche 、 @ griesemerそれは

uintも間違っおいたす。 amd64p32では32ビットです。
実際、math / bigはuintptrの代わりにuintを䜿甚できたかもしれたせんが、Go1では
int / uintは垞に32ビットであるため、uintptrが唯䞀の可胜な解決策になりたす。
math /big.Wordの堎合。

新しいパッケヌゞを蚭蚈しおいるので、互換性はそれほど重芁ではないず思いたす
懞念。 math / bigは間違ったタむプを䜿甚しおいたすが、それは歎史的なものです
事件。 これ以䞊間違いを犯さないようにしたしょう。

い぀も䞀番倚い統䞀型「Word」を䜿う理由がわからない
特定のアヌキテクチャの効率的な敎数型は、
uintptrを䜿甚したす。 ナヌザヌコヌドの堎合、それを魔法のタむプずしお扱うこずができたす。
アヌキテクチャに応じお、32ビットたたは64ビットのいずれか。 あなたが曞くこずができれば
uintptr幅もアヌキテクチャに䟝存したすを䜿甚するコヌド
アヌキテクチャに䟝存しない方法であれば、Wordでも同じこずができるず思いたす。
そしお、Wordはすべおのアヌキテクチャで正しいです。

APIの普及のために、8の関数を陀倖するこずをお勧めしたす
最初のパスでは16ビットタむプ。 それらはめったに䜿甚されず、ほずんど
アヌキテクチャはずにかく32ビットず64ビットの呜什のみを提䟛したす。

math / bigはWordを定矩および゚クスポヌトしたすが、auintptrず盎接互換性がありたせん異なるタむプです。b​​Wordを適切に䜿甚し、その実装に぀いおの仮定を行わないコヌドは、あらゆる皮類のWord実装で可胜です。 。 倉曎できたす。 APIの互換性保蚌に圱響する理由がわかりたせんただ詊しおいたせん。 ずにかく、これは脇に眮いおおきたしょう。 個別に凊理できたす。

明瀺的にサむズ蚭定されたすべおのuintタむプを単玔に実行できたすか uint / uintptrのサむズが定数ずしおわかっおいる堎合は、適切なサむズの関数を呌び出すifステヌトメントを簡単に蚘述できたす。 そのifステヌトメントは定数畳み蟌みであり、それぞれのラッパヌ関数は、むンラむン化されるサむズ蚭定された関数を呌び出すだけです。

最埌に、Wordタむプ数孊/ビッグに䟝存しないに関する正しい解決策は䜕ですか もちろん、数孊/ビットで定矩するこずもできたすが、それは正しい堎所ですか これはプラットフォヌム固有のタむプです。 事前に宣蚀されたタむプ「単語」である必芁がありたすか そしお、なぜですか

ここにuintptrに盎接蚀及しおいる関数シグネチャたたは名前があるのは間違いのようです。 人々は、Goポむンタをこのように少しいじるこずは想定されおいたせん。

自然な機械語型の関数があれば、int / uintを参照できるようになったず思いたす。 64ビットシステムでは32ビットであったため、math / bigではuintを䜿甚したせんでしたが、それ以降は修正されおいたす。 math / bigはそれ自䜓が䞀貫した䞖界であり、独自のタむプbig.Wordを持぀こずは理にかなっおいたすが、このパッケヌゞは、遞択しお遞択するナヌティリティルヌチンのコレクションです。 このコンテキストで新しいタむプを定矩するこずは、それほど説埗力がありたせん。

int / uintバリアントが必芁かどうかはたったくわかりたせん。 それらが䞀般的に必芁な堎合は、このパッケヌゞでそれらを定矩する方が、すべおの呌び出し元にifステヌトメントの蚘述を匷制するよりも理にかなっおいたす。 しかし、それらが䞀般的に必芁になるかどうかはわかりたせん。

math / bigずの朜圚的な䞍䞀臎に察凊するために、ここのAPIでuintptrに蚀及するこずを含たない゜リュヌションが少なくずも2぀ありたす。

  1. math / bigでファむルword32.goずword64.goを、ビルドタグずuintptrを䜿甚しお定矩したす。適切にリダむレクトするラッパヌを受け入れたすコンパむラのむンラむン化が正しいこずを確認したす。

  2. big.Wordの定矩をuintに倉曎したす。 正確な定矩は、APIで公開されおいる堎合でも、内郚実装の詳现です。 それを倉曎しおも、amd64p32を陀いおコヌドを壊すこずはできず、それでもmath / big以倖で問題になる可胜性は非垞に䜎いようです。

@rsc 「64ビットシステムでは32ビットだったのでmath / bigではuintを䜿甚したせんでしたが、それを修正したした。」ああ、そうです、uintptrを遞択した理由を完党に忘れたした。 Go uint / int型の芁点は、マシンの自然なレゞスタサむズを反映する敎数型を持぀こずでした。 big.Wordをuintに倉曎しお、䜕が起こるか芋おみたしょう。

すべお https //go-review.googlesource.com/#/c/36315/を曎新しお、䞊蚘の説明に埓っおuintptr関数のバヌゞョンを陀倖したした。

math / bigを暫定的に曎新しお、math / bitsを䜿甚しお効果を確認したしたhttps://go-review.googlesource.com/36328。

いく぀かのコメント
1私は結果䜜りに傟いおるLeading / TrailingZeros関数uintではなくint 。 これらの結果は、それに応じお倀をシフトするために䜿甚される傟向がありたす。 そしおmath/bigこれを蚌明しおいたす。 䞀貫性を保぀ために、 Onesがuint返すようにするこずにも賛成です。 反論

2私はOneずいう名前のファンではありたせんが、 Leading / TrailingZerosず䞀臎しおいたす。 Populationどうですか

3 Logがこのパッケヌゞに収たらないず䞍満を蚀う人もいたす。 Logたたたたmsbのむンデックスず同等ですx == 0の堎合は-1。 したがっお、これをMsbIndexず呌ぶこずができたすただし、Logの方が優れおいるようです。 あるいは、ビット単䜍のxの長さであるLen関数を䜿甚するこずもできたす。 ぀たり、 `Logx== Lenx-1です。

コメント

私はOneずいう名前のファンではありたせんが、Leading / TrailingZerosず䞀臎しおいたす。 人口はどうですか

なぜ䌝統的なPopcountないのですか

あるいは、ビット単䜍のxの長さであるLen関数を䜿甚するこずもできたす。 ぀たり、 `Logx== Lenx-1です。

LenたたはLengthは、良い名前ず良いアむデアのように聞こえたす。

1.1。

私はOneずいう名前のファンではありたせんが、Leading /ず䞀臎しおいたす
TrailingZeros。 人口はどうですか

ビット数

@aclements䜕を数えたすか

人口は歎史的な理由からより良い名前かもしれたせんが、あなたがその甚語に粟通しおおらず、同じ問題を抱えおいるのであれば、実際には1぀以䞊ずは蚀えたせん。

パッケヌゞ内であっおも、それはやや単調ですが、CountOnesが明確で明癜な名前を付けおいるのかもしれたせん。

@aclements䜕を数えたすか

「ビット」ず呌ばれるパッケヌゞでは、蚭定されたビット以倖に䜕を数えるこずができるかわかりたせんが、CountOnesも問題なく、明らかにより明確です。 「Ones」を远加するず、 LeadingZeros / TrailingZerosの「Zeros」にも察応したす。

これが最も明癜な解釈ですが、あいたいさが残っおいたす。 未蚭定ビットたたは合蚈ビットをカりントしおいる可胜性がありたす最埌の解釈は非垞にありそうにありたせんが、関連する抂念に粟通しおおらず、サフィックスのないカりントはunsafe.SizeOfのように思われるビットを䜿甚しおコヌドを読み取る人にずっおは朜圚的なトラップです

Trailing / LeadingZeroesをミラヌリングするAllOnesやTotalOnesのようなものかもしれたせんが、それらずは異なり、䜍眮が考慮されないように指定したす。

AllOnesは、すべおのものを返すように聞こえたすビットマスクで、たたはすべお1である単語かもしれたせん。

CountOnesずTotalOnesはほが同じように芋えたすが、この操䜜で最も䞀般的に知られおいる名前は「population count」であるため、CountOnesの方が望たしいず思われたす。

いく぀かの倉曎を加えた新しいバヌゞョンhttps://go-review.googlesource.com/#/c/36315/をアップロヌドしたした。

1 Ones名前をPopCount ほずんどの人は、䞀貫性のある、しかしやや単調な名前Onesあたり興奮しおいたせんPopCountが䜕をするのかを正確に知っおいるでしょう。これは、この関数が䞀般的に知られおいる名前です。 他の郚分ずは少し矛盟しおいたすが、その意味は非垞に明確になっおいたす。 これに぀いおはラルフ・ワルド・゚マヌ゜ンず䞀緒に行きたす「愚かな䞀貫性は小さな心のホブゎブリンです...」。

2私は名前を倉曎LogするLenのようにbits.Len 。 数倀xのビット長は、xを2進衚珟で衚すのに必芁なビット数ですhttps://en.wikipedia.org/wiki/Bit-length。 ふさわしいようで、ここでLogする必芁がなくなりたす。これは、「ちょっず面倒な」品質ではありたせん。 Log定矩方法を考えるず、 Len(x) == Log(x) + 1もあるので、これも勝利だず思いたす。 さらに、結果が垞に> = 0になるずいう利点があり、些现な実装で+/- 1の修正がいく぀か削陀されたす。

党䜓ずしお、この時点でこのAPIにはかなり満足しおいたす埌で関数を远加したい堎合がありたす。 私たちが真剣に怜蚎したいず思うかもしれない他の唯䞀のこずは、すべおの結果に眲名を付けるべきかどうかです。 前に指摘したように、トレヌリング/リヌディングれロ関数の結果は、笊号なしでなければならないシフト挔算ぞの入力になる傟向がありたす。 それは、間違いなく笊号なしの倀も返す可胜性があるLenずPopCountだけを残したす。

コメント

math / bigでの私の経隓は、シフトしおいないずきに関数によっおuintモヌドに匷制されるこずに䞍満を感じおいたした。 math / big / prime.goで、私は曞いた

for i := int(s.bitLen()); i >= 0; i-- {

s.bitLenがintをuintではなく返す堎合でも、私は芋ずに確信が持おず、将来のCLがuintを返すように倉曎しない可胜性があるこずも確信しおいなかったため、forルヌプが無限ルヌプになりたした。 この防埡的である必芁があるこずは、問題があるこずを瀺唆しおいたす。

Uintは、intよりも゚ラヌが発生しやすいため、ほずんどのAPIでUintを掚奚しおいたせん。 ずにかくほずんどのシフト匏で必芁なように、数孊/ビットのすべおの関数がintを返し、uintぞの倉換をシフト匏で実行するようにした方がはるかに良いず思いたす。

私は倉曎を提案しおいたせんが、uintを必芁ずするシフトは振り返っおみるず間違いだったず思いたす。い぀か修正できるかもしれたせん。他のAPIを傷぀けなければいいのですが。

末尟のれロずpopcount関数の呌び出しのためにコヌドをgrepした埌、intを返すこずをサポヌトしおいたす。 呌び出しの倧郚分は、短い倉数宣蚀ずint型の比范です。 シフトでの呌び出しにはもちろんuint型が必芁ですが、驚くほどたれです。

マむナヌな調敎をアップロヌドしたした。 +1ずコメントごずに、カりントの結果をintずしお残したしょう。

https://go-review.googlesource.com/36315

RotateLeft/Rightの入力カりントをuintそうしないず、倀が負の堎合に䜕が起こるかを指定するか、蚱可しないようにする必芁がありたす。

最埌に、私たちも離れ去るかもしれないLen以来、すべおの埌にLenN(x) == N - LeadingZerosN(x) 。 意芋は

この時点で重芁なフィヌドバックがなくなった堎合は、このAPIを䜿甚しお、レビュヌ埌に最初の実装をコミットするこずをお勧めしたす。 その埌、実装の調敎を開始できたす。

次のステップでは、他にどの関数を含めるか、具䜓的には2぀の匕数を䜿甚しおキャリヌし、結果を生成しおキャリヌするAdd / Sub /などに぀いお説明したす。 。

@griは10Len関数に぀いお考えおいたすか ((N - clz(x) + 1) * 1233) >> 12

ベヌス2よりも「ビットハッキヌ」ではありたせんが、それでも䟿利です。
17:03ロバヌト・グリヌズマヌで金、2017幎2月10日には[email protected]
曞きたした

マむナヌな調敎をアップロヌドしたした。 +1ずコメントごずにの結果を残したしょう
intずしおカりントされたす。

https://go-review.googlesource.com/36315

RotateLeft / Rightの入力カりントをuintのたたにしたした。それ以倖の堎合は、
倀が負の堎合に䜕が起こるかを指定するか、それを蚱可しない必芁がありたす。

最埌に、LenNx== N-なので、結局Lenを陀倖するこずもできたす。
LeadingZerosNx。 意芋は

この時点で重芁なフィヌドバックがなくなった堎合は、
このAPIを䜿甚しお前進し、その埌最初の実装をコミットしたす
レビュヌ。 その埌、実装の調敎を開始できたす。

次のステップでは、他にどの機胜を䜿甚できるかに぀いお話し合いたいず思うかもしれたせん。
特に、2぀の匕数を消費するAdd / Sub /などを含めたい
キャリヌ、そしお結果を生み出しおキャリヌ。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/golang/go/issues/18616#issuecomment-279107013 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AFnwZ_QMhMtBZ_mzQAb7XZDucXrpliSYks5rbQjCgaJpZM4Lg5zU
。

たた。 この問題の範囲倖になっおいる堎合はご容赊ください。ただし、チェック挔算に賛成です。 䟋 AddN(x, y T) (sum T, overflow bool)

20:16時金、2017幎2月10日には、゚リックLagergren [email protected]
曞きたした

たた。 この問題の範囲倖になっおいる堎合はご容赊ください。
チェックされた算術の支持。 䟋AddNx、y Tsum T、overflow bool

眲名されたオヌバヌフロヌに぀いお話しおいるのですか たたは笊号なしオヌバヌフロヌキャリヌ/ボロヌ

たた、単玔化するために、オヌバヌフロヌ/キャリヌ/ボロヌをタむプTずしお返すこずを奜みたす
倚倍長挔算。

@ericlagergren 基数2 Len関数は、ほがlog2ですが、本質的にはビットカりント関数です。 基数10のLen関数は、実際には察数関数です。 それが有甚であるこずは吊定できたせんが、このパッケヌゞにはあたり適切ではないようです。

はい、 checked挔算を取り入れるずいいず思いたす。最初に珟圚のAPIを閉じお、前埌に移動するのではなく、進歩できるようにしたかっただけです。 これたでにコメントしたほずんどの人はそれに満足しおいるようです。

Add、Sub関数に関しおキャリヌは匕数ず同じ型でなければならないずいう@minuxに同意したす。 たた、これらの関数にはuint匕数以倖に䜕かが必芁だずは思いたせん。芁点は、ほずんどの堎合uintにはプラットフォヌムの自然なレゞスタサむズがあり、それがこれらの操䜜が最も理にかなっおいるレベルであるずいうこずです。

æ•°å­Š/チェックされたパッケヌゞはそれらのためのより良い家であるかもしれたせん。 checked.Addはbits.Addよりも明確です。

@minux笊号付きチェック挔算を考えおいたので、オヌバヌフロヌしたした。

@griesemer reベヌス10 Len 理にかなっおいたす

必芁に応じお、チェック挔算甚のCLを送信できたす。 @jimmyfrascheが別のパッケヌゞ名で䜜成するずいうアむデアが

Add / sub / mulはbitsに属する堎合ず属さない堎合がありたすが、これらの操䜜の甚途はチェックされた数孊だけではありたせん。 より䞀般的には、これらは「ワむド」な算術挔算であるず蚀えたす。 add / subの堎合、1ビットのキャリヌ/オヌバヌフロヌの結果ずオヌバヌフロヌのブヌルむンゞケヌタヌの間にほずんど違いはありたせんが、これらをチェヌン可胜にするために、add-with-carryずsubtract-with-borrowも提䟛する必芁がありたす。 たた、ワむドmulの堎合、オヌバヌフロヌよりも远加の結果にはるかに倚くの情報がありたす。

チェックされた/ワむドな算術挔算を芚えおおくこずをお勧めしたすが、ラりンド2のためにそれらを残しおおきたしょう。

「このパッケヌゞを䜿甚するすべおの人は、PopCountが䜕をするかを正確に知っおいたす」

私は以前にその機胜を䜿甚したこずがあり、どういうわけかPopCount名に慣れおいたせんでしたただし、「pop」を䜿甚するHacker's Delightから実装をピンチしたず確信しおいるため、䜿甚する必芁がありたす。

私はパヌティヌに参加しおいるこずは知っおいたすが、「OnesCount」は私にはかなり明癜に思えたす。ドキュメントのコメントに「PopCount」ずいう単語が蚘茉されおいれば、それを探しおいる人はずにかくそれを芋぀けるでしょう。

チェック/ワむド挔算に関連6815。 しかし、はい、1぀を取りたしょう

@griesemerは曞いた

基数2Len関数は、ほがlog2ですが、本質的にはビットカりント関数です。 10進数のLen関数は、実際には察数関数です。 それが有甚であるこずは吊定できたせんが、このパッケヌゞにはあたり適切ではないようです。

昚幎10月に「10進数の長さ」の問題に察するいく぀かのアプロヌチを比范するためのベンチマヌクを䜜成したした。これをた。

提案ずしお受け入れられたした。 おそらく前進するためのマむナヌな調敎があるでしょう、そしおそれは問題ありたせん。

@rogpeppe  PopCountをOnesCountたした。これは、4぀の芪指を立おたためです PopCountを䜿甚するずいう私の提案のように。 ドキュメント文字列で「人口数」ず呌ばれたす。

@rscごずに、チェック枈み/ワむド算術挔算は今のずころ陀倖したす。

たた、 @ rscごずに、すべおのカりント関数はint倀を返したす。䜿いやすくするためにそしお19113に泚目しお、ロヌテヌションカりントにint倀を䜿甚したす。

単にN - LeadingZerosNであるにもかかわらず、 LenN関数を残したした。 しかし、 RotateLeft / Rightも同様の察称性があり、䞡方がありたす。

TrailingZeroesわずかに高速な実装を远加し、テストを完了したした。

この時点で、䜿甚可胜な最初の実装があるず思いたす。 https://go-review.googlesource.com/36315のコヌド、特にAPIを確認しおください。 私たち党員が満足しおいるなら、これを提出しおもらいたいです。

次のステップ

  • より高速な実装プラむマリ
  • 機胜の远加セカンダリ

新しいパッケヌゞを蚭蚈しおいたす

@minuxあなたは新しい数孊/ビッグを意味したすか どこかでプロセスをたどるこずは可胜ですか

@TuomLarsen  @minuxは「新しいパッケヌゞ」で数孊/ビットを参照したした。 圌は、数孊/ビットが䜿甚される堎合ずしお、数孊/ビッグに぀いお蚀及したした。 将来的には、コメントをより具䜓的にしおください。そうすれば、参照しおいる内容を怜玢しお掚枬する必芁がなくなりたす。ありがずうございたす。

CL https://golang.org/cl/37140は、この問題に぀いお蚀及しおいたす。

Go 1.9の数孊/ビットでコンパむラ支揎の組み蟌み化が発生したすか

@cespare到達するかどうかによっお異なりたす@khr。 それずは別に、プラットフォヌムに䟝存しない適切な実装が必芁です。 math / bigを完党にmath / bitsの䜿甚に移行したくない理由の1぀は、珟圚、math / bigにプラットフォヌム固有のアセンブリがあり、より高速であるためです。

私のプレヌトでは、少なくずもアヌチに぀いおは、すでに組み蟌み関数を実行しおいたす
386、amd64、arm、arm64、s390x、mips、おそらくppc64。

2017幎2月17日金曜日12:54 PM、Robert Griesemer < [email protected]

曞きたした

@cespare https://github.com/cespare到達するかどうかによっお異なり
@khr https://github.com/khr 。 それずは別に、
適切なプラットフォヌムに䟝存しない実装。 私たちがしない理由の1぀
æ•°å­Š/ビッグを完党に数孊/ビットの䜿甚に移行したいのは、珟圚私たちが
math / bigにプラットフォヌム固有のアセンブリがありたす。これはより高速です。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/golang/go/issues/18616#issuecomment-280763679 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/AGkgIIb8v1X5Cr-ljDgf8tQtT4Dg2MGiks5rdgkegaJpZM4Lg5zU
。

x86-64で人口カりントを実装する最速の方法に関するこの蚘事は圹立぀かもしれたせん手䜜業でコヌディングされたアセンブリは、速床ず単玔さにおいお組み蟌み関数を打ち負かしたす

CL https://golang.org/cl/38155は、この問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/38166はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/38311はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/38320はこの問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/38323はこの問題に぀いお蚀及しおいたす。

もう少し議論

自分

math / bits.RotateLeftは珟圚、匕数がれロ未満の堎合にパニックになるように定矩されおいたす。
匕数がれロ未満の堎合に右回転を行うようにRotateLeftを定矩するように倉曎したいず思いたす。

このような基本的なルヌチンを持぀こずは、䞍必芁に厳しいように思われたす。 負の量の回転は、れロ陀算パニックを起こすではなく、ワヌドサむズパニックを起こさないよりも倧きいシフトに類䌌しおいるず私は䞻匵したす。 れロ陀算は、代わりに返す合理的な結果がないため、実際にはパニックに陥る必芁がありたす。 負の量で回転するず、完党に明確に定矩された結果が返されたす。

RotateLeftずRotateRightは、もう䞀方ず䞀緒に実装できるようになりたしたが、別々の関数ずしお保持する必芁があるず思いたす。 暙準的な䜿甚法は、非負の匕数を䜿甚したす。

ここで䜕かをする堎合は、フリヌズする必芁がありたす。 1.9がリリヌスされるず、考えを倉えるこずはできたせん。

ロブ

このようなものが本圓に必芁な堎合は、回転ずいう1぀の関数がありたす。この関数は、巊が正、右が負になりたす。

自分

問題は
ビット.Rotatex、-5

このコヌドを読んだずきに、最終的に巊に回転するのか右に回転するのかは明確ではありたせん。
bits.RotateRight5
æ•°å­Š/ビットに2倍のRotate *関数があるこずを意味する堎合でも、はるかに明確です。

マむケル・ゞョヌンズ

眲名された回転ずは、コヌド内でゞャンプするこずを意味したすね。 残念なようです。

自分

いいえ、提案されたセマンティクスを䜿甚するず、実装は実際には簡単になりたす。 䞋䜍6ビット64ビット回転の堎合をマスクするず、正垞に機胜したす。

関数の数が半分であり、パニックや条件分岐さえもなしにすべおの堎合に非垞に効率的に実行できるため、笊号付き匕数を䜿甚した単䞀のRotateを奜みたす。

ずにかく回転は専門的な機胜なので、それを䜿甚する人々は、正の匕数が巊にシフトし、負の匕数が右にシフトするこずを芚えおおくように求められるこずを確実に快適にしたす。

い぀でも差を分割しお、笊号付き匕数でRotateLeftのみを提䟛できたす。 これにより、方向に䟿利なニヌモニックが提䟛されたすが、機胜の重耇は回避されたす。

@bcmills @robpike https://github.com/golang/go/issues/18616#issuecomment -275598092から始たり、いく぀かのコメントを続けるこの正確なトピックに関する以前のディスカッションも参照しお

@josharianコメントを芋たこずがありたすが、それでも自分のバヌゞョンを奜みたす。 これは氞遠に自転車に乗るこずができたすが、私は実装が簡単で、定矩が簡単で、理解が簡単で、文曞化が簡単になろうずしおいたす。 笊号付き匕数を持぀単䞀のRotate関数は、笊号を定矩する必芁があるこずを陀いお、すべおを満たすず思いたすが、巊が正であるずいうこずは、rotate呜什を䜿甚できる人なら誰でも盎感的に理解できるはずです。

しかし、その巊が正であるずいうこずは、回転呜什を䜿甚できる人なら誰でも盎感的に理解できるはずです。

私は自分が回転呜什を䜿甚できるず考えるのが奜きで、私の盎感は「そうねえ、なぜこれがどの方向であるかを蚀わないのですかおそらく残っおいたすが、確実にドキュメント必芁がありたす。」 正の方向を遞択する堎合は巊回転になるのは盎感的ですが、䜕かが明らかに正しい答えになるにははるかに高いしきい倀があるため、すべおの通話サむトで、䜕も蚀わずに回転しおいる方向が明確になりたす。それ。

読みやすさに関しおは、 time.Duration APIに沿ったものはどうでしょうか。

const RotateRight = -1

bits.Rotate(x, 5 * RotateRight)

倚分ビットによっお定矩された定数たたは倚分読者のための緎習呌び出しサむト

@aclementsしたがっお、匕数の笊号だけが異なる、同じ機胜を持぀2぀のN型の関数になりたす。 今ではAddずSubでそれを蚱容しおいたすが、それが私が考えるこずができる唯䞀の䟋です。

数倀軞では、正の数が右に増加するため、正の数の堎合、笊号で定矩された方向の回転/シフトによっおビットが右に移動するず予想されたす。

それが[文曞化された]反察になるかどうかは問題ありたせんが、私はそれを盎感的ずは蚀いたせん。

@cznicビットは右から巊に曞かれおいたすが

たた、双方向で機胜させる堎合は、 Rotate https://github.com/golang/go/issues/18616#issuecomment-275016583だけを支持したす。

方向性に぀いお@aclementsの懞念に反論ずしお提䟛RotateLeft暩利を回転させるこずも、誀った安心感を提䟛するこずができたすも動䜜するこずそれは蚀う、」 RotateLeftので、確かにそれが回転しおいたせん右"。 ぀たり、 RotateLeftず衚瀺されおいる堎合は、他に䜕もしたせん。

たた、 bits.Rotateは、実際にはスペシャリストコヌドでのみ䜿甚されたす。 これは、倚くのプログラマヌが䜿甚する機胜ではありたせん。 本圓にそれを必芁ずするナヌザヌは、回転の察称性を理解するでしょう。

@nathany

ビットは右から巊に曞かれおいたすが

ビットは単なる2進数です。 基数の桁数は巊から右に曞き蟌たれたす。すべおではないにしおも、ほずんどの右から巊の曞蚘䜓系でも同様です。 123は、癟二十䞉ではなく、癟二十䞉です。

桁の被乗数の环乗が右に枛少するこずは別のこずです。

繰り返しになりたすが、私は方向性を気にしたせん。盎感的な方向性は個人的な想像力の問題であるずいうだけです。

私は回転が奜きです。 私の芋解では、最䞋䜍ビットは盎感的に十分です。

開発者の半数が芚えおいないこずをするのではなく、RotateLeftずRotateRightの䞡方を維持しおください。 ただし、負の数を凊理するのは問題ないようです。

開発者の99は回転呜什をプログラムするこずは決しおないので、明確な方向の必芁性はせいぜい匱いです。 1回の呌び出しで十分です。

この議論を呌び起こした問題は、䞡方を持぀には、負の倀が問題ないかどうか、そうでない堎合はどうするかに぀いお議論する必芁があるずいうこずです。 1぀しかないこずで、その議論党䜓が倱われたす。 すっきりずしたデザむンです。

クリヌンなデザむンに぀いおの議論には倚少共感したすが、それを実珟するために、同じ実装を維持しながら「RotateRight」から「Right」を削陀しなければならないのは奇劙に思えたす。 実際には、質問に答えるように芋える唯䞀の方法は、名前が提起する質問によっお、それを芋る人々にドキュメントを読たせるずいうこずです。
結局のずころ、それは明確な方向ず負の倀の明確な振る舞いの問題です。 䞀般的なケヌスでは、負の倀はおそらくそれほど問題にならないはずです。

私が蚀っおいるのは、Rotateはすべおの人に1぀の質問を提起し、ドキュメントを通じお間接的にそれに答えるこずです。
RotateRightは、ドキュメントを気にかけおいる堎合にそれを読むこずができるそしお読むべきである非垞に少数の人々に1぀の質問を提起したす。

䞀方、Rotateは、おそらく人々がif n < 0 { RotateLeft(...) } else { RotateRight(...) }曞くのを劚げるでしょう。

@ golang / proposal-reviewはこれに぀いお議論し、結局1぀の関数しか持たないこずになりたしたが、呌び出しサむトでさらに明確にするために、 RotateだけでなくRotateLeftずいう名前を付けたした。 負の数は右に回転し、ドキュメントでこれが明確になりたす。

CL https://golang.org/cl/40394は、この問題に぀いお蚀及しおいたす。

CLhttps  //golang.org/cl/41630はこの問題に぀いお蚀及しおいたす。

元の提案ずいく぀かの远加機胜は、この時点で蚭蚈および実装されおいたす。 時間の経過ずずもにこのラむブラリに远加する可胜性がありたすが、珟時点ではかなり「完党」なようです。

最も泚目すべきは、次の機胜を決定たたは実装しおいないこずです。

  • add / mul / etcがオヌバヌフロヌするかどうかをテストしたす
  • 着信キャリヌを受け入れ、結果ずキャリヌたたはそれ以䞊の単語を生成するadd / mul / etcを実装する関数を提䟛したす

個人的には、それらが「ビット」パッケヌゞに属しおいるずは確信しおいたせんおそらくテストはそうです。 倚粟床のadd / sub / mulを実装する関数を䜿甚するず、䞀郚の数孊/ビッグカヌネルの玔粋なGo実装が可胜になりたすが、粒床が正しいずは思いたせん。ベクトルで動䜜する最適化されたカヌネルず最倧倀が必芁です。それらのカヌネルのパフォヌマンス。 add / sub / mulの「組み蟌み関数」だけに䟝存するGoコヌドでそれを達成できるずは思いたせん。

したがっお、今のずころ、倧きな異議がない限り、この問題を「完了」ずしおクロヌズしたいず思いたす。 これを閉じるこずに、来週かそこらで声を䞊げおください。

私はそれらの線に沿っお関数を远加するこずに賛成です。

集合的な機胜をよりよく反映する名前を付ける以倖の理由がない限り、それらは独自のパッケヌゞに属しおいるず匷く信じおいたす。

+1この問題を閉じるずきずheartこれたでに行われた䜜業に぀いお。

異議がなかったので締めくくりたす。

これはAPIに関する将来の決定に察するコメントです、私はこの特定のものが蚭定されおいるこずを理解しおいたす。

Rotateは専門的な機胜です。 LTRたたはRTLは、コンテキストが䞎えられた堎合にのみ関連したす。 @aclementsは、有効な質問を提起したしたが、有効な拡匵ポむントではありたせん。 圌の質問は、「敎数が増加するのず同じように、RTLです」ず答えられた可胜性がありたす。 簡単ですよね

しかし、代わりに、賢さが続きたす。

「スペシャリスト機胜」ずは、ずおも単玔なこずで、すぐに华䞋された可胜性がありたす。 コヌドサンプルを考えるず、コヌド行に遭遇する前であっおも、発生する回転ず方向をすでに理解しおいる可胜性がありたす。 このようなコヌドの前には、通垞、ASCIIの説明甚のドキュメントがそのたたありたす。

粟神的に混乱しおいるのは、GoがAPIの芳点からビットを解釈する暙準的な方法ずしおRTLを単に遞択できたずいうこずではなく、最初に1.9の倉曎をプルアップし、察応するものがないRotateLeftず、負のストラむド。 これは、1.9に䞊陞するこずは非垞に残念なこずですが、委員䌚のような気の遠くなるような決定です。

私は将来のために䜿甚の文脈に固執するこずを願うだけです。 これらすべおは、「なぜRotateLeftに察応するものを提䟛しないのか、なぜネガティブなストラむドでパニックになったり、ストラむドのintずuintに぀いお議論したりするのか」などの質問で自明であるはずです。 結局のずころ、「スペシャリスト機胜」の意味は、賢くないずいう理由で簡単に华䞋されたず思うからです。

APIの正圓化の巧劙さを避けたしょう。 これは、この1.9アップデヌトに瀺されおいたす。

倉曎https://golang.org/cl/90835はこの問題に蚀及しおいたす cmd/compile: arm64 intrinsics for math/bits.OnesCount

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡