C#中double值的精度问题

在开发的时候,遇到一个问题,c#中定义一个double变量,当这个变量在很大的时候,让这个变量加上或者减去一个较小的值不会改变其大小(这个其实与double变量的二进制存储机制相关),就是说加上一个值之后的值.comPareTo(原来的值)返回0,就是说他们相等。

于是我想找到哪个具体的值是在加上或者减去1时,值的改变可以被检测到的。于是有了以下代码。

            //因为相当大的范围内都是可以检测到大小改变的,所以不从1开始,节约时间
            double a = 10000000;
            double pre_a = 0;
            double b = 0;
            double c = 0;
            int c1 = 0;
            int c2 = 0;
            double addValue = 1;
            while (true)
            {
                pre_a = a;

                a += addValue;
                b = a + 1;
                c = b + 1;
                c1 = a.CompareTo(b) ;
                c2 = b.CompareTo(c);
                if ((c1 < 0) && (c2 == 0))
                {
                    //输出最后结果
                    Console.WriteLine("a = " + a + "  b = " + b + "  c = " + c);
                    break;
                }
                if ((c1 < 0) && (c2 < 0))
                {
                    addValue *= 2;
                }
                else
                {
                    //求解过程中,跳过了目标值,回到上一个值从新开始找
                    Console.WriteLine("跳过目标值,a=" + a);
                    a = pre_a;
                    addValue = 1;
                }
            }

求出来的结果是:a=90071992647409921

实际上,根据double值的存储结构应该是可以从理论上推算出来这个值的。详细的机制以及使用的注意事项参见MSDN(下方的链接)。这个具体的理论推算过程先留个坑在这里吧,以后有时间了过来填。

参考:

http://technet.microsoft.com/zh-cn/library/system.double

时间: 2024-10-14 05:58:12

C#中double值的精度问题的相关文章

[坑]c#中double转字符串精度丢失问题记录

在项目遇到了一个比较大的double值,然后出现了一些意想不到的状况: double b=1141.161994934082; b.ToString();//'1141.16199493408' 然后发现最后的一个2被丢弃了,最后经过测试这个跟double的数字位数有关,如果超过16位,最后一位就会被丢弃,也就是说2是第17位,所以被丢弃了,找了很多的办法都没有解决这个问题,所以记录一下. 在sql server 2014存进去这个数字的时候,是没有问题的,但是从查询管理器看到的数字也是少了一个

C++中double值的处理

近日看见了一张来自网上的图 父亲看见这图就觉得十分有意思,就给许多村里的大学生们看让他们算,如图这是一道并不难的三元一次方程组问题,我心里一盘算觉得正常算并不能体现我IT精英的与众不同,于是我就说看我变个程序来解题.结果当然遵循装B遭雷劈的至高真理. 这道题目的答案是3.5,4.5,9.5和3.5. 为了尽快解决问题我就是用了最简单的逻辑方法让计算机用大量的运算去堆答案代码如下 1 #include<iostream> 2 using namespace std; 3 void main()

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

要说清楚Java浮点数的取值范围与其精度,必须先了解浮点数的表示方法与浮点数的结构组成.因为机器只认识01,你想表示小数,你要机器认识小数点这个东西,必须采用某种方法.比如,简单点的,float四个字节,前两个字节表示整数位,后两个字节表示小数位(这就是一种规则标准),这样就组成一个浮点数.而Java中浮点数采用的是IEEE 754标准. IEEE 754 标准 更多详见:https://baike.baidu.com/item/IEEE%20754 IEEE 754 标准是IEEE二进位浮点数

java double 计算损失精度

计算double类型的数时有时候会多出0.000000001,会有不确定个数的0,在计算时将其转为BigDecimal就不会出错. BigDecimal sum = new BigDecimal(0.0);                BigDecimal tmp = new BigDecimal(0.0);                for(int i=0; i<list.size(); i++){                    tmp = new BigDecimal(list

c++中double转换成string型(浮点数的格式化)

在日常编程中--包括对话框.关系数据库.金融程序.SMS程序及一切处理数据文件的程序,需要控制小数点后的小数位的情况非常普遍,本文中将要讲 解如何用简单的方法来控制小数位,另外,还要揭开字符串及数据精度的一点点小秘密. 问题的引出 如有一个函数,其可接受一个long double参数,并将参数转换为字符串,结果字符串应保留两位小数,例如,浮点值123.45678应该生成“123.45”这样的字符串.表面上看来 这是一个意义不大的编程问题,然而,如果真要在实际中派上用场,函数应设计为具有一定弹性,

将258.369 double值转为内存表示(科学计数法)

前言 庖丁解牛 - <<庄子>> 庖丁为文惠君解牛,手之所触, 肩之所倚, 足之所履, 膝之所踦, 砉然向然, 奏刀騞然, 莫不中音, 合于<桑林>之舞, 乃中<经首>之会. 文惠君曰:"嘻, 善哉! 技盍至此乎?" 庖丁释刀对曰:"臣之所好者, 道也, 进乎技矣.始臣之解牛之时, 所见无非牛者.三年之后, 未尝见全牛也.方今之时, 臣以神遇而不以目视, 官知止而神欲行.依乎天理, 批大郤, 导大窾, 因其固然, 技经肯綮之未尝

C# 中的值类型和引用类型

原文 C# 中的值类型和引用类型 值类型(value type):int,long,float,double,decimal,char,bool 和 struct 统称为值类型.值类型变量声明后,不管是否已经赋值,编译器为其分配内存. 引用类型(reference type):string 和 class统称为引用类型.当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间.当使用 new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的

swift中Double转String

swift上手有好几天了.发现swift除了本身的几个基本类型转换,一些比较特殊的数值类型转换需要“桥接”到Objective-C来进行- 代码当然也很简单- var numString = "1.0" var numDouble:Double numDouble = String.bridgeToObjectiveC(numString)().doubleValue //相当于objective-c的" numdouble = [numString doubleValue]

MVC框架中的值提供(一)

在MVC框架中action方法中的Model数据的绑定的来源有很多个,可能是http请求中的get参数或是post提交的表单数据,会是json字符串或是路径中的相关数据;MVC框架中针对这些不同的数据来源抽象了IValueProvider接口; public interface IValueProvider { bool ContainsPrefix(string prefix); ValueProviderResult GetValue(string key); } IValueProvide