X



C++相談室 part132
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん 転載ダメ (ワッチョイ faeb-wbjw)
垢版 |
2017/10/10(火) 00:11:34.01ID:nc/5PI4P0
次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512

C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part131
http://mevius.2ch.net/test/read.cgi/tech/1501295308/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.101【環境依存OK】
http://mevius.2ch.net/test/read.cgi/tech/1500329247/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
0694デフォルトの名無しさん (ブーイモ MMa3-GOXm)
垢版 |
2017/11/15(水) 13:52:35.02ID:qOFIR485M
??数値の比較をしていってある一定の差があるところを区切っていきたいです

たとえば{1,4,7,8,11}って値を先頭から見て行って差が2以上あるところ{1}{4}{7,8}{11}のような感じで区切る
どうすれば実現できるでしょうか
0695デフォルトの名無しさん (スップ Sd9f-Lcj1)
垢版 |
2017/11/15(水) 14:31:02.26ID:l7NNgtZ+d
>>694
「区切る」の定義をしてくれ
入力が文字列じゃなくて数値ってことは、間に区切り文字を挟むとかそういうことじゃないんだろう。
0697デフォルトの名無しさん (ブーイモ MMa3-GOXm)
垢版 |
2017/11/15(水) 14:55:59.73ID:qOFIR485M
>>695
後々区切られたまとまり毎に操作したいので
できればまとまり毎にそれぞれ別の変数に入れたいです

ただ操作上絶対に有り得ない数値を区切り文字として使うのでも良いです

{1}{9999}{4}{9999}{7,8}{9999}{11}{9999}
みたいな形で
0699デフォルトの名無しさん (ワッチョイ 5f93-B4G6)
垢版 |
2017/11/15(水) 15:49:08.40ID:hv/Fx57R0
>>694 の書き出し化けてない?
「??白lの比較をしていって…」と表示されるんだけど。

対象の {1,4,7,8,11} はconstの整数のvectorへの参照で受け取るとして、
結果は要素グループごとに格納したvectorのvectorで返すかな。
各グループの先頭要素へのインデクスを格納したvectorで返すかも。

>>697 を見ると、前者の方が後の使い勝手が良いのかな。
要素グループのvectorのvectorってこと。
0700デフォルトの名無しさん (スップ Sd9f-Lcj1)
垢版 |
2017/11/15(水) 16:08:47.13ID:l7NNgtZ+d
俺の知らない言語の話だったか...
0703デフォルトの名無しさん (ブーイモ MMa3-GOXm)
垢版 |
2017/11/15(水) 16:49:04.26ID:5RHQ4qAcM
>>699
その部分は数値の比較と書きました

要素グループのvectorのvectorですか

どのような感じで書けばいいとかどのような調べかたをすれば良いか教えて頂けないでしょうか

