[戻る]
一括表示

CASTの使い方 投稿者:Zman 投稿日:2017/01/28(Sat) 15:44:33 No.805

CCSCコンパイラ(PCM)でキャストを使うときの考え方を教えてください。

int i1,i2,i3,i4;
long L1,L2;

i1=L1-(i2*i3*i4/L2);

の計算をするとき
ただし、実際の値としては
(i2*i3*i4/L2)はlong範囲内
 L1-(i2*i3*i4/L2)はint範囲内
になるものとします。

1. (i2*i3*i4) がlong範囲を超える場合
  i1=L1-(long long)(i2*i3*i4/L2)
i2,i3,i4,L2 は (long long)に自動変換されて計算される
  
2. (i2*i3*i4) がlong範囲内の場合
(i2*i3*i4/L2) においてL2がlongなのでi2,i3,i4はlongに自動変換されて計算されるので
i1=L1-(i2*i3*i4/L2)

・・・でよいでしょうか?
間違いがありましたら、ご指摘をお願いします。

Re: CASTの使い方 投稿者:n 投稿日:2017/01/28(Sat) 23:50:27 No.806

Zmanさん

はじめましてnです。

i1=L1-(i2*(long)i3*i4/L2);
のように、先にint型変数をキャストする必要があります。

(long long)(i2*i3*i4/L2)では、
i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
演算結果をあとからlonglongにキャストしても手遅れです。

1. (long)i2*i3*i4
または、
2. i2*(long)i3*i4
のように、int型の変数をlong型へキャストします。

同じ優先順位の演算の評価順序は、処理系依存なので、
2のほうが安全です。


> CCSCコンパイラ(PCM)でキャストを使うときの考え方を教えてください。
>
> int i1,i2,i3,i4;
> long L1,L2;
>
> i1=L1-(i2*i3*i4/L2);
>
> の計算をするとき
> ただし、実際の値としては
> (i2*i3*i4/L2)はlong範囲内
>  L1-(i2*i3*i4/L2)はint範囲内
> になるものとします。
>
> 1. (i2*i3*i4) がlong範囲を超える場合
>   i1=L1-(long long)(i2*i3*i4/L2)
> i2,i3,i4,L2 は (long long)に自動変換されて計算される
>   
> 2. (i2*i3*i4) がlong範囲内の場合
> (i2*i3*i4/L2) においてL2がlongなのでi2,i3,i4はlongに自動変換されて計算されるので
> i1=L1-(i2*i3*i4/L2)
>
> ・・・でよいでしょうか?
> 間違いがありましたら、ご指摘をお願いします。

Re^2: CASTの使い方 投稿者:Zman 投稿日:2017/01/29(Sun) 14:33:51 No.807

nさん、回答ありがとうございます。

>i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
そのために i2*(long)i3*i4 としたとき

i2*(long)i3 はlong 範囲内としても
i2*(long)i3*i4 はlong型としてオーバーフローする場合は
i2*(long)i3*(long long)*i4 とすれば

i2*(long)i3 の計算結果(long)をlong long に変換して (long long)i4 に掛けることになる
・・・ということでよいでしょうか?

> Zmanさん
>
> はじめましてnです。
>
> i1=L1-(i2*(long)i3*i4/L2);
> のように、先にint型変数をキャストする必要があります。
>
> (long long)(i2*i3*i4/L2)では、
> i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> 演算結果をあとからlonglongにキャストしても手遅れです。
>
> 1. (long)i2*i3*i4
> または、
> 2. i2*(long)i3*i4
> のように、int型の変数をlong型へキャストします。
>
> 同じ優先順位の演算の評価順序は、処理系依存なので、
> 2のほうが安全です。
>
>
> > CCSCコンパイラ(PCM)でキャストを使うときの考え方を教えてください。
> >
> > int i1,i2,i3,i4;
> > long L1,L2;
> >
> > i1=L1-(i2*i3*i4/L2);
> >
> > の計算をするとき
> > ただし、実際の値としては
> > (i2*i3*i4/L2)はlong範囲内
> >  L1-(i2*i3*i4/L2)はint範囲内
> > になるものとします。
> >
> > 1. (i2*i3*i4) がlong範囲を超える場合
> >   i1=L1-(long long)(i2*i3*i4/L2)
> > i2,i3,i4,L2 は (long long)に自動変換されて計算される
> >   
> > 2. (i2*i3*i4) がlong範囲内の場合
> > (i2*i3*i4/L2) においてL2がlongなのでi2,i3,i4はlongに自動変換されて計算されるので
> > i1=L1-(i2*i3*i4/L2)
> >
> > ・・・でよいでしょうか?
> > 間違いがありましたら、ご指摘をお願いします。

