Function to always round up to the nearest tenth

Pages: 1... 345
Problem solved!!!
You guys are really experts. I really really appreciate it!

Both the two solutions do their jobs well far more than what I initially predicted. However, JLBorges's solution is so full of mystery.

Here is my final code (my test unit) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdlib>

namespace JLBorges
{
    unsigned long long ipow10(unsigned int p) 
    {return (p == 0) ? 1 : 10 * ipow10(p - 1); }

    double round_d(double d, std::streamsize round_prec = 1, bool upDown = true)
    {
        double powval = ipow10(round_prec);

        if(upDown)
        return std::ceil(d * powval) / powval;
        return std::floor(d * powval) / powval;
    }
};


std::streamsize precision_d(double d)
{
    std::stringstream ss;

    ss.setf(std::ios::fixed);

    double d2;
    std::streamsize d_precision = 0;
    for(int i = 0; i <= 20; i++)
    {
       ss.precision(i);    
       ss << d;
       ss >> d2;
       if(d == d2) break;
  
      d_precision += 1; 
      ss.str(""); ss.clear();
    }
    return d_precision;
}


namespace closed_account_5a8Ym39o6
{
    double round_d(double d, std::streamsize round_prec = 1, bool upDown = true)
{
        std::streamsize input_precision = precision_d(d);
        
        std::stringstream ss;
        ss.setf(std::ios::fixed);
        ss.precision(input_precision) ;
        ss << d;
        bool round = false;
        std::string out = ss.str();
        std::string::size_type n;
        std::size_t dot = out.find(".");
        if(dot != std::string::npos && (out.length() - 1 - dot) >= 1 + round_prec)
        {
            round = true;
            n = dot + 1 + round_prec;
        }
        else {
            n = out.length();
        }
        out.resize(n);
        ss.str(""); ss.clear();
        ss.str(out);
        ss >> d;

        if(round && (upDown == true) && d >= 0) d += (1.0 / pow(10, round_prec));
        if(round && (upDown == false) && d < 0) d -= (1.0 / pow(10, round_prec));

        return d;
    }
};


double random_d()
{
     static bool need_random = true;

    if(need_random)
    {
        srand(static_cast<unsigned int>( time(NULL)) );
        need_random = false;
    }

    int n = (rand() % 12) + 1;
    if((rand() % 100) >= 85) n = 1;
    double a = (rand() % 15000);
    double b = 0;
    for(long long i = 0, j = 0; i < n; i++)
    {
        j = (rand() % 9) + 1;
        b = b * 10 + j;
    }
    std::streamsize input_precision = n;
    a += (b / std:: pow(10, input_precision));

    if((rand() % 100) >= 65) a = (-a);
    return a;
}

int main()
{
     std::streamsize round_prec = 1;
     bool upDown = true;
     double d = 0.0;

     const int test_cases = 25;
     for(int N = 0; N < test_cases; ++N)
     {
         std::cout.setf(std::ios::fixed);
         std::cout << "in : ";
         std::cin >> d; 
        
          // d = random_d();
          // std::cout.precision(std::max(precision_d(d), 0));
         // std::cout << d << "\n";

         d = JLBorges::round_d(d, round_prec, upDown);
         // d = closed_account_5a8Ym39o6::round_d(d, round_prec, upDown);

         std::cout.precision(std::min(precision_d(d), round_prec));
         std::cout << "out : " << d << "\n\n";
    }
}


But I don't really know which ideal solution I should choose. They both do excellent jobs. That is why I have two different namespaces : JLBorges && closed_account_5a8Ym39o6. I have learnt quite a lot from the Closed account's solution and grasped the general idea of how the algorithm works. I am no expert and I am here to seek help so I have no right to say which one is worse than the other. But I am interested in your (genuine) thoughts about the two solutions, because you guys are all code experts which is why I love you guys so much.

So :
+ Which solution is more competitive?
+ Which solution looks cleaner and more friendly?
+ Which solution is easier to use?
+ Which solution is faster?
+ Which solution is more reliable?
+ Which solution is more versatile?
+ Which solution is better overall?


And thank you again for helping me. You guys are so great! :D :D
... :D
Last edited on
Cheers... :D
TheIdeasMan wrote:
But you should really prefer JLBorges code - he is the master


For all those questions you ask :+)

However, JLBorges's solution is so full of mystery.


Why? IMO, it's very simple.

... because you guys are all code experts ...


Not all of us (including me), but JLBorges and quite a few others are.
No, it is impossible...

Okay, JLBorges is an absolute C++ master, just like what you say. How long must I have to work and study hard to be able to keep up with him? I am scared, the more I continue to learn like that, the more I become like a bookworm, and the more my life will get ruined. It is not like I do not want to become someone like him, he is my ideal man after all, but I doubt there will be always consequences here and there if I attempt to overdo myself...
Any advice please?
Edit: Sorry if I made assumptions about you being a student - that could be wrong - I apologise if that is the case :+)

Realise that it takes a long time to become an expert - I am very far from that, I envisage a lifetime of learning C++ - there are so many new things all the time.

About those who are experts, they probably have the benefit of at least a Degree, possibly Masters or even PhD. Then they may have 1-4 decades of industry experience as developers. Some of them are Lecturers.

So all that one can do is keep plugging away at it, learn things gradually by writing code, testing things. Solely reading books or reference material, while necessary might not be the only way - it's too easy for things bounce off or not be absorbed by the Noodle :+)

Don't overdo yourself - you still need to have a life. There is family, friends, sport. You also probably don't want to learn C++ at the expense of your other study in that you don't to fail the year because of it. Maybe you could allocate a certain number of hours per week for learning C++? Don't sweat it about becoming an expert, just being a little better than your peers could be a suitable goal.

Also realise that when looking at some complex code, one can usually always break it down into smaller expressions. Examine what they mean in isolation, then think about what it means as a whole. Draw pictures with actual old school pen and paper :+) If you can't figure it out, ask questions here on the forum. If someone has posted code, they would be happy to explain it.

There are different areas or paradigms of C++. There is C code; then C++ with things like overloaded functions, classes etcetera, the STL; then templates; then Template Meta Programming (TMP) IMO this is the most complicated part. So when looking at some complex code, realise it might be part of a paradigm that you are not ready for yet. Then there are things like Design Patterns - another whole area of study.

As well as all that, there are other libraries like boost for example - there is heaps of learning there too. But I would imagine one wouldn't sit down and say I am going to learn boost from beginning to end. Probably better to learn individual things as they might be needed.

Then there are frameworks like Qt - yet another lifetime of things to learn there. Then even more things like using C++ to deal with Databases - PostgreSQL for example.

So in summary, don't sweat it about being in a hurry to try to learn everything in the C++ Galaxy, one can only do so much.

Last edited on
@TheIdeasMan
Thanks so much for your sincere input.

But if I were to leave now, would you say this "Good luck :+)" to me? :)
Of course, but I hope I haven't put you off .

It's like if you wanted to become a Doctor or Dentist - there's lots of study to do, it doesn't happen in a short time. You don't have to try to be the University's top Professor by the end of the year. Also one doesn't have to be a specialist in every field - one could be a GP or a specialist in one field.

As I said you are winning if you are a little bit better than your peers.
Topic archived. No new replies allowed.
Pages: 1... 345