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の出力はわかるのですが、計算過程がわかりません
教えてくださいよろしくお願いします。
No.5ベストアンサー
- 回答日時:
最後に2)に行く前に1)を訂正。
1)の
if ((a[j] > 10) && (j)) {
a[j]-=10;
a[j-1]++;
}
を
if (a[j] >= 10) {
a[j] -= 10;
n += 10;
}
に訂正。
で、最後に2)を。
#include<stdio.h>
#define KETA 120
int main(void){
int a[KETA];
int x,y;
int i,j,n;
for (i = 0;i < KETA;i++) a[i] = 0;
a[KETA-1]=1;
for (x = 1;x <= 80;x++) {
for (i = 0;i < KETA;i++) a[i] *= x;
for (i = 0;i < KETA;i++) {
n = a[i];
a[i]=0;
j=i;
while ((n) && (j >= 0)) {
a[j] += n % 10;
if (a[j] >= 10) {
a[j] -= 10;
n += 10;
}
j--;
n /= 10;
}
}
printf("%d! = ",x);
for (i = 0;i < KETA;i++) if (a[i]) break;
for (;i < KETA;i++) printf("%d",a[i]);
printf("\n");
}
return 0;
}
No.4
- 回答日時:
次に3)を。
#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;
int b[KETA];
int i,j,y,n;
for (i = 0;i < KETA;i++) b[i] = 0;
for (i = 0;i < KETA;i++) {
y=0;
for (j = i;j < KETA;j++) {
y *= 10;
y += a[j];
a[j] = 0;
if (y >= x) break;
}
b[j] = y / x;
n = y % x;
for (;j >= 0;j--) {
a[j] += n % 10;
n /= 10;
}
}
for (i = 0;i < KETA;i++) a[i] = b[i];
printf("a = ");
for (i = 0;i < KETA;i++) if (a[i]) break;
for (;i < KETA;i++) printf("%d",a[i]);
printf("\n");
return 0;
}
No.3
- 回答日時:
まず1)を。
#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;
int i,j,n;
for (i = 0;i < KETA;i++) a[i] *= x;
for (i = 0;i < KETA;i++) {
n = a[i];
a[i]=0;
j=i;
while ((n) && (j >= 0)) {
a[j] += n % 10;
if ((a[j] > 10) && (j)) {
a[j]-=10;
a[j-1]++;
}
j--;
n /= 10;
}
}
printf("a = ");
for (i = 0;i < KETA;i++) if (a[i]) break;
for (;i < KETA;i++) printf("%d",a[i]);
printf("\n");
return 0;
}
No.2
- 回答日時:
#1さんもおっしゃっている通り、全部筆算のようなことをやるだけですよね。
2の出力がわかっても何の役にも立たないと思いますが、検算に使う程度にはなると思うので80の階乗を書いておきます。
71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000
ちなみに、多倍長数演算を行うためのライブラリーを使って計算しました。GNU MP (GMPとも言う) が有名ドコロで、RSAなどの計算のためにOpenSSLにも備わっているという感じでしょうか。
参考までにプログラムを書いておきます。コンパイル、リンクのためにはそれぞれGMP、OpenSSLのヘッダーやライブラリーが必要です。
GNU MPを使った場合
#include <gmp.h>
int
main(void)
{
unsigned int factorial_of;
mpz_t result;
mpz_init(result);
for (factorial_of = 1; factorial_of <= 80; factorial_of++) {
unsigned int num;
mpz_set_ui(result, 1L);
for (num = factorial_of; num > 0; num--)
mpz_mul_ui(result, result, num);
gmp_printf("%Zd\n", result);
}
mpz_clear(result);
return 0;
}
OpenSSLを使った場合
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <stdio.h>
int
main(void)
{
unsigned long factorial_of;
BIGNUM* result = BN_new();
for (factorial_of = 1; factorial_of <= 80; factorial_of++) {
unsigned long num;
BN_one(result);
for (num = factorial_of; num > 0; num--)
BN_mul_word(result, num);
char* out = out = BN_bn2dec(result);
printf("%lu! = %s\n", factorial_of, out);
OPENSSL_free(out);
}
BN_clear_free(result);
return 0;
}
一応これで2.の答えらしいものは出ますが、多倍長数演算を自分でやるのがこの課題だと思うのでこれを出したら0点です。
No.1
- 回答日時:
多倍長数(多倍長整数)は分かりますか?
おそらく何かの授業の課題だと思いますが、多倍長数はbignumと言われる任意の精度の整数を表すことのできるデータ型のことです。
通常の整数の計算は、例えば 32 * 12のように単純に計算すれば良いのですが、intやlongでは桁が足りないような計算では単純に計算する事ができないので、問題のように配列などに格納します。
例えば1つ目の答えが分かっているということで、その答えを x = 512 で割ってみると、
52462354432 / 512 = 102465536
となり a[KETA] で示されている数字(多倍長数)の内容に一致します。
ここまでは分かっているかと思いますが、問題の要点は、配列で表された数字をどうやって計算するかということにあります。
いろいろな考え方がありますが、この計算は「筆算」をするときとよく似ています。
実際に2つの数をどうやって筆算していたかを順を追って考えれば、計算方法は自ずとわかると思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# このプログラミングの問題を教えてほしいです。 キーボードからデータ数nとn個のデータを入力し、平均値 3 2022/12/19 22:51
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 エラーの原因がわからな...
-
比較回数と交換回数表示について
-
複数桁10進数の*桁目だけを抽出...
-
nCmの関数
-
構造体の勉強中です 合計点の高...
-
C言語 配列と関数の練習問題
-
[C言語] 関数を利用する計算
-
実数の整数部,小数部の取得
-
C言語での引数の省略方法
-
数字列を3桁ごとにカンマで区切...
-
アスタリスクでダイヤ型を作る
-
覆面算のプログラムが分かりません
-
C言語の基礎 . 2乗値の差につ...
-
c言語
-
プログラミング
-
【C++】関数ポインタの使い方
-
毎回違う乱数を生成するにはど...
-
if と配列の組み合わせ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語 配列と関数の練習問題
-
複数桁10進数の*桁目だけを抽出...
-
(int *)の意味
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
c言語
-
足して100になるような乱数のア...
-
C言語初心者です、、、お助けく...
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
実数の整数部,小数部の取得
-
課題でつまってます・・・
-
商と剰余を同時に求める(C言語)
-
C言語の配列をC++のvectorに高...
-
std::set<int> で、ある値が何...
おすすめ情報