[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2ch.scのread.cgiへ]
Update time : 08/28 06:40 / Filesize : 306 KB / Number-of Response : 1032
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C++相談室 part162



1 名前:sage [2022/10/31(月) 14:29:35.57 ID:J5sgTSch0.net]
!extend:checked:vvvvv:1000:512
!extend:checked:vvvvv:1000:512
↑同じ内容を3行貼り付けること

次スレは>>980が立てること
無理なら細かく安価指定

※前スレ
C++相談室 part161
https://mevius.5ch.net/test/read.cgi/tech/1653135809/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured

477 名前:デフォルトの名無しさん [2022/12/02(金) 21:26:41.80 ID:OAAJQcGw0.net]
Pythonで経過時刻を測る場合、以下のような方法を使いますが
C++でPythonと同じ計測手法を使うにはどうしたら良いですか?

import time
startTime = time.time()
nowTime = time.time() - startTime
print(nowTime)

478 名前:デフォルトの名無しさん mailto:sage [2022/12/02(金) 21:29:14.69 ID:jlYcEgfQp.net]
OSに依るからなぁ

479 名前:デフォルトの名無しさん mailto:sage [2022/12/02(金) 21:30:36.64 ID:RyVNohK20.net]
なんか面倒くさい<chrono>でがんばる

480 名前:デフォルトの名無しさん [2022/12/02(金) 21:33:56.38 ID:OAAJQcGw0.net]
>>465
Windows限定で使用する予定です。

481 名前:デフォルトの名無しさん mailto:sage [2022/12/02(金) 21:36:34.16 ID:m95xgUV8M.net]
boost::timer::cpu_timerとか?

482 名前:デフォルトの名無しさん mailto:sage [2022/12/02(金) 21:41:06.49 ID:110d0P8E0.net]
>>467
C++ 関係ないけどパフォーマンスカウンターでggrと良いんでは?

483 名前:デフォルトの名無しさん mailto:sage [2022/12/02(金) 21:45:16.03 ID:FW7hEQSS0.net]
std::time とか?

484 名前:デフォルトの名無しさん mailto:sage [2022/12/02(金) 21:48:04.00 ID:0Xa+fucj0.net]
>>460
全然関係ないんだが
鼻で笑えないのか?

485 名前:デフォルトの名無しさん mailto:sage [2022/12/02(金) 22:24:02.82 ID:eNwFIhhK0.net]
OpenMPの一部であるomp_get_wtime()がじつはパフォーマンスカウンタと同じ精度……

ポータブル……



486 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 00:29:43.64 ID:dPKr1JJoM.net]
>>460
keyが10文字の文字列の場合だと大体そんなくらい行くであろうと予想したが、
もうちょっと速い場合もあるかも知れない。

487 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 01:21:25.79 ID:dPKr1JJoM.net]
>>463
要は、JSなどで配列とHash法が同じ書き方が出来るが故に、Hash法が
「配列」みたいには高速ではないということを知らない人が居るのではないかと
思って書いただけ。
x86系の場合、配列は、要素サイズが1,2,4,8の時はa[i]がマシン語の1命令で
1クロック、それ以外の一般サイズだと2命令で、今のCPUだと、
4クロック〜20クロック程度。
ハッシュ法だと、keyが10文字の文字列の場合で、最低でも、まあ、100クロック位
はかかると見ておいたほうがいい。最高だと上限は無いが、まあ、数千〜数万
クロック程度になると考えた方がいい。
これは、マシン語まで見たときの常識的な間隔。

488 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 02:42:14.20 ID:ngGiofKr0.net]
マシン語の1命令で1クロックって、いつの何のCPUだ

489 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 08:52:01.00 ID:+FzzA9JIM.net]
0 以上 64 以下の整数 n に対して 2^n-1 (ビットごとの排他的 OR 演算子ではなく累乗の意味 2**n-1 です)を std::uint64_t 型で返す関数って場合分け無しでスッキリ書けませんかね?

490 名前:はちみつ餃子 mailto:sage [2022/12/03(土) 09:18:16.49 ID:riW5om/o0.net]
>>476
こうかな?
std::uint64_t(-1) >> (64-n)