取っ掛かりが分からなくて
0705デフォルトの名無しさん (ブーイモ MMa3-GOXm)
垢版 |
2017/11/15(水) 16:57:55.30ID:5RHQ4qAcM
>>704
ある方法で手に入れたいくつかの数値を先頭値から見ていき、
前後で差が小さいもの同士でグループ分けしていったあと
そのグループ毎の平均値を出していきたいだけです
0707デフォルトの名無しさん (ワッチョイ 5f78-XysI)
垢版 |
2017/11/15(水) 17:04:07.50ID:QX/ZMY070
こういう泥臭いのは人に聞くよりもスクリプトでもなんでも良いから書いて試行錯誤すればいいと思うのよ
0720デフォルトの名無しさん (スップ Sd82-lBnI)
垢版 |
2017/11/16(木) 21:27:58.68ID:w4cxkmV2d
>>718
新たな馬鹿の登場かな?
0723デフォルトの名無しさん (ワッチョイ 4178-kX9V)
垢版 |
2017/11/17(金) 09:38:50.05ID:S87VOpst0
>>716
STLで使われているアルゴリズムはC++前からあったものばっかだよ
0728デフォルトの名無しさん (スップ Sd82-fw3n)
垢版 |
2017/11/17(金) 18:49:47.16ID:a6b9gyRQd
自力で書いてる人の方が多かった
STLがあっても用途によっては独自になるよな
ディスク上に作るとか、JPEGのハフマン符号みたいに表現が決まってる物とか
0730デフォルトの名無しさん (ワッチョイ 8203-Eq1o)
垢版 |
2017/11/17(金) 20:50:18.49ID:HNipYc2I0
最適化できない? なんで??
テンプレートだろ
0731デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
垢版 |
2017/11/17(金) 21:51:52.32ID:Eetf/DNi0
テンプレート万能説爆誕。
0735デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
垢版 |
2017/11/17(金) 23:17:53.86ID:Eetf/DNi0
ガチガチの最適化が仕様に盛り込まれたとき。
0738デフォルトの名無しさん (ワッチョイ a980-61Vg)
垢版 |
2017/11/17(金) 23:50:29.19ID:sEHgCDk10
最近は凝ったアルゴリズムより単純な配列(vector)の方が速かったりするうえに、余程古いかクソな標準ライブラリを使用してない限りstd::vectorを最適化する余地なんてほぼ無いわな。
0740デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
垢版 |
2017/11/18(土) 00:08:41.90ID:CUoz+hOS0
拡張ライブラリが有ったとしたら、名前空間はstxになるのかね。
0741デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
垢版 |
2017/11/18(土) 00:11:29.34ID:CUoz+hOS0
Qtでウェブサイト作ったら何の問題もなくずっと動き続けてびっくりですよ。
Javaスレの人たちがC++は稼働し続けるとメモリーの分断化で落ちるとか言ってたから、
早く書き直さなきゃって思ってたんだけど。
クライアント用のQtがサーバーで頑健だったのは意外だった。
0742デフォルトの名無しさん (ワッチョイ 4178-kX9V)
垢版 |
2017/11/18(土) 00:14:32.63ID:asu2qdyg0
まぁ意識高い系が言うことなんかその程度ってこった
0744デフォルトの名無しさん (ワッチョイ a980-61Vg)
垢版 |
2017/11/18(土) 01:10:27.30ID:PnwIkFzo0
>>741
クソJavaプログラマーがC++を書くとほぼ間違いなくやるただのメモリリークを俺のせいじゃないということにしたかっただけというのに1票
0745デフォルトの名無しさん (ワッチョイ 25d6-Eq1o)
垢版 |
2017/11/18(土) 06:06:05.59ID:mIICZMYh0
自分のコードでさえ後で読むと読みやすく書いたつもりが裏目に出ていたりする
0748デフォルトの名無しさん (ワッチョイ e18a-RuWE)
垢版 |
2017/11/18(土) 12:02:10.83ID:Erlsd62p0
>>739
古いコンパイラ(つっても10年くらい)だと、クラス内の配列をイジるとクラスオブジェクト自体がイジられたことになるので最適化放棄とかしてたしなー
そういうのだとvectorなんて最適化放棄しまくり。
0750デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
垢版 |
2017/11/18(土) 14:09:50.22ID:fgAW9Gk/0
>>748
オブジェクトXに対するアクセスの最適化放棄はコンパイラの知りえない形での
Xへの副作用が有り得ると判断された場合に行われるがこれは現用コンパイラでも変わらん
改善したというのはコンパイラの能力向上というよりは、テンプレートによるインライン展開のご利益なのでは…
(つまりstd::vectorは元来最適化向きの進化である
0751デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
垢版 |
2017/11/18(土) 14:13:16.03ID:fgAW9Gk/0
例:
次のコードの並びにおいて、
1と3の読み込み結果は同一とはみなされず、1〜3を通してのX.aのレジスタ割り当ては行われない
 1. Xのメンバaを読む
 2. 外部リンケージ(かつ素性の知れた組み込み関数以外)の関数foo()を呼ぶ
 3. Xのメンバaを読む

特効薬はfoo()のインライン展開
0752デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
垢版 |
2017/11/18(土) 14:16:28.52ID:fgAW9Gk/0
なお手動を厭わないなら次の風にしても良い:
 0. auto変数v = X.a
 1. X.aを読む代りにvを読む
 2. 外部リンケージ(かつ素性の知れた組み込み関数以外)の関数foo()を呼ぶ
 3. X.aを読む代りにvを読む

これならいくら古いコンパイラでもvを1〜3を通してレジスタ割り当てすることが気体できる
0753デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
垢版 |
2017/11/18(土) 16:28:12.38ID:gZtBhbAH0
浮動小数点をすべて網羅するループが書きたいのですがどうすればいいでしょうか。
0754デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
垢版 |
2017/11/18(土) 16:29:45.36ID:CUoz+hOS0
ラスボス級が現れた。
0755デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
垢版 |
2017/11/18(土) 16:46:32.60ID:gZtBhbAH0
http://takashiijiri.com/study/miscs/fastsqrt.html
やりたいことは、上のサイトにある高速根号計算の精度検証です。

サイト内では2の根号に対して精度検証していますが
すべての倍精度実数に対して検証をしたいと考えています。

64bitの整数のビット表現を、同じビット表現の倍精度実数に変換できれば
整数についてループを回すことで網羅できると考えています。

変換の方法をご存知の方がいれば教えて頂けないでしょうか。
0763デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
垢版 |
2017/11/18(土) 17:20:21.34ID:gZtBhbAH0
みなさま、レスありがとうございます。

>>757
memcpyでできそうです。ありがとうございます。

int main() {
double f = 0;
for (unsigned long long i = 0; i <= -1; ++i) {
void* fp = static_cast<void*>(&f);
void* ip = static_cast<void*>(&i);
std::memcpy(fp, ip, sizeof(i));

std::cout << f << std::endl;
}
system("pause");
}

>>760
そんなに時間かかるんですかね。。。
1週間ぐらいは覚悟してたんですが。
とりあえず回してみます。
0764デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
垢版 |
2017/11/18(土) 17:32:14.09ID:np1Yc2el0
>>763
https://randomascii.wordpress.com/2014/01/27/theres-only-four-billion-floatsso-test-them-all/
> ... you can test every float bit-pattern (all four billion!) in about ninety seconds. ...

32bit が 90 秒ほどで済ませられるそうな。 64bit だと単純計算で・・・ 735439.6... 年ぐらいかな。
1週間で済ませようと思ったら 38347922 並列ぐらいで走らせればよさそう。

検証する計算内容によっても変わるだろうけど、まぁがんばれ。
0765デフォルトの名無しさん (ワッチョイ a193-oo0Z)
垢版 |
2017/11/18(土) 17:35:34.11ID:hpuIg+Nf0
とりあえず範囲を絞って回してみて、
力任せの方法で受け入れられる処理時間なら単純なプログラムのまま、
時間かかりすぎるようなら先にプログラムを洗練させる、としないと。
0768デフォルトの名無しさん (ワッチョイ a19f-RjUU)
垢版 |
2017/11/18(土) 19:44:12.36ID:euoYf0NO0
>>761
未定義にはならなくね?ポインタtoポインタだからそのまま、で終わりでは。
なお、Cなら

*(long long*)&f = i; // mov命令でコピー
または
f = *(double*)&i; // fmov命令でコピー


>>766
まず仮数部53bit+指数部の偶奇で54bit分でいい。
非正規化数もいらないだろうから仮数部52bit扱いでもいい。
意味が分からないのなら仕様読め>>758
0769デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
垢版 |
2017/11/18(土) 20:29:47.22ID:np1Yc2el0
>>768
type-based aliasing rule (strict aliasing rule) というものがあってな。
(詳しく調べると闇に落ちるから言語オタクでもなければ深堀りはおすすめしない。)

mempcy なら動作が定義されてるかというとそうでもないんで、
明示的に未定義といわれているかどうか(=最適化で問題を起こしやすいかどうか)の違いしかないんだけど。
0774デフォルトの名無しさん (ワッチョイ 4178-kX9V)
垢版 |
2017/11/18(土) 22:06:57.57ID:asu2qdyg0
なんか古い書き方だから2000年ごろからの年季の入ったソースかと思ったら最近の奴なんだな
0776デフォルトの名無しさん (ワッチョイ a19f-RjUU)
垢版 |
2017/11/18(土) 22:42:09.82ID:euoYf0NO0
>>769
調べたけどこれでいいのか?
https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule

これならreinterpret_cast関係ないじゃん。static_castにしたところで変わらん。
ただそれ以前に該当しないだろ。
「同一のメモリを違う型としてaliasしたときにコンパイラがそれに気づけず最適化で削除してしまう」という問題であり、
今回はそうではない。

> mempcy なら動作が定義されてるかというとそうでもないんで
ほんとか?それじゃmemcpyマトモに使えないじゃん。
void*は++で1増えるって仕様に決まったはずで、、、と思ったがこれがgcc拡張だという話があり、このことを言っているのか?

ならグダグダ言わずにCキャストで書けよもう、としか思わないが。
或いはC++的には許せないのかもしれんが static_cast<double>にしてしまうとかか?
0778デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
垢版 |
2017/11/18(土) 23:20:13.09ID:np1Yc2el0
>>776
static_cast じゃコンパイル通らない。

"*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
未定義動作になる。結果は「最適化で削除してしまう」に限らず、何でもアリだよ。
これが「「同一のメモリを違う型としてalias」に該当しないという理屈も無いでしょ。

memcpy の結果が定義されてるのは、同じ型のオブジェクト間でのコピーだけだったかと。
違う型の間で memcpy した結果の値が実は定義されてるということなら実に興味深いので
ぜひ規格の該当箇所を示して欲しい。

この場合の C スタイルキャストの動作は reinterpret_cast に丸投げされるだけなので話は変わらないよ。
0780デフォルトの名無しさん (ワッチョイ a19f-RjUU)
垢版 |
2017/11/18(土) 23:38:32.35ID:euoYf0NO0
>>778
> "*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
してないぞ。
それは「fのアドレスを(long long*)にキャスト(この時点でlong long*型)したアドレスに対しiを書き込め」
であって、つまり long long に long long を書いている。だからmovが出る。
逆に f = *(double*)&i; は double に double を書くから fmov が出る。
その後の最適化で変更されるのはまた別の話。

> static_cast じゃコンパイル通らない。
だったら最初から>>759の言うとおり、reinterpret_castでいいだろ。

> 違う型の間で memcpy した結果の値が実は定義されてる
void* と void* なんだから同じ型だろ。何言ってんだ?

お前、基本的に理解がずれてね?
0781デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
垢版 |
2017/11/18(土) 23:47:06.34ID:np1Yc2el0
>>780
なるほど、オブジェクトの型と式の型との区別がついてないんだね。
そこの理解無しで aliasing rule に関する話は無理だから、
C++ の規格を読み直すなりして区別が付くようになってからの出直しをおすすめする。
0783デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
垢版 |
2017/11/19(日) 00:03:31.90ID:xhmNfS4m0
>>782
そうなると GCC も「全く理解出来てない」ことになるねぇ。
https://wandbox.org/permlink/WMFUTpXAgs2oZuos
> prog.cc:5:17: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
> *(long long*)&f = i;
> ^
> prog.cc:6:18: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
> f = *(double*)&i;
> ^
0785デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
垢版 |
2017/11/19(日) 00:41:57.82ID:p3uF8GIb0
まあ未定義な動作がどこまで行っても未定義な動作であって(教条主義的には)悪なのは確かだが
>>784のリンク先のを読むと
>ストアによってPの値が変わる可能性を考慮しなくてはいけないからだ。
という理由で最適化できないケースがあるから考慮する代りに未定義動作ということにしますた!
というだけで、ストアによってPの値が変わらないなら特に問題を生じないように思える…

で、ストアによってPの値が変わるケースというのは
int main() {
P = (float*)&P; // このキャストによって zero_array の中で TBAA 違反となる
zero_array();
}
みたいな変態的なケースしかなさげ;
0786デフォルトの名無しさん (ワッチョイ a19f-RjUU)
垢版 |
2017/11/19(日) 00:54:18.30ID:SsMAbqSz0
>>784
答え書いてんじゃねーかよ。

> この種の未定義な振る舞いは、-fno-strict-aliasing フラグを指定することで無効にすることができ
つまり指定すれば万事解決だ。
ただその前にwarning出てても動作するとは思うが。

> この種の型の乱用はあまり一般的ではないので、標準委員会は、"妥当な" 型のキャストによる予期しない結果と引き換えに、大幅なパフォーマンス向上を選んだ。
これっていつから?LLVMに乗せた頃からっぽいが、、、日付や元URL見るかぎりC++11からか?
あとこれって、Cもか?
(Cでは俺が書いたようなキャストは常用されているから)
知っている人がいたらよろしく。
0788デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
垢版 |
2017/11/19(日) 01:24:03.10ID:XAwzlQ9S0
C89からずーっとそうだよ
お前が書いてるコードが動いてるのは、コンパイラがそうしないという保証を独自に与えているか(-fno-strict-aliasingはその一例)
さもなくばたまたま動いてるだけ
0789デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
垢版 |
2017/11/19(日) 01:33:36.82ID:xhmNfS4m0
>>786
広く知れ渡ったのは gcc 2.95 で実際にそのルールに基づく最適化が行われるようになってからかな。
https://www.gnu.org/software/gcc/gcc-2.95/features.html
> - Type based alias analysis is enabled by default. ...
そこから数えてももう 20 年近く経つわけだが。

知らずにそんなキャスト常用してるなら是非悔い改めてくれ。
0791デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
垢版 |
2017/11/19(日) 01:37:52.26ID:XAwzlQ9S0
ちなみに-fno-strict-aliasing付けるとこんな基本的な最適化さえ出来なくなって
パフォーマンスが激悪化する可能性があるからな
それを完全に理解した上で万事解決だと言ってるならそれでもいいけどさ

int foo(double* pd){
 int k = 42;
 *pd = 666;
 return k * 2;
}

-fno-strict-aliasingを付けた場合、戻り値を"84"に最適化することは出来ない
なぜならpdのアドレスが&kを指してるかもしれないから
(strict aliasing ruleが効いてればdouble*がintを指してたら未定義動作なのでケアする必要がなく最適化できる)
0793デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
垢版 |
2017/11/19(日) 02:15:02.16ID:XAwzlQ9S0
有効なポインタならね
デタラメなポインタがたまたま&kを指してるかもしれない
普通はそんなのは未定義動作だからケアしないんだけどそれをケアしろって言うのが-fno-strict-aliasing
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況