スレを勃てるまでもないC/C++の質問はここで 25 [隔離病棟]©2ch.net

1 みんな空気読め©2ch.net2016/08/14(日) 00:04:05.53ID:z6U1tRVC

296デフォルトの名無しさん2018/01/27(土) 17:48:38.55ID:2gTl4aTp
√3やsin(1+√2)などの数式が示す値とfloatの大小比較?

297デフォルトの名無しさん2018/01/27(土) 18:07:06.21ID:2gTl4aTp
数式って言うと誤解を与えるのかな?

10進数表記可能な数値
数学的に定義可能な実数
それ以外

閾値はどれ?

298デフォルトの名無しさん2018/01/27(土) 18:28:25.65ID:EckHRazm
>>291
はい、それで問題ありません
上であげた√3の例は計算機で出してfloatには十分だと思える桁数で切っているだけです
入力データや計算誤差自体には許容的です

>>294
閾値の数は文字列から取得するわけではありません
ソースコード中のリテラル値として与えられるもので構いません
求めるものは、単純化して言うと
プログラム上のあるfloat値が、数学的な意味での実数X未満であるかそうでないかのbool値になります

>>297
10進数表記可能な数ということになります
たとえば√3も関数電卓などで求めた値で十分(20桁もあればfloatには十分すぎるだろう)という意味です

299デフォルトの名無しさん2018/01/27(土) 19:52:43.68ID:BU9rpSw9
>>298
floatの有効桁数は7桁だから

float x=1.7320508075688;

とするんじゃなくて、

float x = 1.732051;

とするしかないでしょ
それが嫌なら、もっと精度の高いdoubleを使うようにして

double x = 1.7320508075688;

として、これを閾値とすればいい
そして、そのことを予め顧客に確認しておけばいい
扱うデータの桁数を予め決めておくことは設計時の重要事項でしょ

何も問題は無いと思うけど、何を悩んでるのか分からない。

もし無理数を無理数のまま無制限の精度で扱いたいなら、もうそういうライブラリを使うしかない
あるのか知らんけど

300デフォルトの名無しさん2018/01/27(土) 20:13:29.55ID:EckHRazm
>>299
スレを後から読んだ人に混乱を広げないために念のために書いておきますが、無理数を無理数として扱う必要はありません
ついでに、計算の精度を高めたいわけでもありません

あらかじめ閾値になるfloat値を求めておけば済むというのはわかりますその通りです
早い段階で気づいていました
ですがそれだけだと変更に弱いですよね
実際に書き換えるのが三か月後の自分か赤の他人になるのかはわかりませんが
だれかの手作業で閾値のfloat値を再計算するより信頼性のある方法があれば、ということで質問を始めました

ただ5レス目しないうちから簡単には済まないだろうなとも思っていました

301デフォルトの名無しさん2018/01/27(土) 20:14:24.46ID:tkKoYj6x
だなー
float基準なんだからdoubleでもっときゃいい。これがdoubleでーってなってたら悩むがw

302デフォルトの名無しさん2018/01/27(土) 20:42:46.77ID:EckHRazm
doubleで持つ考えもわかります
ただfloatの丸め方がわかれば(あるいは制御できれば)問題は解決(>>301が悩むdoubleが必要な時にも拡張できる方法)だと思うのですが...
その方法が簡単でないということが分かったことは収穫...?でした

303デフォルトの名無しさん2018/01/27(土) 20:56:05.82ID:tkKoYj6x
floatの丸め方が分かったら、それを求めるために(floatが32ビット型だとしたら最低でも)33ビットで計算しないといけなくなるわけでしょ?
つまりは33ビット型を新たに作ることになるわけで・・・だったら最初からある64ビット型を使たほうがってw

