gxqcn 发表于 2016-11-21 10:10:27

整型与浮点间的快速转换

现需要实现两个函数:
#include <stdint.h>
#include <math.h>

double int64ToDouble( int64_t i64 )
{
        double dRet;

        assert( -( 1LL << 48u ) < i64 && i64 < ( 1LL << 48u ));        // |i64|<2^48

        // 快速将 64 位整型转化成浮点型:dRet = ( double )i64;
        // ...
        // ...

        return dRet;
}


int32_t roundToInt( double * p )
{
        int32_t iRet;

        assert( NULL != p );
        assert( fabs( *p ) < 16777216.0 );        // |*p|<2^24

        // 快速将浮点型 *p 四舍五入存进整型 iRet 中,然后从 *p 自身中扣除该整数部分
        // 等效于:iRet = ( int32_t )*p;    *p -= ( double )iRet;
        // ...
        // ...

        assert( fabs( *p ) <= 0.5 );

        return iRet;
}

它与通用的转换函数略有不同,
主要是入参的取值范围略有收窄,不知可有更快速的算法?
另,要求仅用标准 C 写,以提高可移植性。

gxqcn 发表于 2016-11-21 17:21:19

我查阅了一些资料,第二个函数高效的完成了!并做到了“浮点取整并去整,一气呵成!”

// 浮点取整并去整,一气呵成!本快速算法由 Jason Guo 自创,2016-11-21

const double MAGIC = 6755399441055744.0;   // 1.5*2^52

intptr_t roundToInt( double * const p )
{
    const double f64 = *p + MAGIC;

    assert( fabs( *p ) <= 2251799813685248.0 );    // |*p| <= 2^51
    *p -= f64 - MAGIC;
    assert( fabs( *p ) <= 0.5 );

    return ( *( intptr_t * )&f64 );
}

备注:之所以说是“自创”,是因为当前遍寻网络,仅见“取整”功能而不见“取整且去整”之功能。

当入参 |*p| <= 2^51,运行后 *p 将正好保留去整后的残余小数值;
在 32 位系统下,需入参 |*p| ∈ [ -2147483648.5, 2147483647.5 - DBL_EPSILON ],以保证返回值不溢出。


下面,将尝试进行 int64 --> double 间的快速转换。。。

gxqcn 发表于 2016-11-22 10:13:55

啊哈!第一个函数也搞定了!
没有用强制转换的方法,而且效率更高!
页: [1]
查看完整版本: 整型与浮点间的快速转换