1

I'm currently reading a C++ book from the very beginning to learn it. I already have coding knowledge but I really want to deeply learn C++ by trying to code as much as possible from my own instead of always use libraries. (While i'm learning. I'll use libraries later.)

I'm currently reading about the casts. While i'm reading, I try to make exercises to apply what I just read. But well this time I lost control and it goes far away of what I was practicing (casts) but it was fun to code. [EDIT] I will read Different casts. - thanks @Chnossos

I learned a lot while making this code such as stringsstream, reverse etc..

This is a simple int to base 2 and I wish to know if there is a way to optimize the code, or if it's could be correct like this.

Could be great to learn more with an optimized code to see what experts are doing.

Thanks.

#include <iostream>
#include <iomanip>
#include <sstream>

using namespace std;

int toBase_8(int number){ //basé sur un exemple de chiffre 14 avec base 8 -> 016
    int base(8);
    int entier1;
    double entier2;
    double decimal;
    double resTemp;
    int res;

    resTemp = (double)number / base; //donne 1.75

    entier1 = (int)resTemp; //donne 1 car transforme le double en int alors le int garde seulement l'entier

    decimal = resTemp - entier1; //donne 0.75 restant
    entier2 = decimal * (double)base; // donne 6

    res = ((entier1*10)+(int)entier2); //donne 16

    return res;
}

int toBase_2(float number){
    if (number > 0 && number <= 255){ //s'sassure que le nombre est entre 0 et 255

        int arr[8];
        int pos(0);

        while ((int)number != 0 || pos == 7){ // à chaque tour de boucle, convertie le float en entier et le compare. ajouté le ou pour etre certains de mettre des 0 jusqu'à la fin meme si la premiere condition (!=) est atteinte
            number = number / 2;

            if (number == (int)number){
                arr[pos] = 0; //si entier
            }else{
                arr[pos] = 1; //si decimal
            }
            number = (int)number; // remet le float en int pour la prochaine division. En base 2 chaque nombre decimal doit etre redivisé en entier. Ex.: (9/2) = 4.5. Donne 1 car decimal. Apres on recommence à partir de (4/2) = 2, et non pas 4.5/2. Donne 0 car entier etc..
            pos++;
        }
        reverse(begin(arr), end((arr))); //reverse le array avec algorithm.h car la réponse binaire ce lit sens inverse.

        //mettre le array(int) en string puis en un seul int en utilisant stringstream <sstream>
        stringstream ss;

        for (int d(0); d<(sizeof(arr)/ sizeof(arr[0])); d++){
            ss << arr[d]; //ajoute les int dans le stream
        }

        //METHODE 1: utiliser en string
        //cout << ss.str() << endl; //sort le stream en string

        //METHODE 2: utiliser en int
        int myInt;
        ss >> myInt; //envoie le string dans le int

        //cout << myInt << endl;

        return myInt;
    }else{

        return 0;
    }
}

int main()
{
    cout << setw(8) << setfill('0') << toBase_2(234) << endl;

    // ex.: 14 en base 8 => 016
    //cout << setw(3) << setfill('0') << toBase_8(14) << endl;

    return 0;
}

[EDIT - Final] What I understand from all the answers is in fact that my vision of optimization is not the same as yours. @Chnossos understood the most by gaving me good tips such as cast type differences and dropping all the Double and use Modulo (%) instead. For the rest, I think it's all about your vision of optimization such as use more libraries as possible.

Thanks for the answers. If anybody have other code optimization in the same minding as @Chnossos, your welcome.

MindKind
  • 49
  • 1
  • 12
  • 3
    How come you're trying to "deeply learn C++" and I fail to see a single C++ cast in there... – Chnossos Sep 04 '17 at 17:41
  • 3
    Expressions such as `(int)resTemp;` are called C-style casts and should not be used in C++ at all. – user7860670 Sep 04 '17 at 17:43
  • 1
    @Chnossos how would a C++-style cast help with casting numeric types? – ypnos Sep 04 '17 at 17:43
  • 1
    @Chnossos if I have a float and then I use (int)float then this is a cast no? – MindKind Sep 04 '17 at 17:44
  • @Chnossos and by deeply learn (sorry my english is not my primary language) I mean to not only learn basics things such as loops, arrays, vars etc.. but try to learn how things really works. – MindKind Sep 04 '17 at 17:45
  • @ypnos This is not about achieving the goal of the program here, this is about learning proper C++. Thinking this is okay will lead to potential bugs later down the learning path when the casts get more dangerous. – Chnossos Sep 04 '17 at 17:45
  • @VTT why? This is in my book, wrote by a c++ university teacher.. :\ – MindKind Sep 04 '17 at 17:46
  • @Chnossos ok could you please explain me why it would lead in bugs? – MindKind Sep 04 '17 at 17:47
  • @MindKind When you feel ready, you should [read and learn this](https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used) to understand the difference between C-style casts and C++ casts. – Chnossos Sep 04 '17 at 17:47
  • @Chnossos I don't buy it. The question was to point out how the algorithm could be optimized. – ypnos Sep 04 '17 at 17:47
  • You should get a better book then. If you want to optimize something you typically start with creating a good performance measuring tests that include common and borderline scenarios and then you figure out which places are limiting performance and finally to rework them. – user7860670 Sep 04 '17 at 17:50
  • "[...] instead of other high level languages that use too much of already made functions." imho the greatest thing about c++ is that it has "too much already made functions". At some point you may want to dive into the standard library that contains algorithms for any problem you can think of – 463035818_is_not_an_ai Sep 04 '17 at 17:51
  • @ypnos OP would not have emphasized that he was a beginner trying to do his best to learn if he only wanted comments on the algorithm tho. – Chnossos Sep 04 '17 at 17:52
  • @tobi303 maybe i'm not clear. I think I just can't really explain properly what I want in english. I know c++ have std libraries but comparing to c#, java and other languages c++ ask to have a better knowledge of how things work to achieve things that can be more easily get done in other languages. To have tried c#, java, javascript and other languages, that's my feeling in c++. In the other languages theres a function for everything. Not in C++. – MindKind Sep 04 '17 at 17:55
  • 2
    It looks like you have completely misunderstood what different bases mean. If you "convert" 6 to 110, you don't have six in base 2, you have one hundred and ten. – molbdnilo Sep 04 '17 at 18:28
  • @molbdnilo Again maybe it's not exactly clear What I did for this function is to output a 8 bits binary. When I put 6 to toBase_2(6) the output is 00000110. Apologies for that. – MindKind Sep 04 '17 at 18:46
  • @MindKind `toBase_2(6)` returns one hundred and ten and you're printing it with five leading zeros. It is not binary. A number in binary representation is not "any number with just ones and zeroes". Binary, octal, and decimal are *textual* representations of numbers. – molbdnilo Sep 04 '17 at 18:48

