_ftol 的优化
                              _ftol 是什么? 当你写 C 程序的时候,(int)float_v 就会被编译器产生一个对 _ftol 这个 CRT 函数的调用。
上个世纪听一个做 3d 的朋友提起过,用 x87 指令实现的 _ftol 会很慢,一般用整数指令提供。当时提在心里,2000 年的时候在 RISC 上做开发 (ARM 指令集) 曾经写过一些整数模拟浮点的函数,曾经写过这个转换函数,日子久了,现在也找不回来代码。不过对浮点的 IEEE 标准还是比较清楚的。去年写过一篇 浮点数的精度控制问题 的帖子放在流言中。当时已经被骂过了。
今天工作时又遇到关于浮点数的问题,再写篇 blog 吧,或许还是找骂贴 :)
                           
                           
                              懒的重写 _ftol 的整数指令版本了,google 搜了下,发现果然有人也做过。http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=64008
就是这么一个函数:
                        
int ftol(float f)
{ 
    int a         = *(int*)(&f);
    int sign      = (a>>31); 
    int mantissa  = (a&((1<<23)-1))|(1<<23);
    int exponent  = ((a&0x7fffffff)>>23)-127;
    int r         = ((unsigned int)(mantissa)<<8)>>(31-exponent);
    return ((r ^ (sign)) - sign ) &~ (exponent>>31);       
}
当是效率比较高的。我想,日子已经过去这么久了。当初朋友跟我提这个事情的事情大约是 98,99 年。上面翻出来的老帖是 01 年的。我现在的机器不错,今年新买的 P4 双核的,还是测试一下比较放心。
注:这个函数不能直接替换 CRT 中的 _ftol , CRT 的 _ftol 并不通过堆栈传递参数。
马上随手写了下面的测试程序:
#include "stdio.h"
#define RDTSC  _asm _emit 0x0f _asm _emit 0x31
#pragma warning (push)
#pragma warning (disable: 4035)
inline unsigned __int64 timestamp()
{
	__asm RDTSC
}
#pragma warning (pop)
int int_chop (float f)
{ 
    int a         = *(int*)(&f);
    int sign      = (a>>31); 
    int mantissa  = (a&((1<<23)-1))|(1<<23);
    int exponent  = ((a&0x7fffffff)>>23)-127;
    int r         = ((unsigned int)(mantissa)<<8)>>(31-exponent);
    return ((r ^ (sign)) - sign ) &~ (exponent>>31);    
}
int test1(float f)
{
	return int_chop(f);
}
int test2(float f)
{
	return (int)f;
}
int test3(float  x)
{
	int   t;
	__asm  fld   x  
	__asm  fistp t
	return t;
}
void test(int t,int (*f)(float))
{
	int i;
	for (i=0;i
运行结果如下:
---timing 0---
use int 4449676
(int)   4583873
use x87 1491980
---timing 1---
use int 6097315
(int)   4603592
use x87 1662360
---timing 2---
use int 2427691
(int)   4532759
use x87 1445269
compiler 内置的 _ftol 表现不怎么样,比整数版还是慢了一倍。那个浮点版本是做参考的,虽然快,但是语义和 C 语言要求的不太一样,依赖 rounding mode 的设置。所以不推荐使用。
关于 double 向 int 转换,参考另一篇 blog :double to int 神奇的 magic number
                            
Comments
Posted by: ninja | (9) November 6, 2008 10:59 AM
Posted by: HouSisong | (8) May 19, 2007 10:09 AM
Posted by: sods | (7) March 1, 2006 02:35 PM
Posted by: euclid | (6) February 17, 2006 01:19 PM
Posted by: analyst | (5) December 19, 2005 01:31 PM
Posted by: Cloud
 | (4) 
                                 December 19, 2005 12:32 PM 
                              
Posted by: analyst | (3) December 19, 2005 12:45 AM
Posted by: 一个朋友(不方便留名字) | (2) December 17, 2005 08:27 PM
Posted by: 一个朋友(不方便留名字) | (1) December 17, 2005 08:23 PM