测试给定的数字是否为整数

13
我正在尝试实现一个用户定义的函数,用于测试一个数字是否为整数:
#include <iostream>
#include <typeinfo>
using namespace std;
bool   integer(float k){
                  if (k==20000) return false;;
                  if (k==(-20000)) return  false;
 if (k==0)  return true;
   if (k<0)  return integer(k+1);
   else if(k>0)  return integer (k-1);
   return false;
}
int main(){

    float s=23.34;
       float s1=45;
       cout<<boolalpha;
       cout<<integer(s)<<endl;
       cout<<integer(s1)<<endl;
       return 0;

}

因此,这个想法是,如果一个数字是整数,不管它是正数还是负数,如果我们增加或减少它一,我们必须得到零,但问题是,如何为增加和减少创建上限和下限?


1
我甚至不明白...为什么你认为>20000和<-20000不是整数?为什么你要从范围的中间开始比较,而不是从-20000开始呢? - tenfour
是的,你说得对。我已经把它改成了MAX_INT和MIN_INT。 - user466534
我正在阅读关于数论的部分,其中讨论了二次剩余和质数剩余根等主题,并提供了一个涉及整数术语的算法。如果某个数的平方根是整数,则它就是根的主要原因。 - user466534
2
读者们:这个主题有一个新的、非常全面的问答(https://dev59.com/_V8d5IYBdhLWcg3w41Yp),明确考虑了C++11。 - chappjc
9个回答

38
#include <cmath>

bool is_integer(float k)
{
  return std::floor(k) == k;
}

这个解决方案适用于所有可能的 k 值。我相信这是一种安全比较浮点数的情况,可以使用 ==

命名函数时应该考虑周全。 integer 不会让人知道它实际上做了什么,因此我将函数名称更改为更有意义的内容。

未来,测试一个数字是否为整数应该感觉非常简单,因此您应该有强烈的感觉,最佳解决方案将非常简单。希望您意识到您原始的解决方案因为很多原因都是荒谬的(最大的原因是:对于绝大多数情况,它会导致堆栈溢出)。


1
如果这个floor是在<math.h>中定义的double floor(double),那么这可能不起作用。对于这个floor的调用将把k转换为一个双精度浮点数,并且该函数将返回一个双精度浮点数的下取整值。最好使用float floorf(float),甚至更好的是使用<cmath>中的std::floor(float) - David Hammen
另一个可能出现问题的领域是负数,其中 floor 向远离零的方向舍入。最安全的解决方案是 return std::floor(std::abs(k)) == std::abs(k) - David Hammen
8
为什么这会导致问题?如果它是整数,它就不会被取整。如果它不是整数,无论它被取整到哪里,只要它不等于原来的值,都没有关系,而它又不可能等于原来的值。 - tenfour
这将返回 std::numeric_limits<float>::infinity() 的真值。 - WorldSEnder

12

为什么不直接这样做:

bool integer(float k)
{
    return k == (float)(int)k;
}

(当然可以使用适当的 C++ 类型转换。)


请注意,对于足够大的整数(例如1e100),此操作将返回“false”。(并不是说用户想要的在一般情况下都可以使用浮点数实现。) - Mat
真实的(除了你实际上无法将1e100表示为单精度浮点数!)- 我想对于大多数用例来说,它已经足够好了。 - Paul R
1
@Mat:实际上,对于足够大的k值(绝对值大约为INT_MAX),它具有未定义的行为。 - Steve Jessop

5

这种方法行不通,因为对于足够大的浮点数,x-1 == x

你应该测试浮点数的位模式,以检查小数部分是否为0。


此外,应避免使用递归,因为它是一种非常慢的方法,而且对于|x| -> inf,x+/-1==x。 - Alexey Frunze
2
在几乎所有情况下,这将导致堆栈溢出。 - tenfour

1

它在 limit.h 宏中设置为 INT_MAX(表示最大值)或 INT_MIN(表示最小值),用于整数。

正确答案

 bool integer(float k)
    {
        if( k == (int) k) return true;
        return false;
    }

你是真的建议他在函数中使用这些常量吗?你看到它的作用了吗? - tenfour
不,用户正在询问上限和下限.. :-/ 所以我按照这样的答案回答了。 - Aman Agarwal

1
我们可以使用 math.h 中的 trunc 方法。
#include <math.h>

inline bool IsInt(float n)
{
    return !(n - trunc(n));
}

1
我想到了一种更简单的方法。
考虑一个浮点数,比如1.5。这个数的底部(即1)和顶部(即2)是不同的。对于任何具有小数部分的值都是如此。
另一方面,整数的底部和顶部值相同。因此,检查数字的顶部和底部值将变得容易,从而看到它是否为整数。
#include <cmath>

bool is_integer(float n){
 int c = ceil(n);
 int f = floor(n);
 if(f==c){
  return true;
 } else {
  return false;
 }
}

0
你可以直接使用boost lexical cast头文件。
  bool isinteger(float k){
  try{ 
      int tmp = boost::lexical_cast<int>(k);
      (void*) tmp;
      return true;
  }catch(boost::bad_lexical_cast &c){
  return false;
  }  

boost函数很有趣。 - user466534

0

以下是您问题的可用代码

bool isInteger( double num ) {
    int n = int(num);
    return (num - n == 0);
}

现在我将尝试通过两个边角案例来解释我的代码

案例1给定要检查的数字= 1.10。因此num = 1.10,n = 1。但是,现在num-n = 0.10,这不等于0。因此,代码结果为false!

案例2给定要检查的数字= 1。因此num = 1,n = 1。但是,现在num-n = 0,这等于0。因此,代码结果为true!


你好,你能否给你的回答添加解释? - CharybdeBE
虽然仅提供代码的答案可能回答了问题,但是通过为您的代码提供上下文、解释代码工作原理的原因以及一些参考文献来进一步阅读,您可以显著提高答案的质量。从[答案]:“简洁是可以接受的,但更详细的解释更好。” - Pranav Hosangadi
好的,谢谢大家,我会给它添加一些注释! - mahaturbotorque

-1

嗯,为什么不只是这样呢?

#include <iostream>
using namespace std;
bool is_integer(float check){
        if (int(check) == check)
                return true;
        else return false;
}
int main()
{
        float input;
        cin >> input;
        if (is_integer(input))
        cout << endl << "It's an integer";
        else cout << endl <<" Not an integer";
        return 0;
}

2
你的回答“int(check) == check”的要点已经在其他答案中提到,没有添加任何新内容。 - WorldSEnder
好的!我的错,我没有看到其他帖子。-_- - user5864689

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接