491 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 09:23:14.36 ID:qMCuKdke0.net]
std::uint64_tの加算オーバーフロー時の挙動がunsigned intと同様にwrap aroundなんなら普通に
std::uint64_t foo(const int n) { return ((std::int64_t)1 << n) - (std::int64_t)1; }
で良くねconstexpr的な何かとかでマズい?

492 名前:はちみつ餃子 mailto:sage [2022/12/03(土) 09:26:37.99 ID:riW5om/o0.net]
すまぬ。 >>477 だと n が 0 のときは未定義なのでそれだけ場合分けが必要になってしまうな。
だからといって (std::uint64_t(1) << n) - 1 だと 64 のときが駄目だし、
場合分け無しという条件だと思ったよりめんどいかも?

493 名前:デフォルトの名無しさん (ワッチョイ 8a28-BV3Z) mailto:sage [2022/12/03(土) 09:43:52.56 ID:qMCuKdke0.net]
違った加算オーバーフローの話やなかったorz

シフト演算については
If E1 has an unsigned
type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable
in the result type.
E1 が符号なし型を持つ場合、結果の値は、E1 * 2E2 の、結果の型で表現可能な最大値より 1 大きい値を法とする剰余となる
なので言語規格上は (uint64_t)1 << 64は合法なはず……

494 名前:デフォルトの名無しさん (ワッチョイ 8a28-BV3Z) mailto:sage [2022/12/03(土) 09:49:24.58 ID:qMCuKdke0.net]
訂正orz
誤: 2E2
正: 2**E2 (2のE2乗)

符号付きの型はオーバーフローで例外を発生するアーキテクチャーがあるから
表現できるビット数からあふれるコーディングは未定義動作か何かやが
符号無し型はモジュロ演算になるから溢れてもおk
と言う印象(記憶モード
※ 個人の感想です

495 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv) mailto:sage [2022/12/03(土) 10:04:27.89 ID:riW5om/o0.net]
>>478
> https://timsong-cpp.github.io/cppwp/n3337/expr.shift
> The behavior is undefined if the right operand is negative, or greater than
> or equal to the length in bits of the promoted left operand.

シフト演算子では右オペランドが (昇格済みの) 左オペランドの幅以上の値だったときは未定義。



496 名前:はちみつ餃子 mailto:sage [2022/12/03(土) 10:15:30.26 ID:riW5om/o0.net]
std::bitset を経由すれば大丈夫だということを発見した。

std::uint64_t((compl std::bitset<64>(0)>>(64-n)).to_ullong())

これを「スッキリ」といえるかどうかは微妙なところかもしれぬ……。

497 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 11:26:23.20 ID:qMCuKdke0.net]
>>482
わかりた
ではこう汁、
 指数 n == (n/2) + (n/2) + (n & 1) ※ 除算は結果の小数以下切り捨て
ので
 2**n - 1 = 2**((n/2) + (n/2) + (n & 1)) - 1
 = 2**(n/2) * 2**(n/2) * 2**(n&1) - 1
よって
 std::uint64_t foo(const int n) {
  const std::int64_t x = (std::uint64_t)1 << (n / 2);
  return (x * x * ((std::uint64_t)1 << (n & 1)) - (std::int64_t)1;
 }
でだいたいおk、

498 名前:デフォルトの名無しさん [2022/12/03(土) 11:32:11.79 ID:D7LggL4j0.net]
n?1ull<<(n-1):0

499 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 11:45:55.06 ID:Xj+KmoE3d.net]
(1llu << (n>>1) << ((n+1)>>1)) - 1

500 名前:デフォルトの名無しさん (スップ Sd02-HF5l) mailto:sage [2022/12/03(土) 11:53:09.20 ID:Xj+KmoE3d.net]
constexpr uint64_t TABLE[65] = {
0x0000000000000000,
0x0000000000000001,
0x0000000000000003,
...
0xffffffffffffffff
};

return TABLE[n];

