如何检查是否浮动可以psented作为一个整数正是重新$ P $ [英] How to check if float can be exactly represented as an integer

查看:161
本文介绍了如何检查是否浮动可以psented作为一个整数正是重新$ P $的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我期待确定的合理有效的方式,如果一个浮点值(双击)可重新准确$ P $一个整数数据类型psented( 64位)。

I'm looking to for a reasonably efficient way of determining if a floating point value (double) can be exactly represented by an integer data type (long, 64 bit).

我最初的想法是检查的指数,看它是否是 0 (或更多precisely 127 )。但是,这不会起作用,因为 2.0 将是E = M = 1 ...

My initial thought was to check the exponent to see if it was 0 (or more precisely 127). But that won't work because 2.0 would be e=1 m=1...

所以基本上,我卡住了。我有一种感觉,我可以用位掩码做到这一点,但我只是没有得到我的头围绕如何做到这一点在这一点上。

So basically, I am stuck. I have a feeling that I can do this with bit masks, but I'm just not getting my head around how to do that at this point.

所以,我怎么能检查,看是否有双恰好重新presentable作为一项长期的?

So how can I check to see if a double is exactly representable as a long?

感谢

推荐答案

这里有一个方法,可以在大多数情况下工作。我不知道是否/如何,如果你给它 NaN的 INF ,非常大(溢)会破数字...
结果(虽然我认为他们都将返回false - 不完全重新presentable。)

Here's one method that could work in most cases. I'm not sure if/how it will break if you give it NaN, INF, very large (overflow) numbers...
(Though I think they will all return false - not exactly representable.)

您可以:


  1. 将其转换为整数。

  2. 转换回浮点。

  3. 与原始值进行比较。

事情是这样的:

double val = ... ;  //  Value

if ((double)(long long)val == val){
    //  Exactly representable
}

地板() CEIL()也是公平的游戏(虽然如果值溢出了,他们可能会失败整数):

floor() and ceil() are also fair game (though they may fail if the value overflows an integer):

floor(val) == val
ceil(val) == val


这是一个混乱位掩码的解决方案:结果
这将使用联合类型,双关,并假定IEEE双precision。 <一href=\"http://stackoverflow.com/questions/11639947/is-type-punning-through-a-union-unspecified-in-c99-and-has-it-become-specified\">Union类型双关仅适用于C99 TR2及更高版本。

int representable(double x){
    //  Handle corner cases:
    if (x == 0)
      return 1;

    //  -2^63 is representable as a signed 64-bit integer, but +2^63 is not.
    if (x == -9223372036854775808.)
      return 1;

    //  Warning: Union type-punning is only valid in C99 TR2 or later.
    union{
        double f;
        uint64_t i;
    } val;

    val.f = x;

    uint64_t exp = val.i & 0x7ff0000000000000ull;
    uint64_t man = val.i & 0x000fffffffffffffull;
    man |= 0x0010000000000000ull;  //  Implicit leading 1-bit.

    int shift = (exp >> 52) - 1075;
    //  Out of range
    if (shift < -52 || shift > 10)
        return 0;

    //  Test mantissa
    if (shift < 0){
        shift = -shift;
        return ((man >> shift) << shift) == man;
    }else{
        return ((man << shift) >> shift) == man;
    }
}

这篇关于如何检查是否浮动可以psented作为一个整数正是重新$ P $的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