Re^3: CASTの使い方 投稿者:n 投稿日:2017/01/29(Sun) 16:13:00 No.808

Zmanさん

nです。

i2*(long)i3*(long long)i4
の評価は、もう少し複雑です。

キャスト演算子は前置型の2項演算子です。
(op1)op2と記し、op2のみ評価してop1の型に型変換します。

乗算は優先順位が低いので、キャストより後に評価されます。
ただし、a*b*cの乗算は、どこから先に行われるかわかりません。
a*b
b*c
a*c...等、どれもあり得るのです。

同じソースコードでも、処理系が異なると実行結果も変わり得ます。
人間が行う乗算の順序を前提にしてCの式を考えてはいけません。
互換性を高めるためにも、式を複数行に分けることをお勧めします。

> nさん、回答ありがとうございます。
>
> >i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> そのために i2*(long)i3*i4 としたとき
>
> i2*(long)i3 はlong 範囲内としても
> i2*(long)i3*i4 はlong型としてオーバーフローする場合は
> i2*(long)i3*(long long)*i4 とすれば
>
> i2*(long)i3 の計算結果(long)をlong long に変換して (long long)i4 に掛けることになる
> ・・・ということでよいでしょうか?
>
> > Zmanさん
> >
> > はじめましてnです。
> >
> > i1=L1-(i2*(long)i3*i4/L2);
> > のように、先にint型変数をキャストする必要があります。
> >
> > (long long)(i2*i3*i4/L2)では、
> > i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> > 演算結果をあとからlonglongにキャストしても手遅れです。
> >
> > 1. (long)i2*i3*i4
> > または、
> > 2. i2*(long)i3*i4
> > のように、int型の変数をlong型へキャストします。
> >
> > 同じ優先順位の演算の評価順序は、処理系依存なので、
> > 2のほうが安全です。
> >
> >
> > > CCSCコンパイラ(PCM)でキャストを使うときの考え方を教えてください。
> > >
> > > int i1,i2,i3,i4;
> > > long L1,L2;
> > >
> > > i1=L1-(i2*i3*i4/L2);
> > >
> > > の計算をするとき
> > > ただし、実際の値としては
> > > (i2*i3*i4/L2)はlong範囲内
> > >  L1-(i2*i3*i4/L2)はint範囲内
> > > になるものとします。
> > >
> > > 1. (i2*i3*i4) がlong範囲を超える場合
> > >   i1=L1-(long long)(i2*i3*i4/L2)
> > > i2,i3,i4,L2 は (long long)に自動変換されて計算される
> > >   
> > > 2. (i2*i3*i4) がlong範囲内の場合
> > > (i2*i3*i4/L2) においてL2がlongなのでi2,i3,i4はlongに自動変換されて計算されるので
> > > i1=L1-(i2*i3*i4/L2)
> > >
> > > ・・・でよいでしょうか?
> > > 間違いがありましたら、ご指摘をお願いします。

Re^4: CASTの使い方 投稿者:Zman 投稿日:2017/01/30(Mon) 14:41:51 No.809

回答ありがとうございます。

基本的に
i2*(long)i3 も L1*i2 も L1/i2 も計算結果は long になるということでよいでしょうか?
( 型が異なる場合の掛算・割算の結果は精度の高い型に統一されるということで・・・。)
もし、YES とすれば

>人間が行う乗算の順序を前提にしてCの式を考えてはいけません。
( ) で計算順序を指定して
>互換性を高めるためにも、式を複数行に分けることをお勧めします。

long L10;

L10=i2*(long)i3;
i1=L1- ( ( (long long)L10*i4 ) / L2 );
・・・ということでよいでしょうか?

