Below is the code in C++,
Num *= other.Den;
Den *= other.Num;
if (Den.isNegative()) {
Num = -Num;
Den = -Den;
}
assert(Den.isStrictlyPositive());
where Num and Den are of type LLVM::APInt.
For some reason I am getting the assertion failed. I have checked if the Denominator is negative explicitly and turned it positive. Can someone please let me in what scenario in this code, the assertion can fail? When I run my code against test case it fails. The test case is very large, and I have not been successful in cornering a particular case. The above code is a part of my algorithm which is doing some other job.
Here is the implementation of isStrictlyPositive. It is using the LLVM library file APInt.h.
bool isStrictlyPositive() const {
return isNonNegative() && !!*this;
}
bool isNonNegative() const {
return !isNegative();
}
I'm basing this off the following assumptions:
Strictly positive means > 0
isNegative is < 0
Given the snippet you quoted, the function isStrictlyPositive boils down to:
return isNonNegative() && !!*this;
Which is equivalent to:
return !(*this < 0) && !!*this;
!!*this is equivalent to !(!*this) which is equivalent to !(*this==0) which is equivalent to *this!=0, so the expression is:
return !(*this < 0) && *this!=0;
Which can be simplified to:
return *this>=0 && *this!=0;
Which is really just:
return *this > 0;
So, your issue is that Den is 0 and is therefore not negative and not strictly positive.
0 is neither negative nor strictly positive.
Related
I know there is a very similar question already:
Ternary operator ?: vs if...else
This is more regarding returning bool literals from a function.
Given the following function:
bool inRange(size_t value, size_t upperBound) const
{
return (value >= 0 && value < upperBound) ? true : false;
}
CLion advices me this can be simplified using an "if else" statement instead.
Would this be actually faster because of return value optimization and/or likelihood of certain if branches? (or some other reason).
Or is it maybe a style guide given by CLion?
The recommendation it is suggesting is to change
bool inRange(size_t value, size_t upperBound) const
{
return (value >= 0 && value < upperBound) ? true : false;
}
to
bool inRange(size_t value, size_t upperBound) const
{
return value >= 0 && value < upperBound;
}
this has nothing to do with performance, the ternary is simply redundant. I am quite positive it would compile to the same assembly (proof), the IDE is just suggesting you simplify your redundant logic.
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.
My C++ code looks like this:
int f(int i){
if (i > 0) return 1;
if (i == 0) return 0;
if (i < 0) return -1;
}
It's working but I still get:
Warning: No return, in function returning non-void
Even though it is obvious that all cases are covered. Is there any way to handle this in "proper" way?
The compiler doesn't grasp that the if conditions cover all possible conditions. Therefore, it thinks the execution flow can still fall through past all ifs.
Because either of these conditions assume the others to be false, you can write it like this:
int f(int i) {
if (i > 0) return 1;
else if (i == 0) return 0;
else return -1;
}
And because a return statement finally terminates a function, we can shorten it to this:
int f(int i) {
if (i > 0) return 1;
if (i == 0) return 0;
return -1;
}
Note the lack of the two elses.
Is there any way to handle this in "proper" way?
A simple fix is to get rid of the last if. Since the first two are either called or not the third case must be called if you get to it
int f(int i){
if (i > 0) return 1;
if (i == 0) return 0;
return -1;
}
The reason we have to do this is that the compiler cannot guarantee that your if statements will be called in every case. Since it reaches the end of the function and it might not have executed any of the if statements it issues the warning.
Just help the compiler to understand your code. Rewrite the function the following way
int f(int i){
if (i > 0) return 1;
else if (i == 0) return 0;
else return -1;
}
you could also write the function for example like
int f( int i )
{
return i == 0 ? 0 : ( i < 0 ? -1 : 1 );
}
Another way to write the function in one line is the following
int f( int i )
{
return ( i > 0 ) - ( i < 0 );
}
The compiler doesn't know that all options are covered, because in terms of your function's syntax there's nothing to suggest it.
A simplified example:
int f(int i)
if if if
(int > int), return (int == int), return (int < int), return
A clearer structure like if/else with a return in each yields an Abstract-Syntax-Tree which clearly shows there's a return in each case. Yours, however, is dependent on the evaluation of nodes in the AST, which isn't covered in the syntax check (by which you're being issued a warning).
Beyond pure syntax, if the compiler were to rely on "possible" evaluations as well in trying to figure out the behavior of your program, it would ultimately need to entangle itself and probably hitting the halting problem. Even if it managed to cover some cases, this would probably spawn more questions from users than it would answer, and also risk an entirely new level of bugs.
Sorry for the poor explanatory title, I'm not able to find a better one (yet).
I'm used to code boolean expressions adding some temporary variables to improve the reading of an expression, in other words I dislike this:
// Example 1
// hard to read and understand at first glance
if (value % 2 && value ^ weirdFlags &&
(value > threshold) && (value < ceiling) &&
/* lots of comparisions */)
{ /* do something*/ }
And prefer this:
// Example 2
// this is way easier to read and understand
const bool isEven = value % 2;
const bool flagsChecked = value ^ weirdFlags;
const bool inRange = (value > threshold) && (value < ceiling);
const bool foo = /* lots of comparisions */;
if (isEven && flagsChecked && inRange && foo)
{ /* do something*/ }
But using my favorite coding style, I'm not taking advantage of the lazy logic optimizations because all the temporary values are computed, while with the other coding style only the imprescindible is computed.
There's another solution, that grants the use of the lazy logic optimizations and keeps the code readable, that is comment the code:
// Example 3
// this check test if the value is an even number
// and checks the value with the provided flags
// and assures that the value is in the required range
// and lots of additional comparisions
if (value % 2 && value ^ weirdFlags &&
(value > threshold) && (value < ceiling) &&
/* lots of comparisions */)
{ /* do something*/ }
But there's no warranties about the code comments matches the code below during the code development while a team of programmers are coding day by day the same source file (not all the coders care about the good documentation). That's why I preffer that the code explains itself in a neat way.
So, finally, studying the Example 2 case, that declares temporary values as const, only use them in the boolean expression, in the same scope of the expression and close to the expression itself, the questions are:
In the Example 2, will the compiler perform some kind of optimizations involving the temporary values in order to improve the performance of the boolean expression (lazy evaluation)?
In your own opinion, which of the three examples is the most correct? why?
Thanks for the advice.
Check this out:
if(const bool isEven = value % 2)
if(const bool flagsChecked = value ^ weirdFlags)
if(const bool inRange = (value > threshold) && (value < ceiling))
if(const bool foo = /* lots of comparisions */)
{
/* do something*/
}
Magic!
I always prefer readability over premature optimization until it is proved to be a performance bottleneck.
So in this case example 2. Something else you could do to that is this:
bool Class::isSomething() {
const bool isEven = value % 2;
if(!isEven) return false;
const bool flagsChecked = value ^ weirdFlags;
if(!flagsChecked) return false;
const bool inRange = (value > threshold) && (value < ceiling);
if(!inRange) return false;
const bool foo = /* lots of comparisions */;
if(!foo) return false;
return true;
}
I'm facing an issue regarding the translation in C++ of a bunch of source code written in Visual Basic. In the code there is a call to the method Sign (VB) and various conversions of float to integer... Could you confirm that c++ code for 1, 2, 3 are the same as the VB one? In addition about the implicit conversion I've no idea how the conversion is performed (See 4). Any idea?
1) Method Sign (Visual Basic)
//C++
int sign(float value)
{
if (value < 0) return -1;
else if (value == 0) return 0;
else return 1;
}
2) Method Int (Visual Basic)
//C++
int Int(float value)
{
return ((value >= 0) ? value : floor(value));
}
3) Method CInt (Visual Basic)
//C++
int CInt(const float val)
{
float x = fabs(val - (int)val);
if (fabs(x - 0.5) < 0.0001)
return (int)val;
else
return (int)(val+(val>=0.0?0.5:-0.5));
}
4) And there is also an implicit conversion of double to int. How to make this conversion in c++?
//Visual basic
Dim dt As Integer = -99.2
Thanks you in advance,
1-
It is not the same, floating point values should not be compared to a constant variable (0, in this example). So, this is a better code for it:
const float epsilon = 0.00001f;
if(value < -epsilon) return -1;
if(value > epsilon) return 1;
return 0;
2- It depends on what you want for, for example -5.7. If you want -5, just cast away using (int). for example, if you have a float variable named f, use (int)f. If you want -6, use this function:
int Int(float value)
{
return ((value >= 0) ? (int)value : (int)(value-1));
}
3- It should work but last return statement could be made clearer:
return (int)val + (val>=0.0?1:-1)
4- Doubles are very very similar to floats in C/C++. Do as if you're messing with a float, not double.