501 名前:デフォルトの名無しさん (スップ Sd02-HF5l) mailto:sage [2022/12/03(土) 11:57:41.15 ID:Xj+KmoE3d.net]
x86-64の場合
shl reg, clのclは下位6bitしか見ないから
1ull<<nが正しく動いた場合マシン語レベルでは分岐してることになる

502 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 21:09:42.26 ID:WYd/d9iJ0.net]
>>457
今さら知らなかったとは言えなくて
元々知ってた別人になるしかないもんな

それほどまでに恥ずかしいことだからw

# さあ、おまえが別人かどうかの判断は衆目に任せよう

503 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 23:32:15.77 ID:qMCuKdke0.net]
(ID:Xj+KmoE3d が天才すぎてつらいので埋め)

504 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 23:46:07.24 ID:mCv82Mp+M.net]
ところで、C++でも、Javab磴#でも、メモャ梶[不足例外を封竭ォしない風潮bノなっている
ようです。それは、メモリー不足が起きる可能性があるところの、
文字列合成やコンテナ要素追加が簡単に書けるようになった反面、
その全ての箇所でエラー処理をするのはめんどくさすぎるという
事情から来ていると思います。
しかし、テキスとエディタなどで、一文字や一行追加した時にメモリーが確保できない
場合に、「メモリーが一杯です」などと表示することはMS-DOSならよくあったことで、
そのような場合にメモリー不足例外を補足する事は原理的には可能です。
いまや、そのような場合のメモリー不足はほぼ起き得なくなってますが、エラーを感知
しないで本当に良いと思われますか?
もっと進めれば、メモリー不足例外は、商用アプリでも「完全無視」を決め込んでも良いと
思われますか?

505 名前:デフォルトの名無しさん mailto:sage [2022/12/03(土) 23:47:44.27 ID:mCv82Mp+M.net]
>>491
携帯SIMを使っているので電波にエラーが生じたらしいです:
誤:ところで、C++でも、Javab磴#でも、メモャ梶[不足例外を封竭ォしない風潮bノなっている
正:ところで、C++でも、JavaやC#でも、メモリ不足例外を補足しない風潮になっている



506 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:02:09.11 ID:r/mQBEYb0.net]
>エラーを感知 しないで本当に良いと思われますか?
良い
どうせメモリ不足になったら有効なことはほとんど何もできない

ただしそのかわり処理の不意の中断から絶対に保護すべきリソースとか絶対動かしたままにしてはいけない処理は
例外安全なクラスで管理して確実にクローズ処理せねばならない

jこれはメモリ不足の状況でも同じで、そういうのはヒープを使わないで書くのが最善やが、
内部でヒープを使うライブラリに依存している等でヒープをどうしても使わざるおえないの場合は
事前malloc()→例外捕捉時に解放、というテクが昔からあっる

507 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:02:21.62 ID:BcAMllhiM.net]
スタック的な(?)コンテナで、pop_back()メソッドは戻り値が void型で、
つまり、pop したデータを返しませんが、BJ. stroustrup氏によれば、
それもreturn文で要素をコピー(?)する際に、メモリー不足例外が起きる
可能性考慮したとのことです。
どうしてmoveじゃ駄目なのかもし分かりませんでしたが。

508 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:04:34.95 ID:BcAMllhiM.net]
>>493
>どうせメモリ不足になったら有効なことはほとんど何もできない
MS-DOSの時、テキストエディタなどではメモリー不足になると、
ちゃんとメッセージを出して、なおかつ、その後もメモリーが無い割には
安定動作してました。

509 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:11:51.06 ID:S/+N28Tr0.net]
>>489
まだ粘着してるのかよ...
本人だと思いたいんならそれでいいんじゃね?
おれが本人かどうかに関わらずお前が>>231で本人が謝ってるのにしつこく>>227に粘着するクズであることは確定したし
まあもうそうするしかないんだろうけどw

510 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:17:03.45 ID:r/mQBEYb0.net]
>>494
x = queue.pop();
というのを許

511 名前:すキューの仕様だと
とキュー上のx'とそのコピーxが同時に存在するタイミングが一瞬生じてメモリ不足になりかねないという>>494の懸念の他に、
コピコンが呼ばれる時間の無駄がある