304デフォルトの名無しさん2018/01/27(土) 21:11:10.44ID:EckHRazm
実行時の精度ではなく、コンパイラがソースコード中の数値文字列をどう機械語(float型)に翻訳するかということではないですか?
ソースコード上では20桁もある数値文字列を実際にコンパイラが適切な32ビット型に変換しているので
33ビット型とかいう変な方を導入するまでもないと思うのですが

実行時に実数がどうまとめられたかを知りたいわけじゃないんです

初期化式の右辺に来る数値リテラルをコンパイラ内部で何ビットで処理しようが関係ありませんよね?

実行時にfloatやdouble値の実体を持つ閾値が、切り下げられたか切り上げられたかを判断するのであれば
33ビットの浮動小数点数型が必要になるでしょうけども...

305デフォルトの名無しさん2018/01/27(土) 21:11:56.87ID:BU9rpSw9
>>302
floatの丸め方が知りたかったの?
round、floor, ceil とかあるじゃん

例えば、double型の小数部第6位で切り捨ててfloat型へ代入したければ、ありがちなやり方としては

double d = 1.7320508075688;
float f = floor(d * 100000.0) / 100000.0;

んな感じで

306デフォルトの名無しさん2018/01/27(土) 22:03:45.49ID:EckHRazm
実行時の変数の丸め方ではありませんよ
丸めという言葉はよくなかったかもしれませんすみませんでした
今はfloatの初期化式を書いた時にコンパイラがどう振舞うかということの意味です

それと前に10進数表記可能な数と書いたのは、単にソースコード上で
そう書き表すことのできる(√とかsinとかその他を使わない)数という意味で
10進数の数のある桁で四捨五入するという意味ではありませんでした

丸めという言葉もULPに対するものとして言ってるつもりでした
>>278で出てるのでこちらから出しませんでしたが言葉足らずでした重ねてすみまんせん


元々は1.7777777fupとか1.7777777fdownとか(桁数や表記法はともかく)
お手軽に意図通りの値に初期化できないものかと考えて質問しました
そうすれば、実数から浮動小数点数への翻訳方法(コンパイラによる切り上げ切り下げ)にかかわらず、
ソースコード上に記述されている通りの、数学的な大小関係を損なわないプログラムが書けると考えたからでした

次にいつここへ来るかわからないので今日の私の質問はこれで終わりにします
返答してくれた人たちは本当にありがとうございました

307デフォルトの名無しさん2018/01/28(日) 01:49:55.74ID:x3ZlVnQ6
2進数の小数リテラルの記述が出来るようになるんじゃなかった?
なんで今まで出来なかったのかが不思議だけど
それで満足なのか?

小数のリテラルの、コンパイル時の文字列から値への変換は
普通はその文字列が表す値に一番近い値になる

丸め方を自分で決めたければ、文字列から数値に変換するconstexpr関数を作れば良い

308デフォルトの名無しさん2018/01/28(日) 10:42:15.33ID:YQxX9lfa
2進で書いたってなんの解決にもならんよwww
リテラルのみだとしても結局はdouble分の計算が必要でしょ。計算するのがコンパイル前でも構わなくなるってだけ

309デフォルトの名無しさん2018/01/28(日) 11:03:46.96ID:Y4YkWHjI
二進できっちり仮数部23bitで書けばいいだろう
それなら1ULP未満切り捨てになる

310デフォルトの名無しさん2018/01/28(日) 11:14:12.99ID:YQxX9lfa
やりたいことは、その切り捨てがあるなら切り上げたいってことでしょ
だから切り捨てがあるかないかを事前に計算する必要ある

311デフォルトの名無しさん2018/01/28(日) 11:31:33.17ID:Y4YkWHjI
>やりたいことは、その切り捨てがあるなら切り上げたいってことでしょ

どこをどう読んだらそうなる
>>281は切り上げか切り捨てかどちらか特定できればいいって書いてるだろ

312デフォルトの名無しさん2018/01/28(日) 11:51:46.98ID:YQxX9lfa
> floatを実数Xで初期化する際にfloatではその数を正確に表現できない場合、少し大きいか小さいかでXに近い値になると思います
> そういう正確には表せない場合に、どうすれば初期化される値がXを下回らない最小の値となるようにできますか?

