X



C言語なら俺に聞け 146
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん (ワッチョイ 839f-AnMQ)
垢版 |
2018/04/30(月) 04:47:37.50ID:XX4FB8lc0
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/


C言語なら俺に聞け 144
https://mevius.5ch.net/test/read.cgi/tech/1514025223/

次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512
-
※前スレ
C言語なら俺に聞け 145
http://mevius.5ch.net/test/read.cgi/tech/1519046038/
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
0851デフォルトの名無しさん (ワッチョイ 0b50-2km2)
垢版 |
2018/08/11(土) 00:06:54.68ID:N9ICkOCi0
10000進数多倍長
超単純なFFT
演算は乗算と加算のみ
誤差の感じから100000進数でも大丈夫そうですね

計算式は基本以下を多倍長にしただけ
多少の無駄は除いてますが

----
uint64_t f(uint64_t n){
n++;
uint64_t a = 1;
uint64_t b = 0;
uint64_t t;
for (int i = 0 ; i < 64 ; i++){
t = b * b;
b = 2 * a * b + t;
a = a * a + t;
if (n & 0x8000000000000000){
t = b;
b = a + b;
a = t;
}
n += n;
}
return a;
}
0853デフォルトの名無しさん (ワッチョイ 9f2d-IVAT)
垢版 |
2018/08/11(土) 10:03:32.46ID:ONHM6Q8h0

じゃ、多倍長使って一般項の公式で算出したケースを晒します

スレチと知りつつ C++ で boost/multiprecision バックエンドは gmp
https://wandbox.org/permlink/QqxaauQeHTjJRrYX

# fib(0) .. fib(1000) + fib(10億)
real 0m0.004s
user 0m0.004s
sys 0m0.000s

ま、そりゃ速いですわな……
科学的表記で出力すると速いけど 整数表記しようとするとfib(10億)で2分ぐらい
文字列化でかなり時間を食ってます
0860デフォルトの名無しさん (スップ Sd8a-+oCX)
垢版 |
2018/08/11(土) 11:11:54.17ID:y6G1YdWMd
expの計算の内部ではlog 2を使うし
2進10進変換にはlog_10 (2)を使うので
doubleより高精度で求めるなら
この辺も先に計算しておくことになるでしょう

>>850ははじめから10進での計算なので
10進文字列に変換するのは一瞬
0865デフォルトの名無しさん (ワッチョイ 9f2d-IVAT)
垢版 |
2018/08/11(土) 11:29:35.08ID:ONHM6Q8h0
>>863
https://www.boost.org/doc/libs/1_68_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/gmp_float.html
gmp_floatが number<gmp_float<0>> の typedef なので
"variable precision by setting the template argument to zero"で無限精度指定になってると理解してます
正確に出力させると桁が膨大で検証しにくくてしょうがないな…… これ
0866デフォルトの名無しさん (ワッチョイ de80-oNxq)
垢版 |
2018/08/11(土) 11:39:50.69ID:17qcRus/0
とりあえずかわいそうなぐらい頭悪いヤツしかいないのは分かった

一旦、多倍長演算向けに3つの方法を評価する
ちなみにgmpの関数にフィボナッチの関数がついてる
きっとこの速度にすら届かないと考えられる(まだ動かしてない)

↓多倍長演算使ってない3つの方法の簡単なコードがコレ
https://ideone.com/vhpLPV
※ オマケでアホが書いたコード(>>851)も入ってる
※ オレの適切なありがたい注釈がついてる

1.ひたすら足し算

2.一般項
 多倍長演算をするまえに適切な精度を設定しないといけない
 どれぐらいの精度にすればいいかがまだ未解決 ※ とりあえず2回計算することでいけるような気がしないでもない

3.再帰階乗演算
 https://www.ics.uci.edu/~eppstein/161/960109.html
 探した中でコイツが一番いい感じがする
 > This is a recursive algorithm, so as usual we get a recurrence relation defining time,
 > just by writing down the time spent in a call to matpow (O(1)) plus the time in each recursive call
 > (only one recursive call, with argument n/2). So the recurrence is
 > time(n) = O(1) + time(n / 2)
0871デフォルトの名無しさん (ワッチョイ de80-oNxq)
垢版 |
2018/08/11(土) 12:00:16.70ID:17qcRus/0
↓アルゴリズム5でオレのサンプルではちゃんと動いてるからな
https://ideone.com/vhpLPV

↓オマエのは動かしても適切な結果にならない
https://ideone.com/vhpLPV

