如何判断一个浮点数是整数,要精确计算啊。

时间:2023-01-08 09:45:21
即便结果应该是5.0,可能精度问题就是4.9999999991,那么怎么判断一个浮点数是整数呢.

18 个解决方案

#1


没明白啥意思,看他内存地址中低位的值吧

#2


我举个例子:
比如输入int a,b;
计算double ret=a/b;
判断ret是否为整数.

就是这么一个问题.

#3


好像挺复杂

#4


这个应该列入数学问题,即如何判断一个自然数n等于一个实数a。

设定一个无穷小的delta, 如果|a-n|<delta 则认为相等。

在计算机中,可以考虑浮点数的精度作为delta。

将|a-n|的差值,乘以2的64次方,小于1,即认为a=n。

具体操作就很简单了,写个for循环就能搞定了。

#5


啊。
如果double ret=4.9999991(整数5),
if fabs(ret-(int)ret)<1e-9
then ret是整数

问题就是,在ret未知的情况下,对ret取整,这个ret就变成4了,也就不满足if了。
假如想补足这个丢失精度,可以给ret加上一个数,然后再取整,那么加的这个数定位多少才合适呢?
假设取加数为1e-6,ret加上它之后取整就是5,fabs就满足了.
但如果这个ret的确就是4.99999991, 依靠这种判断也会返回是整数。

那么,这个很小的加数取多小就肯定对了。 是double精度的最右边那位么? (假如double精确到0.0000000001)

#6


给出一个不用计算的方法(不是用任何浮点运算   ),速度很快。 


#include   "stdafx.h " 
typedef   unsigned   short   WORD; 
typedef   unsigned   __int64   UINT64; 

/* 
一个double型浮点数包括8个字节(64bit),我们把最低位记作bit0,最高位记作bit63, 
则一个浮点数各个部分定义为: 
第一部分尾数:bit0至bit51,共计52bit, 
第二部分阶码:bit52-bit62,共计11bit, 
第三部分符号位:bit63,0:表示正数,1表示负数。 
如一个数为0.xxxx   *   2^   exp,则exp表示指数部分,范围为-1023到1024, 
实际存储时采用移码的表示法,即将exp的值加上0x3ff,使其变为一个0到2047范围内的一个值。 

  判断一个数是否整数,可采用如下规则: 
  1.   如果一个数的绝对值小于1,则这个数的阶码小于零,则这个数为小数, 
  2.   如果一个数的绝对值> =2^52,应视为这个数为整数 
  3.   如果一个数x   1 <=x <2^52   且阶码为e,   则: 
        这个数的尾数部分,只有前e   bit   可以出现 '1 ',剩下的52-e比特全部为0, 
如此,则只要判断剩下的   52-e   bit是否为0   即可 
  下面给出程序 
*/ 


int   isInt(double   a) 

WORD   *pWord=(WORD   *)(&a)+3; 
                short   exp   =   (   (*pWord   &   0x7fff)   > > 4   )-0x3ff;   //取得阶码 

if   (   exp <0   )     //a <1 
return   0; 
else   if   (   exp> =52)   //a> =2^52 
return   1; 
else 

UINT64   n=   *((UINT64   *)(&a)); 
n   < <=12; 
return   (n   < <   exp)==0; 



int   main(int   argc,   char*   argv[]) 

double   f1,f2,f3,f4,f5,f6,f7; 

f1=0.5; 
f2=1.0; 
f3=1.1; 
f4=1024.0; 
f5=1024.5; 
f6=2251799813685248.0; 
f7=2251799813685248.5; 
printf( "isInt(%f)=     %d\n ",f1,isInt(f1)); 
printf( "isInt(%f)=     %d\n ",f2,isInt(f2)); 
printf( "isInt(%f)=     %d\n ",f3,isInt(f3)); 
printf( "isInt(%f)=     %d\n ",f4,isInt(f4)); 
printf( "isInt(%f)=     %d\n ",f5,isInt(f5)); 
printf( "isInt(%f)=     %d\n ",f6,isInt(f6)); 
printf( "isInt(%f)=     %d\n ",f7,isInt(f7)); 

return   0; 

#7


比如输入int a,b;
计算double ret=a/b;
判断ret是否为整数.

判a%b是否==0

#8


设个tolerance,把浮点数四舍五入得到一个整数,看原数跟这个整数的差距是否小于tolerance就认为是整数呗
当然,这个tolerance最好跟这个浮点数有关,也就是用相对误差,不要用绝对误差。

#9


5L说的问题,四舍五入不就行了吗。。
(int)(n+0.5)  就是对n四舍五入

引用 5 楼 qq120848369 的回复:
啊。
如果double ret=4.9999991(整数5),
if fabs(ret-(int)ret)<1e-9
then ret是整数

问题就是,在ret未知的情况下,对ret取整,这个ret就变成4了,也就不满足if了。
假如想补足这个丢失精度,可以给ret加上一个数,然后再取整,那么加的这个数定位多少才合适呢?
假设取加数为1e-6,ret加上它之后取整就是5,fabs……

#10


