C++相談室 part144

■ このスレッドは過去ログ倉庫に格納されています
2019/07/22(月) 13:18:35.52ID:gptRHpgT
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part143
https://mevius.5ch.net/test/read.cgi/tech/1560574313/

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

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

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)

----- テンプレ ここまで -----
2019/08/05(月) 22:17:59.20ID:vqN4pUkV
無駄だと思うならtypedefやusingすりゃいいじゃないか
そもそもstringって名前長すぎだろ
2019/08/05(月) 22:26:34.39ID:xngMWyKF
usingである程度の広さのスコープでやるんが正解だろ。
まあこのある程度の広さってのが人によってだいぶ違うだろうが。
2019/08/05(月) 22:37:46.60ID:vqN4pUkV
少なくともstdは普通using namespaceしないよね
でかすぎる
最近良くやるのは
namespace fs=std::filesystem;
だな

まあこれもヘッダで使うなら独自namespaceに入れてからだが
2019/08/05(月) 23:33:53.82ID:/t1yyPXk
using namespace std;をグローバルなスコープでやってしまうと
ソースコードを他に持って行ったとき困る
fooをstd::fooに変換するのはfooの種類が100台になると並みのエディタの置換機能では手間的にアウト
一方std::をとるのなら簡単にできる
std::をつけるのは将来への投資といえる
2019/08/07(水) 02:10:18.89ID:/mJrMLHD
初心者除ける、上級勘違い中級者こそ、出て行ってくれないかな。
本当の上級者は、プログラミング初めての人でも、優しくあたってくれますよ。
2019/08/07(水) 02:48:46.85ID:tJwlIUsZ
>>360=>>348
362360
垢版 |
2019/08/07(水) 03:17:50.31ID:/mJrMLHD
>>360 = not(>>348)
ですが。
証明方法は無いですから、わかりませんけどね。
363360
垢版 |
2019/08/07(水) 03:53:56.72ID:/mJrMLHD
>>342
各1万行30ファイルは、セーフですか?
2019/08/07(水) 08:04:40.03ID:go9nzBX4
入れ子となったクラスの内側のクラスから外側のクラスのprivateメンバにアクセスできるという
内側のクラスの特権はJavaやC#と同じくC++にもあるから、これを使って大規模なStateパターンでも書いた日には
ソースコードの行数も大規模にならざるおえない
このとき上記3言語の中で唯一大規模にならずに済むのはクラスの分割定義が可能なC#だけ
2019/08/07(水) 09:17:55.92ID:eqkXQjzY
まず日本語を勉強しましょう
2019/08/07(水) 09:31:41.35ID:ZWXmwdWw
昨今のプログラミング用語における入れ子は界隈に限らず日常的に使われているが
プログラミング業界では特に再帰的構造を指す場合にも多く使われる

