-3

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....

NAbdulla
  • 85
  • 7
  • 4
    How about `x == 0 && signbit(x)`? – Oliver Charlesworth Nov 08 '15 at 14:53
  • 2
    Is it safe? No, since it's a macro. If you want safe, use an inline function. – Emil Laine Nov 08 '15 at 14:55
  • 1
    There is no language C/C++! Pick one. – too honest for this site Nov 08 '15 at 15:01
  • It might help to know *why* you want to remove them. Can you give an example of a problem you're getting, where the solution would be to turn a negative zero into a positive one? For the time being, I'd just write `static inline NegZero(double x) { if (x == 0.0) { return 0.0; } else { return x; } }`, because AFAIK, `-0.0 == +0.0` must always be true in C and C++. –  Nov 08 '15 at 15:20
  • @Olaf: `EPS` probably stands for "*Epsilon*", which by convention identifies a (typically small) value which defines a thresh hold for a difference for example, a limit in general: https://en.wikipedia.org/wiki/%28%CE%B5,_%CE%B4%29-definition_of_limit – alk Nov 08 '15 at 15:25
  • @alk: I anticipated that. But that would be different, depending for `float`, `double` and `long double`. – too honest for this site Nov 08 '15 at 15:27
  • Why? Appropriate casting could be applied by the compiler. @Olaf – alk Nov 08 '15 at 15:29
  • The bug in the code is the usage of `abs()` which returns `int`. – alk Nov 08 '15 at 15:30
  • @alk: And the compiler would also use the correct value? Note this depends on the type of the argument."epsilon" is a well-defined term in float context. That's why I asked OP to clarify. – too honest for this site Nov 08 '15 at 15:32
  • However, as it stands, this all does not make sense (see my last comment). At least not for `EPS` being `>-1` and `<1`. – alk Nov 08 '15 at 15:36
  • @Rhymoid I am trying to solve [this problem](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=394) and my code is [here](http://ideone.com/47Pnvv). this code is giving -0.0 for some inputs like `-1.4 8.8 1.4 7.1 8.8 7.1`. – NAbdulla Nov 08 '15 at 17:07

1 Answers1

0

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.)