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:/ygW08Jq318デフォルトの名無しさん
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
どんなものにだって馬鹿は出てくるだろうに
どんなものにだって馬鹿は出てくるだろうに
396デフォルトの名無しさん
2019/10/08(火) 21:54:07.26ID:J87hrB1p 「全部ヘッダ」と言われると、そのときの「ヘッダ」の定義がどういうものなのか気になる。
397デフォルトの名無しさん
2019/10/08(火) 21:57:19.52ID:EwyBASw5 趣味でやってる人は全部ヘッダでいいと思う
398デフォルトの名無しさん
2019/10/08(火) 22:09:52.63ID:tSj7di+z >>390
VCのやつは使いまくり
依存するライブラリのヘッダファイルを標準のやつもソリューション内のやつも全部まとめて
stdafx.hの中でインクルードしたらことのほか便利
ただし同じプロジェクトのヘッダファイルを入れだしたら目的を見失って氏ぬ
VCのやつは使いまくり
依存するライブラリのヘッダファイルを標準のやつもソリューション内のやつも全部まとめて
stdafx.hの中でインクルードしたらことのほか便利
ただし同じプロジェクトのヘッダファイルを入れだしたら目的を見失って氏ぬ
399デフォルトの名無しさん
2019/10/08(火) 22:10:50.35ID:hpLG4xMo テンプレート関数は便利だしconstexpr関数は市民の義務だし
結局ほとんどヘッダファイルに書くことになるでしょ
結局ほとんどヘッダファイルに書くことになるでしょ
400デフォルトの名無しさん
2019/10/08(火) 22:30:34.35ID:X4FGjRpd 初心者ですが質問させてください
print(1, 3.14, "abc");とやると引数の中身を順番にスペース区切りで出力してくれるような関数は
可変引数テンプレートの再帰呼出しを使うと便利にできることを知りました。
そこで引数の型に応じて出力の見た目を少し変えたいのですが、
関数の特殊化をすればいいですか?
typeidだと動的な評価になってしまうんですよね?
print(1, 3.14, "abc");とやると引数の中身を順番にスペース区切りで出力してくれるような関数は
可変引数テンプレートの再帰呼出しを使うと便利にできることを知りました。
そこで引数の型に応じて出力の見た目を少し変えたいのですが、
関数の特殊化をすればいいですか?
typeidだと動的な評価になってしまうんですよね?
401デフォルトの名無しさん
2019/10/08(火) 22:33:59.15ID:kGAGzuS0 予想通りの馬鹿回答で笑ってしまった。
やっぱいい判別になるわテンプレバカ。
やっぱいい判別になるわテンプレバカ。
402蟻人間 ◆T6xkBnTXz7B0
2019/10/08(火) 22:37:33.87ID:jfG+k1ni >>400
引数一つに対するテンプレート関数を作って特殊化してそれに少しずつ渡せばできるよ。
引数一つに対するテンプレート関数を作って特殊化してそれに少しずつ渡せばできるよ。
403デフォルトの名無しさん
2019/10/08(火) 22:42:38.66ID:/kdim2Vo C++嫌いなのにいつまで居座るんだろうなこのガイジ
404デフォルトの名無しさん
2019/10/08(火) 22:57:34.25ID:HxNAD6ah 好き嫌いの問題じゃねーんだわ
405デフォルトの名無しさん
2019/10/08(火) 23:04:05.43ID:/kdim2Vo こんな雑談スレ好きな奴以外に需要ないだろ
こんな辺境別に見なくて良いんだよ?
こんな辺境別に見なくて良いんだよ?
406デフォルトの名無しさん
2019/10/08(火) 23:08:13.69ID:hpLG4xMo >>400
c++17以降ならif constexprとstd::is_same_vの使用を検討してみるのもいいかも
c++17以降ならif constexprとstd::is_same_vの使用を検討してみるのもいいかも
407デフォルトの名無しさん
2019/10/09(水) 04:08:22.18ID:NmoqHfbB 400です。頑張ってみましたがどうにもコンパイルエラーが出ます
難しいですねC++は...
void print() {}
template<class... Args>
void print(const char* c, Args... args) {
cout << "[" << c << "]" << endl;
print(args...);
}
template<class First, class... Args>
void print(First first, Args... args) {
cout << first << endl;
print(args...);
}
int main() {
print(1, 3.14, "abc");
return 0;
}
難しいですねC++は...
void print() {}
template<class... Args>
void print(const char* c, Args... args) {
cout << "[" << c << "]" << endl;
print(args...);
}
template<class First, class... Args>
void print(First first, Args... args) {
cout << first << endl;
print(args...);
}
int main() {
print(1, 3.14, "abc");
return 0;
}
408デフォルトの名無しさん
2019/10/09(水) 04:17:51.46ID:NmoqHfbB あ、こういうふうにするとコンパイルできました。引数2個の関数を特殊化したからエラーになった?
テンプレートの展開のされ方がよくわからないけど、とりあえず目的のことはできました
ありがとうございました
void print(const char* c) {
cout << "[" << c << "]" << endl;
}
template<class T>
void print(T t) {
cout << t << endl;
}
template<class First, class... Args>
void print(First first, Args... args) {
print(first);
print(args...);
}
テンプレートの展開のされ方がよくわからないけど、とりあえず目的のことはできました
ありがとうございました
void print(const char* c) {
cout << "[" << c << "]" << endl;
}
template<class T>
void print(T t) {
cout << t << endl;
}
template<class First, class... Args>
void print(First first, Args... args) {
print(first);
print(args...);
}
409デフォルトの名無しさん
2019/10/09(水) 04:21:52.30ID:NmoqHfbB >>406
いわゆる型特性というやつでしょうか?enable_ifを使うのかと思い試したもののうまくいかず、
ネットで調べるとenable_ifと可変引数テンプレートは相性が悪いという意見を見つけたり...
いわゆる型特性というやつでしょうか?enable_ifを使うのかと思い試したもののうまくいかず、
ネットで調べるとenable_ifと可変引数テンプレートは相性が悪いという意見を見つけたり...
410デフォルトの名無しさん
2019/10/09(水) 07:02:07.47ID:8qv563yz >>409
if constexprを使った例はこんな感じ
template<class First, class... Args>
void print(First first, Args... args) {
if constexpr(std::is_same_v<First, const char*>){
std::cout << "[" << first << "]" << std::endl;
} else {
std::cout << first << std::endl;
}
if constexpr(sizeof...(args)>0){
print(args...);
}
}
if constexprを使った例はこんな感じ
template<class First, class... Args>
void print(First first, Args... args) {
if constexpr(std::is_same_v<First, const char*>){
std::cout << "[" << first << "]" << std::endl;
} else {
std::cout << first << std::endl;
}
if constexpr(sizeof...(args)>0){
print(args...);
}
}
411デフォルトの名無しさん
2019/10/09(水) 10:59:59.89ID:RbUf+g7C const char * 自体も class First や class Args と一致するんじゃね
412デフォルトの名無しさん
2019/10/09(水) 21:59:58.44ID:8qv563yz First と Argsの二つがあるのがややこしい場合は畳み込み式でもできるぞ
template<class... Args>
void print(Args... args){
([](auto t){
if constexpr(std::is_same_v<decltype(t), const char*>){
std::cout << "[" << t << "]" << std::endl;
} else {
std::cout << t << std::endl;
}
}(args), ...);
}
template<class... Args>
void print(Args... args){
([](auto t){
if constexpr(std::is_same_v<decltype(t), const char*>){
std::cout << "[" << t << "]" << std::endl;
} else {
std::cout << t << std::endl;
}
}(args), ...);
}
413デフォルトの名無しさん
2019/10/09(水) 22:42:32.58ID:J+0BhmRu win系のOSの画面に1.txt~5.txtがあります。1.txtと2.txtをドラッグして選択したとします。
この状態で3.txt~5.txtを選択したことにするにはどのようなコードを書けば良いですか?
この状態で3.txt~5.txtを選択したことにするにはどのようなコードを書けば良いですか?
415デフォルトの名無しさん
2019/10/10(木) 00:29:05.87ID:uUO69neG エクスプローラにdll注入とか?
416蟻人間 ◆T6xkBnTXz7B0
2019/10/10(木) 01:32:41.34ID:VnnXeZwz 前にやったことがある。
https://github.com/katahiromz/SysNotifyHooker
https://github.com/katahiromz/SysNotifyHooker
417デフォルトの名無しさん
2019/10/11(金) 01:40:25.90ID:n351RXRL std::shared_ptrを構築後に(カスタム)デリータを変更するのは無理?
既にどっかで作成済みのshared_ptrについて、破棄タイミングを後から見れないかなと
既にどっかで作成済みのshared_ptrについて、破棄タイミングを後から見れないかなと
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【地震速報】青森県で震度6強 沿岸部に津波警報 ★6 [ぐれ★]
- 「日の丸にバツ印」掲げた大学生 あいまいな国旗損壊罪に「怖い」 The Mainichi [少考さん★]
- 【音楽】BARBEE BOYS・KONTAが事故で四肢麻痺を公表、新体制で活動は継続 [少考さん★]
- 【野球】野球の未来に危機感「マイナースポーツになる」 宮本慎也氏が開催…学童大会 [尺アジ★]
- 中国「捜索レーダー起動は各国の通常の手法」 火器管制用か回答せず [蚤の市★]
- 【訃報】声優・西村知道さん死去 「SLAM DUNK」安西先生役 9月に体調不良のため一時休業 [少考さん★]
- 中国「日本のネトウヨを根絶してやるからな」。ネトウヨ、人生が終わる [805596214]
- おはようございます [577451214]
- (´・ω・`)刑務所での暮らしwwwwwwwwwwwwwwww
- ぺこーら、地震で同僚が次々配信を止めるなか強行し続けるので悪目立ちするwww [268244553]
- なぜ人間は架空の人物に感情移入するのか
- 【愛国者速報】山上徹也、金に困りTwitterのお金配り垢に応募していた。犯行もお金があったら暫くやらなかったと供述 [856698234]
