• ベストアンサー

VS2010でのint float数値について

int MAX =10; for(int i=0; i<MAX-1; i++) {   float A;   A = i / ( MAX-1 );   float B;   B = i / ( MAX-1.0f );   // A or Bを使って処理 } A、Bの数値は変わるのでしょうか? この後のコードで、 Aの場合、望んだ結果が出なかったのですが Bの場合ですと期待通りの結果が出ました… VisualStudio2010 C/C++ Win7 64bitです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Glory_777
  • ベストアンサー率50% (105/208)
回答No.4

Aの方は、全て0になりそうですが。どうでした? 型の違う数値演算をしているときは、 なるべく精度の高いものに合わせて計算されます。 内部的にキャストが行われているので、予めこれを読んで数式を作る必要があります。 Aの例、i=1のとき --------------------------------------- float A; A = (float) ( 1/9 ); // i=1のときの計算 --------------------------------------- これだと先に括弧の中は(int同士の計算ですから少数以下は切り捨てられて)0になります。 ところが演算の中にintよりも精度の高い型が含まれていると、関連する数値は全て 格上げされて(キャスト)計算されます。 double > float > int みたいな感じで、左のほうが精度が高い。 混在した時は、一番精度の高いものに変換(キャスト)してから演算が行われます。 ですので、Bの例は以下のような変換が行われています --------------------------------------- float B; B = (float) ( (float) 1 / 9.0f ) // i=1のときの計算 --------------------------------------- これならば小数点以下も結果に残ります。 私が書き足した(float)の部分をコンパイラが勝手にやります。 例えば以下の計算結果は0になりますが、 --------------------------------------- int b; b = 1 / 4.0; // 4.0 が暗黙に doubleでの演算を求めている --------------------------------------- これは一回doubleで演算し、0.25と言う答えを得てから、 intにキャストする段階で小数点以下が捨てられます。 (処理系依存ですが、考え方はこれが基本) 以下も同様のキャストが暗黙に行われる --------------------------------------- int b; b = 1 + 4.0; // 4.0 が暗黙に doubleでの演算を求めている --------------------------------------- 答えは5になりますが、一度内部的に 1.0 + 4.0が演算されています。 (処理系依存ですが、考え方はこれが基本) B = i / (MAX - 1.0f ); ですと、MAXは整数ですが、1.0fが暗黙にfloatへのキャストを求めています。 ですので、(MAX - 1.0f)の戻り値の型がfloatになっています。 つまり、 B = i / 9.0f; と透過になり、分母がfloatですので、iが整数でもfloatへのキャストが求められ、 結果的に、全てがfloatで演算されます。 以上ご参考になれば。

majuppitto
質問者

お礼

キャスト変換…完全に忘れてました… なるほどなるほど。 確かにそうです。 Aの結果内容も納得がいきました。 ご丁寧な解説ありがとうございました。

その他の回答 (3)

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.3

VC++ 独自の、ではなく、C/C++ の仕様でそうなっています。 まず基本的なことから。C/C++ の計算や代入ではその演算子の左辺と右辺とで型が違っているときは暗黙的に型変換が行われます。 http://www9.plala.or.jp/sgwr-t/c/sec04.html A は除算の時点でその型が int / int になっているため、 計算結果も int 型にするため小数点以下を切り捨てます。 そして代入の時点で float に変換されます。 B は分母で int + float を行っているためその計算結果が float 型になり、除算が int / float となって結果も float 型になります。つまり、小数点以下を(float のできる範囲で)計算することになります。 そのあとの代入では float を float に代入するだけなので変換は起きません。

majuppitto
質問者

お礼

同文ですが皆様のお陰で解決できました。 ありがとうございました。

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.2

i / (MAX - 1) は全て整数で演算されます。 i / (MAX - 1.0f)はMAXの10の演算相手がfloatなのでfloatに変換されて10fに、10fと1.0fの演算結果もfloatのためiもfloatに型変換されて演算されます。 算術型変換を調べてみてください。

majuppitto
質問者

お礼

同文ですが皆様のお陰で解決できました。 ありがとうございました。

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

自分で結果見て経験したように変わります Aだと(計算式内にintしか存在していないので)整数演算されて小数点以下全部なくなります Bは浮動小数点演算されます

majuppitto
質問者

お礼

同文ですが皆様のお陰で解決できました。 ありがとうございました。

関連するQ&A

  • 共有体でfloat型の数値を2進数へ変換

    実行結果が思ったとおりの値を算出しません。 なぜでしょうか? 回答のほどよろしくお願いいたします。 (例) 小数入力 >5.0 0000 0000 0000 0000 0100 0000 1010 0000 小数入力 >-5.0 0000 0000 0000 0000 1100 0000 1010 0000 (下記ソース) #include<stdio.h> void float_binary(float a); void main (void) { float fl; printf("小数入力 >"); scanf("%f",&fl); float_binary(fl); } void float_binary(float a) { struct float_data{ short int high_byte; short int low_byte; }; union data{ float num; struct float_data bit; }DATA; int i; DATA.num = a; for(i = 0; i<16; i++){ if(i != 0 && i % 4 == 0){ printf(" "); } if(DATA.bit.high_byte < 0){ printf("1"); } else{ printf("0"); } DATA.bit.high_byte = DATA.bit.high_byte << 1; } for(i = 0; i<16; i++){ if(i % 4 == 0){ printf(" "); } if(DATA.bit.low_byte < 0){ printf("1"); } else{ printf("0"); } DATA.bit.low_byte = DATA.bit.low_byte << 1; } }

  • int型とfloat型の演算結果

    C初心者です。 int型とfloat型で割り算をして処理を表示させてます。 以下、実処理の一部です。 int a; int b; a = 3; b = 2; (1) printf("答え=%d:1のはず\n",a/b); (2) printf("答え=%d:1のはず\n",a/(float)b); (3) printf("答え=%d:1のはず\n",(float)a/b); (4) printf("答え=%d:1のはず\n",(float)a/(float)b); 私の予想では(1)~(4)まですべて1が表示されると思っていました。 実際は(1)のみ1で(2)~(4)は0でした。 (2)~(4)はなぜ0と表示されるのですか? ・整数型と実数型で演算した場合、実数型に合わせられてること ・表示が整数型であること なので1が表示されると予想したのですが・・・。

  • float型関数で定義するプログラミング

    今プログラミングを行っているのですが、Xn+1=Xn-f(Xn)/g(Xn)(f(x)=x*x-x-1,g(x)=2x-1,これらはfloat型の関数とすること)で初期値Xo=-2としたときに繰り返しxを求めていき、|f(x)|=<10^-5となるまで計算するプログラムを作成したいのですが結果がおかしくなるので、ここからどう手直しすればいいのかわかりません。 #include<stdio.h> float wa(void); int main(void) { float a,i; for (i = -2; i <= 0.00005; i++) { a = wa(); printf("%f\n", a); } return 0; } float wa(void) { float l = 0, i, m, n, x,b; for (i = -2; i <= 0.00005; i++) { x = i; l *= i; m = x*x - x - 1; n = (2 * x) - 1; b = l - (m / n); } return b; } 結果 -1.000000 -1.000000 -1.000000 正直言ってどういう結果になればいいのかもわかりません。 せめてどういうような結果になるのかだけでも教えていただければありがたいです。

  • float型関数の定義の仕方がわかりません。

    次のプログラミングでfloat型関数を定義しようとしても下の矢印のところにどんな文字を入れても「初期化されてないローカル変数が使用されます。」と出て、どうしてもうまくいきません。 こういう場合どこを直せばエラーが出なくなるのでしょうか? #include<stdio.h> float wa(float  );       ↑ int main(void) { float a; a = wa();      ↑ printf("%f\n",a); return 0; } float wa(float  )       ↑ { float l = 0, i, m, n, x,b; for (i = -2; i <= 0.00005; i++) { x = i; l *= i; m = x*x - x - 1; n = (2 * x) - 1; b = l - (m / n); } return b; }

  • doubleからfloatにすると表示が変になる

    しょうもない質問ですいません。 下記のC言語の行列積のコードでは行列の変数をdoubleとしていますが、これをfloatに全て置き換えると、printfで表示させる結果がバグってしまいます。 原因は何でしょうか? 最近ひさしぶりにC言語を触ったので、しょうもないところでつまずきました。 お願いします。 ----------------------------------------- #include <stdio.h> #include <stdlib.h> #define N 10 //N次の正方行列まで扱えるようにする void matrixmultiply(int n,double a[N][N],double b[N][N],double c[N][N]); int main(int argc, char** argv) { int i,j,n; double A[N][N],B[N][N],C[N][N]; FILE *readin1,*readin2; /*行列の値が書き込まれたファイルを開く*/ if((readin1=fopen("a.dat","r"))==NULL) { printf("a.datを開けません\n"); exit(1); } if((readin2=fopen("b.dat","r"))==NULL) { printf("b.datを開けません\n"); exit(1); } printf("行列の次数を入力してください\n"); scanf("%d",&n); printf("%d次の正方行列の掛け算を行います\n\n",n); /*ファイルから数値を読み込み、配列に代入する*/ for(i=0;i<n;i++) { for(j=0;j<n;j++) { fscanf(readin1,"%lf",&A[i][j]); fscanf(readin2,"%lf",&B[i][j]); } } matrixmultiply(n,A,B,C); //関数を呼び出し行列の掛け算を行う。 /*結果を表示する*/ printf("計算結果\n"); for(i=0;i<n;i++) { for(j=0;j<n;j++) { printf("%lf ",C[i][j]); } printf("\n"); } fclose(readin1); fclose(readin2); return 0; } /*掛け算を行う行列2つと、結果を入れる行列を引数として受け取る。*/ void matrixmultiply(int n,double a[N][N],double b[N][N],double c[N][N]) { int i,j,k; /*受け取った2つの行列の掛け算を行う。*/ for(i=0;i<n;i++) { for(j=0;j<n;j++) { for(k=0;k<n;k++) { c[i][j]+=a[i][k]*b[k][j]; } } } }

  • ■int型の数値から数字文字への変換について

    はじめまして。専門学生のhide1978と申します。 今回、以下のような問題に取り組んでいるのですが、どうしても正しい結果が得られません。どなたか知恵を授けてやってください。よろしくお願いいたします。 ■問題 int型の数値(-32767から32767)を入力して、そのまま10進文字列(char型)として変換する。 ■私が書いたプログラム #include <stdio.h> int NUMtoCHAR(int c){ if(c >= 0 && c <= 9) return (c+'0'); else return c; } void main(void){ signed int i_value; int count, i; double f_value; char c[9]; printf("入力データ:");scanf("%d",&i_value); printf("\n"); for(i = 0; i < 9; i++) c[i] = ' '; if(i_value > 0){ c[0] = '+'; }else if(i_value < 0){ c[0] = '-'; } f_value = (double)i_value; count = 0; while(f_value >= 1){ f_value = f_value / 10.0; count++; } if(count == 0){ c[2] = '0'; }else{ for(i = 2; count > 0 && i < 9; count--, i++){ f_value = f_value * 10.0; i_value = f_value; c[i] = NUMtoCHAR(i_value); f_value = f_value - i_value; } } printf("10進文字 = "); for(i = 0; i < 9; i++) printf("%c", c[i]); printf("\n"); } 上記プログラムを実行して、入力データとして[32767]を入力すると、結果が[32766]となってしまいます。同じように[34]を入力すると[33]という結果になります。 elseの中に入れ子になっているfor文が怪しいということまでは判るのですが、どのように修正してよいか判りません。 大変長い質問で恐縮ですが、よろしくお願いいたします。 ■環境 OS:WindowsXP Compiler:Borland C++ 5.5.1 fowWin32

  • 行列の計算

    #include<stdio.h> #define N 2 #define M 3 void hyoji(float[][M]); int main(){ int i,j,k; float a[N][M] = {{2.0,2.0,2.0},{2.0,2.0,2.0}}; float b[M][M] = {{1.0,1.0,1.0},{2.0,2.0,2.0},{1.0,1.0,1.0}}; float c[N][N]; for(i=0; i<N; i++){ for(j=0; j<M; j++){ c[i][j] = 0; for(k=0; k<M; k++){ c[i][j] += a[i][k] * b[k][j]; } } } hyoji(c); return(0); } void hyoji(float x[][M]){ int i,j; for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("%4.1f ",x[i][j]); } printf("\n"); } } 以上のプログラムで 行列aと行列bをかけ合せた行列cを求めるのですが コンパイルすると 8 8 8 8 8 1 となり、正しい結果がでません。 なにが間違っているのでしょうか?? よろしくお願いします。

  • int型の表せる範囲

    VC++6.0 on win2kです。 int型の表せる範囲は3万ぐらいまでだと思っていたのですが、 #include <stdio.h> #define Max 1000000 void main(){ for(int i=0;i<Max;i++){ printf("%d\n",i); } } というプログラムを走らせると普通に出ます。 int型の範囲とは何を意味するのでしょうか?

  • C+のsqrt

    icpcの過去問(http://www.deqnotes.net/acmicpc/3006/ja)で、答えを #include <cmath> #include <iostream> using namespace std; #define max 1000000 int main(){ //int max = 100; int a,d,n,number[1000010]; for(int i=0;i<max;i++){ number[i] = 1; } number[0]=0;number[1]=0; for(int i=2;i<=sqrt(max)+1;i++){ if(number[i]){ for(int j=i*2;j<max;j=j+i){ number[j] = 0; } } } while(cin >> a >> d >>n,a||d||n){ int count =0; for(int i=a;i<=max;i=i+d){ if(number[i]){count ++; if(count == n){cout << i << endl;break;} } } } } と書いたところ、PKUで Main.cpp F:\temp\11386803.6056\Main.cpp(15) : error C2668: 'sqrt' : ambiguous call to overloaded function math.h(581): could be 'long double sqrt(long double)' math.h(533): or 'float sqrt(float)' math.h(128): or 'double sqrt(double)' while trying to match the argument list '(int)' F:\temp\11386803.6056\Main.cpp(16) : error C2108: subscript is not of integral type というコンパイルエラーがでます。 sqrtの前後で型が違っているのは分かるのですが、具体的にどうなおせばよいかわかりません。

  • floatで並べた2つのdivの高さを揃えるには?

    コーディング初心者です。 以下の内容のcssがかけなくて困っています。 内容は <p id="a">A</p> <div id="b">B</div> <p id="c">C</p> 今はこの3つをfloatで横並びにします。 #a {float: left;} #b {float: right;} #c {float: right;} ここで、BとCに入る内容が変わる場合でも2つの高さが揃うようにしたいのですが、 MTを使用し、Bを表示させないこともあるので、 BとCを<div>で囲み幅を指定することができません。 何か方法はありますでしょうか? 参考のURL等を教えていただけるだけでもたすかります。 よろしくお願いします。

    • 締切済み
    • CSS