C言語関係掲示板

過去ログ

No.1257 longをこえる値を使用するには

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

longをこえる値を使用するには
投稿者---Cはじめ(2004/09/05 11:28:55)


HP-UX11.00で、C言語でプログラムを作成しています。
long型の変数の値を加算し、合計をlong型の変数に格納
するのですが、合計がlongの値の範囲を超えてしまう時
あり、オーバーフローが発生し上手くできません。

どのように対処すればよいか教えてください。



No.16595

Re:longをこえる値を使用するには
投稿者---Sciggepy(2004/09/05 13:40:37)


long型では、LONG_MAXを超える値は使用できません。
符号なしならば、LONG_MAXの2倍程度の値までを扱うことができます。
また、longよりはdoubleの方が扱える整数の範囲が広いようです。
処理系によっては、longより大きい整数を扱うための型が存在することもあります。
それでもだめなら、多倍長演算を使うという手もあります。



No.16606

Re:longをこえる値を使用するには
投稿者---Cはじめ(2004/09/05 22:18:52)


ありがとうございます。

>また、longよりはdoubleの方が扱える整数の範囲が広いようです。
doubleは、整数も扱えるのですか。
自動的に、小数点扱いになりまえんか。

>処理系によっては、longより大きい整数を扱うための型が存在することもあり
>ます。
処理系によってはとは。?
開発している処理、システムによってはということですか。

>それでもだめなら、多倍長演算を使うという手もあります。
多倍長演算とは。
どうのようにするのですか。





No.16607

Re:longをこえる値を使用するには
投稿者---あかま(2004/09/05 23:26:51)


>doubleは、整数も扱えるのですか。
>自動的に、小数点扱いになりまえんか。
整数を扱う分には誤差がでないので大丈夫です。

>処理系によってはとは。?
>開発している処理、システムによってはということですか。
そうです。
この場合は「使っているコンパイラによって」といったほうがわかりやすいかもしれません。

>多倍長演算とは。
>どうのようにするのですか。
わからなければとりあえず検索エンジンで調べる癖をつけてください。


No.16609

Re:longをこえる値を使用するには
投稿者---YuO(2004/09/06 00:08:26)


>整数を扱う分には誤差がでないので大丈夫です。

整数であっても誤差はでます。
doubleの場合だと,格納されている値がFLT_RADIXDBL_MANT_DIGを超えた時点で,整数においても情報落ちが発生します。

ちなみに,
printf("%f\n%f\n", pow(FLT_RADIX, DBL_MANT_DIG), pow(FLT_RADIX, DBL_MANT_DIG) + 1.0);
のBCC 5.5.1での実行結果は,
9007199254740992.000000
9007199254740992.000000

です。


誰も書いていないので書いておくと,
標準Cに対応した処理系であれば,最低64bitの符号付き整数型long long intと,
long long intに対応した符号無し整数型unsigned long long intが常に使えます。
また,処理系に依存する最大の幅を持つ符号付き整数型intmax_tと,
intmax_tに対応した符号無し整数型uintmax_tがstdint.hで定義されています。



No.16633

Re:longをこえる値を使用するには
投稿者---Cはじめ(2004/09/07 00:12:13)


>>doubleは、整数も扱えるのですか。
>>自動的に、小数点扱いになりまえんか。
>整数を扱う分には誤差がでないので大丈夫です。
doubleを使用した場合、誤差がでる見極めはどうすればよいのですか
どこですればよいのですか。

>標準Cに対応した処理系であれば,最低64bitの符号付き整数型long long intと,
>long long intに対応した符号無し整数型unsigned long long intが常に使えます。
long logn int とういう宣言ができるのですか。
値の範囲としては、どこからどこまでなのですか。

>>多倍長演算とは
char型で多倍長演算を行う値を格納し、それを、アルゴリズムに従って行う。?



No.16636

Re:longをこえる値を使用するには
投稿者---シャノン(2004/09/07 10:19:45)


>>標準Cに対応した処理系であれば,最低64bitの符号付き整数型long long intと,
>>long long intに対応した符号無し整数型unsigned long long intが常に使えます。
>long logn int とういう宣言ができるのですか。

標準 C に対応した処理系であれば。
「long」というのは変数の型ではなく、「長い」という修飾です。
普段 long と書いているのも、実は long int(長い int )の略なのです。
long long int てのは、long int よりもっと長い整数型ってことです。

>値の範囲としては、どこからどこまでなのですか。

最低 64 bit って書かれていますよね。
long long int は -263 〜 263 - 1、
unsigned long long int は 0 〜 264 - 1 までです。

>>>多倍長演算とは
>char型で多倍長演算を行う値を格納し、それを、アルゴリズムに従って行う。?

char でも short int でも int でも long int でも long long int でもご自由に。


No.16637

Re:longをこえる値を使用するには
投稿者---シャノン(2004/09/07 14:19:08)


>>>>多倍長演算とは
>>char型で多倍長演算を行う値を格納し、それを、アルゴリズムに従って行う。?
>
>char でも short int でも int でも long int でも long long int でもご自由に。

たとえば、こんな構造体を考えて見ますと…

struct VelyLongInt
{
  bool sign; // - 符合の有無
  long value1; // 最上位 96 - 127 ビットを格納
  long value2; // 64 - 95 ビットを格納
  long value3; // 32 - 63 ビットを格納
  long value4; // 最下位 0 - 31 ビットを格納
};

