浮点数的分数表达问题

从网上看到不少程序员对浮点数精度问题有很多疑问,在论坛上发贴询问,很多热心人..
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
c语言浮点数的精度问题2
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口C语言浮点数问题
C语言浮点数问题 20
在print语句中浮点数值1201.0用科学记数法%2.2e打印输出结果为啥是1.20e+003呢?为什么不是12.01e+002呢?
因为,标准的是,小数点前只能有一位整数。。
要不,就乱了。。
那120.1e+001也行了。不是吗?
&
那个是标准,统一
的感言:谢谢大家的解答,问题解决了!
其他回答 (4)
没看懂迩的意思。
能拿个题来不、?
貌似迩叙述不清楚。
什么是科学计数法呢?
就是说小数点前只能有一位数字。
所以是1.20e+003而不是12.01e+002!
科学计数法就是为了避免这种不同的书写方式才创造出来的。
而且LZ好像是printf()语句吧!
&
要理解这个问题得知道科学计数法的定义,在科学记数法中,一个数被写成一个1与10之间的实数(尾数)与一个10的幂的积,为了得到统一的表达方式,该尾数并不包括10。也就是说E前面的数的绝对值大于等于1而小于10。所以,打印输出结果为啥是1.20e+003,而不是其他的东西。
科学计数法的用法:
1,a.b e c& :a为整数部分,b位小数部分,e或E为标志,c为多少次方。
其中:a要大于等于1 小于10,c一定要为整数& e前面必须有数据。不可:如 e-4;
另外:a也不可省略。
再不懂百度吧!找自己所需,学自己所学。
&
&
等待您来回答
编程领域专家当前位置:&>&&>&
> 正文 php浮点数比较
php浮点数比较问题解析
发布时间:编辑:
有关php浮点数比较的问题解析,不可能精确的用有限位数表达某些十进制分数,计算机内部处理浮点数的方式决定了浮点数不可能100%的精确,所以在处理浮点数运算时会出现精度损失问题。
有关php的比较问题:永远不要比较两个浮点数是否相等。
内部处理浮点数的方式决定了浮点数不可能100%的精确,所以在处理浮点数运算时会出现精度损失问题。
$a&& =&& 15521.42;&
$b&& =&& 15480.3;&
$c = $a-$b;&
var_dump($c);&&& //php4:float(41.)&& php5:float(41.12)&&
var_dump($c == 41.12);&&&& //bool(false)&&
第一条输出语句:在php4下输出$c可能是41.,或类似的结果,后面的1就属于精度损失的部分。
在php5中对这个问题做了些&优化&,输出结果中不会显示不精确的部分,但同时也会忽视这个问题,以为$c==41.12。
第二条输出语句:在php4和php5中都会输出false。
声明:这不是php的问题,而是计算机内部处理浮点数的问题!在c/java中也会遇到同样的问题。
延伸:同样不能使用&、&、&=或&=
那么,应该怎么比较两个浮点数相等呢?
没办法精确的比较两个浮点数相等!
只能在精度范围内比较(比如上面的示例,只需要比较$c在后两位内等于41.12即可)。
function floatcmp($f1,$f2,$precision = 10) {// are 2 floats equal&&
&&& $e = pow(10,$precision);&
&&& $i1 = intval($f1 * $e);&
&&& $i2 = intval($f2 * $e);&
&&& return ($i1 == $i2);&
function floatgtr($big,$small,$precision = 10) {// is one float bigger than another&&
&&& $e = pow(10,$precision);&
&&& $ibig = intval($big * $e);&
&&& $ismall = intval($small * $e);&
&&& return ($ibig & $ismall);&
function floatgtre($big,$small,$precision = 10) {// is on float bigger or equal to another&&
&&& $e = pow(10,$precision);&
&&& $ibig = intval($big * $e);&
&&& $ismall = intval($small * $e);&
&&& return ($ibig &= $ismall);&
有关php浮点数比较不准的解决方法。
var_dump(($a + $b) == 0.8);
打印出来的值居然为 boolean false
对于浮点数有以下警告信息:
浮点数精度
显然简单的十进制分数如同 0.1 或 0.7 不能在不丢失一点点精度的情况下转换为内部二进制的格式。
造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的 8,因为该结果内部的表示其实是类似 7....。
不可能精确的用有限位数表达某些十进制分数。例如,十进制的 1/3 变成了 0.3333333. . .。
不要相信浮点数结果精确到了最后一位,也永远不要比较两个浮点数是否相等。
如果确实需要更高的精度,应该使用任意精度数学函数或者 gmp 函数。
将以上代码改写为:
var_dump(bcadd($a,$b,2) == 0.8);
即可解决浮点数的计算问题了。
本文标题:
本页链接:
12345678910最近工作中遇到一个浮点数引起的问题,由于要计算费用,结果因为汇率的精度问题,导致计算不准确,给业务带来一些麻烦。
其实不少技术人员也多少了解过浮点数这样那样的问题,对于如何处理也可以使用网上的建议方案,使用bigdecimal解决,不过对于为什么会这样还是不理解,感觉浮点数计算问题高深莫测、难以预测。
由于我们在数学中学过四舍五入的近似舍入的方法,但是直接拿来用于开发是有问题的。首先四舍五入法是十进制的舍入法,而计算机本质上都是二进制,二者在进位上并不一致。浮点数不精准问题本质上就是二进制位数受限制引起的问题,比如java中float型总共是4字节32位,其中有效位数是23位(bit),一位符号,8位阶码(用于在有效位数上乘以2的幂次)。二进制默认的舍入方法是向偶数舍入方法,当然这种方法理解上也有点难度,但是至少与四舍五入方法没有直接对应关系,只要正好卡在第23位就需要舍入,因此会出现最后一位是5以上(十进制)依然可能会在二进制中被舍弃的情况,这也就是很多人感到迷惑的原因。double类型机制一样,位数不一样而已,当然精度更高。
二进制比较容易出现精度问题,比如0.1在二进制中无法全部表示(类似于十进制除不尽),只能近似表示,十进制中的数值只有正好是2的幂次的组合才容易用有限位数表示。有兴趣的人可以研究一下。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:9917次
排名:千里之外
原创:32篇
评论:28条
(1)(1)(1)(1)(3)(1)(2)(3)(1)(3)(15)人气:1006289
访问用户量:417
笔记经验:5904
总积分:117
级别:普通会员
搜索本笔记
ta的交流分类
ta的全部笔记
浏览(1005)|(0)
&&交流分类:|笔记分类:
问题的提出: 如果我们编译运行下面这个程序会看到什么? public class Test{ public static void main(String args[]){ System.out.println(0.05+0.01); System.out. println(1.0-0.42); System.out.println(4.015*100); System.out.println(123.3/100); } }; 你没有看错!结果确实是 0.000005 0.0001 401.94 1.9999 Java中的简单浮点数类型float和double不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上面的错误。现在终于理解为什么要有BCD码了。 这个问题相当严重,如果你有9.元,你的计算机是不会认为你可以购买10元的商品的。 在有的编程语言中提供了专门的货币类型来处理这种情况,但是Java没有。现在让我们看看如何解决这个问题。 四舍五入 我们的第一个反应是做四舍五入。Math类中的round方法不能设置保留几位小数,我们只能象这样(保留两位): public double round(double value){ return Math.round(value*100)/100.0; } 非常不幸,上面的代码并不能正常工作,给这个方法传入4.015它将返回4.01而不是4.02,如我们在上面看到的 4.015*100=401.94 因此如果我们要做到精确的四舍五入,不能利用简单类型做任何运算 java.text.DecimalFormat也不能解决这个问题: System.out.println(new java.text.DecimalFormat(&0.00&).format(4.025)); 输出是4.02 BigDecimal 在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。BigDecimal一共有4个够造方法,我们不关心用BigInteger来够造的那两个,那么还有两个,它们是: BigDecimal(double val) Translates a double into a BigDecimal. BigDecimal(String val) Translates the String repre sentation of a BigDecimal into a BigDecimal. 上面的API简要描述相当的明确,而且通常情况下,上面的那一个使用起来要方便一些。我们可能想都不想就用上了,会有什么问题呢?等到出了问题的时候,才发现上面哪个够造方法的详细说明中有这么一段: Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding. The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(&.1&) is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one. 原来我们如果需要精确计算,非要用String来够造BigDecimal不可!在《Effective Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,这也许是一个小小的失误吧。 解决方案 现在我们已经可以解决这个问题了,原则是使用BigDecimal并且一定要用String来够造。 但是想像一下吧,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类Arith来简化操作。它提供以下静态方法,包括加减乘除和四舍五入: public static double add(double v1,double v2) public static double sub(double v1,double v2) public static double mul(double v1,double v2) public static double div(double v1,double v2) public static double div(double v1,double v2,int scale) public static double round(double v,int scale) Java代码 /** * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 * 确的浮点数运算,包括加减乘除和四舍五入。 */ public class Arith{ //默认除法运算精度 private static final int DEF_DIV_SCALE = 10; //这个类不能实例化 private Arith(){ }/** * 提供精确的加法运算。 * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static double sub(double v1,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static double mul(double v1,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 * 小数点以后10位,以后的数字四舍五入。 * @param v1 被除数 * @param v2 除数 * @return 两个参数的商 */ public static double div(double v1,double v2){ return div(v1,v2,DEF_DIV_SCALE); } /** * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 * 定精度,以后的数字四舍五入。 * @param v1 被除数 * @param v2 除数 * @param scale 表示表示需要精确到小数点以后几位。 * @return 两个参数的商 */ public static double div(double v1,double v2,int scale){ if(scale&0){ throw new IllegalArgumentException( &The scale must be a positive integer or zero&); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理。 * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v,int scale){ if(scale&0){ throw new IllegalArgumentException( &The scale must be a positive integer or zero&); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal(&1&); return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } };
相关笔记推荐
精品视频课程推荐
创建规范的XML文档,DTD的作用,并且可以根据要求创建私用的DTD,通过JavaScript解析XML DOM
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制
课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力
技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......
JavaScript的内置对象--Array、String、Date、Math等,可以通过DOM对象进行对象控制,创建控制菜单及复选框的控制,创建二级联动列表框及列表框选项的移动,JavaScript项目,创建基于JS的商品管理系统。
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术
技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容
系统、完整的学习Spring Web MVC开发的知识。包括:Spring Web MVC入门;理解DispatcherServlet;注解式控制器开发详解;数据类型转换;数据格式化;数据验证; 拦截器;对Ajax的支持;文件上传下载;表单标签等内容;最后以一个综合的CRUD带翻页的应用示例来综合所学的知识
浏览(1005)|(0)
&&交流分类:|笔记分类:
版权所有 Copyright(C) 私塾在线学习网

我要回帖

更多关于 浮点数表示 的文章

 

随机推荐