これを読んだらそうなる。特定したらこれが解決するでしょ。その解決のために計算が必要になる

313デフォルトの名無しさん2018/01/28(日) 12:11:57.99ID:Y4YkWHjI
そこしか読まないからそうなる
その後のレスでどちらでもよいと補足しているだろう

314デフォルトの名無しさん2018/01/28(日) 12:20:06.50ID:Y4YkWHjI
というか、

>2進で書いたってなんの解決にもならんよwww

これが否定されたのがそんなに我慢ならなかったのか

315デフォルトの名無しさん2018/01/28(日) 13:17:58.45ID:YQxX9lfa
> double分の計算が必要
むしろこっち否定しろよw

316デフォルトの名無しさん2018/02/01(木) 14:07:29.89ID:BjxdiDzB
二進リテラルでええやろ
それかstd::nextafterで切り上げるか切り下げるか

317デフォルトの名無しさん2018/02/01(木) 20:59:41.19ID:uG0JSReu
二進リテラルはいいが、nextafterはちょい違うな。

318デフォルトの名無しさん2018/02/02(金) 10:30:51.76ID:ahF+s6Dw
2進小数を10進小数に変換出来るツールの提供と
リテラル記述箇所へのコメント

現実的な解はこの辺かと

319デフォルトの名無しさん2018/02/02(金) 12:14:54.40ID:NAEfRvIa
そういう設計にするとバグ出まくり。しかも発見が非常に困難
普通に仮数部足す関数作ってそれかましておけばいいでしょ

320デフォルトの名無しさん2018/02/02(金) 13:00:05.92ID:ahF+s6Dw
足す?
何を?
どうやって?

321デフォルトの名無しさん2018/02/02(金) 13:15:59.60ID:NAEfRvIa
力技でビット演算してもいいし、仮数部1ビットだけ建てたの用意して普通に加算してもいいでしょ

322デフォルトの名無しさん2018/02/09(金) 16:44:31.74ID:9b+Wa+Ns
hoge(int *) という関数があり、hoge(&a) とすれば a に値を返す仕組みとします。
ここで、char a をキャストして hoge((int *)&a) として実行した場合、意図した結果が返されない
ケースがあるのはいいとして、他に問題はありますか?

例えば、hoge()自身は渡されたものが int のポインターなんだから char 以上のメモリー範囲を
超えて書き込むからメモリーが破壊されるといったことが起こりますか?

323片山博文MZ ◆T6xkBnTXz7B0 2018/02/09(金) 17:01:41.47ID:owaGciqs
>>322
最適化を無効にして
char ab = 0x7F;
char a;
char aa = 0x7F;
hoge((int*)&a);
printf("%d, %d, %d\n", ab, a, aa);
で試してみて。

324デフォルトの名無しさん2018/02/09(金) 17:32:12.48ID:9b+Wa+Ns
>>323
既に稼働してるシステムで上記の箇所を見つけはしたものの、何食わぬ顔をして動いていたので
疑問に感じていましたが、新規プロジェクトで試したら一発でしたね。
スタックオーバーフローでした。
どうもありがとうございました。

325デフォルトの名無しさん2018/02/09(金) 20:59:14.12ID:9QnGJOcV
>>322
条件によっちゃよくやる
例えば
char a,b,c,d;
こんなのでaのアドレスに対してint読み出しかけて、abcdくっつけたint16値を取り出すとか
その逆にint16値をaにキャストしてabcd個別にアクセスとか
ただ連続したメモリ空間に入らないことがあるから、
その辺はstructでまとめたり、pragma packやら何やらで指定しとくとか、プラットフォームとコンパイラに合わせる

