【问题标题】:Weird method to check if a float number is negative检查浮点数是否为负的奇怪方法
【发布时间】:2018-02-21 17:09:09
【问题描述】:

在一个 C++ 项目中,我看到了这个:

#include <cstdlib>
#include <cstdio>

static int isNegative(float arg)
{
    char p[20]; // Assume 20 is enough
    sprintf(p, "%f", arg);
    return p[0] == '-';
}

int main()
{
    printf("%d\n", isNegative(-1));
}

我听说sprintf() 可能有问题,因为它可能会导致写入p 时负号消失。真的吗?或者这种方法是防弹的(但非常糟糕的做法)?


PS:忽略-0 的小写。关注sprintf()。我知道存在更好的解决方案,但我只是对这个感到好奇。也欢迎来自 C 的人提供帮助。

【问题讨论】:

  • “或者那个方法是防弹的” 不,不是(还是昨天的样子)。
  • std::signbit "此函数检测零、无穷大和 NaN 的符号位。与 std::copysign 一起,std::signbit 是仅有的两种检查符号的可移植方法之一一个 NaN。”
  • 我有一种似曾相识的奇怪感觉
  • 这是一个测试来显示审稿人是否在关注吗?
  • char p[2]; snprintf(p, sizeof p, "%f", arg); return p[0] == '-'; 足以处理缓冲区大小问题。

标签: c++ c function floating-point printf


【解决方案1】:

您可以使用%+f 确保输出符号(+ 或-)(尽管无论如何都会输出-)。所以我认为对于正常的浮点值是有保证的。

我唯一关心的是特殊值:inf 和 nan。所以我在输出中添加了打印p 并做了一个实验。这是我使用 gcc 6.3 得到的:

printf("IsNegative: %d\n", isNegative(+1.0/+0.0));
printf("IsNegative: %d\n", isNegative(-1.0/+0.0));
printf("IsNegative: %d\n", isNegative(+0.0/+0.0));
printf("IsNegative: %d\n", isNegative(+0.0/-0.0));
printf("IsNegative: %d\n", isNegative(-0.0/+0.0));
printf("IsNegative: %d\n", isNegative(-0.0/-0.0));

结果:

p = +inf
IsNegative: 0
p = -inf
IsNegative: 1
p = -nan
IsNegative: 1
p = -nan
IsNegative: 1
p = -nan
IsNegative: 1
p = -nan
IsNegative: 1

结果只对 nan 看起来很奇怪,除了该方法应该有效。

【讨论】:

  • 正弦和符号是两个非常不同的东西 :) 但我完全不明白你为什么提出%+f。无论如何都会打印- 标志,这是唯一需要检查的东西,对吧?
  • @hvd,你是对的,- 无论如何都应该输出,我添加它是为了方便。例如,如果您想将p[0] 与+ 进行比较,可以使用+。
  • 不幸的是,就像 C 中的许多东西一样,测试并不能证明任何事情。我不希望这在不同的系统上是可靠的方法,尤其是在负 nan 的情况下。
  • @user694733,同意 nan,它可以是编译器/架构/...依赖。我不知道有关它的任何文档。但如果它不适用于“正常”浮动,那就太奇怪了。
  • @gsamaras,如你所愿,我不会感到沮丧 :) 的确,这个问题在实践中并不是非常有用,但同时我不认为它完全没用。
猜你喜欢
  • 1970-01-01
  • 2011-08-13
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多