xにムーブコンストラが定義してありqueue.pop()をムーブ対応に設計したとしても
ムーブコンストラクタが呼ばれる時間の無駄は相変わらず存在する

最も効率が良いのはpop()するタイミングまでキュー上のオブジェクトの参照を返し、
pop()するタイミングではキュー上のオブジェクトの破棄のみ行うという現行のインターフェース、
[]
[ここ壊れてます]

512 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:20:25.80 ID:r/mQBEYb0.net]
>>495
おま環、

513 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:31:29.29 ID:BcAMllhiM.net]
>>497
>x = queue.pop();
>というのを許すキューの仕様だと
>とキュー上のx'とそのコピーxが同時に存在するタイミングが一瞬生じてメモリ不足になりかねないという
よく分かりません。できればもっと詳しくお願いできませんか。
キュー上の x' を x に move すれば駄目なのでしょうか?

>xにムーブコンストラが定義してありqueue.pop()をムーブ対応に設計したとしても
>ムーブコンストラクタが呼ばれる時間の無駄は相変わらず存在する
>最も効率が良いのはpop()するタイミングまでキュー上のオブジェクトの参照を返し、
>pop()するタイミングではキュー上のオブジェクトの破棄のみ行うという現行のインターフェース、

なるほど、参照で返すのは効率がよいのは分かりますが、stroustrup氏によれば、moveは
速いと主張されているわけです。
私はmoveより参照の方が効率が良いと常々思っておりましたが。
彼はmoveが大好きなはずなのですが。

514 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:37:44.43 ID:r/mQBEYb0.net]
>>499
>キュー上の x' を x に move すれば駄目なのでしょうか?
ムーブコンストラが呼ばれる時間の無駄がある(2回目

515 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:41:37.02 ID:BcAMllhiM.net]
>>500
>ムーブコンストラが呼ばれる時間の無駄がある(2回目
なるほど、ならば、スタックポインタだけ元に戻して、値は捨ててしまう
バージョンの pop を用意すれば良いだけでは無いですか、今みたいに。



516 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:43:51.82 ID:BcAMllhiM.net]
>>501
Strousstrup氏によると、メモリー不足になって例外が生じた場合の
対処が難しい、みたいなことを言っていたと思います。
しかし、moveコンストラクタ/代入を使った場合にはメモリー不足も生じませんし、
moveコンストラクタ/代入は例外を生じさせてはいけない、と彼自身は
普段から何度も言及していたと思うんです。

517 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 00:49:09.96 ID:BcAMllhiM.net]
>>502
仮にstackの要素クラスにコピーコンストラクタしかない場合は、メモリー不足が
生じてstd::bad_alloc 例外がthrowされる場合があるとは思いますが、難しい
とは言ってもそれが生じた場合に対処が全く出来ないとは思えません。
あるとすれば、要素がmoveコンストラクタを持っている場合でも、
try catch ブロックを書くことで、オーバーヘッドが生じる
場合があることを彼は恐れていたのでしょうか。

518 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 01:11:37.29 ID:r/mQBEYb0.net]
>>501
ムーブしたかったらqueue.front()が返す参照でキュー上のx'をxか何かにムーブするだけ(※1)で良くね↑?
 x = std::move(queue.front());
 queue.pop_front();

※1: xやx'のクラスにムーブコンストラの定義は必要

>スタックポインタだけ元に戻して、値は捨ててしまう
>バージョンの pop を用意すれば良いだけでは無いですか、今みたいに。
ムーブするpop_front()と、デストラクタを呼ぶだけの今のpop_front()がどこが同じなのかkwsk、

519 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 01:20:22.79 ID:qWdYVkpM0.net]
標準例外安全規則と強い保証がどうのこうの

520 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 01:33:30.77 ID:BcAMllhiM.net]
>>504
マシン語の「pop命令」は伝統的に、スタックポインタを戻すことと、値を読み出すことを
同時に行っていました。
C++の設計では、値の読み出しと、スタックポインタを戻すことが分かれており、命名も
変なのです。
つまり、2つの事を合体させて行なうのが伝統的に「pop」であった伝統や習慣とは
異なる命名をC++はとってしまっているので、心理的に受け入れがたくなっているわけです。