326デフォルトの名無しさん2018/02/10(土) 09:55:27.64ID:sEVENX79
>>325
横からでごめんやけど
int nとchar a,b,c,d,x[12]をunionってのはやら無い方がよさげ?

327デフォルトの名無しさん2018/02/10(土) 10:44:47.90ID:A/uZfZpr
unionで書いたほうがスマートなこともあるな。その逆なこともある
動作自体は何使っても同じだから、ソースの見やすさやclass設計考えながら選択したらいい

328デフォルトの名無しさん2018/02/16(金) 01:33:43.00ID:Ja2iVc8/
構造体の、一部のみゼロ埋めする方法を知りたいです
CコンパイラはMingw-win32のgcc 6.3.0を使ってます

struct aaa_tag{
 uint32_t a;
 uint32_t b;
 uint32_t c;
   :
 uint32_t z;
}
という構造体に、fread(&aaa, sizeof(aaa), 1, fp)でファイルから値を読み込んでいるのですが
実は構造体としてファイルから読み込むべきサイズが条件により変える必要があります
例えば以下のようにです
・bが1の場合は有効なのはaとbのみ。c以降の値はゼロで書き戻す
・bが5の場合は有効なのはa〜wまで。x以降の値はゼロに書き戻す

まずbを読んで、それから必要なサイズを読み出す…も考えたのですがそうではなく、
構造体の途中以降をゼロクリアしようと思っているのですが、これがうまくいきません
if (b == 1)memset(&aaa + sizeof(uint32_t) * 2, 0x00, sizeof(aaa) - sizeof(uint32_t));
等と試行錯誤しているのですが、SIGSEGVが出てしまいます

解決法を教えていただけますか

329片山博文MZ ◆T6xkBnTXz7B0 2018/02/16(金) 06:04:46.72ID:tdYV0Px7
上から順番に読み込むか、fseekで読み込み位置まで移動してから読み込む。
位置はoffsetofとかFIELD_OFFSETという名前のマクロを使う。そのようなマクロがない場合は自作する。
読み込むときは、位置とバイトサイズによく注意すること。また、NULLや無効な場所に読み込んではいけない。

330デフォルトの名無しさん2018/02/16(金) 06:11:24.04ID:W1XJdyx1
☆ 日本の、改憲を行いましょう。現在、衆議員と参議院の
両院で、改憲議員が3分の2を超えております。
『憲法改正国民投票法』、でググってみてください。国会の発議は
すでに可能です。平和は勝ち取るものです。お願い致します。☆☆

331デフォルトの名無しさん2018/02/16(金) 06:26:26.41ID:6scYlSnj
>>328
セグメンテーションフォールトを起こす直接の原因は、
memset() の第1引数 &aaa + sizeof(uint32_t) * 2 の部分だろうね。
printf("%p\n", &aaa);
printf("%p\n", &aaa.c);
printf("%p\n", &aaa + sizeof(uint32_t) * 2);
上の3行の出力を比較検討すると理屈が分かると思うけど説明は長くなる。
というか、俺にはポインタ加算について短く平易に説明する能力がない。


