QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1568|回复: 14

怎样获得一个浮点数的小数位数

[复制链接]
发表于 2004-6-12 10:10:45 | 显示全部楼层 |阅读模式
比如一个数是7.3342,那么它的小数位数就是4,怎样编程实现呢,我在VC里面做,老是得不到正确的结果,郁闷
下面是我的代码
[code:1]
#include "stdio.h"
void main()
{
   float num=7.3342;
   float tmp;
   int count=0;//记录小数位数
   tmp=num;
   while(tmp>1e-6)
  {
      tmp=(tmp-(int)tmp)*10;
      count++;
  }
  printf("%d\n",count);
}
[/code:1]
发表于 2004-6-12 11:04:38 | 显示全部楼层
float num = 7.3342,实际上在机器中表示时,是num = 7.33419991(用gdb看见的)
所以,不可能用这种方式来计数。   
而且,中间的运算步骤,并不像普通想像那样,用debug调试跟踪一下就知道了,这在VC中很简单. :-)  :-)
回复

使用道具 举报

 楼主| 发表于 2004-6-12 18:59:30 | 显示全部楼层
我debug的时候也看到了,可是想不出办法来解决,郁闷
回复

使用道具 举报

 楼主| 发表于 2004-6-13 16:32:07 | 显示全部楼层
有人能告诉我怎么解决吗,或者能提供一段实现代码也可以,谢谢啦
回复

使用道具 举报

发表于 2004-6-13 17:41:06 | 显示全部楼层
我乱写了一个,好像能够工作
[code:1]
#include <stdio.h>
#include <stdlib.h>

int
main(void) {
        float f = 7.33425324;
        char temp[20];
        int i, j;

        snprintf(temp, 20, "%f", f);
        printf("%s\n", temp);

        i = 0;
        while (temp[i] != '.') {
                i ++;
        }
        j = i;
        while (temp[j] != '\0') {
                j ++;
        }
        j --;
        while (temp[j] == '0') {
                j --;
        }
        printf("%d\n", j-i);

        return 0;
}
[/code:1]
回复

使用道具 举报

发表于 2004-6-13 17:41:30 | 显示全部楼层
我个人以为,只能先把float转成字符串,才能处理。
回复

使用道具 举报

发表于 2004-6-13 18:26:55 | 显示全部楼层
据说浮点数不是绝对精确的……
回复

使用道具 举报

发表于 2004-6-13 19:38:31 | 显示全部楼层
浮点数,在计算机里是用FPU来处理的,FPU只能处理所谓的temporary real value的,
它的数据格式分为四种,如果只声明float,就是短浮点型
格式为, 32位(bit),
从左到右,各位的含义如下:
32:符号位,  31-24: 阶数位(8 bits), (隐藏位(0 bit),值衡为一,计算时要用),23-1:尾数位(23 bits) ,

计算方法如下:
1.用阶数位减127得到2的指数, 得到e。
2求和: 2^(隐藏位)+第23位的值*2^(第23位的权值)+
                       第22位的值*2^(第22位的权值)+....+
                             第1位的值*2^(第1位的权值),
           得到sum
  隐藏位的权值为0,依次减一,到第1位,权值为-24
3。2^e*sum 就得到了这个数

举例说
比如0x40a0000,
e=129 - 127 = 2,
因为只有第22位的值是1,它的权值是-2,所以sum=( 2^0+1*2^(-2))=1.25

因此,这个数就是 2^(e) * sum=4*1.25 =5

从浮点型的数值表示形式来看,不可能范围内的每个值都能精确表示,事实上
它是通过 2^e*(2^0+2^(-1)+2^(-2)+...)来近似表示的.
你可以看看这是多少0x3dcccccd
用printf来看是0.1, 你自己算一下,其实是很接近0.1的一个数(用了小数点以后的全部2^(-24)位来近似的)

所以要求浮点型的小数位,意义不是很大,用printf打印的值,是按你参数的精确度来打印的,
你转成字符串,(大部分情况下)就已经把他的精度舍掉了,如果不舍掉精度,那么,
很多小数可能结果都是2^(-24),因为这只是一个近似值而已。
回复

使用道具 举报

 楼主| 发表于 2004-6-13 20:31:48 | 显示全部楼层
谢谢quarkonics,确实可以,只要把里面的那个snprintf改成_snprintf就可以了,我主要是要写一个程序,从数据库中读出很多浮点数,然后根据这些浮点数把坐标轴的单位长度确定下来,以便后面的画图,因为window的画点线都只能用int型,所以我想根据浮点数的小数位数,乘上位数×10,就可以全部转化成整数,也不知道自己这个想法对不对,反正觉得自己数学很差,编程都是乱七八糟的凑,唉,以后不适合吃程序这碗饭,再次谢谢大家的热心帮助
回复

使用道具 举报

发表于 2004-6-13 20:51:43 | 显示全部楼层
:-) ,我想问一下,那个_snprintf和snprintf有什么区别
回复

使用道具 举报

发表于 2004-6-13 21:00:01 | 显示全部楼层
我记得在MYSQL里边查询返回的结果都是字符串,那样的话,直接处理是不是要方便一些呢?
你用的什么数据库?
回复

使用道具 举报

发表于 2004-6-13 22:36:37 | 显示全部楼层
直接用sprintf吧,更好用
回复

使用道具 举报

 楼主| 发表于 2004-6-14 10:27:59 | 显示全部楼层
数据库用的是mdb,用_snprintf是因为编译的时候提示snprintf没有声明,于是跑去查msdn,里面好象只有_snprintf,于是就改了,运行通过。
回复

使用道具 举报

发表于 2004-6-14 17:22:23 | 显示全部楼层
唉,今天打印毕业论文,头都怎大了
回复

使用道具 举报

 楼主| 发表于 2004-6-15 12:41:36 | 显示全部楼层
都打打印了还头大呀,应该是做的时候头大才对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-8 02:47 , Processed in 0.057995 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表