521 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 01:50:30.99 ID:BcAMllhiM.net]
>>506
例えば、Rustのpopは、ちゃんとマシン語の伝統と同じく、
戻り値が読み出された値になっていて、かつ、スタックポインタも戻ります。
C++のはどうしてこうなったのか、と思うように伝統を破ってます。
伝統を知らない人が作ったかのように。

522 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 02:00:59.03 ID:6yRfEQxP0.net]


523 名前:怩ニ値返却を同時にやるpop()が例外安全的に糞だって話はExceptionalC++に1章割いて載ってたはず
今手元にないけど
[]
[ここ壊れてます]

524 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 02:03:07.32 ID:qWdYVkpM0.net]
C++だけでなく、いくつかの言語で、配列にアクセスするのに
push() pop() といった名前の関数があるから、その流れじゃないの
対象はあくまでも配列であって、cpu のスタックとは色々異なるわけだし
そこでどこまでスタックぽく扱うかは、言語の仕様というか設計者のお好みによるというかw

525 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 02:10:09.58 ID:BcAMllhiM.net]
>>508
その辺の話をここに書いていただけると幸いです。



526 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 02:22:20.52 ID:BcAMllhiM.net]
>>510
自己レスですが、
https://stackoverflow.com/questions/25035691/why-doesnt-stdqueuepop-return-value
これですかね。
[Q] Why doesn't std::queue::pop return value.?
[A]
・・・
So, whats the difference, pop function could have done the same thing.

It could indeed have done the same thing. The reason it didn't, is because a pop that returned the popped element is unsafe in the presence of exceptions (having to return by value and thus creating a copy).

Consider this scenario (with a naive/made up pop implementation, to ilustrate my point):

template<class T>
class queue {
T* elements;
std::size_t top_position;
// stuff here
T pop()
{
auto x = elements[top_position];
// TODO: call destructor for elements[top_position] here
--top_position; // alter queue state here
return x; // calls T(const T&) which may throw
}
If the copy constructor of T throws on return, you have already altered the state of the queue (top_position in my naive implementation) and the element is removed from the queue (and not returned). For all intents and purposes (no matter how you catch the exception in client code) the element at the top of the queue is lost.

This implementation is also inefficient in the case when you do not need the popped value (i.e. it creates a copy of the element that nobody will use).

This can be implemented safely and efficiently, with two separate operations (void pop and const T& front()).

527 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 10:36:33.77 ID:9l16UriTd.net]
MMミネヲからはperlerの臭いがする

528 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 11:36:02.70 ID:flilPTWf0.net]
0〜255しか格納されないことが保証されている変数aがあって
その変数の値を以下のイメージのように判定する効率的なやり方はないでしょうか
a == {8, 9, 12}
aが{ }内のいずれかの値に該当しているかどうかを判定したいです
{ }はあらかじめ定数でもよいです

529 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 11:40:31.47 ID:RAGda7mP0.net]
set<int> unko { 8, 9, 12};
if(unko.find(a) != unko.end()) goto hell;

530 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 11:44:07.96 ID:AOlAqVGT0.net]
ルックアップテーブル

531 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 11:54:47.89 ID:flilPTWf0.net]
>>514
>>515
ありがとうございます
アドバイスから、bool型の配列を用意しておいてaを添え字にすればよいと思いました

532 名前:デフォルトの名無しさん [2022/12/04(日) 12:07:00.75 ID:JyCGAu5J0.net]
std::bitset<256>はどうですか?

533 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 16:18:10.81 ID:RV2/jwt7M.net]
>>513
BYTE qqq[256] = {};
void init() {
 qqq[8]=1;
 qqq[9]=1;
 qqq[12]=1;
}

inline BOOL IsInQqq(int a)
{
 return qqq[a];
}

