c言語初心者です、下記の条件を満たすプログラムの書き方がよくわからないのですがどのようにしたらいいのでしょうか?
1・倍精度浮動小数点数のn×n正方行列2つの積を計算するプログラム
2・計算時間は1秒以内
3・nをどこまで大きくできるかチャレンジ
n×n正方行列2つの積を計算するプログラム,計算時間は1秒以内
という条件は満たしているのですが、nをどこまで大きくできるかがうまくできません。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
退会済のようですが・・・今時の環境で1秒に計算できる正方行列のサイズは10万を超えると思います(以下のプログラムで1000までは試しましたが時間が短すぎて計測できませんでした)。10万だとdoubleが8バイトとして約240GBのメモリが必要です。環境依存と言えばそうなのですが・・・いまいち出題者の意図が分かりません。
(FreeBSD 10.3-RELEASE-p11 clang version 3.8.1)
c
1#include <stdio.h> 2#include <stdlib.h> 3#include <time.h> 4 5#define MAXSIZ (10000) 6 7void init(double m[MAXSIZ][MAXSIZ], int siz); 8void mClear(double m[MAXSIZ][MAXSIZ], int siz); 9void multiply(const double mA[MAXSIZ][MAXSIZ],const double mB[MAXSIZ][MAXSIZ],double mC[MAXSIZ][MAXSIZ],int siz); 10void print(const double m[MAXSIZ][MAXSIZ], int siz); 11// 12double mA[MAXSIZ][MAXSIZ]; 13double mB[MAXSIZ][MAXSIZ]; 14double mC[MAXSIZ][MAXSIZ]; 15// 16int main(int agc, char *agv[]) 17{ 18 if( agc != 2 ){ 19 fputs("Error agc!=2\n",stderr); 20 exit(1); 21 } 22 // 23 int matSiz= atoi(agv[1]); 24 // 25 if( matSiz < 1 || MAXSIZ < matSiz){ 26 fputs("Error matSiz\n",stderr); 27 exit(2); 28 } 29 // 30 init(mA,matSiz); 31 init(mB,matSiz); 32 mClear(mC,matSiz); 33 // 34 clock_t st= clock(); 35 multiply(mA, mB, mC, matSiz); 36 clock_t et= clock(); 37 // 38 print(mC,matSiz); 39 printf("MatSiz= %d %f msec\n",matSiz, ((et-st)*1000.0)/CLOCKS_PER_SEC); 40 // 41 return 0; 42} 43// 44void init(double m[MAXSIZ][MAXSIZ], int siz) 45{ 46 for( int i= 0; i < siz; i++){ 47 for( int j= 0; j < siz; j++){ 48 m[i][j]= (double)rand()/(double)RAND_MAX; 49 } 50 } 51} 52// 53void mClear(double m[MAXSIZ][MAXSIZ], int siz) 54{ 55 for( int i= 0; i < siz; i++){ 56 for( int j= 0; j < siz; j++){ 57 m[i][j]= 0.0; 58 } 59 } 60} 61// 62void multiply(const double mA[MAXSIZ][MAXSIZ],const double mB[MAXSIZ][MAXSIZ],double mC[MAXSIZ][MAXSIZ],int siz) 63{ 64 for( int i= 0; i < siz; i++){ 65 for( int j= 0; j < siz; j++){ 66 for( int k= 0; k < siz; k++){ 67 mC[i][j] += mA[i][k]*mB[k][j]; 68 } 69 } 70 } 71} 72// 73void print(const double m[MAXSIZ][MAXSIZ], int siz) 74{ 75 for( int i= 0; i < siz; i++){ 76 for( int j= 0; j < siz; j++){ 77 printf("%2.4f ",m[i][j]); 78 } 79 putc('\n',stdout); 80 } 81} 82 83
投稿2016/12/02 09:42
編集2016/12/02 22:16総合スコア6851
0
こんにちは。
推測ですが、nを#define
することはできても、int n;にできなくて困っているのですよね?
であれば、malloc()で獲得すると良いです。1次元配列になりますが、2次元的にアクセスすることは可能です。
C
1double* array=(double*)malloc(sizeof(array)*n*n); // nxn個の領域を確保する 2 3// とりあえず初期化 4for (int i=0; i < n; ++i) 5 for (int j=0; j < n; ++j) 6 array[j*n+i]=0; // array[i][j]と同等なアクセス 7 8// 必要な処理はここへ 9 10free(array); // 開放を忘れずに
arrayは1次元なのでarray[i][j]とは書けません。
でも、array[j*n+i]ならば、n x n正方配列の(i, j)要素へアクセスしているのと同等です。
投稿2016/11/26 01:02
総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
「n×n正方行列2つの積を計算するプログラム,計算時間は1秒以内」ができているというのであれば、まず、その部分を下記のような関数にします。@detailの内容は適当なので実際の実装にあわせてください。
C
1#include <stdbool.h> 2/** 3 * n x n 正方行列2つの積を計算し、計算時間が1秒以内かを判断する。 4 * @brief 要約説明 5 * @param (int n) 行列のサイズ。n x n 正方行列で計算される。 6 * @return 1秒以内なら true、でなければ false を返す。 7 * @detail 行列の各要素は double (通常はIEEE 754 倍精度浮動小数点数)である。 8 * 行列の各要素は[0, 1)の乱数(randを使用)を用いる。乱数の生成時間は計算時間に含まれない。 9 * 計算時間は clock() を用いてプログラムが使用した時間である。実際に経過した時間ではない。 10 * メモリを確保できない場合は false を返し、errno に ENOMEM をセットする。 11 */ 12bool matrix_product_onesec(int n) 13{ 14 // 実装を書く 15}
あとは、nを増やしながら、上の関数で確認していくだけです。どこまで確認するかは指定できるようにするといいでしょう。
C
1int max_calcable(int m) 2{ 3 for (int i = 1; i <= m; i++) { 4 if (!matrix_product_onesec(i)) return i - 1; 5 } 6 return m; 7}
false
が返ってきたとき、それまで成功していた数、つまり、i - 1
を返すことがコツになります。最大まで達していれば、最大を返します。
投稿2016/11/25 21:14
総合スコア21735
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
課題の意図はこういうことではないでしょうか。(計測処理は端折りました)
double n = 0; while(1秒内) { pow(n,2.0); // math.h n++; } printf("n=%f",n);
投稿2016/11/25 19:26
総合スコア2724
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/12/02 10:12
2016/12/02 22:23