この構造体をひとつの整数として演算できるような仕組みを作れば
128 bit の数が表現できます。多倍長ってのはこんな感じです。
実際には、表現できる長さを無制限にするために

struct VeryLongInt
{
  bool sign;
  int nValues; // 値の配列の要素数
  long *pValues; // 値の配列の先頭へのポインタ
};

のようにすると汎用的になるでしょう。

別のサイトですが
http://www.mtakahashi.com/
こちらの、スレッドNo 11987 番あたりで関連する議題が進行中です。
参考になりますでしょうか。


No.16662

Re:longをこえる値を使用するには
投稿者---シャノン(2004/09/08 11:47:37)


>>>標準Cに対応した処理系であれば,最低64bitの符号付き整数型long long intと,
>>>long long intに対応した符号無し整数型unsigned long long intが常に使えます。
>>long logn int とういう宣言ができるのですか。
>
>標準 C に対応した処理系であれば。
>「long」というのは変数の型ではなく、「長い」という修飾です。
>普段 long と書いているのも、実は long int(長い int )の略なのです。
>long long int てのは、long int よりもっと長い整数型ってことです。
>

余談ですが、long double ってのもあります。
規格は見てないので正しいところはわかりませんが、80bit だとか。
VC++ では未対応で、ただの double として扱われてしまいますが。


No.16667

Re:longをこえる値を使用するには
投稿者---YuO(2004/09/08 12:58:08)


>余談ですが、long double ってのもあります。
>規格は見てないので正しいところはわかりませんが、80bit だとか。

当然ながら,標準においてサイズは未規定です。
標準に書いてある最低の要求は,doubleと同一です。


>VC++ では未対応で、ただの double として扱われてしまいますが。

doubleとlong doubleが同等の扱いをされることと未対応であることは別問題です。
VC++はlong doubleに対応しています。



No.16673

Re:longをこえる値を使用するには
投稿者---シャノン(2004/09/08 13:54:52)


失礼しました。
やはり、ロクに調べもせずに書いちゃ駄目ですね…。

>>余談ですが、long double ってのもあります。
>>規格は見てないので正しいところはわかりませんが、80bit だとか。
>
>当然ながら,標準においてサイズは未規定です。
>標準に書いてある最低の要求は,doubleと同一です。

6.2.5.10 ですか。
規定されているのは「float は double のサブセット、double は long double のサブセット」ということだけで。

>>VC++ では未対応で、ただの double として扱われてしまいますが。
>
>doubleとlong doubleが同等の扱いをされることと未対応であることは別問題です。
>VC++はlong doubleに対応しています。

確かに。
16bit VC++ では long double は 80bit だったらしいですが、
32bit 版では double と同じ扱いとされました。
これを「long double への対応をやめた」と解釈してしまっていた
ようですが、単なる仕様変更なんですね。


No.16648

Re:longをこえる値を使用するには
投稿者---C超初心者(2004/09/08 00:22:33)


C言語をやりはじめて数ヶ月のものです。
横から質問ですが、

long login int
unsigned long long int

と宣言できるのですか。

本とかそのような宣言をしているのをみたことがないのですが
使えるのですか。
コンパイルとかとうるのですか。


No.16649

Re:longをこえる値を使用するには
投稿者---ぽこ(2004/09/08 00:50:25)


>long login int
>unsigned long long int
>
>と宣言できるのですか。
>
>本とかそのような宣言をしているのをみたことがないのですが
>使えるのですか。
>コンパイルとかとうるのですか。

上記の型は新しい(?)Cの規格で採用されています。
コンパイラによって通るものと通らないものがあります。
下のURLを参考にして下さい。

http://seclan.dll.jp/c99d/c99d00.htm


No.16653

Re:longをこえる値を使用するには
投稿者---シャノン(2004/09/08 09:56:29)


>上記の型は新しい(?)Cの規格で採用されています。
>コンパイラによって通るものと通らないものがあります。
>下のURLを参考にして下さい。
>
>http://seclan.dll.jp/c99d/c99d00.htm

VC++ 7.1 は C99 に対応していないはずですが通りました。
独自拡張かな…


No.16657

Re:longをこえる値を使用するには
投稿者---YuO(2004/09/08 10:38:58)


>VC++ 7.1 は C99 に対応していないはずですが通りました。
>独自拡張かな…

そのようですね。
long long intは__int64として扱われるようです。
Fundamental Types (C/C++ Languages) [msdn.microsoft.com]



No.16666

Re:longをこえる値を使用するには
投稿者---C超初心者(2004/09/08 12:52:44)


long login int
unsigned long long int

の型は、何桁まで有効なのですか。

UNIX−Cでプログラムを作っているのですが、対応されている
でしょうか。

初歩的なことを聞いてすみません。



No.16668

Re:longをこえる値を使用するには
投稿者---YuO(2004/09/08 13:01:04)


>long login int
>unsigned long long int
>の型は、何桁まで有効なのですか。

No.16636のシャノンさんの投稿を読みましたか?
最低 64 bit って書かれていますよね。
long long int は -263 〜 263 - 1、 unsigned long long int は 0 〜 264 - 1 までです。


正確には,long long intの範囲は-(263 - 1)から263 - 1ですが。
#たとえば1の補数を利用する処理系。


>UNIX−Cでプログラムを作っているのですが、対応されている
>でしょうか。

コンパイラしだいです。
最新のgccなら対応しているはずです。