スレを勃てるまでもないC/C++の質問はここで 25
[隔離病棟]
©2ch.net (467レス)
スレを勃てるまでもないC/C++の質問はここで 25
[隔離病棟]
©2ch.net http://mevius.5ch.net/test/read.cgi/tech/1471100645/
上
下
前次
1-
新
通常表示
512バイト分割
レス栞
抽出解除
必死チェッカー(本家)
(べ)
自ID
レス栞
あぼーん
リロード規制
です。10分ほどで解除するので、
他のブラウザ
へ避難してください。
271: デフォルトの名無しさん [sage] 2018/01/27(土) 10:10:18.54 ID:EckHRazm floatを実数Xで初期化する際にfloatではその数を正確に表現できない場合、少し大きいか小さいかでXに近い値になると思います そういう正確には表せない場合に、どうすれば初期化される値がXを下回らない最小の値となるようにできますか? たとえば√3(1.7320508075688...)で初期化しようと float x=1.7320508075688f; と書くと xの値が1.732050776となり√3より小さくなってしまうので、そういうのを避けたいです http://mevius.5ch.net/test/read.cgi/tech/1471100645/271
276: デフォルトの名無しさん [sage] 2018/01/27(土) 11:53:27.06 ID:EckHRazm 言葉足らずでしたが、標準やその他ライブラリの数学関数の結果として求めたいのではなく 数値リテラルとして初期化する場合に限ってもらっても結構です 閾値として使うのに、切り上げか切り下げかわかっていないと間違った結果が出て後で困ることになります たとえば単純に閾値未満と以上のデータを別の用紙に印刷するプログラムを以下のように書いた場合 double result = calculation(); double threshold = √3 if (result < threshold) fail_list.add(result); else pass_list.add(result);` print_to_paper(fail_list); print_to_paper(pass_list); 計算精度に限界がある以上(閾値付近での)比較での細かい誤差は気にするなという人もいるでしょうが それ以上に実際に紙面に載る値が要件に反する事態になってしまうと後々困ったことになるのです... >>274 次善の策でそのことも考えますが、要件が変わった場合などに脆さが残りませんか? http://mevius.5ch.net/test/read.cgi/tech/1471100645/276
279: デフォルトの名無しさん [sage] 2018/01/27(土) 14:20:38.41 ID:EckHRazm 説明のために>>276のプログラムをfloatに戻したものを考えると (result < 1.732050776f)という比較ではresultが1.732050776fだった場合に 1.732050776は√3未満であるのに合格リストの方に載ってしまうということです 計算上の誤差があるとかdoubleの有効桁数が多いとかでなく プログラム内の数値の取り扱いに関係なく、実際の紙の上では間違いが起こってほしくないということです うまく説明できてるかどうかわかりませんが、実行時どの程度誤差を許容できるかは問題ではないんです 結果を見せた時に、どうしてこの値がこっちのリストに載っているわけ? 直しておいてくれる? と言われれば、どうせ境界値付近の値なんてどちらのリストに載っていようと計算誤差もあるしいずれにしても正確とは言えないんですよ では通じないんです... ≒をどちらに組み込むかを決めておくというのも、結局は事前に求めておく>>274の手法と同じ手間がかかりませんか 要件の数値(実数)が変われば、切り上げか切り下げのどちらであるかも変わってしまいますから どちらになっているかを確かめなくてはいけないですよね http://mevius.5ch.net/test/read.cgi/tech/1471100645/279
281: デフォルトの名無しさん [sage] 2018/01/27(土) 14:55:39.92 ID:EckHRazm 1.732050776と比較したいのではなく√3です(√3という数も説明の便宜上です念のため) ですからdouble型でも√3が表現できないのは変わらない以上は floatをdoubleにしても問題の起こりやすさが減るだけで起こることに変わりないと思います doubleを使うなら1.7320508075688...よりも多くの桁数を書くことになるというだけです(20桁以上?)... 私の場合有効桁数そのものが問題なのではなく、切り上げか切り下げを指定したいということです あるいはどちらが行われているかがわかればそれで問題ありません(と思います) 加えるとほかの工程に渡す必要があるためdecimal等をサポートするライブラリの使用は非常に厳しいです http://mevius.5ch.net/test/read.cgi/tech/1471100645/281
290: デフォルトの名無しさん [sage] 2018/01/27(土) 16:54:03.59 ID:EckHRazm >>288 元データは文字列で、最大で有効数字8桁くらいの10進数の小数点数です それを単にstrtofで読みこんで、計算過程もずっとfloatです ですけど読み込み時の誤差も含めて計算誤差は特に問題にしなくてもかまいません それこそ計算誤差があるから仕方ないで押し通すこともできると思います ですが、計算結果を2つのグループに分ける際に、実数の閾値に対して忠実でなければならないということです >>284 閾値も計算の精度も32ビットのfloatで問題ないです なので閾値となるfloat値を事前計算すれば、とりあえずは済みます (ですが事後の変更に備えて、安全な方策がないものかと思い始めたわけです) >>283 閾値は実行時に関数を呼び出して計算する必要はありません 単に計算機で求めた桁の多い数字を使って意図通りにfloatを初期化できれば問題は解決です http://mevius.5ch.net/test/read.cgi/tech/1471100645/290
298: デフォルトの名無しさん [sage] 2018/01/27(土) 18:28:25.65 ID:EckHRazm >>291 はい、それで問題ありません 上であげた√3の例は計算機で出してfloatには十分だと思える桁数で切っているだけです 入力データや計算誤差自体には許容的です >>294 閾値の数は文字列から取得するわけではありません ソースコード中のリテラル値として与えられるもので構いません 求めるものは、単純化して言うと プログラム上のあるfloat値が、数学的な意味での実数X未満であるかそうでないかのbool値になります >>297 10進数表記可能な数ということになります たとえば√3も関数電卓などで求めた値で十分(20桁もあればfloatには十分すぎるだろう)という意味です http://mevius.5ch.net/test/read.cgi/tech/1471100645/298
300: デフォルトの名無しさん [sage] 2018/01/27(土) 20:13:29.55 ID:EckHRazm >>299 スレを後から読んだ人に混乱を広げないために念のために書いておきますが、無理数を無理数として扱う必要はありません ついでに、計算の精度を高めたいわけでもありません あらかじめ閾値になるfloat値を求めておけば済むというのはわかりますその通りです 早い段階で気づいていました ですがそれだけだと変更に弱いですよね 実際に書き換えるのが三か月後の自分か赤の他人になるのかはわかりませんが だれかの手作業で閾値のfloat値を再計算するより信頼性のある方法があれば、ということで質問を始めました ただ5レス目しないうちから簡単には済まないだろうなとも思っていました http://mevius.5ch.net/test/read.cgi/tech/1471100645/300
302: デフォルトの名無しさん [sage] 2018/01/27(土) 20:42:46.77 ID:EckHRazm doubleで持つ考えもわかります ただfloatの丸め方がわかれば(あるいは制御できれば)問題は解決(>>301が悩むdoubleが必要な時にも拡張できる方法)だと思うのですが... その方法が簡単でないということが分かったことは収穫...?でした http://mevius.5ch.net/test/read.cgi/tech/1471100645/302
304: デフォルトの名無しさん [sage] 2018/01/27(土) 21:11:10.44 ID:EckHRazm 実行時の精度ではなく、コンパイラがソースコード中の数値文字列をどう機械語(float型)に翻訳するかということではないですか? ソースコード上では20桁もある数値文字列を実際にコンパイラが適切な32ビット型に変換しているので 33ビット型とかいう変な方を導入するまでもないと思うのですが 実行時に実数がどうまとめられたかを知りたいわけじゃないんです 初期化式の右辺に来る数値リテラルをコンパイラ内部で何ビットで処理しようが関係ありませんよね? 実行時にfloatやdouble値の実体を持つ閾値が、切り下げられたか切り上げられたかを判断するのであれば 33ビットの浮動小数点数型が必要になるでしょうけども... http://mevius.5ch.net/test/read.cgi/tech/1471100645/304
306: デフォルトの名無しさん [sage] 2018/01/27(土) 22:03:45.49 ID:EckHRazm 実行時の変数の丸め方ではありませんよ 丸めという言葉はよくなかったかもしれませんすみませんでした 今はfloatの初期化式を書いた時にコンパイラがどう振舞うかということの意味です それと前に10進数表記可能な数と書いたのは、単にソースコード上で そう書き表すことのできる(√とかsinとかその他を使わない)数という意味で 10進数の数のある桁で四捨五入するという意味ではありませんでした 丸めという言葉もULPに対するものとして言ってるつもりでした >>278で出てるのでこちらから出しませんでしたが言葉足らずでした重ねてすみまんせん 元々は1.7777777fupとか1.7777777fdownとか(桁数や表記法はともかく) お手軽に意図通りの値に初期化できないものかと考えて質問しました そうすれば、実数から浮動小数点数への翻訳方法(コンパイラによる切り上げ切り下げ)にかかわらず、 ソースコード上に記述されている通りの、数学的な大小関係を損なわないプログラムが書けると考えたからでした 次にいつここへ来るかわからないので今日の私の質問はこれで終わりにします 返答してくれた人たちは本当にありがとうございました http://mevius.5ch.net/test/read.cgi/tech/1471100645/306
メモ帳
(0/65535文字)
上
下
前次
1-
新
書
関
写
板
覧
索
設
栞
歴
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.018s