534 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 16:45:55.42 ID:RAGda7mP0.net]
inline bool is_8_9_12(uint8_t a)
{
return 0b0001'0011'0000'0000 & 1 << a;
}

535 名前:513 mailto:sage [2022/12/04(日) 17:30:39.25 ID:flilPTWf0.net]
いろいろ例をありがとうございます
pascalからの移行で集合型をどうにか再現できないかと試している中での質問でした
pascalの集合型なら[8, 9, 12](8, 9, 12は一例で、本来は任意の値を指定したい)を
直接使えて便利なので多用していました

アドバイスのおかげで比較は近いことを再現できましたが、
それとは別のケースで[8, 9, 12]を直接関数の引数で指定する方法を探しています
引数で指定する際の値の範囲は0〜31を超えることはなさそうなので
ビットを立てた整数を返す、可変長引数を取る関数を作れば良さそうだと思いました



536 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 17:37:18.99 ID:S/+N28Tr0.net]
>>520
> 集合型をどうにか再現
それが>>517じゃねーの?

> ビットを立てた整数を返す、可変長引数を取る関数を作れば良さそうだと思いました
そういう関数を作れば良さそうだと思います

537 名前:513 (ワッチョイ 3602-WJTY) mailto:sage [2022/12/04(日) 17:49:59.78 ID:flilPTWf0.net]
std::bitset<256>も試してみましたが
{8, 9, 12} こういった形式単独で使えるやり方はないかと調べていました

538 名前:はちみつ餃子 mailto:sage [2022/12/04(日) 18:04:56.88 ID:YO7rrhiC0.net]
std::bitset は unsigned long long を受け取るコンストラクタには constexpr が付いてるので
それより小さいビット数の bitset についてならコンパイル時に計算してしまうことも出来る。

539 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv) mailto:sage [2022/12/04(日) 18:39:41.91 ID:YO7rrhiC0.net]
たぶんやりたいのはこういう感じかな。 (想定は C++17 以上)

#include <bitset>
#include <cassert>
#include <climits>
#include <cstddef>
#include <type_traits>

template <std::size_t N = sizeof(unsigned long long int) * CHAR_BIT, class... T>
constexpr std::enable_if_t<(sizeof...(T) <= N), std::bitset<N>>
make_flagged_bitset(T... args) noexcept {
return std::bitset<N>(((1ULL << args) | ...));
}

// 使用例
int main(void) {
constexpr auto table = make_flagged_bitset(8, 9, 12);
// セットしてないところは偽値
assert(table[0] == false);
assert(table[1] == false);
assert(table[10] == false);
assert(table[20] == false);
// セットしているところは真値
assert(table[8] == true);
assert(table[9] == true);
assert(table[12] == true);
}

540 名前:513 mailto:sage [2022/12/04(日) 19:19:16.77 ID:flilPTWf0.net]
>>524
やりたいことのイメージにすごく近いです
思いもつかない難しい構文で勉強になります
内容を理解して使わせていただきます
ありがとうございました

541 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 19:57:57.00 ID:/CRfCGQ0a.net]
定数でいいならマクロでやるとか
#include <cstdio>
#define _(i) (1 << i)
int main() {
int b = _(8) | _(9) | _(12);
for (int i = 0; i <= 12; i++) {
printf("%d:%d\n", i, (b >> i) & 1);
}
return 0;
}

542 名前:はちみつ餃子 mailto:sage [2022/12/04(日) 20:05:21.16 ID:YO7rrhiC0.net]
>>525
念のために繰り返すけど >>524 は <

543 名前:a href="../test/read.cgi/tech/1667194175/523" rel="noopener noreferrer" target="_blank" class="reply_link">>>523 で述べた性質があるので 64 までしか保証されないし、
エラーチェックをあまり頑張ってないので使い方を間違えたときに捕捉されないかもしれない。
あくまでもおおざっぱにはこういう考えかたでいけるだろうというサンプルだからそのつもりで。
[]
[ここ壊れてます]

544 名前:デフォルトの名無しさん mailto:sage [2022/12/04(日) 20:59:12.00 ID:/CRfCGQ0a.net]
訂正
#define _(i) (1 << i)
より
#define _(i) (1 << (i))
のほうが安心