浮点数有标准的吧
直接取出浮点数的有效值部分与阶码,判断有效值长度是否小于阶码值

#11


引用 9 楼 michael122 的回复:
5L说的问题,四舍五入不就行了吗。。
(int)(n+0.5)  就是对n四舍五入

引用 5 楼 qq120848369 的回复:

啊。
如果double ret=4.9999991(整数5),
if fabs(ret-(int)ret)<1e-9
then ret是整数

问题就是,在ret未知的情况下,对ret取整,这个ret就变成4了,也就不满足if了。
假如想补……


。。原来这是四舍五入,自己想了半天也不知道这样的目的- -.....
明白了,这样做挺标准的.

#12


想简单的一点的话,就这样:
double a;
a = ....;
if(a == (int)a)
   cout << "a是一个整数" << endl;

呵呵。

#13


计算double ret=a/b;

既然a和b都是整数,通过b累加看能不能等于a,就能
判断a是否能整除b,从而判断ret是否整数

#14


引用 13 楼 zengwujun 的回复:
计算double ret=a/b;

既然a和b都是整数,通过b累加看能不能等于a,就能
判断a是否能整除b,从而判断ret是否整数
引用 12 楼 aaa20090987 的回复:
题目条件是我假设的。。。现在随便给一个double,直接判断是否是整数。


想简单的一点的话,就这样:
double a;
a = ....;
if(a == (int)a)
   cout << "a是一个整数" << endl;

呵呵。


你这个还真不对,经过一些除法运算之后,即便是整数5,机器可能存成了4.99999991,(int)之后就是4了,而它明明是5.

michael的方法应该不错了.
double a=4.23, a+0.5=4.73, (int)得4 ,4.23-4大于1e-6,所以不是整数.
double b=4.73, a+0.5=5.23, (int)得5, 5-4.73大于1e-6,所以不是整数。
double c=4.99999991, c+0.5= 5.49999991, (int)得5, 5-4.9999991小于1e-6,所以是整数。

#15


引用 10 楼 sbwwkmyd 的回复:
浮点数有标准的吧
直接取出浮点数的有效值部分与阶码,判断有效值长度是否小于阶码值

顶这个

#16


 如果是java里面的话,这是double和float的特性,如果要做非常精确的浮点运算的话请使用BigDecimal,或者自己控制把浮点数转化为long或者int计算,计算完后在移动小数点的位置,呵呵!

#17


这样做
(int &)a=(int)a
如果相等就是整数
不相等就是浮点数

#18


引用 17 楼 oringe_new 的回复:
这样做
(int &amp;)a=(int)a
如果相等就是整数
不相等就是浮点数

额~~应该是==

#1


没明白啥意思,看他内存地址中低位的值吧

#2


我举个例子:
比如输入int a,b;
计算double ret=a/b;
判断ret是否为整数.

就是这么一个问题.

#3


好像挺复杂

#4


这个应该列入数学问题,即如何判断一个自然数n等于一个实数a。

设定一个无穷小的delta, 如果|a-n|<delta 则认为相等。

在计算机中,可以考虑浮点数的精度作为delta。

将|a-n|的差值,乘以2的64次方,小于1,即认为a=n。

具体操作就很简单了,写个for循环就能搞定了。

#5


啊。
如果double ret=4.9999991(整数5),
if fabs(ret-(int)ret)<1e-9
then ret是整数

问题就是,在ret未知的情况下,对ret取整,这个ret就变成4了,也就不满足if了。
假如想补足这个丢失精度,可以给ret加上一个数,然后再取整,那么加的这个数定位多少才合适呢?
假设取加数为1e-6,ret加上它之后取整就是5,fabs就满足了.
但如果这个ret的确就是4.99999991, 依靠这种判断也会返回是整数。

那么,这个很小的加数取多小就肯定对了。 是double精度的最右边那位么? (假如double精确到0.0000000001)

#6


给出一个不用计算的方法(不是用任何浮点运算   ),速度很快。 


#include   "stdafx.h " 
typedef   unsigned   short   WORD; 
typedef   unsigned   __int64   UINT64; 

/* 
一个double型浮点数包括8个字节(64bit),我们把最低位记作bit0,最高位记作bit63, 
则一个浮点数各个部分定义为: 
第一部分尾数:bit0至bit51,共计52bit, 
第二部分阶码:bit52-bit62,共计11bit, 
第三部分符号位:bit63,0:表示正数,1表示负数。 
如一个数为0.xxxx   *   2^   exp,则exp表示指数部分,范围为-1023到1024, 
实际存储时采用移码的表示法,即将exp的值加上0x3ff,使其变为一个0到2047范围内的一个值。 

  判断一个数是否整数,可采用如下规则: 
  1.   如果一个数的绝对值小于1,则这个数的阶码小于零,则这个数为小数, 
  2.   如果一个数的绝对值> =2^52,应视为这个数为整数 
  3.   如果一个数x   1 <=x <2^52   且阶码为e,   则: 
        这个数的尾数部分,只有前e   bit   可以出现 '1 ',剩下的52-e比特全部为0, 
如此,则只要判断剩下的   52-e   bit是否为0   即可 
  下面给出程序 
*/ 


