【问题标题】:How to remove negative Zeros from c++ codes?如何从 C++ 代码中删除负零?
【发布时间】:2015-11-08 14:47:44
【问题描述】:

如何去除 c/c++ 中的“负零”? 我正在尝试这个-

#define isEq(a, b) ((abs(a-b)<EPS) ? 1 : 0)
#define NegZero(x) (x = isEq(x, -0.0) ? 0 : x)

是否安全且安全? 或者 还有其他简单安全的方法吗? 专门用于竞赛编码。 请帮忙....

【问题讨论】:

  • x == 0 &amp;&amp; signbit(x) 怎么样?
  • 安全吗?不,因为它是一个宏。如果您想要安全,请使用内联函数。
  • 没有C/C++语言!选择一个。
  • 了解为什么您要删除它们可能会有所帮助。你能举一个你遇到的问题的例子,解决方案是将负零变成正零吗?目前,我只写static inline NegZero(double x) { if (x == 0.0) { return 0.0; } else { return x; } },因为AFAIK、-0.0 == +0.0 在C 和C++ 中必须始终为真。
  • @Olaf: EPS 可能代表“Epsilon”,按照惯例,它标识了一个(通常很小的)值,它定义了一个差异的阈值,例如,a一般限制:en.wikipedia.org/wiki/%28%CE%B5,_%CE%B4%29-definition_of_limit

标签: c++ macros negative-zero


【解决方案1】:

使用您在 cmets 中发布的代码,您的方法似乎是正确的:您的答案是一个非常接近于零的负数,并且因为您将其四舍五入为三位数(使用 printf("... %.3lf ...", ...)),它看起来像-0.000。您的方法(使用abs(a - b) &lt; epsilon 检查它是否接近0.0;如果是,则使用0.0,否则使用值本身)大部分是正确的,除了宏不完全适合的问题。

而不是写

printf("(%.3lf,%.3lf)\n", I1.x, I1.y);

我建议使用类似的东西

printf(
    "(%.3lf,%.3lf)\n",
    NegZero(I1.x),
    NegZero(I1.y)
);

并定义(虽然我会选择不同的名称)

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;
    }
}

(混淆 cmets 的原因是在 IEEE 浮点运算中实际上有一个叫做负零的东西。如果是这样的话,建议的解决方案会奏效。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 2014-10-06
    • 2014-10-12
    • 2016-07-27
    • 1970-01-01
    相关资源
    最近更新 更多