简体   繁体   English

Visual C ++ 2008 Express调试器中双精度类型的数值精度

[英]Numerical precision of double type in Visual C++ 2008 Express debugger

I'm using Visual C++ 2008 Express Edition and when i debug code: 我正在使用Visual C ++ 2008 Express Edition,并且在调试代码时:

double x = 0.2;

I see in debugging tooltip on x 0.20000000000000001 我在x 0.20000000000000001的调试工具提示中看到

but: 但:

typedef numeric_limits< double > double_limit; 
int a = double_limit::digits10

gives me: a = 15 给我:a = 15

Why results in debugger are longer than normal c++ precision? 为什么调试器中的结果比正常的c ++精度长? What is this strange precision based on? 这种奇怪的精度基于什么?

My CPU is Intel Core 2 Duo T7100 我的CPU是Intel Core 2 Duo T7100

What you are seeing is caused by the fact that real numbers (read floating-point) cannot be expressed with perfect precision and accuracy in binary computers. 您所看到的是由于以下事实造成的:在二进制计算机中,实数(读取的浮点数)无法以完美的精度和准确性来表示。 This is a fact of life. 这是事实。 Instead, computers approximate the value and store it in memory in a defined format. 取而代之的是,计算机将值近似并以定义的格式将其存储在内存中。

In the case of most modern machines (including any machine your'e running MSVC Express on), this format is IEEE 754 . 对于大多数现代计算机(包括运行MSVC Express的任何计算机),此格式为IEEE 754

Long story short, this is how real numbers are stored in IEEE 754: there is one sign bit, 8 exponent bits and 23 fraction bits (for float data type -- doubles use more bits accordingly but the format is the same). 长话短说,这就是实数在IEEE 754中的存储方式:有一个符号位,8个指数位和23个小数位(对于float数据类型-相应地, doubles使用更多位,但格式相同)。 Because of this, you can never achieve perfect precision and accuracy. 因此,您永远无法获得完美的精度和准确性。 Fortunately you can achieve plenty of accuracy and precision for almost any application including critical financial systems and scientific systems. 幸运的是,对于几乎所有的应用程序(包括关键金融系统和科学系统),您都可以达到足够的精度和精确度。

You don't need to know everything there is to know about IEEE754 in order to be able to use floating-points in your code. 为了能够在代码中使用浮点,您不需要了解关于IEEE754的所有知识。 But there are a few things you must know: 但是,您必须了解几件事:

1) You can never compare 2 floating point values for equality because of the rounding error inherent in floating point calulation & storage. 1)由于浮点计算和存储中固有的舍入误差,您永远无法比较两个浮点值是否相等。 Instead, you must do something like this: 相反,您必须执行以下操作:

double d = 0.2;
double compare = 0.000000001;

double d2 = something;

if( (d - d2 < compare) && (d2 - d < compare) )
{
  // numbers are equal
}

2) Rounding errors compound. 2)舍入误差复合。 The more times you perform operations on a floating point value, the greater the loss of precision. 对浮点值执行操作的次数越多,精度损失就越大。

3) You cannot add two floating points of vastly different magnitude. 3)您不能添加两个大小相差很大的浮点。 For example, you can't add 1.5x10^30 and 1.5x10^-30 and expect 60 digits of precision. 例如,您不能将1.5x10 ^ 30和1.5x10 ^ -30相加并且不能期望60位精度。

The exact value that the double literal 0.2 gives you is 0.200000000000000011102230246251565404236316680908203125. 双字面量0.2给出的确切值是0.200000000000000011102230246251565404236316680908203125。

Most functions that output doubles cut after a certain amount of decimal digits, that's why you are under the illusion that 0.2 actually yields 0.2 大多数输出​​双精度函数的函数都会在一定数量的十进制数字后截断,这就是为什么您会误以为0.2实际上会产生0.2

Here is how I got the exact value: 这是我获得确切值的方式:

public static void main(String[] args)
{
    System.out.println(new java.math.BigDecimal(0.2));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM