#include <stdio.h> int main(int argc, char *argv[]) { float p = 5.1f; int f = (int)(p*100); printf("%d", f); getch( ); return 0; } 我想要输出 510,可是机器nnd居然输出509(竟然敢扣我工钱)。 到底是what's wrong。我上看下看,左看又看,看了又看,就是发现不了错误。 于是我试着把5.1改成5.5,一切正常啊。捣鼓了N个小时后猜想,莫非是浮点数的表示问题, 于是花了很久找到浮点数的机器表示方法,照着规定克隆操作了一下。(据说练过乾坤大 挪移的人什么招式都可以克隆)。 IEEE规定的浮点数的机器表示: 32位机器的 float 是4字节的,共32位。 第1位是符号位,接着8位指数位,接着23位基数位。 以5.1为例。 5 = 101 (2进制) 0.1 = 0.0 0011 0011 0011 0011 0011 0011 .....(无限循环) 所以 5.1 = 101.0 0011 0011 0011 0011 0011 0011 0011 0011 ... 5.1= 1.010 0011 0011 0011 0011 0011 0011 0011 0011 0011... * 2^2 因为第一位总是为1,如果是0,就移动小数点直到是非0的,所以第一位的1丢弃。 得到 010 0011 0011 0011 0011 0011 0011 0011 0011.... 取23位 得到 0100 0110 0110 0110 0110 011 接着看指数部分 指数是2, 根据规定,指数统一+127再转换为无符号8位2进制数, 2+127=129 (1000 0001) 存储的时候指数部分存储在基数之前,这样就有31位了, 因为5.1是正的,所以符号为是0,存储在指数部分之前 这样就得到 0100 0000 1010 0011 0011 0011 0011 0011 我们来看一下机器上是否真的如此 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { float a=5.1; int *i=&a; printf("%x", *i); system("PAUSE"); return 0; } 40a33333 0100 0000 1010 0011 0011 0011 0011 0011 果真是一样的。 这个例子就说明了为什么浮点数有时存在这样的问题。 这个数化为10进制整数的时候, 由于不可能达到5.1(5.099..) 所以×100后截取了前面的值 509。 无奈吧,这个时候想要精确的浮点数的话, 只有自己写高精度算法了。 |
C语言float类型的浮点存储方法
最新推荐文章于 2024-03-21 17:44:40 发布