• 締切済み

掛け算について

いつもお世話になります。 変数サイズと掛け算について教えてください。 下記の2通りの変数の場合、 (1)int test = 307600000 * 8; (2)int test = 2460800000; (1)は、整数定数がオーバーフローしましたというエラーになり、 (2)はエラーになりません。(2)の値は(1)の掛け算の結果です。 質問は、 1.なぜ(1)はダメなのか? 2.(1)をエラーをなくすにはどの変数型宣言をしなければならないのか? よろしくお願い致します。

みんなの回答

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.1

そのようなソースを書けば、エラーなり警告が出るのは当然です。 32ビット符号付 int変数で扱えない数ですから。 (2)の値は(1)の掛け算の結果ではありません。32bitintの範囲ではオーバーフローして、-1666395136(たぶんこれで正しいはず)になります。 たまたま、(1)でエラーになって(2)でエラーにならないのはあなたがお使いのコンパイラの癖でしょう。 gccだと(1)(2)ともにエラーにはならずにwarningが出ます。

the-ai
質問者

お礼

回答ありがとうございます。 そういうことだったんですね。 もう一度勉強します! ありがとうございました。

関連するQ&A

  • 引数別の例外処理

    (1)コマンドラインの1つ目の引数を整数に変換して、int型の変数num1に代入。 (2)コマンドラインの2つ目の引数を整数に変換して、int型の変数num2に代入。 (3)num1とnum2の掛け算結果を標準出力。 (4)例外「NumberFormatException」が発生した場合は、“○(引数の例外発生した方の値)は整数に変換できません”の文字列を標準出力し、プログラム終了。 という問題で、NumberFormatException の○の部分の表示の仕方を教えて下さい。

    • ベストアンサー
    • Java
  • 文字列のメンバ変数を外部変数のように扱いたい

    済みません。質問なのですが、 メンバ変数を外部変数のように扱うにはどうしたらよいのでしょうか? int型などの場合、 class test{ static const int a; }; const int test::a = 10; とすればよいですよね? これをcharの配列にして class test{ static char a[7][32]; }; char test::a[0] = "test"; とすると サイズが0の配列を割り当てまたは宣言しようとしました というコンパイルエラーがでてしまいます…。 多次元配列の場合はstatic変数としてもてないのでしょうか? char** として宣言してもどこでnewを行えばよいか解りません。 コンストラクタの中で行えば そこでstaticではなくなってしまいますし…。 後、できればstringクラスの配列で持ちたいのですが #include <string> class test{ static string test[7]; }; string test::test[0] = "aaa"; なんてことができますでしょうか? 質問内容が解りにくいかも知れませんが どうか教えてください。 宜しくお願いいたします。

  • エクセルのマクロでアドレスを取得したセルの掛け算をしたい

    「個数」と「単価」の変数を設定し、個数×単価の掛け算を算出したいと考えています。下記のように記述したところエラーが出てしまいます。よろしくご教授お願いします。変数「個数」と「単価」の値は取得できています。 個数 = Cells(6,5).Address(rowabsolute:=False,columnabsolute:=False) 単価 = Cells(1, 10).Address(rowabsolute:=False) Range(Cells(6, 10), Cells(6, 10)).Formula = "=時間*コスト"

  • プログラミングがわかりません

    1.多倍長数で表現した整数aとint型で表現した整数xを乗算し、その結果をaに格納するプログラムを作れ。 #include<stdio.h> #define KETA 12 int main(void){ int a[KETA] = { 0, 0, 0, 1, 0, 2, 4, 6, 5, 5, 3, 6}; int x = 512; /*必要な変数があれば適宣宣言しなさい*/ /*多倍長数(c) <-- 多倍長数(a) * int型(x)*/ (ア) 出力省略 return 0; } 実行結果 a = 52462354432 2.多倍長数を用いて1から80までの各整数の階乗を計算し、正しい値を表示するプログラムを作れ。 注意 80の階乗を表現するためには、少なくとも119桁の整数を格納できる多倍長数を用いなければならない。 実行結果 1! = 1 2! = 2 3! = 6 ・・・ 3.多倍長数で表現した整数aとint型で表現した整数xで除算し、その結果をaに格納するプログラムを作れ。 aがxで割り切れない場合に生じるあまりは使用せずに捨ててもよい。 除算の途中で現れる整数はint型で表現できる範囲であることを仮定してもよい。 ソースコード #include<stdio.h> #define KETA 12 int main(void){ int a[KETA] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}; int x = 365; /*必要な変数があれば適宣宣言しなさい*/ /*多倍長数(a) <-- 多倍長数(a) ÷ int型(x)*/ (ア) return 0; } 実行結果 a = 33823777 2はまったくわかりません 1,3の出力はわかるのですが、計算過程がわかりません 教えてくださいよろしくお願いします。

  • 文字列や文字から整数への変換方法について

    文字列(string型)や文字(char型)から整数(int型など)に変換 する時のルールがよく解りません。 たとえば、キーボードから数字を打って、その入力された数字を 数値として整数型の変数に代入したい場合のやり方です。 ちょっとプログラムを作ってみました。 using System; class clmain { private static void Main() { Console.Write("1桁の整数を入れてね "); char ch = char.Parse(Console.ReadLine()); int by1 = (int)ch; int by2 = (int)char.GetNumericValue(ch); Console.WriteLine("by1 = {0}, by2 = {1}, ch = {1}", by1, by2, ch); Console.Write("整数を入れてね "); string st = Console.ReadLine(); /* by = (int)st; コンパイルエラー */ int by3 = int.Parse(st); Console.WriteLine("by3 = {0}, st = {1}", by3, st); } } まず、char型からint型への変換では、  int型変数=(int)char型変数; はコンパイルは通りますけど、実行すると全く違った値が入って しまいます。たとえば char型変数の値が "1" だと、int型変数には 49 が入ります。 int型変数 = (int)char.GetNumericValue(char型変数); と書いてようやく、思い通りの動きをしてくれます。 また、string型からint型への変換では  int型変数=(int)string型変数; はコンパイルエラーになります。 int型変数 = int.Parse(string型変数); とするとコンパイル出来て正しく動きます。 これで質問ですけど、 (1)なぜstring型とchar型で、int型への変換方法が違うのでしょうか? (2)int型変数=(int)char型変数; とすると、上に書いたように、全く 違った(希望しない)値が代入されてしまいます。これは、どういう 動きをしているのでしょうか? また、これはコンパイルエラーに なりませんけど、どういう時にこの書き方をするのでしょうか? 解る方、お願いします。

  • C言語signed long long型の演算

    C言語で以下の演算を行った場合、変数bに格納される値が-1(0xFFFFFFFFFFFFFFFF)になることを期待しておりましたが、参照すると4294967295(0x00000000FFFFFFFF)となってしまいます。 unsigned int a = 1; signed long long b; b = a * (-1); 32bit、64bitのUNIX(Solaris)マシンでそれぞれ確認しましたが、どちらも同じ結果となりました。 変数aの型宣言をsigned intにすると変数bが-1(0xFFFFFFFFFFFFFFFF)になることは確認したのですが、unsigned intだとなぜこのような演算結果となるのかが分かりません。 ※8バイト整数に格納する際に先頭4バイトがなぜ0xFFFFFFFFで補完されないのか? ちなみに変数bの型宣言をsigned long intにすると32bitマシンでは-1となりましたが、64bitマシンでは4294967295となってしまいます。 これは32bitUNIXマシンではsigned long intは4バイト領域であるため-1(0xFFFFFFFF)となり、64bitUNIXマシンでは8バイト領域のため前述と同じ結果になるのだと考えますが、なぜ8バイト整数を使用するとこのような演算が行われるのかが分からないので、演算順序や型変換の優先順位がどのように行われいるのか説明できる方教えてください。

  • 「割り算」 と 「分数の掛け算」

    double型の変数にある値が代入されていて、 その数を半分にしようとしました。 演算部分を /2 としたらエラーが出てしまいました。 いろいろ試した結果、*0.5とすれば ちゃんと計算されるようなのですが、 どうしてこのようなことが起こるのか、よくわかりません。 どなたか、ご教授ください。よろしくお願いします。

  • プログラムの関数化

    皆様に助けていただき、なんとかコーディング出来たのですが、関数化したいと思います。アドバイスお願いします。 int overflow_check1(); int overflow_check2(); int overflow_check3(); int overflow_check4(); int lop; // 左のオペランドに入力する値 int rop; // 右のオペランドに入力する値 int result; // 計算結果 int mod; // 除算の余り int max = INT_MAX; // 表現可能な最大値 int min = INT_MIN; // 表現可能な最小値 char *check; // 変換不能な文字を格納 char op; // 入力する演算子 int main ( int argc, char *argv[] ) { /* 引数の個数チェック */ if ( argc != 4 ) { printf ( "usage : %s lop op rop\n", argv[0] ); exit ( 0 ); } /* 引数を取得して整数型に変換 */ lop = atoi ( argv[1] ); rop = atoi ( argv[3] ); /* 引数の取得 */ op = ( argv[2][0] ); /* startが整数であるか文字であるかのチェック */ lop = strtol ( argv[1], &check, 10 ); if ( errno != ERANGE ) { if ( *check != '\0' ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( -1 ); } /* startに範囲を超えた値を入力した場合 */ } else { printf( "error : 整数型の範囲を超えました。\n" ); exit( -1 ); } /* endが整数であるか文字であるかのチェック */ rop = strtol ( argv[3], &check, 10 ); if ( errno != ERANGE ) { if ( *check != '\0' ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( -1 ); } /* endに範囲を超えた値を入力した場合 */ } else { printf( "error : 整数型の範囲を超えました。\n" ); exit( -1 ); } /* argv[2]が2文字以上の場合 */ if ( strlen ( argv[2] ) >= 2 ) { printf ( "error : 演算子を正しく入力して下さい。\n" ); exit ( -1 ); } /* argv[2]に入力された演算子が'+'の場合 */ switch ( op ) { case '+': overflow_check1(); result = lop + rop; break; /* argv[2]に入力された演算子が'-'の場合 */ case '-' : overflow_check2(); result = lop - rop; break; /* argv[2]に入力された演算子が'*'の場合 */ case '*': overflow_check3(); result = lop * rop; break; /* argv[2]に入力された演算子が'/'の場合 */ case '/' : /* 0による除算 */ if ( rop == 0 ) { printf ( "error : 0による除算は禁止です。\n" ); exit ( -1 ); } overflow_check4(); result = lop % rop; // 剰余を求める break; default: printf ( "error : '+' '-' '*' '/'のいずれかの演算子を入力して下さい。\n" ); exit ( -1 ); } /* 割り算の結果として余りが出なかった場合 */ if ( result == 0 ) { result = lop / rop; printf ( "%d %c %d = %d", lop, op, rop, result ); exit ( 0 ); /* 割り算の結果として余りが出た場合 */ } else { result = lop / rop; mod = lop % rop; printf ( "%d %c %d = %d余り%d", lop, op, rop, result, mod ); exit ( 0 ); } /* 数値1 演算子 数値2 = 演算結果の形式で出力する */ printf ( "%d %c %d = %d", lop, op, rop, result ); exit ( 0 ); } int overflow_check1 () { /* オーバーフローのチェック */ if ( lop > 0 && rop > 0 ) { if ( lop > max - rop ) { printf ( "error : オーバーフローが起こります。\n" ); exit ( 0 ); } } /* オーバーフローのチェック */ if ( lop < 0 && rop < 0 ) { if ( lop < min - rop ) { printf ( "error : オーバーフローが起こります。\n" ); exit ( 0 ); } } return 0; } int overflow_check2 () { /* オーバーフローのチェック */ if ( lop > 0 && rop < 0 ) { if ( lop > max + rop ) { printf ( "error : オーバーフローが起こります。\n" ); exit ( 0 ); } } /* オーバーフローのチェック */ if ( lop < 0 && rop > 0 ) { if ( lop < min + rop ) { printf ( "error : オーバーフローが起こります。\n" ); exit ( 0 ); } } return 0; } int overflow_check3 () { /* オーバーフローのチェック */ if ( lop > max / rop ) { printf ( "error : オーバーフローが起こります。\n" ); exit ( -1 ); } /* オーバーフローのチェック */ if ( rop < max / lop ) { printf ( "error : オーバーフローが起こります。\n" ); exit ( 0 ); } return 0; } int overflow_check4 () { /* オーバーフローのチェック */ if ( ( lop == min ) && ( rop == -1 ) ) { printf ( "error : オーバーフローが起こります。\n" ); exit ( -1 ); } return 0; }

  • ループを使った掛け算のプログラミング

    こんにちわ。 Loopを使い、1~12までの掛け算の表を作ります。Rowが初め、Colが二番の変数になり、 Row、Colともに一つずつ増えます。 1x1=1 1x2=2 ........ 1x12=12 2x1=2 ........ 12x12=144 というようにすべての掛け算を表示させたいのですが、私が作ったプログラムで 上記のように表示されるのか、わからなくなってきてしまいました。 言語は問いませんのでアドバイスお願い致します。 下記が私が疑似コードで書いたものです。 Declare row, col, total As int   For (row=1; row<=12; row++)   For (col=1; col<=12; col++)   Calculate total=row*col   Display "row" + "*" + "col" + "=" + "total"   EndFor EndFor よろしくお願いします。

  • fortranでx=1としても0.9..が入る

    fortranで以下のようなプログラムにてxに1.0^-6を代入し、 その中身を表示しました。 --------------------------------- program test real(8) :: x = 1.0d-6 write(*,*) x write(*,*) x * 1.0d6 write(*,*) int(x * 1.0d6) end program test --------------------------------- しかし、結果は以下のようになり、 0.999999999999999955^-6となってしまいます。 さらに、やっかいなことに10^6倍して 整数型に変換しても0と認識されてしまうのです。 ---------------------------------- $ ./a.exe 9.99999999999999955E-007 1.00000000000000000 0 ---------------------------------- 変数の型も倍精度で宣言し、定数も倍精度(d付き)で 代入しているはずなのですが、なぜこのような現象が 起きるのでしょうか。 ご存知の方いましたら教えて頂けると助かります。 なお、コンパイルはgfortranで行っています。