C言語初心者です。お釣り計算の問題で負の値になってしまう理由は何ですか?

このQ&Aのポイント
  • C言語初心者です。お釣り計算の問題で負の値になる理由を教えてください。
  • printf関数でintのキャストを入れるとお釣り計算が成功するのですが、入れない場合は負の値になってしまいます。
  • 回答お願いします。なぜお釣り計算が負の値になるのか説明してください。
回答を見る
  • ベストアンサー

C言語初心者です。次の問題で質問です。

(問題) 1本198円の清涼飲料水1本と、1本138円の牛乳2本を購入し、 千円札で払った場合のお釣りを求めよ。 ただし、5%の消費税を追加し、お釣りの額は整数とする。 なお、消費税を四捨五入するかどうかは自由とする。 (解答) #include <stdio.h> int main(void) { int drink,milk,money,ans; double tax; drink=198; milk=138; money=1000; tax=1.05; printf("お釣りは%dです。",(int)(money-(drink+2*milk)*tax)); return 0; } printf関数でintのキャストを入れると成功したのですが、入れなければ、負の値になってしまいました。 なぜでしょうか?回答お願いいたします。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

printfの中の%と、それに対応する引数の型は一致させる必要があります。 この対応が間違っていた場合、期待通りの出力にはなりません。 %dに対応する型はintです。 キャスト無しだと、暗黙のキャストによって、double taxに合わされて、(money-(drink+2*milk)*tax)が全体でdoubleになります /* (drink+2*milk) がすべてint同士の計算なのでint → int * doubleは、int→doubleの暗黙のキャストが発生して (drink+2*milk) *tax はdouble → int - doubleは、int→doubleの暗黙のキャストが発生して money-(drink+2*milk) *tax はdouble となります */ このとき printf("お釣りは%dです。",(money-(drink+2*milk)*tax)); とすると、引数を受け渡すときに、double 型の値がメモリに書き込まれます(スタックに積まれます)。 double型の内部表現は、int型とはまったく違うので、1と1.0のような「同じ値」でも、メモリの内容はまったく違うものになります。 printfでは、 %d で引数の領域から値を取ってきますが、このときに型を判断するのは、呼び出したときの型ではなく、%d等の書式に対応した型です。%dの場合は、sizeof(int)分をメモリから取ってきて、intだと解釈します。 先に書いたように、内部構造がまったく違うので、double(の一部)をintと解釈すれば、まったく違う値になってしまいます。 対処法は、%と引数の型を対応させることです。 %dなら相手はintに doubleを使いたいなら、%f等に この不一致は、C言語の仕様上、エラーにはなりません。 コンパイル時に、警告を多く出すように設定した場合に、「警告」になるコンパイラはあります。が、警告はエラーでは無いので一応「正常にコンパイル」できます(警告をエラーにするオプションが、コンパイラにある場合もあります) 警告レベルを上げて、間違えないように注意するしかありません。

その他の回答 (3)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

#include<stdio.h> int main(void) { printf("おつりは%d円\n", 1000 - (int) ((198 + 138 * 2) * 1.05)); return 0; }

  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.3

#1さんの指摘の通りです。 %d を %f にすると浮動小数点表示になります。 蛇足ですが、色々やってみました。 1)浮動小数点のまま表示する printf("お釣りは%fです。\n",(money-(drink+2*milk)*tax)); 2)浮動小数点をINTにキャストする(質問者殿の例) printf("お釣りは%dです。\n",(int)(money-(drink+2*milk)*tax)); 3)整数型のみ使う (105倍して100で割る。小数点以下切捨て) printf("お釣りは%dです。\n",money-((drink+2*milk)*105)/100); 4)整数型のみ使う (四捨五入) printf("お釣りは%dです。\n",money-((drink+2*milk)*105+50)/100); 5)整数型のみ使う誤った例。丸めの誤差が大きくなる例。 printf("お釣りは%dです。\n",money-(drink+2*milk)*(105/100)); ご参考に。

  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.1

>(money-(drink+2*milk)*tax) ここで、double のtax を計算しているために、結果がdoubleになっています。 それを、%dで整数表示したためです。

