今だけ人気マンガ100円レンタル特集♪

ご存知の方教えていただけますか?
以下のコードで実行するとansが0.5ではなく0になってしまうのですが
なぜでしょうか?

int a = 64; // a=1,b=2でも0になってしまいます。
int b = 128;
float ans;
ans = a/b;
printf("ans = %f",ans)

仕様ですか?
大変申し訳ありません。よろしくお願いします。

A 回答 (2件)

一言で言えば、仕様です。


ふたつの側面がありますが。

まずひとつ。Cでは、int 型通しの演算の結果は、int です。
ですから、 a / b の計算結果は、int になります。

次、
ans = a / b ;
は、一見、ans が float なので、float 型の結果が得られそうですが、右辺が int なので、float = int という代入が発生しているに過ぎません。
このため、
a / b の結果が(int として) 0
ans = 0;
という代入が行われて、ans の結果はゼロになります。

これを防ぐためには、a か b のいずれかを float にしてやればいいわけで、
ans = (float)a / b;
ans = a / (float)b;
のいずれも答えは、0.5 になります。

これは、int と float の演算は、「int の方を float に変換した上で計算して、結果は float」という決まりだからです。

ans = (float)a / (float)b;
でも同じですね。

ただ、
ans = (float)(a / b);
では結果はやはりゼロになります。
というか、この場合は、 ans = a / b; と同じことです。

あと、普通の場合、float を使うよりは、double を使った方が良いと思います。
    • good
    • 0
この回答へのお礼

>一見、ans が float なので、float 型の結果が得られそうですが、右辺が int なので、float = int という代入が発生しているに過ぎません

よく理解できました。
ありがとうございます。

>ans が float なので、float 型の結果が得られそうですが
そうなると思っていました。

お礼日時:2007/06/18 20:12

> 仕様ですか?



仕様です。

小学校低学年で習ったことを思い出してみましょう。
64 ÷ 128 = 0 ... 64
ですね。
int型は整数型ですので、演算結果も整数しか扱えません。整数を浮動小数点型の変数(今回であればans)に代入したとしても、元々持っていない情報が補完されるわけではありません。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qint main()、void main()、void main(void)、int main(void)

今日、大学でC言語の講義の時間、先生が、

#include <stdio.h>

void main(void){

}

と宣言してプログラムを書くと教えていました。
main関数には、
main()
void main()
void main( void )
int main()
int main( void )

と、人によりいくつかの描き方があったりします。
どれが本当は正しいのでしょうか?
void mainはすべきではないとなんかの本で読んだのですが・・。

Aベストアンサー

通称C89という以前の言語規格(現行コンパイラの多くが準拠)では、下記のいずれかが正しい。
int main(int argc, char *argv[])
int main(void)

但し、最新のC言語規格(通称C99)では、
<ISO/IEC9899:1999>
or in some other implementation-defined manner.
</ISO/IEC9899:1999>
となっているので、処理系が戻り値のvoidを認めていればvoidも可。
# 組込み系などで戻り値を使わない環境もあるためでしょうか。

なので、コンパイラのマニュアルで戻り値のvoidにしていい/しろと書いてない限り、
voidは言語仕様的には正しくない。(でも動くものもある)

Qdoubleの変数にintとintの割り算の結果を代入するとき

以下のようにするとdには0.5ではなく0が代入されます。

int x = 1, y = 2;
double d = x / y;

これを回避するために以下のようにするのが一般的だと習いました。

//1.
double d = (double)(x) / y; // これでdには0.5が代入される

これを以下のようにしてしまうのに問題はあるでしょうか?

//2.
double d = (double)(x) / (double)(y);
//3.
double d = x / (double)(y);

また、1.と2.と3.ではどれがより良いのでしょうか?
単純に好みの問題なのでしょうか?

以上、よろしくお願いいたします。

Aベストアンサー

恐れ入ります。

単純に好みの問題かと思います。
CやC++の規格に準拠したコンパイラであれば、結果的に同じ式として扱ってくれます。
***
ただし、1,2,3ではない別種の方法を良く用いるので参考までに挙げておきます。

int x = 1;
int y = 2;
double dpoX = 0;
double dpoY = 0;
double d = 0;

dpoX = (double)x;
dpoY = (double)y;
d = dpoX / dpoY; /* 計算するときには、精度を揃えておく */

整数を使う場面では整数を使い、倍精度の計算をするときには倍精度で計算するのが良いかと。混ぜると混乱の元です。
(個人的には、ハナからdoubleで取り扱うべきかと思います)

速度的には前述の1,2,3と同様に、計測できるほどの速度低下にはなりません。
(可読性を犠牲にするのは、「除算は遅いから使いたくない」という様な時だけにする方が良いと思います)

ご参考になれば幸いです。

Qbreak文でループを一気に抜けるには

