Removing Virtual Inheritance - c++

I am working on an embedded project I am trying to remove a virtual number class that has + / - * implemented. removing this class saves a lot of code space so I have replaced + with the following function,
if (BASE(h)->type() == FLOAT && BASE(v)->type() == FLOAT)
{
res = FLOAT(h)->floatValue() + FLOAT(v)->floatValue();
}
else if (BASE(h)->type() == INTEGER && BASE(v)->type() == INTEGER)
{
res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
}
else if (BASE(h)->type() == INTEGER && BASE(v)->type() == FLOAT)
{
res = INTEGER(h)->floatValue() + FLOAT(v)->floatValue();
}
else
{
res = FLOAT(h)->floatValue() + INTEGER(v)->floatValue();
}
Is there a less uglier way to achieve this? cause I have to use the same scheme for other ops and comparison?

#define GETFLOAT(arg) (BASE(arg)->type() == INTEGER ? INTEGER(arg)->floatValue() : FLOAT(arg)->floatValue())
switch(BASE(h)->type()) {
case INTEGER:
if (BASE(v)->type() == INTEGER) {
res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
break;
}
case FLOAT:
res = GETFLOAT(h) + GETFLOAT(v);
}
This actually branches on the type of h twice, but only in the case that (you say in a comment elsewhere) is expensive anyway, the floating-point op. You could avoid that with a goto, but I'm not going to have that argument again. Something like:
switch(BASE(h)->type()) {
case INTEGER:
if (BASE(v)->type() == INTEGER) {
res = INTEGER(h)->intValue() + INTEGER(v)->intValue();
goto finished; // or better: return res;
}
hvalue = INTEGER(h)->floatValue()
break;
case FLOAT:
hvalue = FLOAT(h)->floatValue();
}
res = hvalue + GETFLOAT(v);
finished:
As with Howard's answer, if BASE() or type() is expensive then you could calculate the answer for each argument once, even though it's used twice.

What about doing it in two steps?
isInt1 = BASE(h)->type()==INTEGER;
isInt2 = BASE(v)->type()==INTEGER;
if (isInt1 && isInt2)
op1 = INTEGER(h)->intValue();
op2 = INTEGER(h)->intValue();
res = op1 + op2;
else {
op1 = isInt1 ? (FLOAT(h)->floatValue()) : (INTEGER(h)->floatValue());
op2 = isInt2 ? (FLOAT(v)->floatValue()) : (INTEGER(v)->floatValue());
res = op1 + op2;
}