関連するQ&A

  • c言語についての質問です。

    このような問題が出たのですが、作り方を教えてください。お願いします。 int型というやつで、scanf と printf だけを使ってプログラムを作成しなくてはなりません。問題↓ 本年4月より消費税が5%から8%に変更になった.そこで5%税込商品の金額を入力すると,税抜 商品金額及び8%の税込商品金額を表示するプログラムを作成せよ.但し,1円未満の値は 小数点以下第1位を四捨五入すること.(注:5%の税込金額も四捨五入しているので, 税抜金額を求めるとき注意すること)

  • 私はC言語を習い始めて5日の初心者です。

    私はC言語を習い始めて5日の初心者です。 下記のプログラムが動かないので優しく教えてください。 どうかお願いします。 #include <stdio.h> int main() { int ans1,ans; int total printf("コンビニ行くときは(1:車で 2:自転車で 3:歩いて)行く\n"); scanf("%d",&ans1); printf("1:汗かいた記憶がない 2:たまに汗かく 3:よく汗をかく\n"); scanf("%d",&ans2); total=ans1+ans2; if (total<4) { printf("運動不足です\n"); }else { printf("良く運動していますね\n"); } return(0); }

  • C言語を使用したプログラミング方法で質問です。

    以下のプログラミングで質問です。 以下のプログラミングはscanfで入力した値に消費税(1.05)して、10万円-出力結果(消費税含み) の合計金額のお釣りの枚数を表示してます。この処理に以下のプログラムを追加したいのですが分かりません。どなたか教えて頂けますか? 五百円玉=1or0 入力 五十円玉=1or0 入力 1=有り 0=無し 1&1のとき500円玉、50円玉を使ってお釣りを支払う。 1&0のとき50円玉は使わない 0&1のとき500円玉は使わない 0&0のときどちらも使わない。 #include <stdio.h> int main(void) { int i; int buy; int turi, maisu; int coin_500; int coin_50; printf("購入金 = "); scanf("%d",&i); buy=i*1.05; printf("支払額 = %.d\n",buy); turi = (100000-buy); printf("おつり = %.d\n",turi); printf("五百円玉 = "); scanf("%d",&coin_500); printf("五十円玉 = "); scanf("%d",&coin_50); // 一万円札の枚数を求める // maisu = turi / 10000; //おつりの金額に10000円で割った値 printf( "一万円 = %d\n",maisu ); // 千円札の枚数を求める // turi = turi % 10000; //おつりの金額を10000円で割った余りの値 maisu = turi / 1000; //余りの値を1000で割った数 printf( " 千円 = %d\n",maisu ); // 五百円玉の枚数を求める // turi = turi % 1000; maisu = turi / 500; printf( "五百円 = %d\n",maisu ); // 百円玉の枚数を求める // turi = turi % 500; maisu = turi / 100; printf( " 百円 = %d\n",maisu ); // 五十円玉の枚数を求める // turi = turi % 100; maisu = turi / 50; printf( "五十円 = %d\n",maisu ); // 十円玉の枚数を求める // turi = turi % 50; maisu = turi / 10; printf( " 十円 = %d\n",maisu ); // 一円玉の枚数を求める // maisu = turi % 10; printf( " 一円 = %d\n",maisu ); }

  • 消費税計算

    #include <stdio.h> int main (void) { int price_komi, tax; printf("税込価格を入力してください:"); scanf("%d", &price_komi); tax = (double)(price_komi * 0.05); printf("消費税は%d円です。\n", tax); printf("税抜き価格は%dです。\n",price_komi - tax); return(0); } このプログラムでは消費税計算がうまくできません。型の使い方がよくないと思うのですがわかりません。おねがいします。

  • C言語で・・

    実数データを入力し、小数点以下四捨五入したときの値を表示せよ。 自分では、以下のように作りました。 #include<stdio.h> int main(void) { float f_a,s; int i_a; printf("実数データを入力してください"); scanf("%f",&f_a); i_a=(int)f_a; s=f_a-i_a; if(s>=0.5){ i_a=i_a+1; } printf("%fを四捨五入すると%dです",f_a,i_a); return 0; } 他の作りかたがあれば、教えていただきたいのですが。IF文などの範囲でお願いします。

  • C言語、ポインタについて。

    C言語初心者です。"やさしいC"などの入門書を呼んでいて「ポインタ」につまづきました。 別書を買ったり、サイトを見たりしたのですが、理解できませんでした。 "やさしいC"からの引用なのですが、 正: #include <stdio.h> int add(int *x1,int *x2,int a); int main (void){ int n1,n2,a,ans; printf("2科目分の点数を入力してください。\n"); scanf("%d",&n1); scanf("%d",&n2); printf("加算する点数を入力して下さい。\n"); scanf("%d",&a); ans = add(&n1,&n2,a); printf("%d点加算しましたので\n",a); printf("科目1は%d点となりました。\n",n1); printf("科目2は%d点となりました。\n",n2); } int add(int *x1, int *x2,int a){ *x1+=a; *x2+=a; } 誤: #include <stdio.h> int add(int x1,int x2,int a); int main (void){ int n1,n2,a,ans; printf("2科目分の点数を入力してください。\n"); scanf("%d",&n1); scanf("%d",&n2); printf("加算する点数を入力して下さい。\n"); scanf("%d",&a); ans = add(n1,n2,a); printf("%d点加算しましたので\n",a); printf("科目1は%d点となりました。\n",n1); printf("科目2は%d点となりました。\n",n2); } int add(int x1, int x2,int a){ x1+=a; x2+=a; } この2つの違いはなんでしょうか。 アドレスか、そうでないか、という違いはわかりますが、なぜ"誤"のコードだと正しく処理されないのかがわかりません。 教えてください、お願いします。 (「やさしいC」の回答より引用)

  • C言語もしくは算数の問題

    aに消費税、bに税抜価格で 税込価格を小数点切り捨てで出力しなさいという問題で 以下のようにしたのですが不合格でした a=8, b=126 の答えは136と正解になるのですが、他の検証でバツが出てしまいます どこが間違ってるのか解りません よろしくおねがいします #include <stdio.h> int main() { float a, b; scanf("%f %f", &a, &b); printf("%.f\n", b*(a/100+1)); return 0; }

  • 消費税の端数

    消費税の端数は四捨五入ではダメなのですか? 例:本体159円、消費税7.95円の場合   166.95円になりますがここで四捨五入して   167円ではダメですか?

  • 消費税の計算の仕方。

    消費税の1円未満の端数は、切捨てで計算するのですか?それとも、四捨五入されるのでしょうか。 昨日、1852円買い物しましたら消費税を93円とられました。 正確には92.6円です。 私は消費税は切り捨てるものかと考えていましたが、切り上げ、又は四捨五入して請求しても問題ないのですか?

  • c言語についての質問です

    #include<stdio.h> #define N 3 void inputAns(int *row,int *col,int data[][N]); void printAns(int ID,int data[][N]); int main(){ int row[N]={2,3,6},col[N]={8,5,3},answer[N][N]; int i,ID; printf("Input your ID number :\n"); scanf("%d",&ID);inputAns(row,col,answer); printAns(ID,answer); return(1); } void inputAns(int *row,int *col,int data[][N]){ int i,j; printf(" Input Answers of matrxi Q :\n"); for(i=0;i<N;i++){ for(j=0; j<N; j++){ printf("%2d+%2d=",row[i],col[j]); scanf("%d",&data[i][j]); } } } void printAns(int ID, int data[][N]){ FILE *fp; int i,j; fp=fopen("ans.dat","a+t"); fprintf(fp,"%d\n",ID); for(i=0; i<N; i++){ for(j=0; j<N; j++) fprintf(fp," %3d",data[i][j]); fprintf(fp,"\n"); } fclose(fp); } この百マス計算のプログラムの28行目からを書き換えて以下のような画面出力を求めたいです。 >./a.exe ID=50413001 [ 9/9 ] ID=50413002 [ 5/9 ] ID=50413003 [ 7/9 ] ID=50413004 [ 6/9 ] ID=50413005 [ 5/9 ] == correct rate === 4/5 3/5 5/5 5/5 1/5 4/5 4/5 1/5 5/5 =================== > 読み込むファイル(ans.dat)は以下のものです。 50413001 10 7 5 11 8 6 14 11 9 50413002 10 7 5 11 9 5 13 10 9 50413003 10 7 5 11 5 6 14 10 9 50413004 10 11 5 11 5 6 14 10 9 50413005 9 11 5 11 5 6 14 10 9 読み込みから集計がうまくいかず困っています。 どなたか教えてくれませんか?

専門家に質問してみよう