一个关于浮点数运算的简单问题(急)

chsal 2003-10-16 11:50:16
请看如下的测试程序
#include<stdio.h>

main() {
float a,b;
clrscr();
a=2000.0001;
b=200;
printf("%f",a-b);
getch();
}

预想中的答案应该是1800.0001,但是运行以后却是1800.000122。
如果把a改成200.0001,预想的结果应该是0.0001,但是得到的却是0.000107
如果在运算以后再乘100的话,错误就更大了。
这个问题应该怎么解决呢?
...全文
74 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
fireinsky 2003-10-16
  • 打赏
  • 举报
回复
果真是,double就行了
chsal 2003-10-16
  • 打赏
  • 举报
回复
那关于这个误差是不是就不能克服了呢?
(我用的是Turboc2.0)
chsal 2003-10-16
  • 打赏
  • 举报
回复
但是如果把a,b改为double,a=200.000000001,如果输出格式改为%e,那答案就也不对了,是不是只能用double计算,用%f输出,才能得到正结果,用double算200.000000001-200就永远得不到正确答案了呢?
likangnian0128 2003-10-16
  • 打赏
  • 举报
回复
这是内存误差
与程序无关
——————————————————————————————————————————
不应该称作“内存”误差

是因为浮点数设计的时候就设计成为会有误差的,内存可没有产生误差。
playboyxp 2003-10-16
  • 打赏
  • 举报
回复
这是内存误差
与程序无关
williamVII 2003-10-16
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;

int main(void)
{
float a=200.0001;
float b=200;
cout<<a-b;
}

//偶的结果是0.000106812
//楼主用的是TC2.0吧.
zyp2kyear 2003-10-16
  • 打赏
  • 举报
回复
UP
double a,b就行了
likangnian0128 2003-10-16
  • 打赏
  • 举报
回复
float和double只是数字的一种近似表示,而无法对任何数字都达到绝对精确。

学习一下浮点数在计算机是如何保存为2进制的,就应该明白了。
darcymei 2003-10-16
  • 打赏
  • 举报
回复
float精度不够,改double
chsal 2003-10-16
  • 打赏
  • 举报
回复
谢谢各位
yintongshun 2003-10-16
  • 打赏
  • 举报
回复
呵呵,用double吧
likangnian0128 2003-10-16
  • 打赏
  • 举报
回复
想要绝对精确的计算小数,你只有自己建立一个表示小数的方法、以及可以对这种方法表示的小数进行计算的函数……

而且,这种情况下,小数的计算会相当的慢……
likangnian0128 2003-10-16
  • 打赏
  • 举报
回复
就是说如果想得到准确的小数计算结果,就必须用double计算,用%f或者用限定小数位数的方法去输出结果如%0.6e?
————————————————————————————————————————————
不。

如果使用浮点数,没有任何办法可以保证计算中不出现误差。

实际上,绝大部分的浮点数在内存中的表示都是有误差的(你已经看到0.1在内存中实际上是什么样子了吧?)!但是在显示的时候,因为四舍五入的关系,误差可能刚好被消除掉。

但是,如果浮点数经过一系列计算,误差可能象滚雪球一样,越滚越大,导致显示的时候就会看到明显的存在误差

不过,double比float的误差要小。
chsal 2003-10-16
  • 打赏
  • 举报
回复
也就是说如果想得到准确的小数计算结果,就必须用double计算,用%f或者用限定小数位数的方法去输出结果如%0.6e?
likangnian0128 2003-10-16
  • 打赏
  • 举报
回复
但是如果把a,b改为double,a=200.000000001,如果输出格式改为%e,那答案就也不对了,是不是只能用double计算,用%f输出,才能得到正结果,用double算200.000000001-200就永远得不到正确答案了呢?
————————————————————————————————————————————
浮点数不是对任何数都能达到绝对精确的,相反,浮点数实际保存的值经常会和你想要它保存的值有小小的误差。

