アプリ版:「スタンプのみでお礼する」機能のリリースについて

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の出力はわかるのですが、計算過程がわかりません
教えてくださいよろしくお願いします。

A 回答 (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;
}
    • good
    • 0

次に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;
}
    • good
    • 0

まず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;
}
    • good
    • 0

#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点です。
    • good
    • 0

多倍長数(多倍長整数)は分かりますか?



おそらく何かの授業の課題だと思いますが、多倍長数はbignumと言われる任意の精度の整数を表すことのできるデータ型のことです。

通常の整数の計算は、例えば 32 * 12のように単純に計算すれば良いのですが、intやlongでは桁が足りないような計算では単純に計算する事ができないので、問題のように配列などに格納します。

例えば1つ目の答えが分かっているということで、その答えを x = 512 で割ってみると、

52462354432 / 512 = 102465536

となり a[KETA] で示されている数字(多倍長数)の内容に一致します。

ここまでは分かっているかと思いますが、問題の要点は、配列で表された数字をどうやって計算するかということにあります。

いろいろな考え方がありますが、この計算は「筆算」をするときとよく似ています。

実際に2つの数をどうやって筆算していたかを順を追って考えれば、計算方法は自ずとわかると思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!