I recommend reconsidering your architecture. How much have you saved with this approach, and how much has it cost in performance? Your new approach appears pushes everything to a float (you didn't show the declaration of res, which I presume is float res;.
Examine what this fix does to something like (a+b)*c, where each of a, b, and c are (were) integers. With this fix at hand, you now have a float times an int, which is a lot more expensive computationally than an int times an int.
I suggest using templates and letting C++ type system handle as much of the conversion as possible. This lets you use disparate storage types that don't have to have common virtual base class.
You can also cut down on program size by implementing only one of int+float versus float+int (and similarly with int*float versus float*int). Temporarily implement both int+float and float+int, but intentionally make one raise a compile-time error. Flip the order of the operands where you get failures.

Related

Efficiently preventing duplicate accesses

I have a statement computing a multiply-accumulate operation that looks something like this:
return A->set(A->get() + B->get() * C->get());
Now, A, B, and C may not be unique, and I want to minimize redundant get()s. The only way I can think of optimizing this is with
if (A == B && B == C) {
double a = A->get();
return A->set(a + a * a);
} else if (A == B) {
double a = A->get();
return A->set(a + a * C->get());
} else if (A == C) {
double a = A->get();
return A->set(a + B->get() * a);
} else if (B == C) {
double b = B->get();
return A->set(A->get() + b * b);
} else {
return A->set(A->get() + B->get() * C->get());
}
Is there a more efficient way? What about generalizing this to more than three arguments??
You can store them in a map. The solution can be extended easily to arbitrarily many pointers, but I've used three here for concreteness.
std::unordered_map<MyType *, double> computed_values;
for (MyType *p: {A, B, C}) {
if (computed_values.find(p) == computed_values.end()) {
computed_values[p] = p->get();
}
}
double result = computed_values[A] + computed_values[B] * computed_values[C];
A->set(result);
As others have pointed out, make sure you profile to make sure this is actually worth the overhead of std::unordered_map lookups.
Assuming get() methods are really costly to the extent of producing measurable performance difference,
double a,b,c;
a = A->get();
b = (B==A?a:B->get());
c = (C==B?b:(C==A?a:c->get()));
return A->set(a+b*c);
Assuming the get() methods are reasonably cheap, you'd be better off just doing:
return A->set(A->get() + B->get() * C->get());
The other approach simply inserts a bunch of conditional jumps into your code, which could easily end up being more expensive than the original code.

How to safely compare two unsigned integer counters?

We have two unsigned counters, and we need to compare them to check for some error conditions:
uint32_t a, b;
// a increased in some conditions
// b increased in some conditions
if (a/2 > b) {
perror("Error happened!");
return -1;
}
The problem is that a and b will overflow some day. If a overflowed, it's still OK. But if b overflowed, it would be a false alarm. How to make this check bulletproof?
I know making a and b uint64_t would delay this false-alarm. but it still could not completely fix this issue.
===============
Let me clarify a little bit: the counters are used to tracking memory allocations, and this problem is found in dmalloc/chunk.c:
#if LOG_PNT_SEEN_COUNT
/*
* We divide by 2 here because realloc which returns the same
* pointer will seen_c += 2. However, it will never be more than
* twice the iteration value. We divide by two to not overflow
* iter_c * 2.
*/
if (slot_p->sa_seen_c / 2 > _dmalloc_iter_c) {
dmalloc_errno = ERROR_SLOT_CORRUPT;
return 0;
}
#endif
I think you misinterpreted the comment in the code:
We divide by two to not overflow iter_c * 2.
No matter where the values are coming from, it is safe to write a/2 but it is not safe to write a*2. Whatever unsigned type you are using, you can always divide a number by two while multiplying may result in overflow.
If the condition would be written like this:
if (slot_p->sa_seen_c > _dmalloc_iter_c * 2) {
then roughly half of the input would cause a wrong condition. That being said, if you worry about counters overflowing, you could wrap them in a class:
class check {
unsigned a = 0;
unsigned b = 0;
bool odd = true;
void normalize() {
auto m = std::min(a,b);
a -= m;
b -= m;
}
public:
void incr_a(){
if (odd) ++a;
odd = !odd;
normalize();
}
void incr_b(){
++b;
normalize();
}
bool check() const { return a > b;}
}
Note that to avoid the overflow completely you have to take additional measures, but if a and b are increased more or less the same amount this might be fine already.
The posted code actually doesn’t seem to use counters that may wrap around.
What the comment in the code is saying is that it is safer to compare a/2 > b instead of a > 2*b because the latter could potentially overflow while the former cannot. This particularly true of the type of a is larger than the type of b.
Note overflows as they occur.
uint32_t a, b;
bool aof = false;
bool bof = false;
if (condition_to_increase_a()) {
a++;
aof = a == 0;
}
if (condition_to_increase_b()) {
b++;
bof = b == 0;
}
if (!bof && a/2 + aof*0x80000000 > b) {
perror("Error happened!");
return -1;
}
Each a, b interdependently have 232 + 1 different states reflecting value and conditional increment. Somehow, more than an uint32_t of information is needed. Could use uint64_t, variant code paths or an auxiliary variable like the bool here.
Normalize the values as soon as they wrap by forcing them both to wrap at the same time. Maintain the difference between the two when they wrap.
Try something like this;
uint32_t a, b;
// a increased in some conditions
// b increased in some conditions
if (a or b is at the maximum value) {
if (a > b)
{
a = a-b; b = 0;
}
else
{
b = b-a; a = 0;
}
}
if (a/2 > b) {
perror("Error happened!");
return -1;
}
If even using 64 bits is not enough, then you need to code your own "var increase" method, instead of overload the ++ operator (which may mess your code if you are not careful).
The method would just reset var to '0' or other some meaningfull value.
If your intention is to ensure that action x happens no more than twice as often as action y, I would suggest doing something like:
uint32_t x_count = 0;
uint32_t scaled_y_count = 0;
void action_x(void)
{
if ((uint32_t)(scaled_y_count - x_count) > 0xFFFF0000u)
fault();
x_count++;
}
void action_y(void)
{
if ((uint32_t)(scaled_y_count - x_count) < 0xFFFF0000u)
scaled_y_count+=2;
}
In many cases, it may be desirable to reduce the constants in the comparison used when incrementing scaled_y_count so as to limit how many action_y operations can be "stored up". The above, however, should work precisely in cases where the operations remain anywhere close to balanced in a 2:1 ratio, even if the number of operations exceeds the range of uint32_t.

More general test for same order of magnitude than comparing floor(log10(abs(n)))

I am implementing an optimization algorithm and have diferent heuristics for cases where no or largely different lower and upper bounds for the solution are known or not.
To check, my first approach would be simply taking
if(abs(floor(log10(abs(LBD))) - floor(log10(abs(UBD)))) < 1 )
{ //(<1 e.g. for 6, 13)
//Bounds are sufficiently close for the serious stuff
}
else {
//We need some more black magic
}
But this requires previous checks to be gerneralized to NAN, ±INFINITY.
Also, in the case where LBD is negative and UBD positive we can't assume that the above check alone assures us that they are anywhere close to being of equal order of magnitude.
Is there a dedicated approach to this or am I stuck with this hackery?
Thanks to geza I realized that thw whole thing can be done without the log10:
A working solution is posted below, and a MWE including the log variant posted on ideone.
template <typename T> double sgn(T val) {
return double((T(0) < val) - (val < T(0)))/(val == val);
}
bool closeEnough(double LBD, double UBD, uint maxOrderDiff = 1, uint cutoffOrder = 1) {
double sgn_LBD = sgn(LBD);
double sgn_UBD = sgn(UBD);
double cutoff = pow(10, cutoffOrder);
double maxDiff = pow(10, maxOrderDiff);
if(sgn_LBD == sgn_UBD) {
if(abs(LBD)<cutoff && abs(UBD)<cutoff) return true;
return LBD<UBD && abs(UBD)<abs(LBD)*maxDiff;
}
else if(sgn_UBD > 0) {
return -LBD<cutoff && UBD<cutoff;
}
// if none of the above matches LBD >= UBD or any of the two is NAN
}
As a bonus it can take cutoffs, so if both bounds lie within [-10^cutoffOrder,+10^cutoffOrder] they are considered to be close enough!
The pow computation might also be unecessary, but at least in my case this check is not in a critical code section.
If it would be, I suppose you could just hard code the cutoff and maxDiff.

other ideas for calculating a string that contains e.g. "5 + 3 / 2"

i have written a program, where you give a string as input. this string should be a normal term e.g. "5 + 3 / 2" and all numbers and operators have to be seperated via a whitespace. the term you can type in should be as long as you want it to be, e.g. "1 * 2 * 5 - 1 * 4 + 1 + 5 + 3 + 3 + 3" should be working too. +, -, * and / are the only operators that are allowed to be used.
i have already got a working code. but it ignores the fact of * and / before + and -. but it does everything else perfectly.
the idea is it creates two arrays, one that saves the operators in a char array (called char operators[ ])and the other array saves the integers in a float array (called float values[ ]). then i have this calculation method:
void calc(float values[], char operators[]) {
float res_final;
float res_array[10];
int counter = (sizeof(values) / sizeof(*values));
for (int i = 0; i < getBorder(values); i++) {
if (i == 0) {
res_array[i] = switchFunction(values[i], values[i + 1], operators[i]);
}
res_final = switchFunction(res_array[i], values[i + 2], operators[i + 1]);
res_array[i+1] = res_final;
if (i == getBorder(values)) {
break;
}
}
std::cout << "evaluation of expression is: " << res_final << std::endl;
}
float switchFunction(float val_1, float val_2, char op) {
switch (op) {
case '+': return val_1 + val_2;
break;
case '-': return val_1 - val_2;
break;
case '*': return val_1 * val_2;
break;
case '/': return val_1 / val_2;
break;
}
return 0;
}
well the code is not really pretty, but i couldnt come up with anything more useful. i have so many ideas but it all failed when it comes to the operators. i wanted to define the normal + in '+' and for the rest too, but this wont work.
so if you have any suggestions on how to include point before line or if you have a complete different approach to mine, i would be glad to hear about it :)
In the long run, you want to create an Object that represents the formula.
A good structure would be a tree. An inner node of such a tree is an operator, while a leaf is a number.
Then you write a parser that parses a string into a tree. I'd do this recursive like this:
FormulaNode parse(input){
string left, right;
if(split_string(input, * or /, left, right){
return FormulaNode(* or /, parse(left), parse(right))
if(split_string(input, + or -, left, right){
...
}
return FormulaNode(number, to_value(string))
}
with split_string being a method that tries to split a string by a certain symbol, returns a boolean if that was possible and splits it into the references left and right,
FormulaNode(symbol, left child, right child) being a constructor that creates an inner node,
FormulaNode(number, value) being a constructor that creates a leaf.
Of course, all of this is pseudo-code, didn't want to impose a style on you, just to illustrate the principle. The second constructor might probably only be of the signature FormulaNode(const double). As for symbol, I'd recommend to create something like enumerate OperatorType {addition,...}.
EDIT:
here is a bigger architecture with a somewhat different design:
class FormulaTree{
private:
class FormulaNode{
private:
bool is_number;
//used members if is number
double value;
//used members if not is number / is operator
OperatorType type;
unique_ptr<FormulaNode> left_child, right_child;
public:
FormulaNode(string input);
double evaluate() const;
};
unique_ptr<FormulaNode> root;
public:
Formula(string input);
double evaluate() const;
}
with (in pseudo-code)
FormulaTree::FormulaNode::FormulaNode(string input){
if(input contains * or /){
char symbol = first occurence(input, * or /);
vector<string> split_input= split at first occurence(input, symbol);
type = OperatorType(symbol);
is_number = false;
left_child = make_unique(new FormulaNode(split_input[0]));
right_child = make_unique(new FormulaNode(split_input[1]));
return;
}
if(input contains + or -){
...
}
is_number = true;
value = parse to int(input);
}
(in the long run, you might also want to add something that checks if the input is legal, like "the string is not empty on one side of an operator", "parse to int worked, that is contained no illegal characters" et cetera)
(also, if you continue to expand this, you need some parser that splits it by brackets first)
If you need me to explain anything about this structure, simply ask, I'll edit.
EDIT:
Slava commented that it would be better to derive FormulaNode for the different types. This is right, and I originally edited this to show such a design, but I removed it again because it might easily confuse a beginner.
Especially since such a pattern would require a somewhat different layout - we would want to let the tree itself do the parsing since the derived classes shouldn't know each other. In the long run, you want to learn such things. I'd recommend that you try out the pattern I presented, add your own style, add some more features (like a symbol for power or the option to use a minus to denote a negative number) and then put it on CodeReview. My reasoning is that this is what you want to do anyway and when you do, your code will be attacked at every part anyway, until it's "perfect".

Custom sorting, always force 0 to back of ascending order?

Premise
This problem has a known solution (shown below actually), I'm just wondering if anyone has a more elegant algorithm or any other ideas/suggestions on how to make this more readable, efficient, or robust.
Background
I have a list of sports competitions that I need to sort in an array. Due to the nature of this array's population, 95% of the time the list will be pre sorted, so I use an improved bubble sort algorithm to sort it (since it approaches O(n) with nearly sorted lists).
The bubble sort has a helper function called CompareCompetitions that compares two competitions and returns >0 if comp1 is greater, <0 if comp2 is greater, 0 if the two are equal. The competitions are compared first by a priority field, then by game start time, and then by Home Team Name.
The priority field is the trick to this problem. It is an int that holds a positve value or 0. They are sorted with 1 being first, 2 being second, and so on with the exception that 0 or invalid values are always last.
e.g. the list of priorities
0, 0, 0, 2, 3, 1, 3, 0
would be sorted as
1, 2, 3, 3, 0, 0, 0, 0
The other little quirk, and this is important to the question, is that 95% of the time, priority will be it's default 0, because it is only changed if the user wants to manually change the sort order, which is rarely. So the most frequent case in the compare function is that priorities are equal and 0.
The Code
This is my existing compare algorithm.
int CompareCompetitions(const SWI_COMPETITION &comp1,const SWI_COMPETITION &comp2)
{
if(comp1.nPriority == comp2.nPriority)
{
//Priorities equal
//Compare start time
int ret = comp1.sStartTime24Hrs.CompareNoCase(comp2.sStartTime24Hrs);
if(ret != 0)
{
return ret; //return compare result
}else
{
//Equal so far
//Compare Home team Name
ret = comp1.sHLongName.CompareNoCase(comp2.sHLongName);
return ret;//Home team name is last field to sort by, return that value
}
}
else if(comp1.nPriority > comp2.nPriority)
{
if(comp2.nPriority <= 0)
return -1;
else
return 1;//comp1 has lower priority
}else /*(comp1.nPriority < comp2.nPriority)*/
{
if(comp1.nPriority <= 0)
return 1;
else
return -1;//comp1 one has higher priority
}
}
Question
How can this algorithm be improved?
And more importantly...
Is there a better way to force 0 to the back of the sort order?
I want to emphasize that this code seems to work just fine, but I am wondering if there is a more elegant or efficient algorithm that anyone can suggest. Remember that nPriority will almost always be 0, and the competitions will usually sort by start time or home team name, but priority must always override the other two.
Isn't it just this?
if (a==b) return other_data_compare(a, b);
if (a==0) return 1;
if (b==0) return -1;
return a - b;
You can also reduce some of the code verbosity using the trinary operator like this:
int CompareCompetitions(const SWI_COMPETITION &comp1,const SWI_COMPETITION &comp2)
{
if(comp1.nPriority == comp2.nPriority)
{
//Priorities equal
//Compare start time
int ret = comp1.sStartTime24Hrs.CompareNoCase(comp2.sStartTime24Hrs);
return ret != 0 ? ret : comp1.sHLongName.CompareNoCase(comp2.sHLongName);
}
else if(comp1.nPriority > comp2.nPriority)
return comp2.nPriority <= 0 ? -1 : 1;
else /*(comp1.nPriority < comp2.nPriority)*/
return comp1.nPriority <= 0 ? 1 : -1;
}
See?
This is much shorter and in my opinion easily read.
I know it's not what you asked for but it's also important.
Is it intended that if the case nPriority1 < 0 and nPriority2 < 0 but nPriority1 != nPriority2 the other data aren't compared?
If it isn't, I'd use something like
int nPriority1 = comp1.nPriority <= 0 ? INT_MAX : comp1.nPriority;
int nPriority2 = comp2.nPriority <= 0 ? INT_MAX : comp2.nPriority;
if (nPriority1 == nPriority2) {
// current code
} else {
return nPriority1 - nPriority2;
}
which will consider values less or equal to 0 the same as the maximum possible value.
(Note that optimizing for performance is probably not worthwhile if you consider that there are insensitive comparisons in the most common path.)
If you can, it seems like modifying the priority scheme would be the most elegant, so that you could just sort normally. For example, instead of storing a default priority as 0, store it as 999, and cap user defined priorities at 998. Then you won't have to deal with the special case anymore, and your compare function can have a more straightforward structure, with no nesting of if's:
(pseudocode)
if (priority1 < priority2) return -1;
if (priority1 > priority2) return 1;
if (startTime1 < startTime2) return -1;
if (startTime1 > startTime2) return 1;
if (teamName1 < teamName2) return -1;
if (teamName1 > teamName2) return -1;
return 0; // exact match!
I think the inelegance you feel about your solution comes from duplicate code for the zero priority exception. The Pragmatic Programmer explains that each piece of information in your source should be defined in "one true" place. To the naive programmer reading your function, you want the exception to stand-out, separate from the other logic, in one place, so that it is readily understandable. How about this?
if(comp1.nPriority == comp2.nPriority)
{
// unchanged
}
else
{
int result, lowerPriority;
if(comp1.nPriority > comp2.nPriority)
{
result = 1;
lowerPriority = comp2.nPriority;
}
else
{
result = -1;
lowerPriority = comp1.nPriority;
}
// zero is an exception: always goes last
if(lowerPriority == 0)
result = -result;
return result;
}
I Java-ized it, but the approach will work fine in C++:
int CompareCompetitions(Competition comp1, Competition comp2) {
int n = comparePriorities(comp1.nPriority, comp2.nPriority);
if (n != 0)
return n;
n = comp1.sStartTime24Hrs.compareToIgnoreCase(comp2.sStartTime24Hrs);
if (n != 0)
return n;
n = comp1.sHLongName.compareToIgnoreCase(comp2.sHLongName);
return n;
}
private int comparePriorities(Integer a, Integer b) {
if (a == b)
return 0;
if (a <= 0)
return -1;
if (b <= 0)
return 1;
return a - b;
}
Basically, just extract the special-handling-for-zero behavior into its own function, and iterate along the fields in sort-priority order, returning as soon as you have a nonzero.
As long as the highest priority is not larger than INT_MAX/2, you could do
#include <climits>
const int bound = INT_MAX/2;
int pri1 = (comp1.nPriority + bound) % (bound + 1);
int pri2 = (comp2.nPriority + bound) % (bound + 1);
This will turn priority 0 into bound and shift all other priorities down by 1. The advantage is that you avoid comparisons and make the remainder of the code look more natural.
In response to your comment, here is a complete solution that avoids the translation in the 95% case where priorities are equal. Note, however, that your concern over this is misplaced since this tiny overhead is negligible with respect to the overall complexity of this case, since the equal-priorities case involves at the very least a function call to the time comparison method and at worst an additional call to the name comparator, which is surely at least an order of magnitude slower than whatever you do to compare the priorities. If you are really concerned about efficiency, go ahead and experiment. I predict that the difference between the worst-performing and best-performing suggestions made in this thread won't be more than 2%.
#include <climits>
int CompareCompetitions(const SWI_COMPETITION &comp1,const SWI_COMPETITION &comp2)
{
if(comp1.nPriority == comp2.nPriority)
if(int ret = comp1.sStartTime24Hrs.CompareNoCase(comp2.sStartTime24Hrs))
return ret;
else
return comp1.sHLongName.CompareNoCase(comp2.sHLongName);
const int bound = INT_MAX/2;
int pri1 = (comp1.nPriority + bound) % (bound + 1);
int pri2 = (comp2.nPriority + bound) % (bound + 1);
return pri1 > pri2 ? 1 : -1;
}
Depending on your compiler/hardware, you might be able to squeeze out a few more cycles by replacing the last line with
return (pri1 > pri2) * 2 - 1;
or
return (pri1-pri2 > 0) * 2 - 1;
or (assuming 2's complement)
return ((pri1-pri2) >> (CHAR_BIT*sizeof(int) - 1)) | 1;
Final comment: Do you really want CompareCompetitions to return 1,-1,0 ? If all you need it for is bubble sort, you would be better off with a function returning a bool (true if comp1 is ">=" comp2 and false otherwise). This would simplify (albeit slightly) the code of CompareCompetitions as well as the code of the bubble sorter. On the other hand, it would make CompareCompetitions less general-purpose.