float(double)快速转换int的方法
自己写一个软件渲染器的时候,无意中发现float转换int非常耗时,于是查阅文章,这才有了这个命题,以前不清楚还有这么个机制。网上看了很多文章,搜索到了一个数字6755399441055744,这个是double快速转换int的一个magic number。至于原理我一知半解,主要看效果。经测试,这个函数的效率比c++直接float转int高很多,记录下来以便备忘。
//
// 将64位浮点数转换为32位整数
// 小数部分将四舍五入到偶数
//
//用于double的magic number是1.5*2^52=6755399441055744.0
//对于double来说,相应的magic number就是1.5*2^36
//处理float的速度比汇编低1/3
//编译器优化情况下,比手写汇编快 inline int32_t f_toint(double x)
{
x += 6755399441055744.0;
return *(int32_t*)&x;
} //四舍五入,处理的数据范围是-2^22 ~ 2^22-1, -4194304.0 ~ 4194303.0
inline int32_t f_toint32(float x)
{
//取得符号位,设置掩码
uint32_t n = ((*(uint32_t*)&x) & 0x80000000) ? 0xFFC00000 : 0;
x += 12582912.0f;
return ((*(uint32_t*)&x) & 0x3FFFFF) | n;
}
f_toint32的原型是csdn论坛一个网友说的回复:
inline long magic_f2l( float x ){ static long mask[] = { 0x0, 0xffc00000 }; static float trunc[] = { -.5f, .5f }; int s = ( *(unsigned long*)&x )>>31; x += trunc[s]; x += 12582912.f; return (*(long*)&x) & 0x3fffff | mask[s];}double float_magic_number(int bits)
{
return 1.5 * STD::pow(2.0, double(bits));
}
但magic_f2l()这个函数效率并没有double版本的那么好,原因估计是运算运算太多了,于是我精简了一下:
inline long magic_f2l( float x ){ static long mask[] = { 0x0, 0xffc00000 }; static float trunc[] = { -.5f, .5f }; int s = ( *(unsigned long*)&x )>>31;//这里得到float的符号位,如果是负数,最后结果就和0xFFC00000进行or运算。这里有个位移操作 x += trunc[s];//这里有个加法和数组取值操作 x += 12582912.f; return (*(long*)&x) & 0x3fffff | mask[s];//数组取值}inline int32_t f_toint32(float x)
{
//取得符号位,设置掩码
uint32_t n = ((*(uint32_t*)&x) & 0x80000000) ? 0xFFC00000 : 0;//一个三元操作符,直接储存掩码
x += 12582912.0f;//魔法数字加法
return ((*(uint32_t*)&x) & 0x3FFFFF) | n;//直接or运算
}
float(double)快速转换int的方法的更多相关文章
- sql server数据库如何存储数组,int[]float[]double[]数组存储到数据库方法
原文地址:https://www.zhaimaojun.top/Note/5475296 将数组存储到数据库的方法 (本人平时同csharp编写代码,所以本文中代码都是csharp代码,有些地方jav ...
- 二进制&八进制&十六进制之间的快速转换------ 心算&笔算方法总结
二进制数 0&1两种元素: 8进制数 0-7 八种元素: 十六进制数 0-9,a,b,c,d,e, ...
- 关于c中 int, float, double转换中存在的精度损失问题
先看一段代码实验: #include<limits> #include<iostream> using namespace std; int main() { unsigned ...
- JAVA float double数据类型保留2位小数点5种方法
/** * Java 两个整数相除保留两位小数,将小数转化为百分数 * java中,当两个整数相除时,由于小数点以后的数字会被截断,运算结果将为整数,此时若希望得到运算结果为浮点数,必须将两整数其一或 ...
- C++中将string类型转换为int, float, double类型 主要通过以下几种方式:
C++中将string类型转换为int, float, double类型 主要通过以下几种方式: # 方法一: 使用stringstream stringstream在int或float类型转换为 ...
- QT中QString 与 int float double 等类型的相互转换
Qt中 int ,float ,double转换为QString 有两种方法 1.使用 QString::number(); 如: long a = 63; QString s = QString:: ...
- [C++] string与int, float, double相互转换
参考:http://blog.csdn.net/candadition/article/details/7342380 将string类型转换为int, float, double类型 主要通过以下几 ...
- boolean和Boolean, char和Character , byte和Byte, short和Short, int和Integer , long和Long , float和Float, double和Double的区别 , String和StringBuffer的区别
Java提供两种不同的类型:引用类型和原始类型(内置类型).Int是java的原始数据类型,Integer是java为int提供的封装类. Java为每个原始数据类型提供了封装类. 其中原始数据类型封 ...
- 有关C++的数据类型(int,long,short,float,double等等)
再看C++ prime plus 第六版的时候 对数据类型又一次有些乱了,在看了这篇博客后,重新清晰起来了. 有关C++的数据类型(int,long,short,float,double等等)
随机推荐
- 最短路——Dijkstra算法
模板 水模板ing #include <cstdio> #include <cstring> #include <algorithm> #include <i ...
- java collection集合
集合:用于存储对象的容器.集合中可以存储任意类型的对象,长度可变. 集合和数组的比较 集合和数组都是存储对象的容器,不同的是,数组可以存储基本数据类型(int.short.long.char.Bool ...
- 基于GDAL的栅格图像空间插值预处理
转自 基于GDAL的栅格图像空间插值预处理——C语言版 基于GDAL的栅格图像预处理 前言 栅格数据和矢量数据构成空间数据的主要来源,怎样以开源方式读取并处理这些空间数据?目前有多种开源支持包,这里只 ...
- Java: 创建自带依赖库的Jar包
pom.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...
- Meteor在手机上运行
在本章中,我们将学习如何在Android设备上运行你的应用程序.最近Meteor刚刚添加此功能适用于Windows操作系统,所以我们需要更新 Meteor 应用到 1.3测试版. 注 在写的时候本教程 ...
- 微信小程序 自定义组件(modal) 引入组件
项目结构: 步骤一:创建组件 声明这一组文件为自定义组件 modal.json { "component": true, // 自定义组件声明 "usingCompone ...
- 基于Spring-SpringMVC-Mybatis的简单样例
复习下 好久没搞过撸过代码了! 这个样例包括一个完整的增删改查! 源代码地址http://download.csdn.net/detail/wangdianyong/8909903
- HDU1306 String Matching 【暴力】
String Matching Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- 简单JS全选、反选代码
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org ...
- inter 也支持linux开发了
http://www.intel.cn/content/www/cn/zh/intelligent-systems/bay-trail/atom-processor-e3800-family-over ...