浮点数到整数的快速转换.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
浮点数到整数的快速转换

浮点数到整数的快速转换浮点数到整数的快速转换 在计算机图形运算中,常常要将浮点数转换为整数,例如在图像的光栅化阶段,就要执行大量的类型转换,以便将浮点数表示的坐标转化为整数表示的屏幕坐标。 ---------------------------------------------------------------------------------------- // // 强制类型转换 // 小数部分将被裁剪掉 // int_val = (int)float_val; ---------------------------------------------------------------------------------------- 嘿嘿,很高兴你居然和我一样单纯!这个操作实在是太TINY了,以至于我从来没想过它是怎么实现的,直到某天某个家伙跟我说,不要使用标准C类型转换,因为那太慢了!我当时的震惊不下于倒霉的冒险者遇上了龙。 标准C类型转换最大的优点是,它是独立于平台的,无论是在X86上跑,还是在PowerPC上跑,你什么都不用担心,编译器会为你搞定一切。而这也恰恰是它最大的缺点——严重依赖于编译器的实现。而实际测试表明,编译器所生成的代码,其速度实在不尽人意。 一个替代的方法是直接对数据位进行操作。如果你对IEEE浮点数的表示法比较熟悉的话(如果你压根什么都不知道,请先查阅文末附录中的资料),这是显而易见的。它提取指数和尾数,然后对尾数执行移位操作。代码如下: ---------------------------------------------------------------------------------------- // // 将32位浮点数fval转换为32位整数并存储在ival中 // 小数部分将被裁剪掉 // void TruncToInt32 (int ival, float fval) { ival = *(int *)fval;// 提取尾数 // 注意实际的尾数前面还有一个被省略掉的1 int mantissa = (ival 0x07fffff) | 0x800000;// 提取指数 // 以23分界,指数大于23则左移,否则右移 // 由于指数用偏移表示,所以23+127=150 int exponent = 150 - ((ival 23) 0xff); if (exponent 0) ival = (mantissa -exponent); else ival = (mantissa exponent);// 如果小于0,则将结果取反 if ((*(int *)fval) 0 ival = -ival; } ---------------------------------------------------------------------------------------- 该函数有一个BUG,那就是当fval=0时,返回值是2。原因是对于语句mantissaexponent,编译器使用了循环移位指令。解决方法是要么对0作特殊处理,要么直接用汇编来实现。 这个函数比标准的C转换要快,而且由于整个过程只使用了整数运算,可以和FPU并行运行。但缺点是,(1)依赖于硬件平台。例如根据小尾和大尾顺序 的不同,要相应地修改函数。(2)对于float和double要使用不同的实现,因为二者的数据位不同。(3)对于float,只能保留24位有效值, 尽管int有32位。更快的方法是使用FPU指令FISTP,它将栈中的浮点数弹出并保存为整数: ---------------------------------------------------------------------------------------- // // 将64位浮点数fval转换为32位整数并存储在ival中 // 小数部分将四舍五入到偶数 // inline void RoundToIntFPU (int ival, double fval) { _asm { fld fval mov edx, dword ptr [ival] fistp dword ptr [edx] } } ---------------------------------------------------------------------------------------- 很 好,无论速度还是精度似乎都相当令人满意。但如果换一个角度来看的话,fistp指令需要6个cycle,而浮点数乘法才仅仅需要3个cycle!更糟的 是,当fistp运行的时候,它必须占用FPU,也就是说

文档评论(0)

me54545 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档