> Zmanさん
>
> nです。
>
> i2*(long)i3*(long long)i4
> の評価は、もう少し複雑です。
>
> キャスト演算子は前置型の2項演算子です。
> (op1)op2と記し、op2のみ評価してop1の型に型変換します。
>
> 乗算は優先順位が低いので、キャストより後に評価されます。
> ただし、a*b*cの乗算は、どこから先に行われるかわかりません。
> a*b
> b*c
> a*c...等、どれもあり得るのです。
>
> 同じソースコードでも、処理系が異なると実行結果も変わり得ます。
> 人間が行う乗算の順序を前提にしてCの式を考えてはいけません。
> 互換性を高めるためにも、式を複数行に分けることをお勧めします。
>
> > nさん、回答ありがとうございます。
> >
> > >i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> > そのために i2*(long)i3*i4 としたとき
> >
> > i2*(long)i3 はlong 範囲内としても
> > i2*(long)i3*i4 はlong型としてオーバーフローする場合は
> > i2*(long)i3*(long long)*i4 とすれば
> >
> > i2*(long)i3 の計算結果(long)をlong long に変換して (long long)i4 に掛けることになる
> > ・・・ということでよいでしょうか?
> >
> > > Zmanさん
> > >
> > > はじめましてnです。
> > >
> > > i1=L1-(i2*(long)i3*i4/L2);
> > > のように、先にint型変数をキャストする必要があります。
> > >
> > > (long long)(i2*i3*i4/L2)では、
> > > i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> > > 演算結果をあとからlonglongにキャストしても手遅れです。
> > >
> > > 1. (long)i2*i3*i4
> > > または、
> > > 2. i2*(long)i3*i4
> > > のように、int型の変数をlong型へキャストします。
> > >
> > > 同じ優先順位の演算の評価順序は、処理系依存なので、
> > > 2のほうが安全です。
> > >
> > >
> > > > CCSCコンパイラ(PCM)でキャストを使うときの考え方を教えてください。
> > > >
> > > > int i1,i2,i3,i4;
> > > > long L1,L2;
> > > >
> > > > i1=L1-(i2*i3*i4/L2);
> > > >
> > > > の計算をするとき
> > > > ただし、実際の値としては
> > > > (i2*i3*i4/L2)はlong範囲内
> > > >  L1-(i2*i3*i4/L2)はint範囲内
> > > > になるものとします。
> > > >
> > > > 1. (i2*i3*i4) がlong範囲を超える場合
> > > >   i1=L1-(long long)(i2*i3*i4/L2)
> > > > i2,i3,i4,L2 は (long long)に自動変換されて計算される
> > > >   
> > > > 2. (i2*i3*i4) がlong範囲内の場合
> > > > (i2*i3*i4/L2) においてL2がlongなのでi2,i3,i4はlongに自動変換されて計算されるので
> > > > i1=L1-(i2*i3*i4/L2)
> > > >
> > > > ・・・でよいでしょうか?
> > > > 間違いがありましたら、ご指摘をお願いします。

Re^5: CASTの使い方 投稿者:n 投稿日:2017/01/30(Mon) 18:43:46 No.810

Zmanさん

nです。

通常の算術型変換の一部である汎整数拡張は、
long型までならokですが、longlong型については、
処理系依存と考えられます。
テストプログラムの実行等で確認してください。

評価順序をコントロールする場合は、
;で複数の式の文とするか、,(コンマ演算子)を用います。

式が評価される順序は、規格では未規定です。
「式は括弧の存在に関係なく、演算子の優先順位規則に適合する任意の順序で評価されうる。」
ソースコードの可読性の点からも、丸括弧多用はお勧めできません。

 long L10;

 L10=i2;
 L10*=i3;
 i1=L1-L10*(long long)i4/L2;
または、
 L10=i2,L10*=i3,i1=L1-L10*(long long)i4/L2;


