質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

560閲覧

2進数から64進数 表現

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/01/25 02:37

編集2020/02/04 04:40

コマンドラインに非負整数 n と 正整数 B (2 ≦ B ≦ 64) が与えられたとき、 n、B に続けて n の B 進表現とその桁数 m を1行として書き出すプログラムを作りたいです。
その書き出す形式はつぎのとおりです。

数値 n、B は、 必要最小限の桁数で書き出し、その間に @ を書き出す。
その後、前後に空白を置いて = を書き出し、続けて、n の B 進表現を必要最小限の桁数で書き出す。
その後に、n の B 進表現を書き出した桁数 m を角括弧 [ ] で括って必要最小限の桁数で書き出す。
これらの書出しが全て終わったところで改行を書き出す。
プログラムは、つぎの仕様をもつ関数 show の関数定義が与えられているとして作ること。

int show(int value, int base);

// 非負整数 value の base進表現を

// 必要最少の桁数で標準出力に書き出す

// 2<=base<=64

// この関数は書き出した桁数を返す

// なお、六十四進までの数値表現に使う数字と

// その表す値の対応はつぎのとおりとする

//  数字 0123456789ABCDEF

//   値  0         10

//  数字 GHIJKLMNOPQRSTUV

//   値 16   20         30

//  数字 WXYZabcdefghijkl

//   値 32       40

//  数字 mnopqrstuvwxyz+/

//   値 48 50         60

c

1#include <stdio.h> 2#include "show.h" 3int main(int argc, char *argv[]){ 4 5 ・・・ コマンドラインから与えられる整数値 n, B を使って 6 n の B 進表現を書き出すとともに、それを書き出すのに要した 7 必要最小限の桁数を書き出す。 8 ただし、関数 show を使用する 9 10 return 0; 11}

実行例
コマンドライン入力
100 2
標準出力
100@2 = 1100100[7]
コマンドライン入力
65531 8
標準出力
65531@8 = 177773[6]
コマンドライン入力
2146041533 64
標準出力
2146041533@64 = 1/wVwz[6]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

C

1/** 2 * teratail 回答コード 237386 3 * 質問: https://teratail.com/questions/237386 4 * コンパイル環境: GCC または Clang またはその互換コンパイラー、Visual C++は不可 5 * 必須ライブラリ: GMP https://gmplib.org/ 6 * コンパイル方法: 7 * gcc -Wall -Wextra -O2 -std=c11 -pedantic-errors q237386.c -lgmp 8 */ 9 10#include <errno.h> 11#include <gmp.h> 12#include <stdio.h> 13#include <stdlib.h> 14#include <string.h> 15#define NDEBUG 16#include <assert.h> 17 18static char *nb_get_str(const mpz_t n, int b) 19{ 20 static const char nb_chars[] = "0123456789" 21 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 22 "abcdefghijklmnopqrstuvwxyz" 23 "+/"; 24 assert(mpz_sgn(n) > 0); 25 assert(b >= 2 && b <= 64); 26 if (b <= 62) { 27 // mzp_get_strは2進数から62進数までしか対応していない 28 char *nb_str = mpz_get_str(NULL, b, n); 29 if (nb_str == NULL) return NULL; 30 return nb_str; 31 } else { 32 // 63進数と64進数は62進数よりは桁数が必ず小さくなる 33 size_t nb_size = mpz_sizeinbase(n, 62); 34 size_t nb_nums[nb_size]; 35 char *nb_str = (char *)malloc(nb_size + 2); 36 if (nb_str == NULL) return NULL; 37 38 mpz_t tmp; 39 mpz_init_set(tmp, n); 40 mpz_t q, r; 41 mpz_inits(q, r, NULL); 42 size_t *p = nb_nums; 43 while (mpz_sgn(tmp) != 0) { 44 mpz_tdiv_qr_ui(q, r, tmp, b); 45 mpz_set(tmp, q); 46 *(p++) = (size_t)mpz_get_ui(r); 47 } 48 if (p == nb_nums) { 49 strcpy(nb_str, "0"); 50 } else { 51 char *ps = nb_str; 52 do { 53 *(ps++) = nb_chars[*(--p)]; 54 } while (p != nb_nums); 55 *ps = '\0'; 56 } 57 mpz_clears(tmp, q, r, NULL); 58 59 return nb_str; 60 } 61} 62 63int main(int argc, char *argv[]) 64{ 65 if (argc != 3) return 0x01; 66 67 const char *n_str = argv[1]; 68 const char *b_str = argv[2]; 69 70 mpz_t n; 71 if (mpz_init_set_str(n, n_str, 10) != 0) return 0x10; 72 if (mpz_sgn(n) <= 0) return 0x11; 73 74 errno = 0; 75 long b_l = strtol(b_str, NULL, 10); 76 if (errno != 0) return 0x20; 77 if (b_l < 2 || b_l > 64) return 0x21; 78 int b = (int)b_l; 79 80 char *nb_str = nb_get_str(n, b); 81 if (nb_str == NULL) return 0x30; 82 83 printf("%s@%s = %s[%ld]\n", n_str, b_str, nb_str, strlen(nb_str)); 84 85 free(nb_str); 86 mpz_clear(n); 87 return 0; 88}

まずshow関数は使ってはいけません。現代のほとんどの環境において、intの最大値はたったの2147483647です。つまり、2147483648以上与えられてた場合に対応できません。問題文にはnの上限が書いていないため、メモリとコマンドラインによる制限までは使用できるとみなさなければなりません。よって、show関数は問題解決のまったく役に立たない関数なので捨ててください

さて、後は簡単で多倍長整数を使えば良いだけです。自分で実装するのは大変面倒なので、GMPを使いました。ただ、GMPは62進数までしか表示できないため、63進数以上は独自で実装する必要があります。面倒ですが、進数の仕様に従って書くだけなので、とても簡単でしょう。

投稿2020/01/26 03:01

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

解決することができました。

投稿2020/01/26 09:39

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Don't ask, search.
See https://teratail.com/questions/11252
Mr. Cateye gives you good advice.
Feel free to ask me to rewrite in Latin.
(Japanese? No way! You are a language learner, aren't you? Try to use it to be a good bilingual!)

投稿2020/01/25 14:36

majiponi

総合スコア1720

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問