C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part144
https://mevius.5ch.net/test/read.cgi/tech/1563769115/
このスレもよろしくね。
【初心者歓迎】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/ (日本語)
----- テンプレ ここまで -----
探検
C++相談室 part145
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2019/09/13(金) 17:13:24.60ID:/ygW08Jq295デフォルトの名無しさん
2019/10/03(木) 21:59:37.34ID:A/fPHEZe >>294 エラーメッセージとか出てないの?
296デフォルトの名無しさん
2019/10/03(木) 22:06:09.67ID:BrhogHgJ297デフォルトの名無しさん
2019/10/03(木) 22:13:42.78ID:Uq6PP8Ux ありがとうございました。
通りました。
つか、そんなtemplate文の使い方初めて知った・・
通りました。
つか、そんなtemplate文の使い方初めて知った・・
298デフォルトの名無しさん
2019/10/03(木) 22:31:15.90ID:zkquM/gX この場合Aがテンプレートなので、Aの先のgetが何者かコンパイラは判断つかないので
"<" が比較演算なのかテンプレートのかっこなのか判断つかないから
らしい
clangは教えてくれるんだから判断ついてるわけだが・・・
まったく醜い文法を持った言語だよ
"<" が比較演算なのかテンプレートのかっこなのか判断つかないから
らしい
clangは教えてくれるんだから判断ついてるわけだが・・・
まったく醜い文法を持った言語だよ
299デフォルトの名無しさん
2019/10/03(木) 22:49:50.59ID:BrhogHgJ この場合のエラーメッセージ、GCCはほんとに何言ってるのか分からないのを出すのでclang様様
300デフォルトの名無しさん
2019/10/04(金) 01:11:35.70ID:gSpEwnzq C++テンプレートのプログラミングでのエラーを読み解く訓練をしているうちに
実世界での初心者が投げてくる質問へのエスパー力がやしなわれる
これ豆
実世界での初心者が投げてくる質問へのエスパー力がやしなわれる
これ豆
301デフォルトの名無しさん
2019/10/04(金) 02:30:32.92ID:gpJXYiEy そのうちエラーメッセージを見ずにエラーを修正できるようになる
302デフォルトの名無しさん
2019/10/04(金) 02:54:08.89ID:P4b1n6up ちなVC2015か2017か忘れたけど、一時期までのVCは
その場合のtemplateを書くと逆にエラーにされてた
その場合のtemplateを書くと逆にエラーにされてた
303デフォルトの名無しさん
2019/10/04(金) 03:18:41.39ID:I4catYuR goで変数用いて
*******
*****
***
*
***
*****
*******
って出力するにはどうすりゃいいのっと
*******
*****
***
*
***
*****
*******
って出力するにはどうすりゃいいのっと
304デフォルトの名無しさん
2019/10/04(金) 03:19:28.61ID:I4catYuR あ、↑のは砂時計みたいな形にしたい
306デフォルトの名無しさん
2019/10/04(金) 04:19:18.14ID:I4catYuR >>305
申し訳ないが初心者ゆえ、数字の二重ループはできるけどそれを文字列にする仕方がわからず
申し訳ないが初心者ゆえ、数字の二重ループはできるけどそれを文字列にする仕方がわからず
307デフォルトの名無しさん
2019/10/04(金) 05:45:45.52ID:jwb6jSs+ goスレ行け
308デフォルトの名無しさん
2019/10/04(金) 08:20:48.47ID:FzFdUbJu >>298
なぜか偶然ですが、このスレを見る前から昨日からその辺に関係するパーサーを
作っていて悩んでいたところなんですが、
多くの言語では、+,-,*,/,<,> などの演算子が混ざったいわゆる「数式」は文脈に依存せずに
上位のコンパイル作業に入る前に、いったん「数式ツリー」に直すことが出来ます。
ここで「文脈に依存せず」というのは、変数名、関数名、型名などの宣言情報を
調べなくても済むという(いわゆる意味解析の結果の情報を必要としないと言う
)ことです。
ところが、template機能が入った後のC++では、A<B と書いたとき、
< がテンプレートの記号なのか比較演算子なのかは A がテンプレート名であるか
どうかによって決まります。
Bが型名であることが明確な場合には文脈によらず < はテンプレート記号だと断定
できます。ところが、Bに 1, 456, 3.1415 のような数値や、"Hello" などの文字列
が来ている場合には、(その場では)判断が付きません。
文脈に依存せずに判断を付けたいなら、もっと先まで呼んで、< に対応する >
があるかどうかを調べるといける可能性があります。
1. "<"に対応する">"が存在するかどうか調べれば、これまでの宣言情報を使わなくても
トークン・ツリーを作ることが出来る。トークン・ツリーと言ったのは、数式とは
限らないからです。例えば、A<B> x[100]; などとすることがありますが、A<B>
は型名であり、数式では有りません。ただし、他の多くの言語では数式ツリーは
作ることが多いのですが、トークン・ツリーはまず作りません。
2. 1の方法を使わないなら、宣言情報を調べて、Aがtemplate名であるかどうかを調べる
必要がある。ところが、Q::A<B> などのような場合があるので、そんなに
単純な作業でく、Q::A が型名なのか、変数名なのかはちゃんと調べる必要がある。
なぜか偶然ですが、このスレを見る前から昨日からその辺に関係するパーサーを
作っていて悩んでいたところなんですが、
多くの言語では、+,-,*,/,<,> などの演算子が混ざったいわゆる「数式」は文脈に依存せずに
上位のコンパイル作業に入る前に、いったん「数式ツリー」に直すことが出来ます。
ここで「文脈に依存せず」というのは、変数名、関数名、型名などの宣言情報を
調べなくても済むという(いわゆる意味解析の結果の情報を必要としないと言う
)ことです。
ところが、template機能が入った後のC++では、A<B と書いたとき、
< がテンプレートの記号なのか比較演算子なのかは A がテンプレート名であるか
どうかによって決まります。
Bが型名であることが明確な場合には文脈によらず < はテンプレート記号だと断定
できます。ところが、Bに 1, 456, 3.1415 のような数値や、"Hello" などの文字列
が来ている場合には、(その場では)判断が付きません。
文脈に依存せずに判断を付けたいなら、もっと先まで呼んで、< に対応する >
があるかどうかを調べるといける可能性があります。
1. "<"に対応する">"が存在するかどうか調べれば、これまでの宣言情報を使わなくても
トークン・ツリーを作ることが出来る。トークン・ツリーと言ったのは、数式とは
限らないからです。例えば、A<B> x[100]; などとすることがありますが、A<B>
は型名であり、数式では有りません。ただし、他の多くの言語では数式ツリーは
作ることが多いのですが、トークン・ツリーはまず作りません。
2. 1の方法を使わないなら、宣言情報を調べて、Aがtemplate名であるかどうかを調べる
必要がある。ところが、Q::A<B> などのような場合があるので、そんなに
単純な作業でく、Q::A が型名なのか、変数名なのかはちゃんと調べる必要がある。
309デフォルトの名無しさん
2019/10/04(金) 08:25:56.64ID:FzFdUbJu >>308
補足
「Bが型名であることが明確な場合には文脈によらず < はテンプレート記号だと断定
できます。」
の部分ですが、B<CPerson(実引数列) などとした場合、CPersonは型名ですが、
CPerson(実引数列) 全体は、型名ではなくCPersonクラスの引数つき
コンストラクタを呼び出した結果の「一時オブジェクト」です。なので、
Bが変数名の場合は、< は比較演算子の可能性があります。
補足
「Bが型名であることが明確な場合には文脈によらず < はテンプレート記号だと断定
できます。」
の部分ですが、B<CPerson(実引数列) などとした場合、CPersonは型名ですが、
CPerson(実引数列) 全体は、型名ではなくCPersonクラスの引数つき
コンストラクタを呼び出した結果の「一時オブジェクト」です。なので、
Bが変数名の場合は、< は比較演算子の可能性があります。
310デフォルトの名無しさん
2019/10/04(金) 08:33:37.62ID:FzFdUbJu >>308
誤:なぜか偶然ですが、このスレを見る前から昨日からその辺に関係するパーサーを
正:なぜか偶然ですが、このスレを見る前の昨日からその辺に関係するパーサーを
誤:文脈に依存せずに判断を付けたいなら、もっと先まで呼んで、< に対応する >
正:文脈に依存せずに判断を付けたいなら、もっと先まで読んで、< に対応する >
誤:単純な作業でく、Q::A が型名なのか、変数名なのかはちゃんと調べる必要がある。
正:単純な作業ではなく、Q::A がtemplate名なのか、変数名なのかはちゃんと調べる必要がある。
誤:なぜか偶然ですが、このスレを見る前から昨日からその辺に関係するパーサーを
正:なぜか偶然ですが、このスレを見る前の昨日からその辺に関係するパーサーを
誤:文脈に依存せずに判断を付けたいなら、もっと先まで呼んで、< に対応する >
正:文脈に依存せずに判断を付けたいなら、もっと先まで読んで、< に対応する >
誤:単純な作業でく、Q::A が型名なのか、変数名なのかはちゃんと調べる必要がある。
正:単純な作業ではなく、Q::A がtemplate名なのか、変数名なのかはちゃんと調べる必要がある。
311デフォルトの名無しさん
2019/10/04(金) 08:37:14.54ID:P4b1n6up312デフォルトの名無しさん
2019/10/04(金) 08:41:34.48ID:FzFdUbJu313デフォルトの名無しさん
2019/10/04(金) 09:33:34.23ID:8yIxxMU3 >>311
ようクソバカ
ようクソバカ
314デフォルトの名無しさん
2019/10/04(金) 09:41:54.97ID:P4b1n6up315デフォルトの名無しさん
2019/10/04(金) 11:43:51.24ID:FzFdUbJu >>308
C++言語をパースする方法として、結論的には、2.ではダメで、1.でなくてはならないようです。例として、A<実引数列>::B の場合を考えると、template は実体化する
際の実引数によって展開される内容は大幅に変わりますので、
A<int>::B とした場合には、B は template 名で、
A<string>::B とした場合には、B は変数名であることもありえます。すると、
A<int>::B<C> の場合の B<C> は template 実体化ですが、
A<string>::B < C の場合は、変数B と変数 Cに対しての比較演算となります。
なので、もし、>>308 の 2.のやり方でパース使用とすると、Aがtemplate名であると
分かっただけでは B が「何なのか」を結論付けるには不十分で、A<実引数列>の
実引数列をほとんど完全に調べ上げてから、その方名に応じた template A の
定義を探して template の overload 解決をしてから、A<実引数列> 部分(のclass)を
完全に「特定」する必要があります。ここまでやるとなると、コンパイラの層分けが
上手く出来ないことになります。
C++言語をパースする方法として、結論的には、2.ではダメで、1.でなくてはならないようです。例として、A<実引数列>::B の場合を考えると、template は実体化する
際の実引数によって展開される内容は大幅に変わりますので、
A<int>::B とした場合には、B は template 名で、
A<string>::B とした場合には、B は変数名であることもありえます。すると、
A<int>::B<C> の場合の B<C> は template 実体化ですが、
A<string>::B < C の場合は、変数B と変数 Cに対しての比較演算となります。
なので、もし、>>308 の 2.のやり方でパース使用とすると、Aがtemplate名であると
分かっただけでは B が「何なのか」を結論付けるには不十分で、A<実引数列>の
実引数列をほとんど完全に調べ上げてから、その方名に応じた template A の
定義を探して template の overload 解決をしてから、A<実引数列> 部分(のclass)を
完全に「特定」する必要があります。ここまでやるとなると、コンパイラの層分けが
上手く出来ないことになります。
316デフォルトの名無しさん
2019/10/04(金) 12:03:58.19ID:FzFdUbJu >>315
A::B くらいの場合なら、意味解析の情報だけを元に、Bが何なのかを特定をすることは
可能です。ところが、A<1+2,decltype(x*y)>::B の様な場合、x, y の意味論的な型
を調べた後、x*yに適応可能な operator*() 関数が定義されて言うかどうかも調べ、
定義されていれば、その戻り値の型を調べてx*y の型として、A<・・・> の部分が
結局何なのかを特定しなくてはなりません。今述べた x*y の部分の処理は、
トークン解析層(?)より上位のコンパイル層で行う処理です。なのでこのやり方
だと、コンパイラ内部の「層」の切り分けが難しくなります(技術的に不可能な
わけではありませんが。)。
A::B くらいの場合なら、意味解析の情報だけを元に、Bが何なのかを特定をすることは
可能です。ところが、A<1+2,decltype(x*y)>::B の様な場合、x, y の意味論的な型
を調べた後、x*yに適応可能な operator*() 関数が定義されて言うかどうかも調べ、
定義されていれば、その戻り値の型を調べてx*y の型として、A<・・・> の部分が
結局何なのかを特定しなくてはなりません。今述べた x*y の部分の処理は、
トークン解析層(?)より上位のコンパイル層で行う処理です。なのでこのやり方
だと、コンパイラ内部の「層」の切り分けが難しくなります(技術的に不可能な
わけではありませんが。)。
317デフォルトの名無しさん
2019/10/04(金) 12:07:27.45ID:FzFdUbJu318デフォルトの名無しさん
2019/10/04(金) 12:36:35.66ID:cK/f4a5x319デフォルトの名無しさん
2019/10/04(金) 12:41:17.15ID:G1/ISgxb c++って文法に曖昧さがないことどうやって保証してんだろ
形式的なアプローチ無理だと思うんだが
形式的なアプローチ無理だと思うんだが
320デフォルトの名無しさん
2019/10/04(金) 13:05:22.64ID:MVQV/kgg いや、そんな保証は端っから諦めてるだろ
引数なしの関数宣言とデフォコン呼び出しの曖昧さなんか
長年放置してたのをC++11でようやく対応したし
関数ポインタにキャストするoperatorはtypedef使えとか
言語としての完全性なんか重視してない
引数なしの関数宣言とデフォコン呼び出しの曖昧さなんか
長年放置してたのをC++11でようやく対応したし
関数ポインタにキャストするoperatorはtypedef使えとか
言語としての完全性なんか重視してない
321デフォルトの名無しさん
2019/10/04(金) 13:28:40.80ID:FzFdUbJu >>319
曖昧さはあるといわれています。例えば、CPersonというクラスがあったとき、関数内で
CPerson person();
と書いた場合、person という名前で、戻り値の型が CPerson の関数のプロトタイプ宣言なのか、
CPerson クラスの person という変数名(オブジェクト名)の定義なのかの曖昧さがあります。
後者は、CPerson person("name", 25, MALE); などと同じ系統で、実引数が全く無い場合
に相当します。
また、template class の場合に、
A<B<・・・>>
と書くと、>> が右シフト演算子に解釈されてしまうので、回避するために空白を1つ入れて
A<B<・・・> >
としなければならなかった(過去形)時代も有ります。
しかし、パーサーを作る側からすれば、">>" を ">" 2個 だと解釈するのはかなり大変な
労力が必要でです。
また、x < y を比較演算のつもりで A< x < y > などと書くと、A<・・・>
の中に x という template class 名に対しての x<y> が入っていると解釈
されてしまい、> が足りないというエラーになるかもしれません。
回避するには、
A< (x < y) >
と書くと良いと思われます。
曖昧さはあるといわれています。例えば、CPersonというクラスがあったとき、関数内で
CPerson person();
と書いた場合、person という名前で、戻り値の型が CPerson の関数のプロトタイプ宣言なのか、
CPerson クラスの person という変数名(オブジェクト名)の定義なのかの曖昧さがあります。
後者は、CPerson person("name", 25, MALE); などと同じ系統で、実引数が全く無い場合
に相当します。
また、template class の場合に、
A<B<・・・>>
と書くと、>> が右シフト演算子に解釈されてしまうので、回避するために空白を1つ入れて
A<B<・・・> >
としなければならなかった(過去形)時代も有ります。
しかし、パーサーを作る側からすれば、">>" を ">" 2個 だと解釈するのはかなり大変な
労力が必要でです。
また、x < y を比較演算のつもりで A< x < y > などと書くと、A<・・・>
の中に x という template class 名に対しての x<y> が入っていると解釈
されてしまい、> が足りないというエラーになるかもしれません。
回避するには、
A< (x < y) >
と書くと良いと思われます。
322デフォルトの名無しさん
2019/10/04(金) 14:48:30.02ID:D8qarNFk C++というより3Dプログラミングの質問で申し訳ないのだけど、
行列ライブラリglmの以下のコードがbugってる気がするので詳しい人がいたら確認して欲しい。
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& v)
{
vec<3, T, Q> Tmp = v;
// Axis of rotation must be normalised
T len = glm::length(Tmp);
if(abs(len - static_cast<T>(1)) > static_cast<T>(0.001))
{
T oneOverLen = static_cast<T>(1) / len;
Tmp.x *= oneOverLen;
Tmp.y *= oneOverLen;
Tmp.z *= oneOverLen;
}
T const AngleRad(angle);
T const Sin = sin(AngleRad * static_cast<T>(0.5));
return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
}
クオータニオンqをベクタ軸v周りにAngleRad回転させる関数のソースらしいんだが、
最後の行掛け算の順番が逆のような気がする。
qua<T,Q>(...) * qが正解だと思うんだ。
glmはファイル構成がバージョン間で結構派手に変更されてるんで、
最近のバージョンではext/quaternion_transform.inlに上のコードが含まれてる。
古いバージョンではgtx/quaternion.inlにあったような気がする。
行列ライブラリglmの以下のコードがbugってる気がするので詳しい人がいたら確認して欲しい。
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER qua<T, Q> rotate(qua<T, Q> const& q, T const& angle, vec<3, T, Q> const& v)
{
vec<3, T, Q> Tmp = v;
// Axis of rotation must be normalised
T len = glm::length(Tmp);
if(abs(len - static_cast<T>(1)) > static_cast<T>(0.001))
{
T oneOverLen = static_cast<T>(1) / len;
Tmp.x *= oneOverLen;
Tmp.y *= oneOverLen;
Tmp.z *= oneOverLen;
}
T const AngleRad(angle);
T const Sin = sin(AngleRad * static_cast<T>(0.5));
return q * qua<T, Q>(cos(AngleRad * static_cast<T>(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
}
クオータニオンqをベクタ軸v周りにAngleRad回転させる関数のソースらしいんだが、
最後の行掛け算の順番が逆のような気がする。
qua<T,Q>(...) * qが正解だと思うんだ。
glmはファイル構成がバージョン間で結構派手に変更されてるんで、
最近のバージョンではext/quaternion_transform.inlに上のコードが含まれてる。
古いバージョンではgtx/quaternion.inlにあったような気がする。
323デフォルトの名無しさん
2019/10/04(金) 14:55:11.92ID:FzFdUbJu324デフォルトの名無しさん
2019/10/04(金) 15:01:05.28ID:FzFdUbJu325デフォルトの名無しさん
2019/10/04(金) 15:02:02.33ID:FzFdUbJu326デフォルトの名無しさん
2019/10/04(金) 15:45:42.88ID:P4b1n6up OpenGL系は縦ベクトルだね
D3Dを前提にしたライブラリとは逆になる(行列も転置
D3Dを前提にしたライブラリとは逆になる(行列も転置
327デフォルトの名無しさん
2019/10/04(金) 15:58:00.91ID:FzFdUbJu >>326
数学や物理学では縦ベクトルが多いが、D3Dはそれに従ってない。
数学や物理学では縦ベクトルが多いが、D3Dはそれに従ってない。
328デフォルトの名無しさん
2019/10/04(金) 16:08:07.51ID:JXWhYfPM テンプレが糞だと思う瞬間はいくつもあるが
その一つはネストしてるときの閉じ括弧
>> じゃだめで > > ってわざわざ分けないといかんうざい
その一つはネストしてるときの閉じ括弧
>> じゃだめで > > ってわざわざ分けないといかんうざい
329デフォルトの名無しさん
2019/10/04(金) 16:08:35.30ID:P4b1n6up >数学や物理学では縦ベクトルが多いが、D3Dはそれに従ってない。
みたいだね
D3Dからそれ以外に移るとみんなここで引っかかるけど
実は行列周りは(大文字は行列として)
OpenGLに合わせるとA*B*C*xとなるのを
D3Dではx*C*B*Aと書けた方が、左からの計算が全部結果がベクトルなので計算量が減るというメリットはある
MSはC++での書きやすさと効率を考えたのかもしれない
みたいだね
D3Dからそれ以外に移るとみんなここで引っかかるけど
実は行列周りは(大文字は行列として)
OpenGLに合わせるとA*B*C*xとなるのを
D3Dではx*C*B*Aと書けた方が、左からの計算が全部結果がベクトルなので計算量が減るというメリットはある
MSはC++での書きやすさと効率を考えたのかもしれない
330デフォルトの名無しさん
2019/10/04(金) 16:09:02.58ID:JXWhYfPM331デフォルトの名無しさん
2019/10/04(金) 16:11:58.82ID:P4b1n6up >>328
C++11からは連続して書けるようになったで
C++11からは連続して書けるようになったで
332デフォルトの名無しさん
2019/10/04(金) 16:14:31.61ID:MVQV/kgg C++03いやC++98?のまま更新止まってるやつ
俺が想像するより遙かに多いのかもしかして
もうC++11でさえ要注意な旧規格になってるんだが
俺が想像するより遙かに多いのかもしかして
もうC++11でさえ要注意な旧規格になってるんだが
333デフォルトの名無しさん
2019/10/04(金) 16:16:30.52ID:JXWhYfPM >>329
メモリ上の順序も変わるぞ
SIMDとかで計算されるときの効率にも影響する
必ずしもD3D(横ベクトル方式)が高速化に都合が良いとは言えないんじゃないか
行列の各要素のメモリ上の並びって
glの行列AとD3Dの行列A'はいちいち転置しなくても結局同じになるんだっけ
メモリ上の順序も変わるぞ
SIMDとかで計算されるときの効率にも影響する
必ずしもD3D(横ベクトル方式)が高速化に都合が良いとは言えないんじゃないか
行列の各要素のメモリ上の並びって
glの行列AとD3Dの行列A'はいちいち転置しなくても結局同じになるんだっけ
334デフォルトの名無しさん
2019/10/04(金) 16:22:07.03ID:P4b1n6up ああ確かにメモリの中身は同じだった
格納方式も違うから結果的に同じになるんだよね
そこが余計ややこしい
格納方式も違うから結果的に同じになるんだよね
そこが余計ややこしい
335デフォルトの名無しさん
2019/10/04(金) 16:29:39.34ID:FzFdUbJu >>329
行列計算は、縦ベクトル方式、横ベクトル方式でも、(それぞれで)「結合則」があるので、
A*B*C*x = A*(B*(C*x))
でもあり、
A*B*C*x = ((A*B)*C)*x)
でもあり、どっちで計算しても結果は同じになる。
また、3D計算の場合、点の座標がいくつあっても、行列を一度計算しておくと、
使いまわしできるので、先に行列の方を計算しておいて、最後に座標の変換
を行うと、点が2個以上あるときには効率が高い。
行列計算は、縦ベクトル方式、横ベクトル方式でも、(それぞれで)「結合則」があるので、
A*B*C*x = A*(B*(C*x))
でもあり、
A*B*C*x = ((A*B)*C)*x)
でもあり、どっちで計算しても結果は同じになる。
また、3D計算の場合、点の座標がいくつあっても、行列を一度計算しておくと、
使いまわしできるので、先に行列の方を計算しておいて、最後に座標の変換
を行うと、点が2個以上あるときには効率が高い。
336デフォルトの名無しさん
2019/10/04(金) 16:31:49.50ID:FzFdUbJu337デフォルトの名無しさん
2019/10/04(金) 16:38:53.10ID:FzFdUbJu338デフォルトの名無しさん
2019/10/04(金) 16:40:53.55ID:P4b1n6up >>335
確かに(OpenGLでも上で書いたような式が使えるライブラリ使うとして)括弧でくくったりして優先順位変えればいいし
言う通り行列はまとめればいいんだけど
どちらにもメリットデメリットあると言いたかった
確かに(OpenGLでも上で書いたような式が使えるライブラリ使うとして)括弧でくくったりして優先順位変えればいいし
言う通り行列はまとめればいいんだけど
どちらにもメリットデメリットあると言いたかった
339デフォルトの名無しさん
2019/10/04(金) 16:51:20.07ID:FzFdUbJu >>338
実は、アメリカで有名な 3D Graphics の本が、横ベクトル方式を採用していた
事が関係しているかもしれない。要はその本が数学や物理の標準とは何故か
逆の記法を採用していたということ。
実は、アメリカで有名な 3D Graphics の本が、横ベクトル方式を採用していた
事が関係しているかもしれない。要はその本が数学や物理の標準とは何故か
逆の記法を採用していたということ。
340デフォルトの名無しさん
2019/10/04(金) 17:00:49.77ID:FW+Y/3wm >>337
GL
(A*B*C)*(x0(縦),x1(縦),x2(縦),x3(縦), ... , xN(縦))(横)
D3D
(x0(横),x1(横),x2(横),x3(横), ... , xN(横))(縦)*(C*B*A)
が最速やね
GL
(A*B*C)*(x0(縦),x1(縦),x2(縦),x3(縦), ... , xN(縦))(横)
D3D
(x0(横),x1(横),x2(横),x3(横), ... , xN(横))(縦)*(C*B*A)
が最速やね
>>335
行列って結合則は約束されてましたっけ?
行列って結合則は約束されてましたっけ?
342デフォルトの名無しさん
2019/10/04(金) 20:17:27.71ID:gZky9oRw 当たり前だろ。
そんなレベルの知識しかないからフォントライブラリ書けないんだよ
そんなレベルの知識しかないからフォントライブラリ書けないんだよ
>>342
では証明してください(キリッ)
では証明してください(キリッ)
344デフォルトの名無しさん
2019/10/04(金) 21:24:32.75ID:FzFdUbJu >>343
ベクトル部分はおいておくとして、まず正方行列の部分だけに限定すれば
A(BC)=(AB)C ・・・(1)
が証明できれば どんな場合でも結合側が成り立つことが数学的帰納法で
証明できます。なので、A,B,C が正方行列の時に(1)を証明すれば全体の証明が
ほぼ終わります。
【(1)の証明】
行列の積の定義により
(AB)ij=Σ_{k=1}^n A_{ik} B_{kj} ・・・(2)
です。なので、
{(AB)C}mn = Σ_l(AB)_{ml}C_{ln}
= Σ_k Σ_l A_{mk} B_{kl} C_{ln} ・・・(3)
です。全く同様に、
{A(BC)}mn = Σ_k A_{mk} (BC)_{kn}
= Σ_k A_{mk} Σ_l B_{kl} C_{ln}
= Σ_k Σ_l A_{mk} B_{kl} C_{ln} ・・・(4)
となり、(3), (4) が一致することから、
{A(BC)}mn = {(AB)C}mn
が言えます。これが (1) に他なりません。 (Q.E.D)
次に、このように3つの行列の場合ではなく、一般の個数の行列の場合、
最初に書いたように数学的帰納法を使います。それは、あなた自身で
お考えください。考える力の練習になります。
ベクトル部分はおいておくとして、まず正方行列の部分だけに限定すれば
A(BC)=(AB)C ・・・(1)
が証明できれば どんな場合でも結合側が成り立つことが数学的帰納法で
証明できます。なので、A,B,C が正方行列の時に(1)を証明すれば全体の証明が
ほぼ終わります。
【(1)の証明】
行列の積の定義により
(AB)ij=Σ_{k=1}^n A_{ik} B_{kj} ・・・(2)
です。なので、
{(AB)C}mn = Σ_l(AB)_{ml}C_{ln}
= Σ_k Σ_l A_{mk} B_{kl} C_{ln} ・・・(3)
です。全く同様に、
{A(BC)}mn = Σ_k A_{mk} (BC)_{kn}
= Σ_k A_{mk} Σ_l B_{kl} C_{ln}
= Σ_k Σ_l A_{mk} B_{kl} C_{ln} ・・・(4)
となり、(3), (4) が一致することから、
{A(BC)}mn = {(AB)C}mn
が言えます。これが (1) に他なりません。 (Q.E.D)
次に、このように3つの行列の場合ではなく、一般の個数の行列の場合、
最初に書いたように数学的帰納法を使います。それは、あなた自身で
お考えください。考える力の練習になります。
345デフォルトの名無しさん
2019/10/04(金) 22:10:52.87ID:cDY60lSZ doubleの値を++aした時にaの値は+1と規定されてる?
346デフォルトの名無しさん
2019/10/04(金) 23:19:26.96ID:FzFdUbJu >>345
boolen型以外では、++x は正確に x+=1 と等価です。
x+=1 は、正確に x = x + 1 と等価です。x がポインタ型の場合は、
BYTE 単位で見ると object size 単位で増加しますが、double/float/int/short/char
などの「算術型」の場合は、単純に 1 が足されるだけです。
https://en.cppreference.com/w/cpp/language/operator_incdec
For non-boolean operands, the expression ++x is exactly equivalent to x += 1, and the expression --x is exactly equivalent to x -= 1, that is, the prefix increment or decrement is an lvalue expression that identifies the modified operand.
boolen型以外では、++x は正確に x+=1 と等価です。
x+=1 は、正確に x = x + 1 と等価です。x がポインタ型の場合は、
BYTE 単位で見ると object size 単位で増加しますが、double/float/int/short/char
などの「算術型」の場合は、単純に 1 が足されるだけです。
https://en.cppreference.com/w/cpp/language/operator_incdec
For non-boolean operands, the expression ++x is exactly equivalent to x += 1, and the expression --x is exactly equivalent to x -= 1, that is, the prefix increment or decrement is an lvalue expression that identifies the modified operand.
347デフォルトの名無しさん
2019/10/04(金) 23:36:52.32ID:NJj/Utu/ >>346
ありがとうございます。
という事はキャストの時におかしくなっているのかな?
aの値は0.0〜100.0程度
for(double i = a; i < 1000.0; ++i){
std::cout << (int)i << "," << std::endl;
}
期待している結果: 1,2,3,4,5...と連番になる
たまに起こる結果: 1,2,3,5,6...と歯抜けになる
ありがとうございます。
という事はキャストの時におかしくなっているのかな?
aの値は0.0〜100.0程度
for(double i = a; i < 1000.0; ++i){
std::cout << (int)i << "," << std::endl;
}
期待している結果: 1,2,3,4,5...と連番になる
たまに起こる結果: 1,2,3,5,6...と歯抜けになる
348デフォルトの名無しさん
2019/10/04(金) 23:42:33.92ID:8yIxxMU3 丸められただけでは
349デフォルトの名無しさん
2019/10/04(金) 23:55:23.10ID:YWySipM2350デフォルトの名無しさん
2019/10/05(土) 00:03:15.79ID:bnoeYdBm 行列の結合則なんて高校で習っただろ
線形代数わからないプログラマって生き残れないと思うわ
線形代数わからないプログラマって生き残れないと思うわ
351デフォルトの名無しさん
2019/10/05(土) 00:05:26.41ID:KADe2ROY >>347
・そのコードは、完全に上記の通りですか?
例えば、ループ回数が1000回より遥かに多くなると、
誤差の都合でそうなることがあるかもしれませんが、1000回くらい
だと、正しい処理系ではその現象は起きないはずです。
・そのコードは、完全に上記の通りですか?
例えば、ループ回数が1000回より遥かに多くなると、
誤差の都合でそうなることがあるかもしれませんが、1000回くらい
だと、正しい処理系ではその現象は起きないはずです。
352デフォルトの名無しさん
2019/10/05(土) 01:17:38.13ID:d5aP5JOP キャストする前にlround呼んだらええんちゃうん。
353デフォルトの名無しさん
2019/10/05(土) 01:44:04.24ID:VkhEKreX (0.2+0.3)+0.4 == 0.2+(0.3+0.4)の結果がfalseになるのは正しいの?
354デフォルトの名無しさん
2019/10/05(土) 01:54:00.97ID:Lbi5NeET 浮動小数点を勉強しておいで
355デフォルトの名無しさん
2019/10/05(土) 02:07:17.64ID:5hJZ4CgN 有効数字1桁の計算で誤差は生じない
356デフォルトの名無しさん
2019/10/05(土) 07:04:22.03ID:UfPJq4d2357デフォルトの名無しさん
2019/10/05(土) 08:03:13.32ID:9T2eUTn8 >>336
本当、人って色々だな
俺はC++98は未完成感があまりに強くて続きはまだかと待ちかねていた
具体的には例えば右辺値参照だ
一時オブジェクトにいちいちconstがつくのがイヤでイヤで待望のやつがやっと来た
本当、人って色々だな
俺はC++98は未完成感があまりに強くて続きはまだかと待ちかねていた
具体的には例えば右辺値参照だ
一時オブジェクトにいちいちconstがつくのがイヤでイヤで待望のやつがやっと来た
358デフォルトの名無しさん
2019/10/05(土) 08:28:45.86ID:iS4eZEWC359デフォルトの名無しさん
2019/10/05(土) 08:49:33.11ID:KADe2ROY >>353
計算誤差です。
(0.2+0.3)+0.4 == 0.2+(0.3+0.4) が偽になっても
(0.2+0.3)+0.4 == (0.2+0.3)+0.4 や
0.2+(0.3+0.4) == 0.2+(0.3+0.4)
は必ず真になることが保障されています。
計算誤差です。
(0.2+0.3)+0.4 == 0.2+(0.3+0.4) が偽になっても
(0.2+0.3)+0.4 == (0.2+0.3)+0.4 や
0.2+(0.3+0.4) == 0.2+(0.3+0.4)
は必ず真になることが保障されています。
360デフォルトの名無しさん
2019/10/05(土) 08:55:38.66ID:KADe2ROY >>359
コンピュータにおける浮動小数点は、内部表現は10進数ではなく2進数
で表現されており、有効桁数は 10 進数で 8 桁や 15桁などではなく
2進数で xx BIT という風になっています。
0.2, 0.3, 0.4 は、10進数だと、有効桁数が1桁でも完全に区切れが
よく表現できていますが、2進数の表現だと厳密には無限小数になってしまい、
どんなに有効桁数を長くしても厳密には表現できません。そのため計算誤差
が生じるのです。0.5 や 0.25 や 0.125 は 2 進数でも区切れ良く表現できるため、
(0.125+0.25)+0.5 == 0.125+(0.25+0.5)
は誤差が生じることがないため、必ず真になるはずです。
コンピュータにおける浮動小数点は、内部表現は10進数ではなく2進数
で表現されており、有効桁数は 10 進数で 8 桁や 15桁などではなく
2進数で xx BIT という風になっています。
0.2, 0.3, 0.4 は、10進数だと、有効桁数が1桁でも完全に区切れが
よく表現できていますが、2進数の表現だと厳密には無限小数になってしまい、
どんなに有効桁数を長くしても厳密には表現できません。そのため計算誤差
が生じるのです。0.5 や 0.25 や 0.125 は 2 進数でも区切れ良く表現できるため、
(0.125+0.25)+0.5 == 0.125+(0.25+0.5)
は誤差が生じることがないため、必ず真になるはずです。
361デフォルトの名無しさん
2019/10/05(土) 10:06:32.18ID:e1uvrqu3 >>360
浮動小数の計算誤差を考慮して比較する時にstd::abs(a-b) < std::numeric_limit<double>::epsilon()というふうにするのはどう思う?
浮動小数の計算誤差を考慮して比較する時にstd::abs(a-b) < std::numeric_limit<double>::epsilon()というふうにするのはどう思う?
362デフォルトの名無しさん
2019/10/05(土) 11:34:20.93ID:KADe2ROY363デフォルトの名無しさん
2019/10/05(土) 11:37:49.72ID:7pdQvekm 実用数学
364デフォルトの名無しさん
2019/10/05(土) 11:43:08.23ID:rY1OpV0v >>361
機械イプシロンはそういうふうに使うものじゃない
機械イプシロンはそういうふうに使うものじゃない
365デフォルトの名無しさん
2019/10/05(土) 12:09:22.39ID:uol03Q2n cpprefjpが>>361と全く同じ間違いしてたわ馬鹿が湧くのはこいつのせいか
cppreference.comは正しかったからそっち見れ
cppreference.comは正しかったからそっち見れ
366デフォルトの名無しさん
2019/10/05(土) 12:34:57.85ID:dFaPF8AB >>365
x-yの元になっているxやyがどのような計算過程を経てきたかわからないのに
std::abs(x-y) <= std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
でxとyがalmost equalsと言い切ってよい根拠とは、
ちゅか常識的に考えて、x、yがそれぞれ±e、±gの誤差を有するなら
std::abs(x-y) <= std::numeric_limits<T>::epsilon() * (std::abs(e) + std::abs(g))
あたりの判定に落ち着かねばおかしい(これで正解とは言っていない
なんでstd::abs(x+y)みたいな場合によっては莫大な値になりえる係数を掛けねばならないの?
x-yの元になっているxやyがどのような計算過程を経てきたかわからないのに
std::abs(x-y) <= std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
でxとyがalmost equalsと言い切ってよい根拠とは、
ちゅか常識的に考えて、x、yがそれぞれ±e、±gの誤差を有するなら
std::abs(x-y) <= std::numeric_limits<T>::epsilon() * (std::abs(e) + std::abs(g))
あたりの判定に落ち着かねばおかしい(これで正解とは言っていない
なんでstd::abs(x+y)みたいな場合によっては莫大な値になりえる係数を掛けねばならないの?
367デフォルトの名無しさん
2019/10/05(土) 13:04:02.75ID:rY1OpV0v イプシロンに誤差を掛けても意味ない。
つか、許容誤差の絶対値が与えられているならイプシロン使う必要もない。
cppreference.comのは許容誤差をULP単位で与える場合のやりかたで、
abs(x+y)はxとyの指数のうち大きい方を意味するものだったはず。
つか、許容誤差の絶対値が与えられているならイプシロン使う必要もない。
cppreference.comのは許容誤差をULP単位で与える場合のやりかたで、
abs(x+y)はxとyの指数のうち大きい方を意味するものだったはず。
368デフォルトの名無しさん
2019/10/05(土) 13:12:59.71ID:uol03Q2n >>366
なんか色々根本的に勘違いしてる
cppreference.comのalmost_equal関数の仕事はあくまで与えられたxとyがalmost equalかどうかの判定だよ
> x、yがそれぞれ±e、±gの誤差を有するなら
なにこれ?「誤差」って何に対する何の誤差?
なんか色々根本的に勘違いしてる
cppreference.comのalmost_equal関数の仕事はあくまで与えられたxとyがalmost equalかどうかの判定だよ
> x、yがそれぞれ±e、±gの誤差を有するなら
なにこれ?「誤差」って何に対する何の誤差?
369デフォルトの名無しさん
2019/10/05(土) 13:28:00.03ID:dFaPF8AB370デフォルトの名無しさん
2019/10/05(土) 14:05:34.77ID:dFaPF8AB >abs(x+y)はxとyの指数のうち大きい方を意味するものだったはず。
xが (xの符号)×1.bbbb...×2^m
yが (yの符号)×1.cccc...×2^n
だとしたときに、m>nだとすると
x + y =
{ (xの符号)×1.bbbb... + ((yの符号)×1.cccc...×2^-(m-n)) } ×2^m
として計算されるのでだいたい2^m(x≒yなら2^(m+1))という意味か左様か、
xが (xの符号)×1.bbbb...×2^m
yが (yの符号)×1.cccc...×2^n
だとしたときに、m>nだとすると
x + y =
{ (xの符号)×1.bbbb... + ((yの符号)×1.cccc...×2^-(m-n)) } ×2^m
として計算されるのでだいたい2^m(x≒yなら2^(m+1))という意味か左様か、
371デフォルトの名無しさん
2019/10/05(土) 14:08:05.45ID:dFaPF8AB んまーulpをxとyの来歴に応じて調整すべき量とするなら
cppreference.comのalmost_equal関数は理解してやらないでもない
cppreference.comのalmost_equal関数は理解してやらないでもない
372デフォルトの名無しさん
2019/10/05(土) 16:03:17.50ID:NXndjuW4 だれか、俺に分数を教えてくれないか?
足し算と引き算がマジ解らなくなってるんだ。
https://ideone.com/IfCcGz
一番のネックはネガフラグの扱い。
マイナスとプラスの反転演算でどうかくとスマートだろうか。
だれか教えてプリーズ。
足し算と引き算がマジ解らなくなってるんだ。
https://ideone.com/IfCcGz
一番のネックはネガフラグの扱い。
マイナスとプラスの反転演算でどうかくとスマートだろうか。
だれか教えてプリーズ。
373デフォルトの名無しさん
2019/10/05(土) 16:21:25.21ID:bnoeYdBm 分子に符号もたせりゃいいだろ
374デフォルトの名無しさん
2019/10/05(土) 16:25:36.94ID:NXndjuW4 >>373
え、それでよかったっけ?
え、それでよかったっけ?
375デフォルトの名無しさん
2019/10/05(土) 16:34:31.54ID:hwiNAqBO376デフォルトの名無しさん
2019/10/05(土) 17:18:56.47ID:NXndjuW4 一応以下のような感じになった。Thx!
http://coliru.stacked-crooked.com/
http://coliru.stacked-crooked.com/
377デフォルトの名無しさん
2019/10/05(土) 17:19:54.63ID:NXndjuW4378デフォルトの名無しさん
2019/10/05(土) 17:28:26.58ID:QHD8CUaF >>377
1. constexprにしてもいいんじゃない?
2. 出力関数作成しよう
template<typename Char>
std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, const Fraction& frac){
return os << frac.GetNumerator() <<'/'<<frac.GetDenominator();
}
1. constexprにしてもいいんじゃない?
2. 出力関数作成しよう
template<typename Char>
std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, const Fraction& frac){
return os << frac.GetNumerator() <<'/'<<frac.GetDenominator();
}
379デフォルトの名無しさん
2019/10/05(土) 19:08:43.36ID:NXndjuW4380デフォルトの名無しさん
2019/10/05(土) 19:46:54.47ID:NXndjuW4381デフォルトの名無しさん
2019/10/05(土) 19:58:28.51ID:NXndjuW4 フィードバックハブに投げておいた。
382デフォルトの名無しさん
2019/10/06(日) 10:28:58.03ID:yc9LKsYB >>380
マルチ禁止
マルチ禁止
383デフォルトの名無しさん
2019/10/06(日) 13:42:53.69ID:bPt7YQEe >>382
ソーリー。
ソーリー。
384デフォルトの名無しさん
2019/10/07(月) 19:17:43.20ID:PHxdOQnu C++ってなんでヘッダファイルいるんですか
最近マシン早いんだし
全部ソースに書いてインポートすればいいのに
最近マシン早いんだし
全部ソースに書いてインポートすればいいのに
385デフォルトの名無しさん
2019/10/07(月) 19:38:58.27ID:Xs+XlBV4 やれば?(クレヨンしんちゃん風に)
386デフォルトの名無しさん
2019/10/07(月) 19:52:54.51ID:9pxPpXZa 来年まで待ってね
387デフォルトの名無しさん
2019/10/07(月) 20:58:42.59ID:A3KSW75p388デフォルトの名無しさん
2019/10/07(月) 21:05:07.29ID:8FnUNDHt >>387
たまに趣味で何でもかんでもtemplateでゴリゴリ実装してるとガチでそれになるww
たまに趣味で何でもかんでもtemplateでゴリゴリ実装してるとガチでそれになるww
389デフォルトの名無しさん
2019/10/07(月) 21:26:10.24ID:YMM6HSZT >>385
ヤレばデキるは魔法の言葉
ヤレばデキるは魔法の言葉
390デフォルトの名無しさん
2019/10/08(火) 09:06:39.07ID:xr4jQIWZ プリコンパイルヘッダーって使ってます?
使っているプロジェクト見たことないですわ。
使っているプロジェクト見たことないですわ。
391デフォルトの名無しさん
2019/10/08(火) 20:03:58.69ID:kGAGzuS0 >>387
こういう馬鹿野郎が出てくるからメタプロとかテンプレ好き連中ってのは嫌いなんだよ。
こういう馬鹿野郎が出てくるからメタプロとかテンプレ好き連中ってのは嫌いなんだよ。
392デフォルトの名無しさん
2019/10/08(火) 21:04:41.31ID:OCfPMe68 C++なんて趣味でやってるんだからテンプレ好きでもええやん
393デフォルトの名無しさん
2019/10/08(火) 21:16:41.69ID:/kdim2Vo 出てくることの何が嫌なんだろうか
はっきり言って病気だ
はっきり言って病気だ
394デフォルトの名無しさん
2019/10/08(火) 21:42:59.95ID:lGNioH0G headerオンリーってのは可搬性に優れた良いものだろ
特にテンプレート多用している奴は、一部関数だけソースファイル分離する意味が薄い
特にテンプレート多用している奴は、一部関数だけソースファイル分離する意味が薄い
395デフォルトの名無しさん
2019/10/08(火) 21:43:38.32ID:asJ1ctJB >>391
どんなものにだって馬鹿は出てくるだろうに
どんなものにだって馬鹿は出てくるだろうに
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- ネット殺到「高市総理の責任」「完全に高市リスク」「負けるな」中国が水産物輸入停止→流石に総理批判の声も「どう責任取る?」 ★7 [樽悶★]
- 【速報】公然わいせつの疑いで逮捕・送検・略式起訴のAぇ! group 草間リチャード敬太メンバー 脱退を発表 「心の病の療養」に専念 [Ailuropoda melanoleuca★]
- 中国国際航空が日本便を減便へ、春節休みも SNSでは投稿相次ぐ [七波羅探題★]
- 「二枚舌は許されない」中国外務省 高市総理の発言を批判… [BFU★]
- 小野田紀美 経済安保相「悪いことをする外国人、日本にいない状況つくる」 [Hitzeschleier★]
- 【🐼🇨🇳】「高市総理VS中国」で日本からパンダはゼロに? 上野動物園「パンダ返還期限」まであと4カ月…★2 [BFU★]
- 【高市悲報】中国→日本の貨物便、死ぬほど運賃が上昇してる模様。。今後大幅値上げラッシュ来るぞ [467637843]
- 恐ろしい😈のちゅちょちゅちょ・ちぇびるのお🏡
- 【悲報】立憲岡田「間違った答弁をした高市総理に問題がある」→愛国者ブチギレ炎上 [834922174]
- 【高市悲報】日本政府、またウソがバレる。中国「撮影してたのは日本メディア」 [834922174]
- 山上妹 「この人は母親じゃない、母親の形をした統一教会信者だ」 [507895468]
- 立憲民主党「他に高市に質問したらダメなことはなんですか?どこに地雷が埋まっているのかわかりません」⬅なんて答える? [158478931]