#include <stddef.h> // offsetof()マクロの定義
if (b == 1)memset(&aaa.c, 0x00, sizeof(aaa) - offsetof(struct aaa_tag, c);

で動くと思うけど、
ダミーの構造体に読み込んでから、bの値を見て有効な部分だけ
(あらかじめ0クリアしておいた)返却用の構造体にコピー、とする方が素直かも。

332デフォルトの名無しさん2018/02/16(金) 12:40:06.06ID:6scYlSnj
カッコの対応が合ってないね。

× if (b == 1)memset(&aaa.c, 0x00, sizeof(aaa) - offsetof(struct aaa_tag, c);
○ if (b == 1)memset(&aaa.c, 0x00, sizeof(aaa) - offsetof(struct aaa_tag, c));

333デフォルトの名無しさん2018/02/16(金) 20:12:13.91ID:hi0D4ZsY
>>328
構造体のアラインメントでぐぐれ

334デフォルトの名無しさん2018/02/16(金) 20:28:30.02ID:Ja2iVc8/
328です
皆様情報ありがとうございました
構造体先頭から末尾までのmemsetとは事情が違うということが分かりました

offsetof()やダミーの構造体など、方針を見直します

ありがとうございました

335デフォルトの名無しさん2018/02/16(金) 21:00:38.75ID:hi0D4ZsY
だからアラインメントでぐぐれって・・・
それむこうにすればできるから

336デフォルトの名無しさん2018/02/16(金) 21:26:52.07ID:5NiD1AgL
328のセグフォはアドレスとポインタの違いが分からない時にやらかすミス

337デフォルトの名無しさん2018/02/16(金) 22:05:59.54ID:qDhjnryl
アライメント無視して詰め込むとミスってバスエラーになるからやらないな

338デフォルトの名無しさん2018/02/16(金) 22:59:31.13ID:IhCFworu
>>335
>>328のケースではアラインメントを無効化してもダメだろうよ

339デフォルトの名無しさん2018/02/16(金) 23:35:42.63ID:wAiK151t
>>336が正解だろう。アライメントは関係ない。

340デフォルトの名無しさん2018/02/16(金) 23:47:57.54ID:Ja2iVc8/
>>335
アライメントについては、OS、アプリ共に32ビットであり、
メンバも32ビットに揃える(パディングはさせない)ように
考慮されてはいるので、無効にしてみましたが変化はなさそうです

__attribute__ ((packed))付与有無でsizeof(aaa)としてみましたが、
どちらも4バイト×メンバ数となり、やぱりパディングは
されていないのかなと

>>336
構造体は、パディングに関わらず先頭以外の場所へmemsetやmemcpyで
触ってはならないのだろう、という思いに至り、方針を見直そうと思ったのですが
実際、書くとしたらどう書くことになるのでしょう
例えば、a〜zまで並べられているメンバ中、cからyまでゼロで埋める…みたいなので…

341デフォルトの名無しさん2018/02/17(土) 00:10:47.04ID:OoNlElF9
&aaa+1はaaaの外を指す

342デフォルトの名無しさん2018/02/17(土) 00:34:30.85ID:2kmwzB0g
>>340
構造体の途中をmemcpyとかで書き換えるのは問題ないよ。
>>331も指摘しているとおり、元のコードの問題はアドレスの計算が間違っていること。
&aaa+1なら、aaaの先頭アドレスに1を足した値ではなく、aaaの先頭アドレスにsizeof(aaa)を1つ分足した値になるよ。

343デフォルトの名無しさん2018/02/18(日) 12:45:11.42ID:SXTB1pky
C#の質問なのですがスレが他に無いのでここで質問させてください。

VisualStudio2017でDLLの作成をしようと思っています。
DLLプロジェクトのなかでSystem.ConsoleやSystem.IO.Pathクラスを使用したいのですができません。
「現在のコンテキストに 'Path' という名前は存在しません。」というエラーです。

コンソールアプリのプロジェクトなら問題なく使用できます。
どうすればDLLのプロジェクトでも使用できるようになりますか?

344デフォルトの名無しさん2018/02/18(日) 13:17:23.84ID:G+NN3epc
ふらっと C#,C♯,C#(初心者用) Part135
ttps://mevius.5ch.net/test/read.cgi/tech/1517749348/

C#, C♯, C#相談室 Part95
ttps://mevius.5ch.net/test/read.cgi/tech/1508180530/

あたりじゃダメなん?

345デフォルトの名無しさん2018/02/18(日) 14:14:22.93ID:SXTB1pky
>>344
すみません検索の仕方を間違えていたようです;;
そちらで質問させていただきます!お手数おかけしました。

346デフォルトの名無しさん2018/05/23(水) 20:32:19.60ID:Au5e7VGg
僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』

17PZB

新着レスの表示
レスを投稿する