int   isInt(double   a) 

WORD   *pWord=(WORD   *)(&a)+3; 
                short   exp   =   (   (*pWord   &   0x7fff)   > > 4   )-0x3ff;   //取得阶码 

if   (   exp <0   )     //a <1 
return   0; 
else   if   (   exp> =52)   //a> =2^52 
return   1; 
else 

UINT64   n=   *((UINT64   *)(&a)); 
n   < <=12; 
return   (n   < <   exp)==0; 



int   main(int   argc,   char*   argv[]) 

double   f1,f2,f3,f4,f5,f6,f7; 

f1=0.5; 
f2=1.0; 
f3=1.1; 
f4=1024.0; 
f5=1024.5; 
f6=2251799813685248.0; 
f7=2251799813685248.5; 
printf( "isInt(%f)=     %d\n ",f1,isInt(f1)); 
printf( "isInt(%f)=     %d\n ",f2,isInt(f2)); 
printf( "isInt(%f)=     %d\n ",f3,isInt(f3)); 
printf( "isInt(%f)=     %d\n ",f4,isInt(f4)); 
printf( "isInt(%f)=     %d\n ",f5,isInt(f5)); 
printf( "isInt(%f)=     %d\n ",f6,isInt(f6)); 
printf( "isInt(%f)=     %d\n ",f7,isInt(f7)); 

return   0; 

#7


比如输入int a,b;
计算double ret=a/b;
判断ret是否为整数.

判a%b是否==0

#8


设个tolerance,把浮点数四舍五入得到一个整数,看原数跟这个整数的差距是否小于tolerance就认为是整数呗
当然,这个tolerance最好跟这个浮点数有关,也就是用相对误差,不要用绝对误差。

#9


5L说的问题,四舍五入不就行了吗。。
(int)(n+0.5)  就是对n四舍五入

引用 5 楼 qq120848369 的回复:
啊。
如果double ret=4.9999991(整数5),
if fabs(ret-(int)ret)<1e-9
then ret是整数

问题就是,在ret未知的情况下,对ret取整,这个ret就变成4了,也就不满足if了。
假如想补足这个丢失精度,可以给ret加上一个数,然后再取整,那么加的这个数定位多少才合适呢?
假设取加数为1e-6,ret加上它之后取整就是5,fabs……

#10


浮点数有标准的吧
直接取出浮点数的有效值部分与阶码,判断有效值长度是否小于阶码值

#11


引用 9 楼 michael122 的回复:
5L说的问题,四舍五入不就行了吗。。
(int)(n+0.5)  就是对n四舍五入

引用 5 楼 qq120848369 的回复:

啊。
如果double ret=4.9999991(整数5),
if fabs(ret-(int)ret)<1e-9
then ret是整数

问题就是,在ret未知的情况下,对ret取整,这个ret就变成4了,也就不满足if了。
假如想补……


。。原来这是四舍五入,自己想了半天也不知道这样的目的- -.....
明白了,这样做挺标准的.

#12


想简单的一点的话,就这样:
double a;
a = ....;
if(a == (int)a)
   cout << "a是一个整数" << endl;

呵呵。

#13


计算double ret=a/b;

既然a和b都是整数,通过b累加看能不能等于a,就能
判断a是否能整除b,从而判断ret是否整数

#14


引用 13 楼 zengwujun 的回复:
计算double ret=a/b;

既然a和b都是整数,通过b累加看能不能等于a,就能
判断a是否能整除b,从而判断ret是否整数
引用 12 楼 aaa20090987 的回复:
题目条件是我假设的。。。现在随便给一个double,直接判断是否是整数。


想简单的一点的话,就这样:
double a;
a = ....;
if(a == (int)a)
   cout << "a是一个整数" << endl;

呵呵。


你这个还真不对,经过一些除法运算之后,即便是整数5,机器可能存成了4.99999991,(int)之后就是4了,而它明明是5.

michael的方法应该不错了.
double a=4.23, a+0.5=4.73, (int)得4 ,4.23-4大于1e-6,所以不是整数.
double b=4.73, a+0.5=5.23, (int)得5, 5-4.73大于1e-6,所以不是整数。
double c=4.99999991, c+0.5= 5.49999991, (int)得5, 5-4.9999991小于1e-6,所以是整数。

#15


引用 10 楼 sbwwkmyd 的回复:
浮点数有标准的吧
直接取出浮点数的有效值部分与阶码,判断有效值长度是否小于阶码值

顶这个

#16


 如果是java里面的话,这是double和float的特性,如果要做非常精确的浮点运算的话请使用BigDecimal,或者自己控制把浮点数转化为long或者int计算,计算完后在移动小数点的位置,呵呵!

#17


这样做
(int &)a=(int)a
如果相等就是整数
不相等就是浮点数

#18


引用 17 楼 oringe_new 的回复:
这样做
(int &amp;)a=(int)a
如果相等就是整数
不相等就是浮点数

额~~应该是==