整型与浮点间的快速转换
现需要实现两个函数:#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 写,以提高可移植性。 我查阅了一些资料,第二个函数高效的完成了!并做到了“浮点取整并去整,一气呵成!”
// 浮点取整并去整,一气呵成!本快速算法由 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 间的快速转换。。。 啊哈!第一个函数也搞定了!
没有用强制转换的方法,而且效率更高!
页:
[1]