オマエのはお話にならないぐらいペケ
↓ペケの理由もちゃんとコメントに書いてある
https://ideone.com/vhpLPV
0874デフォルトの名無しさん (ワッチョイ de80-oNxq)
垢版 |
2018/08/11(土) 12:06:47.07ID:17qcRus/0
オマエは基本的にオツムに問題がある
病院へいったほうがいい
0875デフォルトの名無しさん (スップ Sd8a-+oCX)
垢版 |
2018/08/11(土) 12:07:58.68ID:y6G1YdWMd
nが32bitなら0x80000000にしないと

多倍長で動かすためのテストコードだから
桁数が小さい時の計算回数は全く無視
ループが進んでからやっと演算がはじまる
0876デフォルトの名無しさん (ワッチョイ de80-oNxq)
垢版 |
2018/08/11(土) 12:09:49.79ID:17qcRus/0
64回しかループしてない

 Σ n
 n→64

はいくつになる
0878デフォルトの名無しさん (ワッチョイ de80-oNxq)
垢版 |
2018/08/11(土) 16:36:24.18ID:17qcRus/0
1.と3.は簡単にできた
https://ideone.com/cmAQzO

gmplibのフィボナッチは n=10,000,000 を
0.7秒ぐらいで処理できる
オレが作ったのは4秒ぐらいかかる

m,10000000,4.008508,3.989280
g,10000000,0.724954,0.717120

全然かなわない
少しやってみて面倒そうだから後回しにしてた一般項やってみるか
0881デフォルトの名無しさん (ワッチョイ de80-oNxq)
垢版 |
2018/08/11(土) 19:41:53.58ID:17qcRus/0
https://ideone.com/2by35t

精度評価用のログ取得処理

32bit版GMPの仮数部は初期値が64bitで32bitずつ増えていく模様
ちなみに64bit精度で一瞬で求まるフィボナッチ数のサイズ(bit)予測値はほぼ誤差なし
※ 9999件まで確認したが誤差は発生してない
※ 保険で、1dword(32bit - 最小単位) 分、余分に足しとけば、この予測値で間違いがおきることはまずないと考えられる

フィボナッチ数のサイズ(bit)予測値から必要な精度が予測できる
※ 9999件まで確認したが
※ フィボナッチ数のサイズ(bit)の1dword(32bit - 最小単位) 分より大きい誤差は発生してない

↓コレがその結果
http://fast-uploader.com/file/7089539563485/
http://fast-uploader.com/file/7089539604357/

数学的に証明したわけではないが、きっとコレで間違いなくいける
つまり予測値に64bit足しとけば間違いがおきることはない
0882デフォルトの名無しさん (ワッチョイ de80-oNxq)
垢版 |
2018/08/11(土) 19:44:24.09ID:17qcRus/0
で、>>881の結果に基づいて
一般項で処理するコードを書いた

 https://ideone.com/QKTrLi
 一般項で処理

やってみたが
一般項で処理なんかするとともかく遅い

6,942,482 bitsの一般項の計算で
お話にならないぐらいものすごい時間がかかる

calculation 6942482bits
f,10000000,35.082393,34.855636
g,10000000,0.722054,0.720584

つまり、結論としてフィボナッチ数を求めるなら
GMPに用意されてる関数を使うのが一番

再帰階乗演算使う方がはるかにマシ
一般項で求めるのはウンコ
0883 ◆QZaw55cn4c (ワッチョイ ea60-Qb5F)
垢版 |
2018/08/11(土) 19:56:34.45ID:vW2Ha+vq0
>>882
gmp の生Cインターフェースを叩くとは、勇気がありますね
私は、C++ インターフェース gmp_class でやることはあっても gmp を C インターフェースで叩くことはありません
あれは、あとから見てなにがなんだかわからなくなってしまう…

a + b√5, a, b ∈Z で表される数は、それ同士を足しても掛けても、その結果はやはり a + b√5 の形になるのだから(そして結果は整数になることがわかっているのだったらなおさら)、
√5 を開かずにその係数を有理数の範囲で計算するようにすれば(>>807)、ずいぶんと違うと思います >>824, >>842
0890デフォルトの名無しさん (ワッチョイ 6fc3-5rxo)
垢版 |
2018/08/11(土) 22:26:14.75ID:UyVMPuF50
C言語でゲームがアクションゲームが作りたくてプログラミングはじめた
実際にプログラミングって楽しいと感じてる
でも入門書通りソートアルゴリズムを勉強してて、基本交換法やら基本選択法は楽にフローチャートもコードも書けたのに、そのあとにやった クイックソートとか単純挿入法では面白いぐらい苦戦した(どっちももうできるようになったけど)
これって、俺のアルゴリズムを考える能力が乏しいってことなのかな
それともはじめはみんなこんなもの?
0891デフォルトの名無しさん (ワッチョイ 6fc3-5rxo)
垢版 |
2018/08/11(土) 22:26:40.35ID:UyVMPuF50
×ゲームがアクションが
◯アクションゲームが
0895デフォルトの名無しさん (ワッチョイ 0b50-2km2)
垢版 |
2018/08/11(土) 23:13:57.75ID:N9ICkOCi0
n log nより遅いように見えるのは
サイズが大きいとキャッシュから外れるため