545 名前:513 mailto:sage [2022/12/04(日) 23:12:00.77 ID:flilPTWf0.net]
これまでビット演算を意識したことがなかったので考え方を知れて助かります
提示いただいた例から自分でも調査が進められそうでなんとかなりそうです
いろいろありがとうございました



546 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 01:35:26.13 ID:gMitSG4kM.net]
>>529
ビット演算より、速度は、>>518が一番速いかも。

547 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 10:23:03.76 ID:DqBKeem4M.net]
一々メモリアクセスが発生して直感的には遅そうだけど

548 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 10:35:35.88 ID:hYIKK9DOp.net]
オプティマイズされるからなぁ
記述だけで速度なんか分からないよ

549 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 11:26:10.51 ID:9YGPhFSH0.net]
多分>>526が一番速いと思う
b と i がレジスタに乗れば最近のプロセッサーならシフトは1クロックだし
>>524は最適化が上手く行けば同じ位になりそう

550 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 12:04:38.42 ID:AHxKL62Z0.net]
俺なら3クロックでイッちゃうけどね

551 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 13:51:14.89 ID:0xhTnbB50.net]
速度重視なら>>518だろ
メモリ食うけど、つーてもキロバイト未満だし
古いワンチップマイコンとかじゃなきゃ微々たるもん
ハードできる人ならワイヤードロジックって手もある

552 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 13:53:40.80 ID:iLlZW1brp.net]
速度重視ならアセンブラ…

いや、何でも無い

553 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 14:04:07.58 ID:0Re98eJO0.net]
(Cだけど)昔は isalpha や is~ 系のやつはテーブル参照で実装してたのがあった

554 名前:はちみつ餃子 mailto:sage [2022/12/05(月) 14:25:03.89 ID:6Xcp09rU0.net]
集合を扱うには std::set を使うのが楽だと思う。
集合を集合っぽく扱える機能は一通りそろってるからたぶん集合型というものに期待していることはだいたい含まれるよ。
Pascal の集合型のことはよう知らんけど。

(一般的に) std::set は二分木で実装されるという都合上、やりたいことによっては性能 (速度) 上の不満が生じることもあるかもしれないけど、
具体的な問題が出る前に先回りして考えてもだいたい徒労だしな。

>>537
実行時にロケールを切り替える必要性からじゃない?

555 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 14:43:13.12 ID:9YGPhFSH0.net]
>>537
今でもそうじゃないの?
>>520 > 引数で指定する際の値の範囲は0~31を超えることはなさそうなので
と言う条件だからビット演算の方が早いかもって話であって 、-1~255の範囲ならたいていの環境でテーブル引くのが最速だと思う



556 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 14:45:20.89 ID:oclBynCfd.net]
>>535
テーブル参照はキャッシュが絡むから
単純ではない

557 名前:513 mailto:sage [2022/12/05(月) 15:16:20.05 ID:jV16hsjJ0.net]
0〜255を格納する方は定数でしか使わないので>>518のやり方にしました
0〜31くらいまでしか使わない方は、変数に格納された任意の値の集合を
そのまま引数に渡したり、積集合や差集合を求めるのを想定しています

確かにstd::setがその用途ですね
速度が遅そうで敬遠していましたが、実際にはこれがボトルネック

558 名前:ノなることはないと思います
initializer_listと合わせれば、ほぼPascalと同じ使用感でいけるので、ビット演算のテクニックは
引き続き研究しつつ、いったんstd::setで実装しようと思います
[]
[ここ壊れてます]

559 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 15:31:21.47 ID:0xhTnbB50.net]
>>540
constexprも絡むね

560 名前:530 (オイコラミネオ MM71-NwO+) mailto:sage [2022/12/05(月) 17:26:36.58 ID:rfCFGpMmM.net]
>>540
キャッシュの話になると本当の速さがなかなか分からなくなってくる。
(CPUアーキテクチャやその他の処理の仕方に依存してしまうし。)
キャッシュがある CPU において、キャッシュミスが発生した場合は、
>>526の方が速いであろうと予測はされる。

