前提
c++で数値を基数変換し格納、表示するクラスを作っています
実現したいこと
コンストラクタ
数値を入力し、n進数の各桁を配列に格納したい
発生している問題・エラーメッセージ
2進数で1が連続した値 (2^n - 1) が出力され、正しく基数変換できない
問題があると思われるコードを抜粋、修正したものです
入力された数値を2進数で逆順に出力する(ことを期待したい)コードです
c++
1#include <cstdint> 2#include <iostream> 3int main(){ 4 uint64_t num; 5 std::cin >> num; 6 for(uint8_t i = 0; i < 64; i++){ 7 std::cout << (num != (num >>= 1) << 1); // 問題箇所 8 } 9 std::cout << std::endl; 10 return 0; 11}
該当のソースコード
c++
1// main.cpp 2#include <cstdint> 3#include <iostream> 4#include "base.hpp" 5int main(){ 6 uint64_t a; 7 std::cin >> a; 8 std::cout << Base(2, a) << std::endl; 9 return 0; 10}
c++
1// base.hpp 2#ifndef base_hpp 3#define base_hpp 4#include <cstdint> 5#include <iostream> 6class Base{ 7 char* number; 8 uint64_t base; 9 uint64_t* num; 10 uint64_t digit; 11 void add(uint64_t* base_a, const uint64_t* base_b); 12public: 13 Base(const char* number, uint64_t num, uint64_t digit = 64); 14 Base(uint64_t base, uint64_t num, uint64_t digit = 64); 15 friend std::ostream& operator<<(std::ostream& os, Base base_a); 16}; 17#endif
c++
1// base.cpp 2#include "base.hpp" 3void Base::add(uint64_t* base_a, const uint64_t* base_b){ 4 uint8_t carry = 0; 5 for(uint64_t i = 0; i < digit; i++){ 6 uint64_t temp = base_a[i] + base_b[i] + carry; 7 carry = temp < base_a[i] + carry || base <= temp; 8 base_a[i] = carry? temp - base: temp; 9 } 10 return; 11} 12Base::Base(const char* number, uint64_t num, uint64_t digit): 13base(0), num(new uint64_t[digit]{}), digit(digit){ 14 while(number[base]) base++; 15 this->number = new char[base]; 16 for(uint64_t i = 0; i < base; i++){ 17 this->number[i] = number[i]; 18 } 19 uint64_t* twice = new uint64_t[digit]{1}; 20 if(num != (num >>= 1) << 1) add(this->num, twice); // 問題箇所 21 for(uint64_t i = 1; i < digit; i++){ 22 add(twice, twice); 23 if(num != (num >>= 1) << 1) add(this->num, twice); // 問題箇所 24 } 25 return; 26} 27Base::Base(uint64_t base, uint64_t num, uint64_t digit): 28number(new char[base]{}), base(base), num(new uint64_t[digit]{}), digit(digit){ 29 const char number[] = 30 "0123456789" 31 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 32 "abcdefghijklmnopqrstuvwxyz"; 33 for(uint64_t i = 0; i < base && i < 62; i++){ 34 this->number[i] = number[i]; 35 } 36 uint64_t* twice = new uint64_t[digit]{1}; 37 if(num != (num >>= 1) << 1) add(this->num, twice); // 問題箇所 38 for(uint64_t i = 1; i < digit; i++){ 39 add(twice, twice); 40 if(num != (num >>= 1) << 1) add(this->num, twice); // 問題箇所 41 } 42 return; 43} 44std::ostream& operator<<(std::ostream& os, Base base_a){ 45 uint64_t digit = base_a.digit; 46 uint64_t i = 0; 47 for(; i < digit; i++) if(base_a.num[digit - i - 1]) break; 48 if(i == digit) os << base_a.number[0]; 49 else for(; i < digit; i++) os << base_a.number[base_a.num[digit - i - 1]]; 50 return os; 51}
試したこと
問題箇所の式を次のように変更したところ、うまく動作しました
c++
1// uint64_t temp; 2// ... 3((temp = num) != (num >>= 1) << 1);
c++
1(num != num >> 1 << 1); 2num >>= 1;
補足情報(FW/ツールのバージョンなど)
google colaboratory で g++ を使用しています

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/11/15 09:03
2022/11/15 09:10
2022/11/16 00:25
2022/11/16 00:31
2022/11/16 00:32
2022/12/17 14:44