そこに非常に現代的な特殊用語たる「出し子」が加わると
一般人は入れ子と出し子が対になっていると思い込む
2019/08/07(水) 09:45:33.66ID:Io4EJaZl
入れ子の内側のクラスは別ファイルに定義できる
2019/08/07(水) 09:55:09.68ID:FLvBFSJD
好きなだけわけてincludeすればいいじやん
2019/08/07(水) 23:36:21.14ID:gdjRebyd
スコープにあった変数名の長さにするべきとかそういうのお前らは習ってねーの?
2019/08/07(水) 23:50:58.34ID:db+FOt2P
そういう感覚的なルールいらない
チェックできないルールはなくていい
2019/08/08(木) 00:01:50.09ID:QQC8VFJ9
>>370
感覚的な部分を必要とすべきでないなら全てアセンブラで書けばか。
2019/08/08(木) 03:03:18.83ID:2Zq4F03j
>>370
チェック出来るルールに完璧に沿って書けてるボクちゃん偉い!エッヘン!
ってこと?
ユーザーからしたらクソの役にも立たねーよそれ
2019/08/08(木) 03:51:27.57ID:TsWml31+
errnoに謝罪しる
2019/08/08(木) 05:46:38.89ID:FTUf1Nuq
>>367
1行で2クラス以上定義しないという原則を守る限り、30億状態あったら外側のクラスはどうがんばっても30億行未満では書けない
この場合でも30億行未満で書けるのは分割定義できる言語だけ
また、内側のクラスを使わない普通のStateパターンなら30億ファイルに分割してかけばだいたいおk
(1状態から遷移し得る状態の数による。30億状態のどれにでも遷移しえる状態、
 みたいな極端なやつはさすがに遷移先状態クラスの#includeで30億行になるが

>>368
おk
2019/08/08(木) 06:53:52.07ID:5ZN2ymvH
頭悪そう
2019/08/08(木) 10:31:27.94ID:llWdm4EH
それは設計の問題でしょ
30億通りのstateパターンで設計する方が悪い
言語の問題じゃあないな
あり得ないヘンな例を持ち出してdisる詐欺師の方法だ
2019/08/08(木) 21:15:10.76ID:lDut6bjR
>>359
ファイル単位でそのまま使えや
コピペして改変部分があるとか当たり前のこと言うなよwwww
2019/08/08(木) 22:58:59.35ID:TsWml31+
コンパイル時に発覚する程度のエラーなら許容範囲でしょ。
2019/08/09(金) 00:11:55.59ID:LbUkdyT/
c++で想定外の場合にエラーメッセージとその行数を出して終了させたいのですが、
どのようにしたらできますか?
下記のようにしてもexitした行数が出ません。。

::fprintf(stderr, "error.\n");
exit 1;

perlのdie()のようなものをイメージしています。
2019/08/09(金) 00:39:22.71ID:Ps8ScE7S
::fprintf(stderr, "error. (line: \d)\n", __LINE__);
とか
2019/08/09(金) 22:56:01.92ID:nHekiGzf
丁寧にエラーメッセージ出すよりデバッガでバックトレースかけた方が早かったりするのは内緒
2019/08/09(金) 23:44:34.34ID:4GlakzRE
右辺値参照ってconst参照という認識でOKですか?
2019/08/10(土) 01:07:05.35ID:uRDSBt/F
>>382
moveで中身を奪い取るからconstじゃだめよ。
2019/08/10(土) 06:27:08.55ID:9vKRFOhk
>>381
そりゃデバッガ使える状況ならその方が速いことは誰でも知ってるだろw
385379
垢版 |
2019/08/10(土) 09:48:42.90ID:bGTBV06s
>>380
その方法で目的の動作ができました。
行の最後にexit入れたら一行でかけて良さげな感じです。
ありがとうございました。
::fprintf(stderr, "error. (line: \d)\n", __LINE__); exit(0)

>>381,384
バックトレースというものを知らなかったのでググりました。
色々なものがあるようですが、gdbの下記程度の使い方なら自分でもできそうなので
これをちょっとづつ使ってみようと思います。

ttps://rat.cis.k.hosei.ac.jp/article/devel/debugongccgdb1.html
2019/08/10(土) 15:57:01.40ID:lQ/anG82
ググってもなかなか出てこないが__LINE__はlong型だったと思った!
2019/08/10(土) 16:00:35.87ID:Azv7NalM
>>386
intじゃないの?
まあクロスの場合開発環境側のintな気もするが
2019/08/10(土) 16:25:20.56ID:SX6PRfyx
intでダメなファイルとかそもそもコンパイルできねーだろ。
2019/08/10(土) 16:36:59.44ID:Azv7NalM
2GBの¥nの後にソースかいてみるとわかるかなw
2019/08/10(土) 16:48:09.53ID:9vKRFOhk
>>387
> まあクロスの場合開発環境側のintな気もするが
そんなアホなw
2019/08/10(土) 16:57:47.58ID:Azv7NalM
いや、多分そこまで考えてないから、コンパイラ上ではintもしくはsize_tで
マクロ展開時は文字列化して接尾の型指定とかつけないだろ

勝手につけられると逆に困るし
2019/08/10(土) 17:01:16.99ID:lQ/anG82
int型はターゲットアーキテクチャーで一番自然な型というのが本来の意味なのでソースコードの最大行数と関係する理由が無い
C++の最新規格ではどうなったかわからんが、longは規格上32 bit固定なのに対してintは16 bitのアーキテクチャーが有り得るはず
2019/08/10(土) 17:02:52.50ID:sTg7TrG2
32bit固定?
2019/08/10(土) 17:06:31.95ID:Azv7NalM
longが32bit固定なシステムは64bitでは異端じゃね
まあwindowsはLLP64っぽいが
2019/08/10(土) 19:05:34.69ID:bGTBV06s
バイナリファイルを一度に読み込もうとしています。
圧縮ありファイルと圧縮なしファイルを以下のように判定して読み込もうとしているのですが、
ファイルの全てを読み込む方法がわかりません。
@Aはどのようにしたら良いですか?

http://codepad.org/FwYwQ62R
2019/08/10(土) 19:14:37.23ID:J81sqFQj
std::
これ自体は大した量ではないとは思うけど
これが何百何千と書かないといけないなら省略できる方法は必要だと思う
省略して且つ安全で簡単な方法が無いのが問題なんだと思う

ここまで読んででusing宣言を書き連ねたファイルを用意して
関数定義の次の行で#includeするのが今の所一番良い様な気がした

const何かも余りに書きすぎるので
これも何らかの形で省略できる記法を搭載できないのだろうかとは思ってる
classのpublic:
みたいに
const:
とかするとその後は記載しなくてもconst宣言になる
みたいな方法を搭載したりはしないのか?
と何時も疑問に思う
2019/08/10(土) 19:18:00.44ID:kKf7NMjX
>>395
malloc
2019/08/10(土) 19:26:04.25ID:jgcB4xBs
>>396
constこそusing書き連ねたファイル用意してincludeすればいいのでは

using cchar = const char;
using cuchar = const unsigned char;
using cint = const int;
using cuint = const unsigned int;
2019/08/10(土) 20:32:30.45ID:pnnBC1tu
>>396
その疑問の答えは、あなたが具体的な提案を標準化委員会に持っていかない理由の答えと同じでしょう。
2019/08/10(土) 20:36:22.66ID:qcH7oj7q
constじゃないのにmut書かされる方が面倒
2019/08/10(土) 20:51:51.67ID:TQTMDKQQ
c++20のimportで解決するだろうか。
2019/08/11(日) 00:40:56.64ID:khTmYGk1
>>397
ありがとうございます。
とりあえず圧縮なしの方は以下で取得できたようです。
ここで一点疑問です。
mallocの値がぴったり正しいかの確認をしようと、下記5行目のdatasize+1を-2や-3にしたのですが、
printf()で最後まで値が正常に出てきます。
datasize-3としてもたまたま連続して拾っているだけなので問題ありだと思うのですが、
malloc(datasize)ではなく、malloc(datasize+1)でぴったりメモリ確保ができているのでしょうか?

unsigned char* data;
long datasize;
fseek(fp, 0, SEEK_END);
datasize = ftell(fp);
data = (unsigned char*)malloc(datasize+1); // +1を-2, -3にしてもprintf()では最後まで正常な値が出てくる。
if( data == NULL ){
exit(1);
}
fseek(fp, 0, SEEK_SET);
fread(data, 1, datasize, fp);
fclose(fp);
for(int i=0; i < datasize; i++){
printf("%02x\n", data[i]);
}
2019/08/11(日) 00:49:51.23ID:KV8Qszx5
割り当てされてない領域に書き込むというのは、C/C++ではあり得る。
そこに他に意味のあるデータがあれば、そのデータは壊れる(データ破壊)。
2019/08/11(日) 07:16:49.27ID:bWvktEwN
>>402
処理系によるけど大抵の処理系では指定されたサイズをきっちり確保とかはしなくて16バイト単位くらいで確保する
なのでそのdatasizeの値によっては-15とかしても大丈夫な場合すらあることがある
もちろん動作は保証されない
2019/08/11(日) 08:16:38.18ID:8PrAFYrU
> malloc(datasize)ではなく、malloc(datasize+1)でぴったりメモリ確保ができているのでしょうか?
malloc(datasize)で十分、malloc(datasize+1)だと1つ余分
freadでもprintfでもdatasize個までしかアクセスしていないので
2019/08/11(日) 09:14:50.61ID:G1nCiIo0
とりあえずvalgrindかけてみるのが良い。
2019/08/11(日) 10:12:56.60ID:rgBQlH0q
昔みたいにメモリ枯渇なんてそうないし誰かがデータ破壊やらかして休みに呼び出し食らいたくないので16バイトくらい余計に確保しとこ
2019/08/11(日) 10:13:58.51ID:5go57VsQ
なんでビット単位で確保できないんですか?
2019/08/11(日) 10:36:40.97ID:x7hs8Ubh
面倒だし遅いし...
2019/08/11(日) 10:41:05.01ID:EQYlQ9TU
CPUがそう出来てないから
411395
垢版 |
2019/08/11(日) 11:36:18.32ID:khTmYGk1
>>404
malloc()は数を指定していて、for分でアクセスしているdataは配列だから最後はdatasize-1ということですね。
僕の理解と合いました。
malloc(datasize)とします。
ありがとうございます。

次にgzipの全読み込みも調べています。
とりあえず下記でout.dbと展開後のaaa.dbのcksum値が一致したのでちゃんと読み込めたと思います。
※1のところで配列に格納すれば良いと思うのですが、最初は配列の数が確定していないので
配列数を決定することができません。
読み込むファイルサイズはギガバイトクラスの大きなファイルなので、なるべく速度を維持したまま
一つの配列に格納したいのですが、どうすれば良いですか?

FILE *wfp;
gzFile rzp;
unsigned char buf[8192*1000] = {0};

rzp = gzopen("aaa.db.gz", "rb");
wfp = fopen("out.db", "wb");

while((cnt = gzread(rzp, buf, sizeof(buf))) > 0){
fwrite( buf, sizeof( unsigned char ), cnt, wfp );
※1 ここで全データを一つの配列に格納したい。
}

gzclose(rzp);
fclose(wfp);
2019/08/11(日) 12:32:14.46ID:G+0fIs5w
gzipって全部読まないと展開後の長さ分からないんじゃね
2パスにするとか
2019/08/11(日) 17:00:08.00ID:x7hs8Ubh
qiitaでさC++のタグ検索したらcppreference.comが公式リファレンスと書かれてたけどここ公式なの?
2019/08/11(日) 17:08:33.67ID:CsmlJ4sC
>>413
https://ja.cppreference.com/w/Cppreference:FAQ
このサイトの背後にいるのは誰ですか?
cppreference.com は世界中の C++ 愛好家のグループによって作成され、メンテナンスされています。
415395
垢版 |
2019/08/11(日) 18:01:46.19ID:khTmYGk1
>>412
コメントありがとうございます。
全部読む以外に調べる方法は無いんですね。
ということでrealloc()で拡張していくことを考えてみました。
下記で作られた解凍後のデータがgunzipで解凍したものと一致したので大丈夫そうです。
ありがとうございました。

#define MAX_BYTE 8192*1000

data = (unsigned char*)malloc(MAX_BYTE);
rzp = gzopen("aaa.db.gz", "rb");
long data_size = 0;
while((cnt = gzread(rzp, data+data_size, MAX_BYTE)) > 0){
data_size += cnt;
data_new = (unsigned char*)realloc(data, data_size+MAX_BYTE);
if( data_new == NULL ){
free(data);
::fprintf(stderr, "拡張失敗\n");
exit(EXIT_FAILURE);
}
// アドレスが変化した場合
if( data != data_new ){
// free(data); // 元オブジェクトは解放済みのため不要
data = data_new;
}
}
gzclose(rzp);

// 解凍後データを書き込み
wfp = fopen("out.db", "wb");
fwrite( data, sizeof( unsigned char ), data_size, wfp );
fclose(wfp);
2019/08/11(日) 18:25:47.16ID:bWvktEwN
>>415
そんなでかい領域をreallocすると何度もコピーするはめになるから>>412の言うように2パスにするか、各領域をリストで繋いて最後に一気にコピーするようにした方がいい
417395
垢版 |
2019/08/11(日) 19:34:48.78ID:khTmYGk1
>>416
2パスをググってもそれらしいものがなかったのですが、どういうものなのでしょうか?
あと、「各領域をリストで繋いて」というのはvectorに追加しながら最後に連結するということでしょうか?
2019/08/11(日) 19:44:47.41ID:bWvktEwN
>>417
> 2パスをググってもそれらしいものがなかったのですが、どういうものなのでしょうか?
1回目(Pass 1)ではデータの格納はせずにサイズだけ取得する
合計サイズ分を確保して2回目(Pass 2)で実際に格納するってこと

> あと、「各領域をリストで繋いて」というのはvectorに追加しながら最後に連結するということでしょうか?
そう言うこと
でかいデータはコピーにも時間がかかるからできるだけコピーしないようにした方がいい
419395
垢版 |
2019/08/11(日) 20:30:35.16ID:khTmYGk1
>>417
2パス良さそうですね。
gzread(rzp, data+data_size, MAX_BYTE)
のところを下記のようにNULLにしてもちゃんとファイルの最後まで動いているようなのですが、これがデータ格納せずにサイズを取得するということでしょうか?
gzread(rzp, NULL, MAX_BYTE)
2019/08/11(日) 20:43:01.53ID:khTmYGk1
すみません、NULLだとそもそも一回も取得できずに終わっていました。。
データ格納せずに一回ファイル精査するのってどうするんでしょうか?
2019/08/11(日) 21:37:44.09ID:vST/kP4M
>>420
固定長のバッファを1つ用意して、そこに上書きしながら繰り返し読み込めばいい。内容は上書きされて読めなくなるけど、読み捨てるつもりなので気にしない。
2019/08/11(日) 21:42:34.43ID:bWvktEwN
(最終的なところに)格納しないってことな
適当なバッファを1つ用意して毎回そこに格納しとけばいい
2019/08/11(日) 21:43:08.15ID:bWvktEwN
あっ、被ってた
2019/08/11(日) 22:55:38.50ID:khTmYGk1
>>421,422
そういうことですか、理解できましたありがとうございます。
2019/08/12(月) 00:27:35.40ID:Y24CRytA
vectorだって償却定時間なのに
ホントに2回読む方が速いんか?
2019/08/12(月) 00:55:04.06ID:owwy1DHX
valgrindってみんな開発に使ってるの?死ぬほど遅いんですが
2019/08/12(月) 09:13:50.21ID:QXujyVaw
でかい領域のreallocで毎回コピーが発生するというのは都市伝説、
と言いたいところだが他のスレッドが動いているとそうとも言い切れないかそうか、
この場合の2パス方式はgzipが2回走るのがいかにも実行時間の無駄でいやすぐる
最初に大きめの領域をmallocして足りんかったら2パスに切り替えるという投機的なやり方のが良い
2019/08/12(月) 09:18:32.18ID:QXujyVaw
だいたいいかにgzip様といってもファイルを毎回1/10まで圧縮できるわけはないのだから
読み込むファイルサイズの10倍を確保しておけばほぼ1パスで済む
展開後の実サイズがわかったら展開後の実サイズぴったりにreallocで縮小すれば良い

ちなメモリの断片化はガン無視
実使用サイズの倍のメモリも用意できないようなプアな環境のならmallocやreallocする設計から見直さねばならない
見直すべき
2019/08/12(月) 10:16:31.87ID:Mc0sgLDk
>>427
意味わからん
スレッドなんて関係ないだろ
2019/08/12(月) 10:19:40.97ID:QXujyVaw
>>429
ヒープメモリはスレッドで共有される
もしヒープメモリを使う他のスレッドが一切無いなら
realloc()でサイズ拡大してもコピーは生じない(後ろに領域伸ばせるから
この説明でまだ疑念が渦巻くのならプログラミング言語Cをきちんと読み直した砲が良い
(あのmalloc()実装例がmalloc()実装の全てとは言わんが基本
2019/08/12(月) 10:26:54.62ID:q+3SbcDd
そうとは限らんのでは?
2019/08/12(月) 10:28:45.76ID:Mc0sgLDk
>>430
断片化って知ってる?
> 後ろに領域伸ばせるから
これ常にできるわけじゃないよ
> この説明でまだ疑念が渦巻くのならプログラミング言語Cをきちんと読み直した砲が良い
お前がなw
2019/08/12(月) 10:35:35.84ID:q+3SbcDd
特にこの場合はgzipを使うからね
アウトプット用のメモリを確保した上でgzipを実行するわけだけど
gzipが内部で動的にメモリを確保するかしないかは知らんけど、多分するでしょ
そうすると新たに論理アドレス空間が使われるから
連続したメモリ空間を後ろに拡張できるかって言われるとね
2019/08/12(月) 10:43:33.86ID:QXujyVaw
>>431-433
んまーそれはそうやったorz
あと今回のgzip展開ルーチン呼び出し前にmallocした領域がたまたま後ろに居る可能性もあるな!
しかし>>428-428は断片化が生じないと言っているのではないし主目的のgzip読み込みに関しては
断片化による影響を受けにくくしているのだから大枠問題無い
良い良い、良いではないか
435395
垢版 |
2019/08/12(月) 11:18:22.87ID:lzJUIRtk
色々とご意見ありがとうございます。
どなたかの役にたてばと思い僕が調べた内容をお知らせします。

gzip展開後に5GBくらいになるデータでテストしてみました。

@time ./a.outで簡易的に時間取得
Arealloc方式の場合 >>415 の下記部分でコピーが何回発生しているかをカウントしてみる
// アドレスが変化した場合
if( data != data_new ){
// free(data); // 元オブジェクトは解放済みのため不要
data = data_new;
copy +=1; // コピーした回数をカウント
}else{
not_copy +=1; // コピーせずに拡張できた回数をカウント
}

結果は以下のようになりました。
強力なサーバでメモリが潤沢にあるためか、コピーがほとんど発生しないようで
realloc方式が早かったです。
本日祝日でサーバ使用者が少なく、よりコピー回数が減っていると思います。
個人PCでchromeにメモリ食われたりするとコピーが増えて逆転するかもしれないですね。
環境に合わせて変えようと思います。

# 2パス方式(約27秒)
./a.out 25.12s user 1.27s system 99% cpu 26.479 total

# realloc方式(約15秒)
./a.out 12.73s user 1.46s system 99% cpu 14.263 total
-> コピー 1
-> notコピー 636
2019/08/12(月) 11:33:43.60ID:ejXFqJv3
と言うことは、vectorだと遅くなるんかね
2019/08/12(月) 12:00:43.69ID:QXujyVaw
malloc()されたりrealloc()されたりするヒープメモリは仮想アドレス空間に対応した普通のOSならプロセス毎に別空間だから
他のプロセス(他のサーバ利用者が居る or chrome)があってもヒープメモリの断片化に関係しないはず…

さらに、2パス方式の時間が1パス方式の倍になるのはメモリコピーよりもgzip展開を2回もやることが利いているでケテーイ
438395
垢版 |
2019/08/12(月) 16:26:30.60ID:lzJUIRtk
すみません、また疑問が出てきたので相談させてください。
今読み込んだバイナリファイルの解析をしています。
ある一部の8バイトがビッグエンディアン形式で下記になっていて、これが少数点の数値で「2.500000e-04」となるようです。
3e 10 62 4d d2 f1 a9 fc

次に下記URLを参考に調べると今使っているサーバはリトルエンディアンでした。
(CPUはintel)
ttps://qiita.com/ryuichi1208/items/31442f9e8a7a7c94aeec
このため ビックエンディアン→リトルエンディアン の変換が必要と思うので下記のようにしました。

unsigned char t[8];
double little;
for (int i = 0; i < 8; i++) {
t[i] = data[7-i]; // バイトオーダーの変換
printf("%02x ", t[i]);
}
printf("\n");
memcpy(&little, t, 8);
printf(" %e\n", little);

---結果---
fc a9 f1 d2 4d 62 10 3e
9.536743e-10
----------

ちゃんと反転できていますが、結果は期待値「2.500000e-04」ではありませんでした。

>>続きます
439395
垢版 |
2019/08/12(月) 16:29:26.29ID:lzJUIRtk
次に実際の値を16進数表示したときの確認として下記を実行したところ、結果は以下のようになりました。
int main(){
double data = 2.500000e-04;
unsigned char *p;
int i;
p = (unsigned char *)&data;
for (i = 0; i < 8; i++) {
printf(" %02X", p[i]);
}
printf("\n");
printf("%e\n", data);
return 1;
}

---結果---
FC A9 F1 D2 4D 62 30 3F
2.500000e-04
----------

比較すると、最初の6バイトは同じですが最後の2バイトが違いました。
どうやったらバイナリデータに入っている 「3e 10 62 4d d2 f1 a9 fc」 を 「2.500000e-04」 に変換できるかわかりますでしょうか?
ビッグエンディアン→リトルエンディアン の変換時にもうひと工夫いるのでしょうか?
2019/08/12(月) 16:44:49.60ID:L6hDiPeu
2.500000e-04のIEEE754表現は3f30624dd2f1a9fcだぞ
元のバイナリの解釈間違ってんだろ
2019/08/12(月) 16:54:28.94ID:dO9cEAMi
>>426
開発っつーか本当にどうしようもないバグの場合は使う。
遅いって言っても5〜10倍くらいだろ。
2019/08/12(月) 16:55:20.98ID:L6hDiPeu
2.500000e-04/9.536743e-10≒262144=2^18だからどっかで誰かが18ビットシフトしてないか調べろ
あとはそのバイナリ作った野郎に聞け
2019/08/12(月) 17:38:07.40ID:ejXFqJv3
decimal64だったりして
サーバのCPUは何?
444395
垢版 |
2019/08/12(月) 18:15:44.42ID:lzJUIRtk
>>440,442
データの方が違うんですかね。。
今調べてますがまだわかりません。

>>443
xeonです。
decimal64というのはまだ調べていませんがまたちょっと違う変換になるんですかね?
2019/08/12(月) 18:17:10.91ID:ejXFqJv3
サーバじゃないか
もとデータ生成したビッグエンディアンのCPUは何かと
446395
垢版 |
2019/08/12(月) 18:32:01.51ID:lzJUIRtk
同じサーバで生成されました。
生成したソフトは販売されているものなので問題はないと思うし、
他のソフトで読み取ってもちゃんと 2.5e-04 が出てくるのでデータに問題はなさそうです。
なぜそう読めるのか不思議です。。
2019/08/12(月) 18:32:06.77ID:Mc0sgLDk
Big Endian だし IBM フォーマットとか?
2019/08/12(月) 18:34:28.15ID:Mc0sgLDk
>>446
> 生成したソフトは販売されているものなので問題はないと思うし、
なぜそのソフトの名前を書かないの?
> 他のソフトで読み取ってもちゃんと 2.5e-04 が出てくるのでデータに問題はなさそうです。
他のソフトって何よ?
みんなエスパーじゃないんだから出せる情報は出しなよ
449395
垢版 |
2019/08/12(月) 19:04:19.39ID:lzJUIRtk
>>448
すみません、calmaという大昔のもので今はもう販売されていません。
2019/08/12(月) 19:44:21.64ID:Mc0sgLDk
Calmaでググるとこれがヒットするけどこれかな?
https://en.m.wikipedia.org/wiki/Calma
これだとかなり古いソフトウェアだから浮動小数点のフォーマットが違うような気がする
451395
垢版 |
2019/08/12(月) 21:13:36.45ID:lzJUIRtk
>>450
数値をバイナリ変換していそうなコードを今見つけました。
ただのビッグエンディアン表記ではなさそうです。
もう少し調べて見ます。
452395
垢版 |
2019/08/12(月) 22:32:15.08ID:lzJUIRtk
下記で数値からバイナリへの変換ができましたが、何の計算をしているのかさっぱりわかりません……
逆変換できるのでしょうか?

http://codepad.org/oSvOJP1p

---結果---
変換前の値:0.000250
変換後の値:3e 10 62 4d d2 f1 a9 fc
----------
2019/08/12(月) 22:37:12.67ID:S6a2ieXo
>>452
>>447
2019/08/12(月) 22:47:45.27ID:ikUKzGwn
浮動小数の正規化っぽいけど
( A < 0.0625 ) || ( A >= 1.0 ) ってのが特殊だと思う
何かそういう事情があったんでしょう
浮動小数の正規化ってのは検索すればわかる
別環境でデコードするだけならたぶん気にしなくて大丈夫
2019/08/12(月) 22:50:05.37ID:ikUKzGwn
確かに、IBM方式ってやつっぽい
気にしないといかんわw
無駄なこと書いてごめんね
456395
垢版 |
2019/08/12(月) 23:17:08.77ID:lzJUIRtk
>>453-455
ありがとうございます。
今 IBMフォーマット や IBM方式 でググってますが中々それらしいものが出てきません。
かなりマイナーなものなのでしょうか?
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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