C言語なら俺に聞け 144
■ このスレッドは過去ログ倉庫に格納されています
ちょっと整頓させてくれ。
>>702 の場合
二つ目の unsigned char
01001011 ... 最初の値
01001010 ... 新しい値
00000001 ... 変化したビット
一つ目の unsigned char
11010110 ... 最初の値
11010111 ... 二つ目の unsigned char の変化にともない新たに取るべき値
00000001 ... 変化したビット (二つ目の unsigined char の変化したビットと等しい)
>>703 の場合
二つ目が0b010000111に変化 ... ビット数が増えとるやん!
>>710 の言う通り「二つ目」のビット変化をexor(^演算子)で抽出した結果を
「一つ目」のビットに作用させれば良さそうだけど、
「二つ目」のビットが1から0に変化したときには「一つ目」にはどう反映させたいの? >>710
ありがとうございます。
何となくですが少しイメージが浮かんできました。
>>711
すみません。
二つ目が 0b01000011 に変化の間違いです。 1001110
1101001
1101000
1101111
1101110
1100111
1101111
0100000
1100100
1100101
0100000
1001111
1001011 こ、こうか・・・
1001110 N
1101001 i
1101000 h
1101111 o
1101110 n
1100111 g
1101111 o
0100000
1100100 d
1100101 e
0100000
1001111 O
1001011 K 2つめ着目ビットが 0 -> 1 となったとき 1つめ対象ビットを 反転/0/1 にする
2つめ着目ビットが 1 -> 0 となったとき 1つめ対象ビットを 反転/0/1 にする
0->1 でも 1->0 でも 1つめ対象ビットを反転すればいいのけ?
new_1st = old_1st ^ (old_2nd ^ new_2nd); >>716
正にその通りです!
その式で思ってる通りに制御できました!
ありがとうございましたm(_ _)m 全くの初心者です。
「2の3乗を求める」という計算プログラムを勉強しています。
最終的には3^1024を求めたいのですが。
ネットで見ていると30乗ぐらいまではプログラムがあるのですが
1024乗ぐらいになると難易度的に難しくなるのでしょうか? >>718
3^1024=(3^2)^512
3^2≒10ってことで、だいぶ大雑把だけど
3^1024≒10^512
10進数で500桁以上の大きな数になりますね。
どの型の変数を使う? >>718
やることは3に3を1,023回掛けるだけだから難しくはない
ただ>>719の言うようにかなりでかい値になる(ちょっとpythonで計算したら489桁だった)から普通のlong intとかではオーバーフローする
なので
多倍長整数 C言語
とかでググるがよろし DOSで4000桁の電卓つくるにはって考えてたことあったな。 >>718
自力でどうにか解決できたらプログラミングの力がつくよ、がんばって! >>718
GMPというフリーのライブラリを使えば3^1024は簡単に求まるぞ BCD(二進化十進)ライブラリを拾ってくるのが汚れた大人だけど、
若者は勉強のためにBCDライブラリを作ってみては? >>725
10進の世界を前提に計算するのは、メリットがよくわからないんですが 10進じゃないと0.1が無限に数字が続くらしい
よく分からんけど >>728
10進だと 1/3 が無限に数字が続きますよね
それはさておき、多桁長+浮動小数点が落としどころではないかと
すると、BCD の意義がよくわからないのです 効率よく2進値を10進表記するアルゴリズムが思いつくならメリット無いかもな。 とりあえず質問者の意図にそって
多倍長整数演算と言うことに絞ろう 16進ダンプしたとき読みやすい
それだけ
3増し符号とか使ってたやついる? >すると、BCD の意義がよくわからないのです
科学技術計算は浮動小数点でいいが、リアルなお金の計算とかでは10進で計算するのがディフォールト
2進と10進では結果が大幅にちやうから。
ま俺の財産なら誤差0.1円くらいかもしれんが、、 いま必死に考えてる
昔のCPUは絶対に持っていた機能だ
レジスタが8ビットだとすると、256以上のデータが表現できなくなるけど、そんなことはない
だから何か仕組みがあるはず
プログラマが勝手にこのビットが立ったら2の15乗だとか自由に決めて、8ビビットの重み付けをしてるんだとおもう
あとは計算と結果の表現次第だ
指数法則を使えばできそうだけど、これはなかなか面白い課題だね >>737
キャリーフラグと言ってレジスタの範囲を超える加減算があると1になるビットがステータスレジスタにある
32ビットCPUにだってあるぞ >>741
C で多桁長計算を記述するときは、キャリーフラグという便利なものが使えないので、いちいちマスクしたり、と苦労しますね
http://mevius.2ch.net/test/read.cgi/tech/1434079972/28
C で書かないほうが楽で記述量も少ないかもしれない
>>718 は初学者には無理かもしれません アセンブラだと当たり前のようにキャリーフラグを見るけど
高級言語だとキャリーフラグを活用してるのは皆無じゃないかと
思えてくるのが悲しい I/Oがメモリにマッピングされてるんだから見れると思ってる
ぼくはそういうプログラミングがしたい Reno版のカーネルのソース読んだとき、
VAXのHDDのドライバが分かりやすくてビビった。
メモリマップドI/Oだた。 ここの人達ってOpaqueポインタとか使ってます? とりあえず本買ってきて読んでいます。3月末ぐらいにはなんとか結果を出したい・・・ とりあえずプログラム初心者だが将来有望な頭脳をもった奴を
2人ほど用意した・・・。 >>742
うーん。最上位ビット使えばできるのでは?
まあしかしアセンブラ使った方が効率はいいだろうな。
CPU違ったら動かんけど。 >>748
実ソースではvoidポインタしか見たことない 3進数用にBCD3を定義する
1桁を2進数2bitで表現して
最下位桁の次に2bitのエンドコード11を付与する
例えば
0=00 11
1=01 11
2=10 11
3=01 00 11
4=01 01 11
5=01 10 11
6=10 00 11
7=10 01 11
8=10 10 11
9=01 00 00 11
...
3^1024=01 00 00 ...(00 が1020個(左右に書いたもの含めると1024個))... 00 00 11 >>754 議論の本質から逸れた混ぜ返しになるけど、
BCD が 二進化十進数 binary coded decimal の略なら、
3進数の場合は binary coded tricimal で BCT ではないかしら。
3進数が tricimal なのか、ちょいと自信がないけど、
とりあえずネット検索でヒットする言葉みたい。 >>756
訂正ありがとう。確かに ternary が辞書に載ってる言葉みたいね。
triple あたりからの類推では到達できない綴りだったわ。
これからは注意して取り締まることにする。 従来のbooleanの変数が1個だけあっても、2進数とは呼ばんだろ。 2進数なら無駄なく表せるけど
struct {
bool b1:1;
bool b2:1;
bool b3:1;
bool b4:1;
bool b5:1;
bool b6:1;
bool b7:1;
bool b8:1;
}
3進数だと3バイトずつセットにしないと無駄なく表せないよね
3進数使うメリットあんの? 自然対数の底2.71828…により近い3進数の方が効率が良いっておばあちゃんが言ってた。
2進数なのは単に電気で表しやすいからだって。 元の質問が3の累乗を求める問題だから3進数の方が単純化できるというだけのこと このあたりのソース揃ってるソフトでC言語の勉強してるわ。
スカパーの録画環境も構築できるし。
https://www65.atwiki.jp/psky/ const char ○○とchar ○○について。
○○はフォルダ名。
後者ではエラー、前者ではエラーにならない場合何が考えられますか?
CとC++だと記述が違うとかあります? 恐らく何らかの標準関数の引数にでもした時にエラーが発生したんだろうけど、具体的なことが分からないので何とも言えない
constについてはCとC++では微妙に扱いが違う >>766
そりゃ2値で3進数を表現しようとしてるから当たり前
1本の線が3値になるようなハードなら3進数の方がやり易い エラー発生箇所の最小のコードとエラー内容を張らないと憶測だらけに >>776
それはソフト屋さんの思考やね
ハード的に0ピッタリなんてできなくて結局ある範囲を見る必要があるから1V, 2V, 3Vでも-1V, 0V, 1Vでもたいしてハードは変わらない curl.exeをsystemコールするのだけど
その標準出力をバフに入れたり、バフの値を標準入力に入れたりするのってどうすればできるのだろう? >>779
オプションをつけて標準入力をcurl.exeで〜とかってのはコマンドライン上で実現できてるけど
それをコードで実現する方法が知りたいです const 無しのポインタ変数にリテラル文字列を与えると
C++だと (リテラル文字列の)指し先を書き換える気あるのかボケェ と警告やエラーになるですよ
Cは過去のコードの互換性の為に黙ってることが多い
(けどオプションで警告したりエラーにしたりするんだっけか?) "!"!"!MOHYO!"!"!"2"
1.[[[HUn≒MUL=POSI≠MAHO+Set*HUGE=SAGE=LOGE=NOISIA=0≒1]]]
2-[[[[[[[E=RAT%2^10%SPELAn!%]&!TOWA&!PEG#!NOLNOL8!#!HYAGO!2#]1*2=1]U]S]0]O]!#PAL!
3--->PAGODOL7&!@17,2222734.15&[[[%%RENRAK6,9,99"^10"]#$11.2%}]KAIJ]{
41.2SSS = RALQI2.β{{{RA4,0,238^97,1,$.S.L.E.I.L."Q5352.15Q"JOL"5*3>>>41.3q}}}>1.2<0
.3φTALHOSI"0">>>105.10<1.235<1.2>51≠52===55.632>V="E=0.835"of"1.32","632",0.683,1.end
{ >>779-780
Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。
例えば下は、メモ帳の実行ファイルの場所を探す
resText = ""
IO.popen("where notepad") { |io| resText = io.read }
puts resText
出力結果
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe >>779-780
Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。
これで、サイトのHTML が取れる
resText = ""
IO.popen("curl サイトのURL") { |io| resText = io.read }
puts "終了ステータス : #{$?}", resText >>779
system()ではなくpopen()使うと楽だ。 色々ありがとう
>>785
Linuxだからそいつは無理なんだ...
>>787
>>788
すまん
Cは決定で、さらに言うとexecvで実行も決定なんだ
実行部のソースコードの変更はしたくないので... curl.exe を Linux で?
こりゃ触っちゃダメな人だな Linux なら、curl はコマンドである。
環境変数PATH も通っている
which curl で、
/usr/bin/curl
>>787
これは、Windows10 のWSL 上の、Ubuntu 16.04 で、Ruby で実行したもの >>790
すまねぇ
正確に言うとcurlだった
実行ファイルってのを言いたかったんだけど紛らわしかったわ....
>>791
コマンドラインで実行をコード上からして
その結果をメモリに書き込みたいって感じ
int main()
{
char* buff[1024]
execv(curl..........)
}
子プロセス作成とかは書いてないけどこのexecvの結果をbuffにいれたい >>779 と >>789 は同じ投稿者なのかな?
「curl.exeをsystemコールする」という文の意味は、
実際には curl.exe でなく /usr/bin/curl かどこかの Linux のコマンド、
systemコールと言っても system() 関数でなく execv() 関数で呼ぶ、
という条件でいいの? >>793
同じです
メチャクチャ困惑させてすみません
そうです #include <unistd.h>
#include <stdio.h>
int main() {
int pp[2];
pid_t pid;
pipe(pp); // パイプを生成 (エラーチェック略)
pid = fork(); // プロセスを複製 (エラーチェック略)
if (pid > 0) {
// 親プロセス: 子プロセスから情報を受け取る
close(0); // 標準入力のディスクリプタを閉じる
dup(pp[0]); // パイプの入力を標準入力に複製
close(pp[0]); // パイプの入力を閉じる
close(pp[1]); // パイプの出力側は使わない
char buf[1024];
int nbytes = read(0, buf, sizeof(buf)); // 子プロセスからのデータ受け取り
printf("[%*s]\n", nbytes, buf); // 受け取ったデータの確認
} else {
// 子プロセス: 外部コマンドを呼び出し、標準出力経由で親プロセスに送る
char *cmds[] = { "/usr/bin/echo", "hello, darling", NULL }; // ダミーの外部コマンド
close(1); // 標準出力のディスクリプタを閉じる
dup(pp[1]); // パイプの出力を標準出力に複製
close(pp[1]); // パイプの出力を閉じる
close(pp[0]); // パイプの入力側は使わない
// 外部コマンドの呼び出し (エラーチェック略)
execv(*cmds, cmds);
}
return 0;
} 自分で fork, exec するなら pipe() 作って dup() で繋げ。
やり方はUNIXやLinuxのシステムコールに関する入門書みたいなのがあれば必ず書いてあると思うのでそういうのを見るか、またはググれば世界中で解説やサンプルプログラムが見つかると思う。
かなり基本的な事だ。 急造のデッチ上げだけど、こんな感じかな。
要点は、名前なしパイプを作って標準入出力と差し替える。
外部コマンドの標準出力はパイプを通って出ていく、
呼び出した側は標準入力を読むとパイプから入ってくる。
32行制限に収めるために行が詰めたら見にくいね。 などと書いている最中に真上にサンプルプログラム出現w curlだったら、オプションで全部ファイルに書き出せるじゃないか 親プロセス側は標準入力をパイプに差し替える必要ないね。
パイプのディスクリプタから素直に読みゃいいんだわ。
// close(0); // (不要)標準入力のディスクリプタを閉じる
// dup(pp[0]); // (不要)パイプの入力を標準入力に複製
// close(pp[0]); // パイプの入力側はまだ閉じちゃダメ!
close(pp[1]); // パイプの出力側は使わない
// int nbytes = read(0, buf, sizeof(buf)); // (変更)
int nbytes = read(pp[0], buf, sizeof(buf)); // 子プロセスからのデータ受け取り
close(pp[0]); // 使用済みパイプの入力を閉じる >>801
本物らしいな
しかも解説ドキュメント付
やっぱオープンソースよりプロプライエタリのほうが忖度が充実してるね 流出どころかAppleがそもそも堂々と公開してるじゃないか >>808
OSのソースコードはないじゃん(´・ω・`) ■ このスレッドは過去ログ倉庫に格納されています