C言語関係掲示板

過去ログ

No.1239 intとlongの私のプログラムにご指導願います。

[戻る] [ホームページ]
No.2272

intとlongの私のプログラムにご指導願います。
投稿者---クワトロ(2004/07/09 11:09:00)


先日の私の質問に答えてくださった皆様には感謝しております。
ありがとうございました。
それで、私のプログラムなのですが、私自身まだCというのにどんな型があるのか把握できてないのですが、プログラムを見ていただきたいと思います。宜しくお願いします。
#include <stdio.h>

int main(void)
{
    long int seki;
    long int i = 3000000000;
    int j  = 2000;
    seki = i * (long int)j;
    
    printf("seki = %ld\n",seki);
    printf("i = %ld\n",i);
    printf("j = %d\n",j);
    printf("%d",sizeof(long int));
    
    return 0;
}

で、結果が
seki = -69312512
i = -1294967296
j = 2000
4
となります。
マイナスがつくので何かおかしいと思うのですが、わかりません。
宜しくお願いいたします。


No.2274

Re:intとlongの私のプログラムにご指導願います。
投稿者---REE(2004/07/09 11:47:57)


intやlongの扱える範囲を超えているために、オーバーフローしているだけです。



No.2275

Re:intとlongの私のプログラムにご指導願います。
投稿者---クワトロ(2004/07/09 11:53:06)


>intやlongの扱える範囲を超えているために、オーバーフローしているだけです。

ありがとうございます。
扱える範囲を越えているのは、承知しています。
文章が足りなくてご迷惑おかけしました。
longで扱いたいのに、intと同じ桁数までしか扱えないので、
どのようにしたらlongとして扱えるのでしょうか?
無理なのでしょうか・・・


No.2278

Re:intとlongの私のプログラムにご指導願います。
投稿者---tetrapod(2004/07/09 12:16:08)


具体的に int や long が何桁であるかは「C/C++ 規格書では」決められていません。
long >= int であることは決められています。
つまり long (long int) 型と int 型が同じサイズであってもかまいません。
Visual C++ 6.0 や Borland C 5.5.x などでは long と int の大きさは
同じ (32bit) です。

なので __int64 のような (規格書では決められていない、処理系固有の) 型を
使いましょう、というコメントが得られているわけです。




No.2279

Re:intとlongの私のプログラムにご指導願います。
投稿者---shu(2004/07/09 14:41:13)


short (int)とlong (int)を使えば思うような計算ができるんじゃないでしょうか。

(整数型)
short int ≦ int ≦ long int
short int は short と記述可能
long int は long と記述可能

http://www9.plala.or.jp/sgwr-t/c/sec13.htmlより引用。

環境によって
sizeof(short) と sizeof(int) が等しかったり
sizeof(long) と sizeof(int) が等しかったりしますが、
sizeof(short) と sizeof(long) が等しくなるということは、
あまり無いかと思います。


No.2280

Re:intとlongの私のプログラムにご指導願います。
投稿者---たいちう(2004/07/09 15:07:12)


> short (int)とlong (int)を使えば思うような計算ができるんじゃないでしょうか。

クワトロさんのやりたいことは大きい数(ex. 3,000,000,000 * 2,000)を
正しく扱えることだと思いますので、short と long では解決できないでしょう。

クワトロさんが誤解しているのは、long が (3,000,000,000 * 2,000) を扱える
と思っていることではないでしょうか。
java の long でしたら扱えますが、C言語では(sizeof(long) == 4 の場合)
オーバーフローします。

なので、

> なので __int64 のような (規格書では決められていない、処理系固有の) 型を
> 使いましょう、というコメントが得られているわけです。

のコメント通り __int64 を使うのがいいでしょう。

# 多倍長というロジックもあります。過去ログに良いサンプルが多数ありますが、
# 初心者にはやや難しいです。


No.2285

Re:intとlongの私のプログラムにご指導願います。
投稿者---RAPT(2004/07/10 01:20:31)


また、通常、C言語では、式の中で整数型による演算値はint型になります。
VC++6で、__int64 型を使った事がありますが、この場合も 32bit値を
超える演算をする場合、__int64::operator+=() など、直接、値の処理
を行なって解決しました。

具体的には、
__int64 a = LONG_MAX, b;
b = a + 500;
とはできなくて、
__int64 a = LONG_MAX, b;
b = a;
b += 500;
のように処理を行ないました。

昔使用していた開発環境では、int型は16bitでした。

いずれにしろ、規格上では、sizeof(long) >= sizeof(int) であること
しか保証されないので、あとは環境依存だとしか言い様がありません。



No.2286

Re:intとlongの私のプログラムにご指導願います。
投稿者---YuO(2004/07/10 01:35:19)


>また、通常、C言語では、式の中で整数型による演算値はint型になります。

少し詳しい型変換の説明の3.通常の算術型変換は読みましたか?

unsigned long longを含む演算では常にunsigned long longになりますし,
longとintの演算は常にlongになります。


> VC++6で、__int64 型を使った事がありますが、この場合も 32bit値を
> 超える演算をする場合、__int64::operator+=() など、直接、値の処理
> を行なって解決しました。

????
__int64型は普通に四則演算可能です。
cl 11.00.7022とcl 13.00.9466で試しましたが,ちゃんと+で演算ができますよ。
#VC++6は持っていないので試していませんが。


何らかの勘違いをしているのではないでしょうか?



No.2287

Re:intとlongの私のプログラムにご指導願います。
投稿者---RAPT(2004/07/10 05:43:45)


あれれ? また勘違い?
以前、どこかの文献でそう読んだ気がするのですが。