> 回答ありがとうございます。
>
> 基本的に
> i2*(long)i3 も L1*i2 も L1/i2 も計算結果は long になるということでよいでしょうか?
> ( 型が異なる場合の掛算・割算の結果は精度の高い型に統一されるということで・・・。)
> もし、YES とすれば
>
> >人間が行う乗算の順序を前提にしてCの式を考えてはいけません。
> ( ) で計算順序を指定して
> >互換性を高めるためにも、式を複数行に分けることをお勧めします。
>
> long L10;
>
> L10=i2*(long)i3;
> i1=L1- ( ( (long long)L10*i4 ) / L2 );
> ・・・ということでよいでしょうか?
>
> > Zmanさん
> >
> > nです。
> >
> > i2*(long)i3*(long long)i4
> > の評価は、もう少し複雑です。
> >
> > キャスト演算子は前置型の2項演算子です。
> > (op1)op2と記し、op2のみ評価してop1の型に型変換します。
> >
> > 乗算は優先順位が低いので、キャストより後に評価されます。
> > ただし、a*b*cの乗算は、どこから先に行われるかわかりません。
> > a*b
> > b*c
> > a*c...等、どれもあり得るのです。
> >
> > 同じソースコードでも、処理系が異なると実行結果も変わり得ます。
> > 人間が行う乗算の順序を前提にしてCの式を考えてはいけません。
> > 互換性を高めるためにも、式を複数行に分けることをお勧めします。
> >
> > > nさん、回答ありがとうございます。
> > >
> > > >i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> > > そのために i2*(long)i3*i4 としたとき
> > >
> > > i2*(long)i3 はlong 範囲内としても
> > > i2*(long)i3*i4 はlong型としてオーバーフローする場合は
> > > i2*(long)i3*(long long)*i4 とすれば
> > >
> > > i2*(long)i3 の計算結果(long)をlong long に変換して (long long)i4 に掛けることになる
> > > ・・・ということでよいでしょうか?
> > >
> > > > Zmanさん
> > > >
> > > > はじめましてnです。
> > > >
> > > > i1=L1-(i2*(long)i3*i4/L2);
> > > > のように、先にint型変数をキャストする必要があります。
> > > >
> > > > (long long)(i2*i3*i4/L2)では、
> > > > i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> > > > 演算結果をあとからlonglongにキャストしても手遅れです。
> > > >
> > > > 1. (long)i2*i3*i4
> > > > または、
> > > > 2. i2*(long)i3*i4
> > > > のように、int型の変数をlong型へキャストします。
> > > >
> > > > 同じ優先順位の演算の評価順序は、処理系依存なので、
> > > > 2のほうが安全です。
> > > >
> > > >
> > > > > CCSCコンパイラ(PCM)でキャストを使うときの考え方を教えてください。
> > > > >
> > > > > int i1,i2,i3,i4;
> > > > > long L1,L2;
> > > > >
> > > > > i1=L1-(i2*i3*i4/L2);
> > > > >
> > > > > の計算をするとき
> > > > > ただし、実際の値としては
> > > > > (i2*i3*i4/L2)はlong範囲内
> > > > >  L1-(i2*i3*i4/L2)はint範囲内
> > > > > になるものとします。
> > > > >
> > > > > 1. (i2*i3*i4) がlong範囲を超える場合
> > > > >   i1=L1-(long long)(i2*i3*i4/L2)
> > > > > i2,i3,i4,L2 は (long long)に自動変換されて計算される
> > > > >   
> > > > > 2. (i2*i3*i4) がlong範囲内の場合
> > > > > (i2*i3*i4/L2) においてL2がlongなのでi2,i3,i4はlongに自動変換されて計算されるので
> > > > > i1=L1-(i2*i3*i4/L2)
> > > > >
> > > > > ・・・でよいでしょうか?
> > > > > 間違いがありましたら、ご指摘をお願いします。

Re^6: CASTの使い方 投稿者:Zman 投稿日:2017/02/01(Wed) 16:46:16 No.811

nさん、回答ありがとうございます。

> テストプログラムの実行等で確認してください。
OK でした。
勉強になりました。

