【Delphi】玩转浮点数转整数

Delphi中提供了三个函数:

Trunc: 将浮点数的整数部分返回。
Round: 将浮点数四舍五入后返回整数部分。
Int: 将浮点数的小数部分去掉,返回只保留了整数部分的Extended型。

在D2007 + Win7 + Intel平台下测试, 由于Int返回的并非整型,我们把它排除掉。测试结果是 Round 性能高出Trunc好几倍。

为什么Trunc慢了呢,查看了System中的ASM代码,Trunc有11行指令,Round则只有5行。

出于好奇,通过网络研究下Trunc的算法,知道了在 IEEE 754 里规定双精度浮点数是 64 位,而其中符号位占 1 位,指数部分是 11 位,那么尾数部分就是 52 位,那么 1 * 2^52 = $10000000000000。设要取整的浮点数为V, 那么通过符点数运算的对阶法, PInteger(V + $10000000000000 的结果)^ 就是计算结果了。

于是有了下面的函数:

再来测试看看:

 

 

// 注: GetTimestamp 为高精度计时器返回单位为ms(与QWorker中的返回0.1ms有所不同),可换成GetTickCount。

测试结果如下:

QQ截图20150619103148

 

 

 

 

 

哈哈,居然成了最快的了。

要注意的是, MyTrunc 我这里并没有像System的Trunc那样写汇编代码,一是那样不能inline了,二是通过观测编译结果发现已经是很简单的几行指令了。

通过对MyTrunc简单个修改下,成了MyRound:

参考资料:

http://www.360doc.com/content/14/0308/22/3520047_358884576.shtml

 

分享到:

2 条评论

沙发空缺中,还不快抢~