__int64 での演算ですが、以前作成した環境のときは、直接演算
できなかったのは確かです。それとも、コンパイル時に何か特に
指定しなければならない、とかあったのかなぁ。
# 普段は __int64 型はあまり使わないのでよく分かりません。



No.2299

Re:intとlongの私のプログラムにご指導願います。
投稿者---クワトロ(2004/07/12 15:33:25)


皆様ご親切にありがとうございました。
javaではintとlongで扱える範囲が明確に異なっていたので、Cでもそうだろうと勝手に思い込んでしまっていました。
つまりは私の環境ではintもlongも同じ範囲しか扱えないということだと認識しました。(間違っていたら指摘お願いします。)
shortとlongでやってみようと思います。
また、__int64というのは初めて見た記述ですが、どこを調べたらそのようなことがわかるのでしょうか?



No.2300

Re:intとlongの私のプログラムにご指導願います。
投稿者---shu(2004/07/12 15:53:02)


>javaではintとlongで扱える範囲が明確に異なっていたので、Cでもそうだろうと勝手に思い込んでしまっていました。

これは知らなかったです。
ひとつ勉強になりました。ありがとうございます。

>つまりは私の環境ではintもlongも同じ範囲しか扱えないということだと認識しました。(間違っていたら指摘お願いします。)
>shortとlongでやってみようと思います。

オーバーフローする場合としない場合を確認するだけなら、shortとlongで十分ですね。
只、オーバーフローする場合は、もう確認済みですよね。
じゃぁオーバーフローしない場合は・・・当たり前の様に普通に表示されます。
(でも、やっぱり確認してみてくださいね。)

>また、__int64というのは初めて見た記述ですが、どこを調べたらそのようなことがわかるのでしょうか?

ヘッダファイル limits.h か、
limits.h ファイルから呼び出されているファイルに、
いろんな型の最大値と最小値が載っていますよ。


No.2302

Re:intとlongの私のプログラムにご指導願います。
投稿者---クワトロ(2004/07/12 15:56:51)


>ヘッダファイル limits.h か、
>limits.h ファイルから呼び出されているファイルに、
>いろんな型の最大値と最小値が載っていますよ。

返事が行き違いになってしまいました。
教えていただいてありがとうございます。
ところで、limits.hってファイルはincludeする必要はないのでしょうか?
includeしなくても、__int64が使えましたし、大きい数値を表示もできました。
何度も質問するようですいません。


No.2303

Re:intとlongの私のプログラムにご指導願います。
投稿者---shu(2004/07/12 21:11:46)


>ところで、limits.hってファイルはincludeする必要はないのでしょうか?
>includeしなくても、__int64が使えましたし、大きい数値を表示もできました。
>何度も質問するようですいません。

stdio.h から段階的に limits.h が呼び出されているのかなぁと思ったのですが、どうやら違うようでした。
limits.h(Borlandの5.5だから limits.h から呼び出された _lim.h かな?)では、
型の最大値と最小値などが、マクロ定義されています。

「最大値」と「最小値」などが「マクロ定義」されているだけで、その型が使える使えないとは関係ありません。
#include <limits.h> がない場合、SHRT_MIN や LONG_MAX など表現がマクロ定義されていない状態になります。


No.2304

Re:intとlongの私のプログラムにご指導願います。
投稿者---クワトロ(2004/07/13 09:46:27)


>>ところで、limits.hってファイルはincludeする必要はないのでしょうか?
>>includeしなくても、__int64が使えましたし、大きい数値を表示もできました。
>>何度も質問するようですいません。
>
>stdio.h から段階的に limits.h が呼び出されているのかなぁと思ったのですが、どうやら違うようでした。
>limits.h(Borlandの5.5だから limits.h から呼び出された _lim.h かな?)では、
>型の最大値と最小値などが、マクロ定義されています。
>
>「最大値」と「最小値」などが「マクロ定義」されているだけで、その型が使える使えないとは関係ありません。
>#include <limits.h> がない場合、SHRT_MIN や LONG_MAX など表現がマクロ定義されていない状態になります。

何度も返事ありがとうございます。
が、私にはまだよく理解できない(難しいので意味がわからない)部分がありますので、もう少し勉強します。
ありがとうございました。


No.2305

Re:intとlongの私のプログラムにご指導願います。
投稿者---ニタチ(2004/07/13 10:07:40)


__int64を使えるとかじゃなくて、limits.hをインクルードして、
printf("%ld\n", LONG_MAX); などとすれば、その型の最大値がわかるってことです。
それぞれの型の最大値や最小値が知りたいなら、_lim.hの中を見てみるといいです。

#define _I64_MAX        9223372036854775807i64   /* maximum signed   __int64 value */

という風に、それぞれの型の最大値と最小値が、マクロ定義されています。



No.2301

Re:intとlongの私のプログラムにご指導願います。
投稿者---クワトロ(2004/07/12 15:53:04)


>皆様ご親切にありがとうございました。
>javaではintとlongで扱える範囲が明確に異なっていたので、Cでもそうだろうと勝手に思い込んでしまっていました。
>つまりは私の環境ではintもlongも同じ範囲しか扱えないということだと認識しました。(間違っていたら指摘お願いします。)
>shortとlongでやってみようと思います。
>また、__int64というのは初めて見た記述ですが、どこを調べたらそのようなことがわかるのでしょうか?

とりあえず、short型の掛け算でshortを越える計算をしてみて、
それをlongの変数に入れて出力したのと、shortの変数に入れて出力した結果が異なることが確認できました。
ありがとうございました。
__int64はsizeofで28とでました。大きい数値が扱えるんですね、
未熟な私は知りませんでした・・。