フーリエ変換はメモリのランダムアクセスが頻発するので
キャッシュに入るかどうかで大きく時間が変わる

適当に並び変えながら変換することで
キャッシュヒット率を上げたり
メインメモリに収まりきらない巨大サイズをHDDを使いながら変換することも出来るのだが、
今回はシンプルさ重視の為見送り

世の中にある高速FFTライブラリに差し替えれば
もっと高速化する
0896デフォルトの名無しさん (ワッチョイ 0b50-2km2)
垢版 |
2018/08/11(土) 23:25:51.63ID:N9ICkOCi0
>>887
環境依存

float, double がそれぞれIEEE754のbinary32とbinary64準拠の場合はおおよそ

-3.4028234663852885981*10^38 ≦ float ≦ 3.4028234663852885981*10^38
-1.7976931348623157081*10^308 ≦ double ≦ 1.7976931348623157081*10^308

正確には以下の範囲
float : ±(2^24-1)*2^104
double : ±(2^53-1)*2^971

これに追加して±∞, NaN などがある

組み込みなどではdoubleも32bitであることも多い
0897デフォルトの名無しさん (ワッチョイ 0b50-2km2)
垢版 |
2018/08/11(土) 23:33:36.42ID:N9ICkOCi0
C言語スレだから ^ は排他的論理和の意味で使うべきでしたかね

-340282346638528859811704183484516925440 ≦ binary32 ≦ 340282346638528859811704183484516925440

-1797693134862315708145274237317043567980705675258449965989174768
0315726078002853876058955863276687817154045895351438246423432132
6889464182768467546703537516986049910576551282076245490090389328
9440758685084551339423045832369032229481658085593321233482747978
26204144723168738177180919299881250404026184124858368
≦ binary64 ≦
1797693134862315708145274237317043567980705675258449965989174768
0315726078002853876058955863276687817154045895351438246423432132
6889464182768467546703537516986049910576551282076245490090389328
9440758685084551339423045832369032229481658085593321233482747978
26204144723168738177180919299881250404026184124858368
0898デフォルトの名無しさん (ワッチョイ 0b50-2km2)
垢版 |
2018/08/11(土) 23:41:42.36ID:N9ICkOCi0
>>888
単純なバグでした

size_t が64bit前提の部分があったのと、
非常に恥ずかしいですが以下のような動作不定なコードがありました
a->data[i++] = b->data[i] + carry;
私のローカル環境だとたまたま動いていたようです

intが16bitだとまだヤバそうですが、
16bit環境で動かすことはないと思うので気にしないことにします
0902デフォルトの名無しさん (アウアウエー Sac2-+AzL)
垢版 |
2018/08/12(日) 07:44:42.21ID:P7wTPSJQa
蛇とJSとアセンブラ少しかじったんだけどCの効率的な勉強法ある?
主に蛇のチューニングと、これから勉強する予定なんだけど組み込み用マイコンのプログラムを書くために使う

小型のドローンもどきにのせたマイコンに、学習済みパターンをのせて動作制御したい
0906デフォルトの名無しさん (アウアウエー Sac2-+AzL)
垢版 |
2018/08/12(日) 07:57:10.98ID:P7wTPSJQa
聞いといて申し訳ないんだけど全然知らないんだよね門外漢で
シンプリンク?とか言うやつでいいかなと思ってるけど、種類により出来ること出来ないことも分からない
0907デフォルトの名無しさん (ワッチョイ 0b50-+oCX)
垢版 |
2018/08/12(日) 08:08:39.25ID:3JJNsMDc0
文法をざっくり本とかで覚えたらあとは実践
高速化なら具体例を提示すれば私がアドバイスしますよ

高速化する場合はクリティカルポイントを絞ってから
時間がかからない所は高速化せずにそのままにしておくこと

アルゴリズムや式など、
上位の改良の方が高速化に寄与しやすいので
まずは上の方から考えること
下を高速化することで上が見にくくなって上の改良を妨げるようじゃ本末転倒なので
0914デフォルトの名無しさん (ブーイモ MM4f-oNxq)
垢版 |
2018/08/12(日) 10:04:57.52ID:sdNRpf8zM
>>911
K&Rって言えよ。余計わかりにくい。

>>909
K&Rは「既にプログラミングできる人がCの文法を覚える用」だから、本当に最小セットしか乗ってない。
ただ、それでいい人=上級者からは絶賛されてる。彼らにとってはいわゆる入門書は冗長すぎるから。
十分にPythonと『アセンブラ』を使え、文法だけ知ればいけるのなら、K&Rはすごくいい。
PythonやJS等の上級言語しか使ったことなく、ポインタって何?なら、
殆どの人はポインタで躓くので、K&Rだけではかなり厳しいと思う。

