Convertitore da decimale a binario
Questo programma potrebbe sembrare pigro, ho anche provato a iterare attraverso il vettore ma le prestazioni erano scarse, quindi ho usato questo approccio pigro che ha più prestazioni
#ifndef BINARY_HH
#define BINARY_HH
/**************************************************************************
* Name: Binary.hh
* Author: Samuel Oseh
* Date: 27/09/2020
* File Info: This file contains class method-function prototypes
* Purpose: Binary Converter is a program that converts a decimal
* to its binary equivalents and also performs other calculations
**************************************************************************/
#include <vector>
#include <string>
class Binary {
public:
Binary( const int &, const char & );
~Binary() {}
Binary( const Binary & );
void printBinary() const;
void toBinary();
char getType() const;
int getDecimal() const;
Binary &operator+=( const Binary &binaryToAdd );
Binary &operator-=( const Binary &binaryToSub );
Binary &operator*=( const Binary &binaryToMul );
Binary &operator/=( const Binary &binaryToDiv );
bool operator==( const Binary &binaryToCompare ) const;
inline bool operator!=( const Binary &binaryToCompare ) const {
return !( *this == binaryToCompare );
}
const Binary &operator=( const Binary &binaryToCopy );
private:
char type;
int decimal;
std::vector< int > binary{};
};
#endif
/**************************************************************************
* Name: Binary.cc
* Author: Samuel Oseh
* Date: 27/09/2020
* File Info: This file contains class method-function definitions
* Purpose: Binary Converter is a program that converts a decimal
* to its binary equivalents and also performs other calculations
**************************************************************************/
#include <iostream>
#include <stdexcept>
#include "Binary.hh"
Binary::Binary( const int &d, const char &t ) {
if ( tolower( t ) == 'd' )
type = t;
else
throw std::invalid_argument( "type must be 'd' only." );
if ( d < 0 )
throw std::invalid_argument( "decimal value must be greater than 0." );
decimal = d;
}
Binary::Binary( const Binary &binaryToCopy ) {
decimal = binaryToCopy.decimal;
type = binaryToCopy.type;
for ( unsigned int counter = 0; counter < binaryToCopy.binary.size(); ++ counter ) {
binary.push_back( binaryToCopy.binary[ counter ] );
}
}
void Binary::toBinary() {
if ( type == 'd' ) {
int val = decimal;
while ( val != 0 ) {
binary.insert( binary.begin(), val % 2 );
val /= 2;
}
}
else {
throw std::invalid_argument( "Invalid type conversion" );
}
}
void Binary::printBinary() const {
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot print binary object without converting it" );
for ( int number : binary ) {
std::cout << number << "";
}
}
char Binary::getType() const {
return type;
}
int Binary::getDecimal() const {
return decimal;
}
Binary &Binary::operator+=( const Binary &binaryToAdd ) {
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
if ( binaryToAdd.binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
int decimalSum = decimal + binaryToAdd.decimal;
Binary *b = new Binary( decimalSum, 'd' );
b->toBinary();
*this = *b;
delete b;
return *this;
}
Binary &Binary::operator-=( const Binary &binaryToAdd ) {
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
if ( binaryToAdd.binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
int decimalSum = decimal - binaryToAdd.decimal;
if ( decimalSum < 0 ) {
throw std::invalid_argument( "Can not perform subtraction from a lesser binary" );
}
Binary *b = new Binary( decimalSum, 'd' );
b->toBinary();
*this = *b;
delete b;
return *this;
}
Binary &Binary::operator*=( const Binary &binaryToMul ) {
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
if ( binaryToMul.binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
int decimalSum = decimal * binaryToMul.decimal;
Binary *b = new Binary( decimalSum, 'd' );
b->toBinary();
*this = *b;
delete b;
return *this;
}
Binary &Binary::operator/=( const Binary &binaryToDiv ) {
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
if ( binaryToDiv.binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
int decimalSum = decimal / binaryToDiv.decimal;
Binary *b = new Binary( decimalSum, 'd' );
b->toBinary();
*this = *b;
delete b;
return *this;
}
bool Binary::operator==( const Binary &binaryToCompare ) const {
if ( decimal == binaryToCompare.decimal )
return true;
return false;
}
const Binary &Binary::operator=( const Binary &binaryToCopy ) {
decimal = binaryToCopy.decimal;
type = binaryToCopy.type;
binary.clear();
for ( unsigned int counter = 0; counter < binaryToCopy.binary.size(); ++ counter ) {
binary.push_back( binaryToCopy.binary[ counter ] );
}
return *this;
}
Risposte
Panoramica
Penso che la parte più significativa sia questa:
int decimal;
Probabilmente non è un numero decimale. Nella maggior parte dei computer moderni questo è memorizzato come un numero binario (sebbene in alcuni computer estremamente vecchi usassero i decimali ma hanno rinunciato ai computer decimali a favore del binario molto rapidamente).
Il problema con il tuo codice è che un numero è un numero. La sua base è importante solo quando la visualizzi, la analizzi o la memorizzi. La memorizzazione del numero è un'astrazione di cui si è preso cura il livello hardware (l'hardware sa come memorizzare / ed eseguire operazioni di base sugli interi). Quindi l'unica cosa per te è il livello di presentazione (stampa e analisi).
Decimal 10:
Binary 1010
Hex 0xA
Questi sono tutti semplicemente la rappresentazione visiva dello stesso concetto. Abbiamo già il concetto di un numero intero fornito dalla lingua che intrappresenta un valore.
Revisione del codice
Il tparametro type è superfluo qui.
Binario :: Binario (const int & d, const char & t) {
Il valore dè già un numero. Hai solo bisogno del tipo se stai convertendo da una rappresentazione visiva (cioè una stringa). Altrimenti è sempre un numero.
Non sono sicuro del motivo per cui non supporti i valori negativi:
if ( d < 0 )
throw std::invalid_argument( "decimal value must be greater than 0."
Non è così difficile?
Questo potrebbe essere semplificato:
for ( unsigned int counter = 0; counter < binaryToCopy.binary.size(); ++ counter ) {
binary.push_back( binaryToCopy.binary[ counter ] );
}
// Simpler to write:
binary = binaryToCopy.binary;
Se si desidera memorizzare localmente una rappresentazione di testo facile da convertire, è possibile utilizzare std::bitset<32>.
std::bitset<32> binary;
void Binary::toBinary() {
binary = decimal; // converts it into a bitset.
// bitsset when put on a stream will show 1/0
// Note internally it is just an int.
}
Certo è bello avere una funzione di stampa.
void Binary::printBinary() const {
Ma in C ++ normalmente usiamo operator<<per posizionare i dati su un flusso di output. Quindi è bello scrivere la funzione appropriata che lo fa. Non può semplicemente chiamare la printBinary()funzione. Ma dovrai modificare la tua funzione di stampa per accettare un flusso (puoi impostarlo per impostazione predefinita std::outper compatibilità all'indietro.
void Binary::printBinary(std::ostream& str = std::cout) const {
binary.toBinary(); // You can convert see next section.
out << binary; // Assuming you used std::bitset.
}
friend std::ostream& operator<<(std::ostream& str, Binary const& b)
{
b.printBinary(str);
return str;
}
Puoi convertire il numero in un metodo const.
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot print binary object without converting it" );
L' binaryoggetto sta memorizzando lo stato temporaneo (cioè non rappresenta lo stato dell'oggetto. Rappresenta un valore facilmente stampabile dello stato corrente. Quindi questo è un posto perfetto per contrassegnare un membro come mutabile.
mutable std::bitset<32> binary;
Ora puoi aggiornare lo stato in una funzione const:
Una volta che il valore è stato convertito in un numero, il suo tipo è irrelavante.
char Binary::getType() const {
return type;
}
Non stai restituendo un decimale. Stai restituendo un numero.
int Binary::getDecimal() const {
return decimal;
}
In realtà è memorizzato come binario, sai.
Wow, sembra un sacco di lavoro.
Binary &Binary::operator+=( const Binary &binaryToAdd ) {
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
if ( binaryToAdd.binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
int decimalSum = decimal + binaryToAdd.decimal;
Binary *b = new Binary( decimalSum, 'd' );
b->toBinary();
*this = *b;
delete b;
return *this;
}
Innanzitutto non creiamo tipi dinamici:
Binary *b = new Binary( decimalSum, 'd' );
b->toBinary();
*this = *b;
delete b;
Questo può essere semplificato per:
Binary b( decimalSum, 'd' );
b.toBinary();
*this = b;
Ma perché fare tutto ciò, perché non semplificare un altro passaggio e rimuovere l'oggetto intermedio.
decimal += binaryToAdd.decimal;
binary.clear(); // Not sure if you need this but probably.
toBinary();
Non sei sicuro del motivo per cui devono essere già convertiti?
if ( binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
if ( binaryToAdd.binary.size() == 0 )
throw std::invalid_argument( "Cannot add binary object without converting it" );
Sbarazzati di quello.
La stessa cosa vale qui:
Binary &Binary::operator-=( const Binary &binaryToAdd ) {
Binary &Binary::operator*=( const Binary &binaryToMul ) {
Binary &Binary::operator/=( const Binary &binaryToDiv ) {
// ^ Note in C++ (unlike C) the & and * go with the type (traditionally).
Hai implementato la famiglia di operatori + =. Questo rende il passaggio successivo così semplice. Sono sorpreso che tu non abbia implementato la + famiglia di operatori.
Binary Binary::operator+(Binary const& rhs) const {
Binary newValue(*this); // copy;
return newValue += rhs; // Add to the copy and return.
}
Questo può essere semplificato:
if ( decimal == binaryToCompare.decimal )
return true;
return false;
Per
return decimal == binaryToCompare.decimal;
Se ti accorgi che stai facendo:
if (test) {
return true;
}
else {
return false;
}
This is the same as
return test; // as test must be a boolean value (or convertible to cone).