How to remove negative Zeros from c++ codes? - c++

How to remove "negative zero" in c/c++?
I am trying this-
#define isEq(a, b) ((abs(a-b)<EPS) ? 1 : 0)
#define NegZero(x) (x = isEq(x, -0.0) ? 0 : x)
Is it okay and safe?
or
is there any other easy and safe way?
Specially for contest coding.
please help....

With the code you posted in your comments, your approach seems correct: your answer is a negative number that is very close to zero, and because you're rounding it to three digits (using printf("... %.3lf ...", ...)), it looks like -0.000. Your approach (check if it's close to 0.0 using abs(a - b) < epsilon; if it is, use 0.0, otherwise use the value itself) is mostly correct, except for the issue that macros aren't exactly a good fit.
Rather than writing
printf("(%.3lf,%.3lf)\n", I1.x, I1.y);
I would suggest using something like
printf(
"(%.3lf,%.3lf)\n",
NegZero(I1.x),
NegZero(I1.y)
);
and define (although I'd pick different names)
static inline bool isEq(double x, double y) {
return abs(x, y) < EPS;
}
static inline NegZero(double x) {
if (isEq(x, 0.0)) {
return 0.0;
} else {
return x;
}
}
(The reason for the confused comments is that there actually is something called negative zero in IEEE floating point arithmetic. If that were the case, the suggested solutions would have worked.)

Related

Why would someone write an if condition containing a float like this?

I am looking through some code previously written by a senior developer in my company and I am curious about the reasoning behind the somewhat convoluted looking if statement they wrote (I would ask them directly if possible).
The code is intended to check if temperature readings from a sensor are valid. I believe negative readings were valid at the time, which explains the use of std::abs() and comparison of that to 0.000001 instead of just using temperature > 0, however I am unsure why they chose to subtract 0. as well. I have included a minimum working example, but the focus of my question is on why the statement includes the - 0. (just to convert float to a double? That seems to be what VSCode thinks it does) and if my assumption about needing to accept negative values while also needing to invalidate (very near) zero readings in the form of floats sounds correct.
#include <optional>
#include <iostream>
void check_temp(std::optional<float> prev_temp, float cur_temp){
if ((!prev_temp && std::abs(cur_temp - 0.) < 1e-6) ||
(prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0))
{
std::cout << "Temperature error detected!\n";
}
return;
}
int main(int argc, char const *argv[])
{
std::optional<float> prev_temp = std::nullopt;
float cur_temp = 0;
while(1){
std::cout << "Enter temp: ";
std::cin >> cur_temp;
check_temp(prev_temp, cur_temp);
prev_temp = cur_temp;
}
return 0;
}
And to be very clear, the specific line (condition) I am looking for clarification on is:
(!prev_temp && std::abs(cur_temp - 0.) < 1e-6)
clarification on:
(!prev_temp && std::abs(cur_temp - 0.) < 1e-6)
!prev_temp certainly tests if a previous temperature exist. Since it does not (in this clause), code continues "as if" previous temperature was zero. The subtraction with 0.0 instead of 0.0f is an oversight on the original programming. The same functionality and simpler code would have been std::abs(cur_temp - 0.0f) for illustrative purposes.
There is no reason for a double constant 1.0e-6 except for a pedantic compare against 1.0e-6 vs 1.0e-6f - which are different values. IOWs, 1.0e-6f < 1.0e-6 might be true, so the equivalent replacement is std::abs(cur_temp) <= 1e-6f - note the <=.
The compare against the double 100.0 again is weak programming. Nothing gain by using double. It might not emit different code had is been 100.f with a good optimizing compiler.
IMHO
if ((!prev_temp && std::abs(cur_temp - 0.) < 1e-6) ||
(prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0))
better as
if ((!prev_temp && std::abs(0.0f - cur_temp) < 1e-6f) ||
(prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0f))
The only reason I see for masterfully coding in this fashion is to try to steer the compiler output. Such coding applies to the compiler of that vintage. Better now to code for clarity.

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.

Prevent non-integer division

I am writing a Qt application as a hobby that prompts users to answer basic arithmetic questions using the add, minus, multiply and divide operators. The questions are generated, and everytime a question is correctly answered new operands are generated and a new operator used.
In some cases, a question might come up as '4 / 5' or '3 / 2' which implies the answer is a non-integer value to be entered. A requirement that I've set is that there are no irrational numbers in the program at all: that means no irrational answers, operands, operators or whatnot.
In my class I have a validator function which validates every question that's generated.
void ArQuestion::validate()
{
int answer = getActualAnswer();
if ((pOperand2 % 2 != 0) ||
pOperator == operators::DIVIDE)
{
if (static_cast<int>(answer) != answer)
{
generate();
}
}
}
Where getActualAnswer() retrieves the actual answer of the question.
Unfortunately my validator isn't working, and presumably the static_cast trick isn't working either. When I run the program there are still questions that ask irrational division questions (questions which produce irrational answers). What I want the validator to do is function in a way that prevents questions (only under division questions) from asking irrationally such as '3 / 4' or '7 / 9'. If the question is irrational, then it should generate a new question.
My question is thus: what algorithm is there for me to prevent non-integer division questions from being asked?
This should be fairly reliable,
bool quotient_is_integral(double n, double d)
{
double dummy;
return std::modf(n/d, &dummy) == 0.0;
}
What you're looking for is a way to determine if a division problem returns an integer answer, here's a small function to do it.
#include <iostream>
#include <cmath>
#include <limits>
bool check(double l, double r)
{
double real_answer = l / r;
int target_answer = static_cast<int>(real_answer);
double checked_answer = target_answer;
if(std::fabs(real_answer - checked_answer) > std::numeric_limits<double>::min())
{
std::cout << "Invalid.\n";
return false;
}
return true;
}

Comparing double error C++

recently I bump into a problem while comparing a double in an if statement. I was trying to cout the number of whole numbers in a double. Being a beginner, I am not sure what gone wrong in my code.
This is my code:
#include <iostream>
using namespace std;
int main(){
int x=0;//convert double to int
long double Out;//Result
long double In=10;//Input double
//Loop Begin
while(In>0){
x=In;//convert double to int
Out= (x/In);//Out(test if whole number, will return 1)
//test for 1
////////////////
if(Out == 1 ){
cout<<"[Whole Number] ";
}
////////////////
//test end
cout<<"In :"<<In<<", ";
cout<<"X :"<<x<<", ";
cout<<"Out :"<<Out<<endl;
In-=0.1;//decrease to finish loop (eventually)
}
//Loop End
cin.get();
return 0;
}
This program will test and output the whole numbers in the double (In). I realized that the accuracy of the double was affecting the if statement which is why I can't get the "[Whole Number]" result. Although I found out that if I used (0.9999) in "if(Out >= 0.9999)" the comparison would work. But I am not sure of a solution, please help! Much appreciated!
Your while loop never stops , its a infinite loop . You are not doing anything with the value of "In" in the while loop hence it will always be greater than 0 ,therefore a infinite loop .
You should probably approach the problem more directly with modf:
double int_part, frac_part;
frac_part = std::modf(in, &int_part);
if (frac_part == 0) {
// int_part contains integer value.
} else {
// process the double non-integer floating point value.
}
Your code works perfectly fine. If you subtract 0.1 from 10.0, then chances are that the result is not an integer due to rounding errors, and your code tells you exactly that. The code isn't wrong, your expectations are wrong.
if (Out >= 0.9999)
is obviously not a solution, because it will always be true if In >= 10000.0.
Do to the way floating point numbers are converted to binary representation by the computer they are inherently inaccurate and thus make logical comparisons somewhat challenging (http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems). When performing such comparisons to floating point numbers you typically will do so utilizing an epsilon constant (http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm) that represents the maximum acceptable error in the comparison. In your case you need to select a suitable value for epsilon (say .000001). Then change your comparison to:
if(abs(out - 1) < epsilon){ //Take the difference between out and 1
cout<<"[Whole Number]"; //If it is "close enough" print to console
}
I am more of a Java guy but I believe you will need #include stdlib.h to utilize the abs() function.
Hope that helps!
Try using the modulus operator: http://www.cprogramming.com/tutorial/modulus.html
Something like if(In % 1 == 0) should work.

C++ translated to objective-C

I'm looking into translating some code from C++ to Objective C and I ran into an instance that contains a function with a const notation at the end. I'm quite rusty on C++ and I don't remember what this would represent (I have been googling though). I'd like to know how to force this over to Objective-C. Currently, here's what I have:
C++ code:
float RenderingEngine1::RotationDirection() const
{
float delta = m_desiredAngle - m_currentAngle;
if (delta == 0)
return 0;
bool counterclockwise = ((delta > 0 && delta <= 180) || (delta < -180));
return counterclockwise ? +1 : -1;
}
Objective-C:
-(float)getRotationDirection{
float delta = desiredAngle - currentAngle;
if (delta == 0) {
return 0;
}
bool counterclockwise = ((delta > 0 && delta <= 180) || (delta < -180));
float test = counterclockwise ? +1 : -1;
NSLog(#"%f",test );
return counterclockwise ? +1 : -1; //problem
}
Edit: found the error of my ways and it was just an addition problem somewhere else in the program ('I love the easy ones'). That being said, I do want to ensure that the const declaration will not interfere with any further issues and want to check to ensure whether or not there should be any declarations I need to make (such as singleton methods and such). Thank you guys for the answers!
const in c++ means that this method doesn't alter the state of the object, thus it may use just const methods, and it can't alter class variables unless they're declared mutable.
If your class is immutable, you can safely assume that every method you've declared is the equivalent of a const method.
However, since you aren't altering any ivar, you're "translating" the code properly (logically speaking), as you aren't mutating any ivar.
I don't see any particular problem with your code, there shouldn't be a syntax (neither semantic) error.
PS: That's not how you should compare floating point numbers, look here.