アセンブラのインデックスレジスタがポインタそのものなのだが、ピンと来るか?
ピンと来るなら、まずK&R買って、だめなら入門書でいいと思う。
意味不明だと思うのなら、最初から入門書を買え。
0916デフォルトの名無しさん (アウアウエー Sac2-+AzL)
垢版 |
2018/08/12(日) 10:28:59.49ID:P7wTPSJQa
ありがとう
とりあえず苦Cは確定で、メインとしてK&R 使えるか本屋で見てくる

正直上級者どころか初心者を脱したかどうかレベルだから合わないかもだが
数学でチューリングマシンがーって机上の勉強やってたからかアセンブラはすんなりいった
行けそうだったらK&R使ってみる

てことで本屋行ってくる
0918デフォルトの名無しさん (ブーイモ MM4f-oNxq)
垢版 |
2018/08/12(日) 11:36:54.26ID:zEU3SQsmM
>>916
> 数学でチューリングマシンがーって机上の勉強やってたからかアセンブラはすんなりいった
これって理論畑から行くとチューリングマシンがプログラミングより先に来るんか?
正直、それが何の役に立つのかはよく分からんが…
0921デフォルトの名無しさん (ブーイモ MM4f-oNxq)
垢版 |
2018/08/12(日) 12:31:18.04ID:zEU3SQsmM
>>919
それって自然言語に対してって事?
なら逆にチューリングマシンの範囲を超える事象って何?
単純に言えば、それは未来永劫今の構造のCPUでは無理ってことになるはずだが、
そんな分野があるのか?
0926デフォルトの名無しさん (スプッッ Sd8a-J+gX)
垢版 |
2018/08/15(水) 06:16:23.73ID:fPb+tE65d
Java屋なんですけど自己啓発のために学生時代以来のCを夏休みに勉強しようと思ってます
開発環境のオススメを教えてください
自分が思いつくところでは…
・Vimとgcc
・VScode
・eclipse
こんな所ですが皆さんどうされてますか?
MacもWindowsも両方手元にはあります
0935デフォルトの名無しさん (スッップ Sdea-mlTV)
垢版 |
2018/08/15(水) 14:58:02.44ID:1MwRKcc7d
VisualStudioで良いとか口が裂けても言えねぇよ
MSVCはこのご時世ですらpure CはC89だぞ?
初心者で知らないならともかくこういうスレでVSをCの環境として勧める奴何者だよ
0941デフォルトの名無しさん (ワッチョイ 1b9f-x/tb)
垢版 |
2018/08/15(水) 15:59:23.74ID:BN2igdfy0
そういやLinuxとかのCUIでTurboCみたいな環境ってあるのかな?
あると外部からsshでログインしている時に使えて良いのだが。
0942デフォルトの名無しさん (アウアウウー Sa2f-02HX)
垢版 |
2018/08/15(水) 16:22:31.09ID:fRV95OwVa
>>940
年寄りぶったガキが「古い環境でもコンパイル可能なコード」にこだわってるせいでどんどんコードが汚くなるのよ。
>>941
emacsじゃだめってことなんだろうねえ。
webベースのIDEでいろいろあるんだろうけど、決定版があったら知りたいわ
0944デフォルトの名無しさん (ワッチョイ 1b9f-x/tb)
垢版 |
2018/08/15(水) 17:03:06.47ID:BN2igdfy0
>>942
emacsねえ。あれは複雑過ぎて今更覚える気になれない。
まああれが多機能過ぎるせいで他が伸びなかったって感じはするなあ。
0946デフォルトの名無しさん (ワッチョイ 0b93-6ZXu)
垢版 |
2018/08/15(水) 17:13:57.27ID:2ovpzQjs0
vimでエディットして :make でビルド、
エラーや警告は quickfix 機能でシラミ潰し。

強く薦める気はないし、他の人に使い方を教えるほどの技量はないけど、
個人的にはこの組み合わせが便利だわ。
errorformat オプションを設定すれば、どんなコンパイラや変換ツールでも
ソースファイルのエラー箇所を呼び出してくれるからね。
0951デフォルトの名無しさん (ワッチョイ 9ff2-2km2)
垢版 |
2018/08/15(水) 17:56:50.28ID:/SQznhgr0
そういう意味じゃたしかに、C99規格に入れられたいくつかの機能は便利だ。
なので訂正する↓
msvcがC99準拠じゃないからといって困ることなんてそんなにないしな。
レス数が950を超えています。1000を超えると書き込みができなくなります。

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