break文でループを一気に(2個以上)
抜けたい場合はどのようにすればいいのでしょうか?
たとえば下のプログラムで1から2に抜けたい
すなわちifとforの2つの中括弧を同時に抜けたい場合には
どうやってbreak文を記述すればいいのでしょうか?
(goto文は使わないということでお願いします。

int k=0;
int i;

for (i=1;i<10;i++){
  k++;
  printf("%d",k);
  if (k == 5){
    printf("a");
    break;・・・・・・・・・1→
  }
}
printf("finish");・・・・・・・・・2←

Aベストアンサー

No.2 です。

> for文を2つ一気に抜ける場合にはどうしたらいいんでしょうか?

この場合は、素直に goto 文を使うか、No.1 さんのようにフラグで制御するしかないでしょう。

私はC言語実務経験20年以上ですが、goto 文について言えば、「無闇やたらに使うべきではないが、使うべき所で使うのをためらってはいけない」ということです。
よく、「何が何でも絶対に goto は使うな!」と言う人がいますが、これは間違っています。
たった1個の goto 文を避けるために、フラグなどを組み合わせて複雑怪奇な構造にすることの害の方が、余程大きいです。

QIOException ってどういうときに起こるのでしょうか?

IOException ってどういうときに起こるのでしょうか?

http://www.atmarkit.co.jp/fjava/rensai2/javaent12/javaent12.html
を見て勉強しています。

  catch ( IOException e) {
    System.out.println( "キーボードが故障しているのかもしれません" );
  }

と書いてあります。
ハード(キーボード)が故障しているのを Java のプログラムのレベル(ソフトウェア)で感知できるというのがよくわかりません。「

NumberFormatException の方はわかるのですが・・・

Aベストアンサー

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接続だったりするわけですけど、
InputStreamは、その入力元の情報を持っていないので、
データを読み取る際は常に
IOExceptionをキャッチするコードを書かなくてはいけません。
たとえ、絶対にIOエラーが発生しないストリームだとしても。

さらに付け加えるなら、
そもそも「標準入力=キーボード」であるとは限りません。
(一般的にはキーボードであることが多いですが。)
Javaでは、
System.setIn(InputStream)
を呼び出して、標準入力を変えてしまうことができますし、
標準入力を指定してプログラムを実行することができるOSもあります。

追伸1:
例外をキャッチしたときは、
スタックトレースをプリントすることをおすすめします。
catch (IOException e) {
e.printStackTrace();
}

追伸2:
そのプログラムでIOExceptionを発生させる最も簡単な方法は、
readLine()を呼び出す前に
標準入力(System.in)を閉じてしまうことです。
System.in.close();

現実的には、キーボードからの入力でIOExceptionが発生することは、
ほとんどあり得ないと思います。
そもそも、キーボードが故障していたとしても、
IOExceptionは投げられないでしょう。
「キーボードが故障しているのかもしれません」というのは、
その記事の著者が冗談で書いたのだと思います。

ではなぜ、try-catchを書かなくてはいけないのか?
InputStreamやBufferedReaderは、
データ入力を抽象化したものだからです。
実際の入力元はキーボードだったり、ファイルだったり、
ネットワーク接...続きを読む

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Q構造体の初期化方法について

こんばんわ。
何度も申し訳ありません。

VC++.NET 2003を用いてコンソールプログラミングを行っています。前回この掲示板を利用して複数回実行するプログラムを作成し、そこに構造体を用いたプログラムを作成しました。以下に概要を示します。

グローバルで構造体を宣言しているため、複数回実行を行うプログラムでは前回の値が格納されたままであると思い、毎回実行時に構造体の初期化を行いたいと思っています。

そこで、以下に示します構造体の初期化はどのように記述すればよいのでしょうか?0で初期化したいと思っています。

よろしくお願い致します。

#define MAX 2000
//グローバル
struct tag{
int Npkt;
int gettime;
int rPkt;
int lossPkt;
}rdata[MAX];

main(){
  //for文で複数回実行処理
  for(i=0;i<=5;i++){
  //ここで構造体の初期化を記述する
//例として、5回プログラムを実行する
  }
}

こんばんわ。
何度も申し訳ありません。

VC++.NET 2003を用いてコンソールプログラミングを行っています。前回この掲示板を利用して複数回実行するプログラムを作成し、そこに構造体を用いたプログラムを作成しました。以下に概要を示します。

グローバルで構造体を宣言しているため、複数回実行を行うプログラムでは前回の値が格納されたままであると思い、毎回実行時に構造体の初期化を行いたいと思っています。

そこで、以下に示します構造体の初期化はどのように記述すればよいのでしょうか?0で初...続きを読む

Aベストアンサー

★まとめ
・既に『memset』関数や、『ZeroMemory』関数の回答があるので構造体の全体、1部の
 初期化の記述例を紹介します。
・それと『#include <memory.h>』を記述しないとメモリ関係の関数が利用できません。
 『ZeroMemory』関数の場合は『#include <windows.h>』があればそのまま利用できます。

●構造体全体を初期化
ZeroMemory( rdata, sizeof(rdata) ); または、
memset( rdata, 0, sizeof(rdata) ); です。

●構造体一部を初期化
ZeroMemory( &rdata[i], sizeof(struct tag) ); または、
memset( &rdata[i], 0, sizeof(struct tag) ); です。
※rdata[i]の1データだけ初期化します。

余談:
・『ZeroMemory』関数は Win32 API と分類されていますが、実体は『memset』関数に
 『#define』されているだけです。でも、戻り値を『VOID』型にキャストされているので
 『memset』関数のリターン値を取得できません。→第一引数のアドレスが『memset』関数
 ではリターンします。
・以上。おわり。

参考URL:http://taka.no32.tk/tips/Win32/ZeroMemory.html

★まとめ
・既に『memset』関数や、『ZeroMemory』関数の回答があるので構造体の全体、1部の
 初期化の記述例を紹介します。
・それと『#include <memory.h>』を記述しないとメモリ関係の関数が利用できません。
 『ZeroMemory』関数の場合は『#include <windows.h>』があればそのまま利用できます。

●構造体全体を初期化
ZeroMemory( rdata, sizeof(rdata) ); または、
memset( rdata, 0, sizeof(rdata) ); です。

●構造体一部を初期化
ZeroMemory( &rdata[i], sizeof(struct tag) ); または、
m...続きを読む

QSystem.inをClose()すると例外が発生する。

こんにちは、tokopokoといいます。

■次のプログラムを実行すると、エラーになります。
なぜエラーになるのか、ご存知の方はいらっしゃいませんか。

import java.io.*;

class TestInput {
public static void main(String[] args) {
System.out.println("first = \"" + getInputValue("first?") + "\"");
System.out.println("second = \"" + getInputValue("second?") + "\"");
}

public static String getInputValue(String message) {
String returnString = "";
System.out.print(message);
BufferedReader input = null;
try {
input = new BufferedReader(new InputStreamReader(System.in));
returnString = input.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return returnString;
}
}

■実行例
D:\>javac TestInput.java

D:\>java TestInput
first?100
first = "100"
second?java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145
)
at java.io.BufferedInputStream.read(BufferedInputStream.java:308)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at TestInput.getInputValue(TestInput.java:14)
at TestInput.main(TestInput.java:5)
second = ""

■私の環境は以下の通りです。
OS: Microsoft Windows XP Professional SP2
java: java version "1.6.0_03"

こんにちは、tokopokoといいます。

■次のプログラムを実行すると、エラーになります。
なぜエラーになるのか、ご存知の方はいらっしゃいませんか。

import java.io.*;

class TestInput {
public static void main(String[] args) {
System.out.println("first = \"" + getInputValue("first?") + "\"");
System.out.println("second = \"" + getInputValue("second?") + "\"");
}

public static String getInputValue(String message) {
String returnStri...続きを読む

Aベストアンサー

メソッドの最初の呼び出しでSystem.inをclose()したので、それを再openしないかぎり次以降の呼び出しはIOExceptionになります。われわれ一般のプログラマがSystem.inを再生成/再オープンすることはできないので、close()しないほうがいいですね。

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

Qerror C3867 関数呼び出しには引数リスト

VS2008 VC++ 環境にて、コンパイルで、「error C3867: 'CFrrjiftestDlg::MyDataHandler': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&CFrrjiftestDlg::MyDataHandler' を使用してください」 が発生しました。ネットで類似のエラーを見ましたが、エラーは回避できませんでした。どうすれば、エラーが直るのか教えてください。

【エラー箇所のソース】
void CFrrjiftestDlg::OnBnClickedButton1()      ← このソースは、frrjiftestDlg.cpp で記述
#include "frrjiftestDlg.h"      

  この間にいろいろな処理を記述

Cortex_SetDataHandlerFunc(MyDataHandler);   ← この行でエラー発生

【frrjiftestDlg.h のヘッダ】 
void MyDataHandler(sFrameOfData* FrameOfData); ← これを記述

【MyDataHandler の記述】
void CFrrjiftestDlg::MyDataHandler(sFrameOfData* FrameOfData)  ← これは、frrjiftestDlg.cpp で記述

 この後に処理を記述

ざっと、こんな感じで書いています。

エラーの説明をみると、「メンバへのポインタを作成するために '&CFrrjiftestDlg::MyDataHandler' を使用してください」となっていますが、いろいろ書いてみましたが、だめでした。

VS2008 VC++ 環境にて、コンパイルで、「error C3867: 'CFrrjiftestDlg::MyDataHandler': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&CFrrjiftestDlg::MyDataHandler' を使用してください」 が発生しました。ネットで類似のエラーを見ましたが、エラーは回避できませんでした。どうすれば、エラーが直るのか教えてください。

【エラー箇所のソース】
void CFrrjiftestDlg::OnBnClickedButton1()      ← このソースは、frrjiftestDlg.cpp で記述
#include "frrjifte...続きを読む

Aベストアンサー

いや、だから、

Cortex_SetDataHandlerFunc() の引数にはメンバ関数を渡せないんじゃないですか?
通常の関数とメンバ関数は互換ではありませんよ?


人気Q&Aランキング