1 Answers1

5

The easiest (and probably most efficient) way to provide the binary representation of an integer number is to use std:bitset:

int input;
std::bitset<sizeof(int)> bits(input);
std::cout << bits.to_string() << std::endl;

Done.


Regarding the octal (base 8) representation you can simply use the std::oct I/O manipulator:

std::cout << std::oct << input << std::endl;

As you wanted to know about your own handrolled code, here are some hints how to do that efficiently:

  • Don't use float or double to do that. Rather stick to (unsigned) int values and use modulo (%) and integer division operations in a loop to extract digits.
  • If you have extracted digits for your chosen base you can turn them into ASCII character representation by adding '0'.
  • The bit shift operator (>>) and binary and operator (&) would be useful to identify single bit values, and turn these into '0's and '1's for representing base 2 values.

As you are so eager to learn yourself, I'll leave to read about the above and put that information together into a working solution for you.


Could be great to learn more with an optimized code to see what experts are doing.

You can always inspect and study the implementations of the std::bitset and std::oct implementations of any free C++ compiler (GCC, Clang, ...) to see what the real experts have done to implement that.

user0042
  • 7,917
  • 3
  • 24
  • 39
  • This does not answer the `if it's could be correct like this.`part of OP question. – Chnossos Sep 04 '17 at 17:48
  • Using template and libraries will not make me learn how things work. – MindKind Sep 04 '17 at 17:49
  • @Chnossos I leave it to you to answer that part. – user0042 Sep 04 '17 at 17:50
  • @MindKind The implementation of this stuff can be inspected. You may study that code to learn from. – user0042 Sep 04 '17 at 17:52
  • 2
    @MindKind yes it will. If you want the details you can always look at the source of a implementation. If you want to learn c++ you also have to learn how to use what the standard lib offers you – 463035818_is_not_an_ai Sep 04 '17 at 17:52
  • @tobi303 got it. I just try to code as much as possible from my own instead of always use libraries. – MindKind Sep 04 '17 at 18:00
  • @MindKind _"I just try to code as much as possible from my own instead of always use libraries. "_ That's probably a very silly idea and won't get you much productive as a professional developer. – user0042 Sep 04 '17 at 18:01
  • @user0042 Jeez.. That's to learn! After that I will use libraries to get more productive. I'm that much not clear or what? – MindKind Sep 04 '17 at 18:04
  • 1
    @MindKind As mentioned, study the implementation of those standard libraries. That will boost (pun intended) your knowledge. No need to get upset BTW. – user0042 Sep 04 '17 at 18:06
  • @user0042 Don't worry i'm not upset for that heh ;) but I'm just trying to learn the smartest way possible (for me) and everybody seems to not understand. Add the fact I cannot express 100% clearly what I want to say in english.. it's giving me hard time :D Thanks for your thoughts. – MindKind Sep 04 '17 at 18:12
  • @MindKind Some hints for starters to fix _your code_: Drop all the `double` values there and use the modulo operator (`%`) and integer division. Digits can be represented as ASCII characters from their integer numbers and adding `'0'`. – user0042 Sep 04 '17 at 18:15
  • @MindKind by inspecting the implementations you learn about how they are implemented, but not necesarrily how to use them. If anything then c++ is both high level and low level language. Even if you care about low level stuff, you dont have to reinvent the wheel. E.g. `std::vector` lets you do cool stuff without having to having to care about memory allocations etc., but if you want you can always get a pointer to the first element and treat it like a plain c-style array – 463035818_is_not_an_ai Sep 04 '17 at 18:33
  • @MindKind I extended my answer a bit to point you into the right direction(s). – user0042 Sep 04 '17 at 18:34
  • @user0042 Make sense, good idea. I completely forgot the modulo operator. Thanks. – MindKind Sep 04 '17 at 18:48
  • @tobi303 Yes your exact. I already learned pointers, references etc.. I know I can create dynamic arrays using vector instead of using a pointer. I did some exercises when I read that and that exactly what I try to do. I mean instead of say why should I care about pointer, reference and memory if vector automatically manage the memory. Well, that's my point. Using pointers and references instead of vector learned me how things are set to the memory etc.. – MindKind Sep 04 '17 at 18:53
  • @MindKind If you'd studied the `std::vector` implementation you might have noticed how to avoid the many pitfalls and obstacles lurking with that. – user0042 Sep 04 '17 at 18:56