そもそも、キャッシュの働きが弱いラズパイPICO、Arduino、ESP32 などでは
恐らく>>518 の方が速い。
そもそもシフト演算がシフト量に比例して遅くなるマイコンもあるだろうし。
Z80や8086はそうだった。

x86、x64の場合、
この関数を使うループの中で、他の目的のためにメモリーを大規模に使った場合は、
>>526の方が速いが、沢山メモリーを使わなかった場合は、>>518の方が速い。

561 名前:513 (ワッチョイ 3602-g9pY) mailto:sage [2022/12/05(月) 17:29:22.78 ID:jV16hsjJ0.net]
std::setは集合演算が思った使い勝手ではなかったです
>>526と列挙型を組み合わせることにしました
長々とスレを消費し申し訳ありませんでした
どのレスも参考になり助かりました

562 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9e3e-7kHv) mailto:sage [2022/12/05(月) 18:42:52.30 ID:6Xcp09rU0.net]
>>544
イテレータを受け渡すのがめんどいな。
そのへんは適当なラッパー関数 (または演算子オーバーロード) を定義すればいいんでないの。
たぶんこんな感じにしたいのかな?
https://wandbox.org/permlink/kpYoEhyGaykqITEG

563 名前:デフォルトの名無しさん (ワッチョイ 915f-7kHv) mailto:sage [2022/12/05(月) 18:43:23.85 ID:k8gztHb50.net]
>>544
> std::setは集合演算が思った使い勝手ではなかったです
詳しく。

564 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 18:56:45.80 ID:k8gztHb50.net]
>>545 なるほどめんどくさいな。
よく考えたら contains すら C++20 からっていうのもひどい話よな。

565 名前:デフォルトの名無しさん mailto:sage [2022/12/05(月) 20:18:26.80 ID:Rd1Rhxq6a.net]
江添が女性支援に批判的で笑ったわ



566 名前:513 mailto:sage [2022/12/05(月) 20:57:35.77 ID:jV16hsjJ0.net]
>>545
ありがとうございます
いろいろ知識や考えが足りませんでした
おかげ様で理想形に近づけることができました

std::set<T> operator*(const std::set<T>& x, std::initializer_list<T> init)
foo * _(1, 3, 5)
https://wandbox.org/permlink/14GBm1DqQ6iUaRPq

567 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 09:26:29.57 ID:S4cyJC5Ur.net]
>>548
ツイフェミに批判的なだけだったわ

568 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 09:51:28.64 ID:mFLMdD4Ga.net]
まあ、「ザ・男」ってタイプだからな
ケチがディテールにこだわるのもありがち

569 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 11:12:56.86 ID:63yxghiR0.net]
今や絶滅危惧種となったテキトーこくの嫌いな人

570 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 13:12:15.09 ID:9i6eYS/u0.net]
そういう人ここは比較的多いでしょ?

571 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 13:47:59.27 ID:63yxghiR0.net]
配列がハッシュだなんて裏も取らずに信じちまうやつもか?

572 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 14:38:33.85 ID:mFLMdD4Ga.net]
テーブルのアクセスに使う添字はインデックス?キー?

573 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 14:47:42.28 ID:iX2JPZR5d.net]
サブスクリプト

574 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 15:21:19.75 ID:RihiShBFa.net]
>>554
まだいたのかよ、よほど悔しかったんだなw

575 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 15:50:10.05 ID:iX2JPZR5d.net]
信じてたやつが返事してるな
今度こそ別人ではあるまい



576 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 15:56:04.19 ID:iX2JPZR5d.net]
HDDを指さしてメモリと言ってたやつのほうがまだマシ
記憶装置という点でそんなに大外れではないからな

配列を指さしてハッシュと言うやつは
アメリカザリガニを指さして飛行機と言うようなもんで
どうやっても擁護不可能

577 名前:デフォルトの名無しさん mailto:sage [2022/12/06(火) 16:49:16.67 ID:RihiShBFa.net]
>>496 にレスできないクズ乙w






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](;´∀`)<306KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef