二进制-初学C……求助float有效数字的问题

问题描述

初学C……求助float有效数字的问题
关于浮点数有效数字我有很多疑惑,我发现我读入一个浮点数后再输出,两个数字是不相等的。开始我以为是我输入的数字超过了float有效数字位数的原因,但是下面这个程序证明不是这个原因:

#include <stdio.h>#include <float.h>int main(void){float test;char data[7];printf(""Float has at least %d effective numbersn"" FLT_DIG);printf(""Then i'm gonna check it!n"");printf(""test data:_______bbbbbbb"");scanf(""%f""&test);printf(""please input again to confirm it:_______bbbbbbb"");scanf(""%s""&data);printf(""So %f is supposed to be %s"" test data);return 0;}

就是先查了一下我的机子规定float至少几个有效数字,然后输入一个数字,输两边,一次存成float,一次存成字符串,最后检验float是不是真有这么多有效数字
结果:

这是怎么回事啊……我大概知道为什么会有这种情况,就是计算机把十进制转二进制存储再转十进制的过程出了问题……可是明明是机器告诉我有至少六位有效数字,那我输个六位有效数字的数不应该会出错的吧?

不知道哪位朋友能给我解答一下……是程序写错了吗?还是说有效数字的问题我理解错了?怎么样能让数值准确的输出呢?按照这种情况,岂不是大部分的运算的都是不准确的?

解决方案

float数据 机器内是2进制数,
1位符号位
8位指数位
23位“尾数”位
共32 位 2进制数。
平时讲 有效数字 是6~7位 ,指10进制。

通常程序输入的数是10进制,进入机器后要化成2进制,计算完又转十进制输出。
10进制到2进制,2进制到10进制 转换,有的数化不净,有的数化得净。
如同10进制分数化10进制小数,有的化得净(例如 4分之1,变0.25),有的化不净(例如 3分之1,变0.33333....)。

10进制到2进制,2进制到10进制 转换,化得净的效数字7位,化不净的效数字6位,因为最后一位有舍入误差。
例如:
float xy;
x=0.51; // 化不净
y=0.5; // 化得净
printf(""x=%.8f y=%.8""xy); // 输出 0.50999999 0.50000000

解决方案二:

 有效数字是指,浮点数中表示尾数的二进制的多少,这个有效数字是二进制的,换算成10进制大概是*0.3(2^10 = 10^3)

解决方案三:
有效数字和保留6位小数没有任何关系。二进制和10进制转换不是一一对应的,可以有误差。

比如说,你有一个“3进制”的弹簧秤,它的刻度是1/3斤。那么它的有效精度是1/3斤。现在称出来是5/3斤,用10进制表示是1.66666666....
你不能说它的精度有那么高。

解决方案四:
这个要去看看IEEE标准。

解决方案五:
老实说,我都不清楚float还有有效位数FLT-DIG这个系统值,而细看float的存储方式,这个值的准确性实在难以保证。
我们都知道,float是用4个字节——相当于一个int的内存单元——来存储数值的,至于具体的存储细节,这篇转载的文章写得很清楚:http://blog.csdn.net/yezhubenyue/article/details/7436624,所以,如果要使用6位有效数字的计算,使用更高精度的double或其他类型,或者自行通过字符串来实现10进制的加减乘除,完全可以实现所需的精度需求(我记得大二时候有个作业就是实现大数计算,网上这方面的资料很多的)

时间: 2024-10-31 09:14:47

二进制-初学C……求助float有效数字的问题的相关文章

[c#]二进制反序列化问题求助

问题描述 问题描述如下1我编写了一个数据结构,简单的list,然后list的填充的也是自己编写的一个class,生成了对应的dll.最后将这个lis用t二进制序列化.2新建一个解决方案编写反序列化的程序,该调用了之前数据结构生成的dll.同时因为一些需要,我在新的解决方案中也重新实现了之前的数据结构,并添加了个方法.3想将原来的二进制数据,转化为在新解决方案中编写的数据结构.4我的尝试--我使用SerializationBinder(见下面代码)将list的类型成功的重新定位了,但是list的内

初学,求助net.mindview.util.Print.*导入的问题

问题描述 classpath路径已经设置完毕,左边的util包已经出现了,但导入还是失败!请帮忙一下,不尽感激!!!

poj-初学搜索 求助 POJ 3309 思路...

问题描述 初学搜索 求助 POJ 3309 思路... RT 链接: 点击打开 解决方案 http://blog.csdn.net/libin56842/article/details/41873215

Vim技能修炼教程(13) - 变量

VimScript变量 上节我们介绍了Python和Ruby来编写Vim插件的方式. 不过,Python和Ruby并不是所有的Vim都支持的功能,如果以最小依赖的原则来说,还是原汁原味的Vimscripts是放置四海Vim而皆灵的方式.当代码规模变大时,Python,Ruby,Perl这些语言的引入将带来较高的效率.但是Vimscripts仍然是最基本的Vim语言,值得我们首先学好. 变量 做为一种脚本语言,Vimscript当然是支持变量的. 不过Vimscript的特色是,显式指定作用域.也

java中的反射的变量定义问题

问题描述 java中的反射的变量定义问题 新人初学,还望各位能多多帮助 我在学习反射的过程中,遇到这样一个问题 String s1 = new String (new StringBuffer("abc")); 这条语句我看了下JDK文档,发现String的构造函数中有一个构造方法的参数是StringBuffer的对象,然后又看了看StringBuffer的定义,发现这条语句等于 String s1 = "abc"; 为什么要这样写呢, 还有 Constructor

二进制-求助,怎么将编码结果用 bit 位存到文件中

问题描述 求助,怎么将编码结果用 bit 位存到文件中 对一篇英文文章出现的字符进行Huffman编码,然后要将编码表和英文文章保存到文件中,编码结果必须是二进制形式,即0和1要用bit位表示,不能用字符'0'和'1'表示 解决方案 计算机最小单位是字节 8位 解决方案二: 我知道啊,所以不能用字符型的,要用bit位啊 解决方案三: 文件可以在打开时,以二进制的形式打开. if( (fp=fopen(filename,"wb"))== NULL ) { printf("Can

c++ 编程问题-大神!求助!初学!C++想编写一个基于命令提示符的日记本

问题描述 大神!求助!初学!C++想编写一个基于命令提示符的日记本 初学C++想编写一个基于命令提示符的日记本代码没有报错,但是程序不能按步骤执行.菜单项1.写日记2.查看历史(暂时不实现)3.退出编译环境用的visual studio 2013 代码如下:/*menuinputsave*/#include using namespace std;const int d_array=20;void diary_menu();int judge_dparameter();void cycle_me

c++-初学C++中类的使用,求助

问题描述 初学C++中类的使用,求助 初学类的使用,在Accelerated C++上遇到编程题目如下:编写一个类以及相关的函数以为学生产生成绩,用P/F表示成绩假设只根据期中和期末成绩来计算,而且,如果一个学生的平均考试分数大于等于60的话,那这个学生及格输出时列出学生姓名并列出相应的成绩,成绩用P/F表示从data.txt读入成绩信息,将成绩输出到result.txt data.txt截图如下: 以下是我的代码:#include#include#include#include#include

在输入一个实数,输出对应的double和float类型在内存中的二进制内容

问题描述 在输入一个实数,输出对应的double和float类型在内存中的二进制内容 在输入一个实数,输出对应的double和float类型在内存中的二进制内容 解决方案 #include <iostream> using namespace std; int main() { double x = 1.234; float y = 1.234; char * a = (char *)(void *)&x; char * b = (char *)(void *)&y; cout