在工作中我发现了一个C#浮点数的精度问题,以下的程序运行结果并未得到我预期的结果:

view source

print?

01 namespace FloatTest
02
03     class Program
04     
05         static void Main(string[] args)
06         
07             double a = 0.0001;
08             float b = 0.1F;
09   
10             int c = (int)((a * 1000) / b);
11   
12             Console.WriteLine("c = {0}", c);
13   
14             Console.ReadLine();
15         
16     
17 }

我期望的结果是得到1,结果程序返回的结果为c = 0

这让我想到了可能是因为浮点数采用IEEE754的表示方法,在运算中b会转换成double,可能是在转换中算法的问题导致精度丢失,为了证实该问题,我做了下面的实验:

view source

print?

01 namespace FloatTest
02
03     class Program
04     
05         static void Main(string[] args)
06         
07             double a = 0.0001;
08             float b = 0.1F;
09   
10             int c = (int)((a * 1000) / b);
11   
12             Console.WriteLine("a = {0}", a);
13             Console.WriteLine("b = {0}", Convert.ToDouble(b));
14             Console.WriteLine("c = {0}", c);
15   
16             Console.ReadLine();
17         
18     
19 }

这次果然得到了意料中的结果:float在转成double的时候出现了精度的丢失问题

a = 0.0001
b = 0.100000001490116
c = 0

如果是在类型转换的时候导致的精度丢失,那我把b改为double应该可以解决这个问题:

view source

print?

01 namespace FloatTest
02
03     class Program
04     
05         static void Main(string[] args)
06         
07             double a = 0.0001;
08             double b = 0.1;
09   
10             int c = (int)((a * 1000) / b);
11   
12             Console.WriteLine("a = {0}", a);
13             Console.WriteLine("b = {0}", Convert.ToDouble(b));
14             Console.WriteLine("c = {0}", c);
15   
16             Console.ReadLine();
17         
18     
19 }

这次却是得到我们期望的结果:

a = 0.0001
b = 0.1
c = 1

因此,在程序中,我们应该尽量的避免浮点数类型转换导致的精度丢失。

我在GCC上做了同样的实验,结果不管哪种方式得到的结果都是正确的,我只能说可能是double Convert.ToDouble(float)的实现的原因导致的。

C#中float, double的精度问题的更多相关文章

  1. Java中float/double取值范围与精度

    Java浮点数 浮点数结构 要说清楚Java浮点数的取值范围与其精度,必须先了解浮点数的表示方法,浮点数的结构组成,之所以会有这种所谓的结构,是因为机器只认识01,你想表示小数,你要机器认识小数点这个 ...

  2. float,double等精度丢失问题 float,double内存表示

    问题提出:12.0f-11.9f=0.10000038,"减不尽"为什么? 来自MSDN的解释: http://msdn.microsoft.com/zh-cn/c151dt3s. ...

  3. java中float/double浮点数的计算失精度问题(转)

    如果我们编译运行下面这个程序会看到什么? public class Test  {    public static void main(String args[]) {                ...

  4. 神奇:java中float,double,int的值比较运算

    float x = 302.01f;    System.out.println(x == 302.01); //false  System.out.println(x == 302.01f); // ...

  5. 打印出C# 中float ,double 在内存中的存放形式

    float floatA = 2.2f; ); ; i < ;++i ) { uint temp = 0x80000000 & (a << i); ) { Console.W ...

  6. Java 中的浮点数取精度方法

    Java 中的浮点数取精度方法 一.内容 一般在Java代码中取一个double类型的浮点数的精度,四舍五入或者直接舍去等的方式,使用了4种方法,推荐使用第一种,我已经封装成工具类了. 二.代码实现 ...

  7. 【转】JAVA程序中Float和Double精度丢失问题

    原文网址:http://blog.sina.com.cn/s/blog_827d041701017ctm.html 问题提出:12.0f-11.9f=0.10000038,"减不尽" ...

  8. Java中浮点类型的精度问题 double float

    要说清楚Java浮点数的取值范围与其精度,必须先了解浮点数的表示方法与浮点数的结构组成.因为机器只认识01,你想表示小数,你要机器认识小数点这个东西,必须采用某种方法.比如,简单点的,float四个字 ...

  9. 精确计算java中float和double的精度

    [本文相关的代码放在github上.地址为:https://github.com/VigourJiang/StructuredFloat] Java中double类型的格式基本遵循IEEE 754标准 ...

随机推荐

  1. 多个activity跳转保留内存使用intent传递数据问题_新手

    /////本来是做的activity跳转,普通那种,但是会在调回来会销毁原来的,重新调用onCreate方法, 后来参考[http://blog.csdn.net/qq_26918031/articl ...

  2. SpringMVC框架(四)文件的上传下载,上下文路径

    文件目录: SpringMVC配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...

  3. 在SQLSERVER中创建DBLINK,操作远程服务器数据库

    --配置SQLSERVER数据库的DBLINK exec sp_addlinkedserver @server='WAS_SMS',@srvproduct='',@provider='SQLOLEDB ...

  4. java使用spark/spark-sql处理schema数据(spark1.6)

    1.spark是什么? Spark是基于内存计算的大数据并行计算框架. 1.1 Spark基于内存计算 相比于MapReduce基于IO计算,提高了在大数据环境下数据处理的实时性. 1.2 高容错性和 ...

  5. 为啥REST如此重要?

    摘要:REST——表征状态转移,由于REST模式的Web服务更加简洁,越来越多的Web服务开始采用REST风格设计和实现.例如,Amazon.com提供接近REST风格的Web服务进行图书查找:雅虎提 ...

  6. Why does eclipse automatically add appcompat v7 library support whenever I create a new project?

    Best ways to solve these: Firstly in project,Right click->properties->Android.There you can se ...

  7. CoreCLR源码探索(七) JIT的工作原理(入门篇)

    很多C#的初学者都会有这么一个疑问, .Net程序代码是如何被机器加载执行的? 最简单的解答是, C#会通过编译器(CodeDom, Roslyn)编译成IL代码, 然后CLR(.Net Framew ...

  8. Guava快速入门

    Guava快速入门 Java诞生于1995年,在这20年的时间里Java已经成为世界上最流行的编程语言之一.虽然Java语言时常经历各种各样的吐槽,但它仍然是一门在不断发展.变化的语言--除了语言本身 ...

  9. win10 uwp 进度条 WaveProgressControl

    昨天看到了有个大神做出好看的进度条样式,于是我就去抄袭他的代码,但是发现看不懂,于是本文主要翻译就是大神说这个控件如何做. 本文翻译 https://stackoverflow.com/a/46057 ...

  10. 【转】S3C2440与SDRAM NorFlash NandFlash连线分析

    一.SDRAM(HY57V561620F)连线分析 1.  S3C2440 有27根地址线ADDR[26:0],8根片选信号ngcs0-ngcs7,对应bank0-bank7,当访问bankx 的地址 ...