这是二进制表示小数时产生的问题,
大家都知道,二进制表示整数(在一定的数值范围内)是没有误差
形如abcd(a、b、c、d均为0或者1)的二进制表示a*2^3+b*2^2+c*2^1+d*2^0
用类似方法去表示小数点后面的部分的时候
形如.abcd(a、b、c、d均为0或者1)的二进制表示a*2^-1+b*2^-2+c*2-3+d*2^-4
例如.1010就表示:1*0.5+0*0.25+1*0.125+0*0.0625 = 0.625
如果想要表示十进制的0.1,用8位二进制的浮点数就是:
.00011001 = 1*2^-4+1*2^-5+1*2^-8 = 0.09765625,和0.1有误差

尽管可以增加二进制的位数(例如64位)来提高精度,
但有的小数在浮点数的表示方法下,无论多少位,都是没有办法精确表示的。
chsal 2003-10-16
  • 打赏
  • 举报
回复
fireinsky(喜子) 答案是:9.999894246e-10 还是不对啊
fireinsky 2003-10-16
  • 打赏
  • 举报
回复
chsal():用double计算,用%e输出是因为你的输出精度不够造成,你可以试试这个%0.10e输出
Python编程基础教程本教程旨在帮助初学者了解Python编程的基础知识和高级应用。我们将介绍Python的各个方面,包括基础语法、数据类型、控制结构、函数、文件操作、面向对象编程、模块和包、异常处理、装饰器、生成器、迭代器以及协程。1. Python基础Python是一种解释型、交互式的编程语言。它具有简单易学的语法和丰富的库,使得开发过程既快速又高效。在开始学习Python之前,建议您先熟悉基本的计算机科学概念,例如变量、数据类型、运算符等。2. 数据类型Python具有多种数据类型,包括数字(整数和浮点数)、字符串、布尔值、列表、元组、集合和字典等。这些数据类型在Python中有着广泛的应用,从简单的数值计算到复杂的数据处理。3. 控制结构控制结构是编程中的基本组成部分,它们决定了程序如何执行。Python支持条件语句(if-elif-else)和循环语句(for和while),可以根据程序中的特定条件和情况来选择适当的操作。4. 函数函数是封装一段代码的便捷方式,它们可以在需要时被调用。在Python中,您可以定义函数,并使用参数来传递数据。函数可以返回值,以便在调用它们时使用。5. 文件操作文件操作是编程中常见的任务之一。Python提供了许多内置的函数和方法来进行文件操作,如读取、写入和删除文件等。此外,Python还支持对文件进行高级操作,如读写二进制文件、文件锁定等。6. 面向对象编程面向对象编程是一种流行的编程范式,它使用类和对象的概念来构建复杂的系统。Python支持面向对象编程,您可以使用类来定义对象,并使用继承和多态等特性来扩展和定制对象的行为。7. 模块和包模块和包是Python中组织代码的重要工具。模块是一个包含Python代码的文件,而包则是一个包含多个模块的目录。通过使用模块和包,您可以轻松地组织和管理大型项目中的代码。8. 异常处理异常处理是Python中处理错误的方式之一。当程序中出现错误时,Python会抛出一个异常。通过使用try-except语句块,您可以捕获并处理这些异常,以确保程序的稳定性。9. 装饰器装饰器是Python中的高级功能之一,它允许您在函数或方法之间添加额外的功能,而不改变其原始实现。装饰器是一种强大的工具,可用于实现各种功能,如日志记录、性能分析等。10. 生成器生成器是Python中的一种特殊类型的迭代器。通过使用生成器函数和方法,您可以在需要时生成数据,而不是一次性生成所有数据。这使得生成器在处理大量数据时非常有用,因为它们可以节省内存空间。11. 迭代器和协程迭代器和协程是Python中的两个重要概念。迭代器允许您遍历容器类型的数据结构(如列表和元组),而协程则是一种异步编程的方式,它允许您在程序中执行多个任务并发执行。这两个概念在处理大量数据和高性能应用程序方面非常有用。

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