> Zmanさん
>
> nです。
>
> 通常の算術型変換の一部である汎整数拡張は、
> long型までならokですが、longlong型については、
> 処理系依存と考えられます。
> テストプログラムの実行等で確認してください。
>
> 評価順序をコントロールする場合は、
> ;で複数の式の文とするか、,(コンマ演算子)を用います。
>
> 式が評価される順序は、規格では未規定です。
> 「式は括弧の存在に関係なく、演算子の優先順位規則に適合する任意の順序で評価されうる。」
> ソースコードの可読性の点からも、丸括弧多用はお勧めできません。
>
>  long L10;
>
>  L10=i2;
>  L10*=i3;
>  i1=L1-L10*(long long)i4/L2;
> または、
>  L10=i2,L10*=i3,i1=L1-L10*(long long)i4/L2;
>
>
> > 回答ありがとうございます。
> >
> > 基本的に
> > i2*(long)i3 も L1*i2 も L1/i2 も計算結果は long になるということでよいでしょうか?
> > ( 型が異なる場合の掛算・割算の結果は精度の高い型に統一されるということで・・・。)
> > もし、YES とすれば
> >
> > >人間が行う乗算の順序を前提にしてCの式を考えてはいけません。
> > ( ) で計算順序を指定して
> > >互換性を高めるためにも、式を複数行に分けることをお勧めします。
> >
> > long L10;
> >
> > L10=i2*(long)i3;
> > i1=L1- ( ( (long long)L10*i4 ) / L2 );
> > ・・・ということでよいでしょうか?
> >
> > > Zmanさん
> > >
> > > nです。
> > >
> > > i2*(long)i3*(long long)i4
> > > の評価は、もう少し複雑です。
> > >
> > > キャスト演算子は前置型の2項演算子です。
> > > (op1)op2と記し、op2のみ評価してop1の型に型変換します。
> > >
> > > 乗算は優先順位が低いので、キャストより後に評価されます。
> > > ただし、a*b*cの乗算は、どこから先に行われるかわかりません。
> > > a*b
> > > b*c
> > > a*c...等、どれもあり得るのです。
> > >
> > > 同じソースコードでも、処理系が異なると実行結果も変わり得ます。
> > > 人間が行う乗算の順序を前提にしてCの式を考えてはいけません。
> > > 互換性を高めるためにも、式を複数行に分けることをお勧めします。
> > >
> > > > nさん、回答ありがとうございます。
> > > >
> > > > >i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> > > > そのために i2*(long)i3*i4 としたとき
> > > >
> > > > i2*(long)i3 はlong 範囲内としても
> > > > i2*(long)i3*i4 はlong型としてオーバーフローする場合は
> > > > i2*(long)i3*(long long)*i4 とすれば
> > > >
> > > > i2*(long)i3 の計算結果(long)をlong long に変換して (long long)i4 に掛けることになる
> > > > ・・・ということでよいでしょうか?
> > > >
> > > > > Zmanさん
> > > > >
> > > > > はじめましてnです。
> > > > >
> > > > > i1=L1-(i2*(long)i3*i4/L2);
> > > > > のように、先にint型変数をキャストする必要があります。
> > > > >
> > > > > (long long)(i2*i3*i4/L2)では、
> > > > > i2*i3を評価した段階でint型のオーバーフローが起こり得ます。
> > > > > 演算結果をあとからlonglongにキャストしても手遅れです。
> > > > >
> > > > > 1. (long)i2*i3*i4
> > > > > または、
> > > > > 2. i2*(long)i3*i4
> > > > > のように、int型の変数をlong型へキャストします。
> > > > >
> > > > > 同じ優先順位の演算の評価順序は、処理系依存なので、
> > > > > 2のほうが安全です。
> > > > >
> > > > >
> > > > > > CCSCコンパイラ(PCM)でキャストを使うときの考え方を教えてください。
> > > > > >
> > > > > > int i1,i2,i3,i4;
> > > > > > long L1,L2;
> > > > > >
> > > > > > i1=L1-(i2*i3*i4/L2);
> > > > > >
> > > > > > の計算をするとき
> > > > > > ただし、実際の値としては
> > > > > > (i2*i3*i4/L2)はlong範囲内
> > > > > >  L1-(i2*i3*i4/L2)はint範囲内
> > > > > > になるものとします。
> > > > > >
> > > > > > 1. (i2*i3*i4) がlong範囲を超える場合
> > > > > >   i1=L1-(long long)(i2*i3*i4/L2)
> > > > > > i2,i3,i4,L2 は (long long)に自動変換されて計算される
> > > > > >   
> > > > > > 2. (i2*i3*i4) がlong範囲内の場合
> > > > > > (i2*i3*i4/L2) においてL2がlongなのでi2,i3,i4はlongに自動変換されて計算されるので
> > > > > > i1=L1-(i2*i3*i4/L2)
> > > > > >
> > > > > > ・・・でよいでしょうか?
> > > > > > 間違いがありましたら、ご指摘をお願いします。

- WebForum -