float与int之间类型转换的低效是由其bit存储结构决定的(见图)。例如:
int i = 5;
float f = i;
其中i与f的二进制存储结构是不同的,二者的转化涉及到了存储结构的转换。
对于i来说,
5 => 5 * 2^0
5 => 2.5 * 2^1
5 => 1.25 * 2^2
因此当i向f进行转换时,需要计算小数部分23bits中每一位的值,使其无限接近0.25。后再计算exp部分使exp-127的值为2。从而得到最终的f。
另外一个例子:
int i = 5;
float f = *(*float)&i;
在这个例子中,由于i的存储结构并不会发生变化,也就是
00000000 00000000 00000000 00000101
但是它会被按照float的存储方式来解释,也就是
1.(2^(-21)+2^(-23)) * 2^(0-127)


good!
int的存储很简单,就是16进制而已(或者说2进制),那么float或者double的存储机制是什么我还不清楚。不过我经常遇到的是比较两个float是否相近,这个也不能用简单的operator==,因为如果按bit比较,两个相近的数可能千差万别。
根据float,double的bit representation(图中所示),他们并不是精确值,而是近似值,所以通过==进行比较的结果一定是不稳定的,有的case返回true,有的返回false,这主要取决于具体的环境(e.g.,compiler,CPU结构,等等)。因此只能从接近程度上(某个范围内)去比较。
我还有个问题,我在比较浮点数的时候,有两个方法:(我用的是Boost的方法)
BOOST_CHECK_CLOSE(a, b, eps)
BOOST_CHECK_SMALL(a)
第一个方法判断a和b的差值是否小于一定阀值eps
第二个方法则用来判断一个浮点数是否足够小(接近0)
我曾经有这么一个用例,当a和b都接近0的时候,无法使用check_close,因为其统计算法是用比例来做的,但如果我们的a是0的话,这个比例不存在(因为比例要除以0),所以在这种情况下我只能用check_small
我想问问你,你是否研究过这方面的内容呢?虽然我认为比较两个浮点数是否相近应该就比较其差值的绝对值是否小于一个阀值即可,但boost的实现仿佛是从统计学来做的,对于0的比较很有问题。
boost库我没有用过,所以细节不是很清楚。但就两个浮点数是否相等来说,采用“相对”的概念更为合适。比方说设定阀值为0.00001,相比较的两个数约为1000000,那么这个阀值就显得太小。如果相比较的两个数约为0.001,这个阀值又显得太大。因此,和绝对阀值相比,BOOST_CHECK_CLOSE的percentage tolerance 更为合适。
对的,BOOST_CHECK_CLOSE就是用的percentage tolerance方法,但这个方法首先要取得比值,所以当比较两个为0的数的时候就出现问题了,因为在取比值的时候,0被用作了除数.所以当比较0的时候,我改用了BOOST_CHECK_SMALL, 不知道percentage tolerance的方法如何比较0