CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Jan 2002
    Posts
    10

    exact representation of double

    Does anyone know how to exactly represent doubles like "0.1". I know that binary representation of decimal numbers are not always exact. What I am looking for is a technique to work around this problem.

    when you do something like
    double x = 0.1;

    internally x is "0.10000..000001" (may have missed some zeros, but that is irrelevant; what is important here is the trailing 1)

    what I want is to store x in some way so that it is "0.10000 ...00"

    Also, some comments on double comparison will be helpful. I know about the "delta" technique; does anyone know of any other?

    Your help is much appreciated.
    Thanks.

  2. #2
    Join Date
    Jan 2002
    Location
    Germany
    Posts
    20
    Hi,

    maybe that helps, maybe not. It's copied from the Visual Studio help:


    Floating-point decimal values generally do not have an exact binary representation. This is a side effect of how the CPU represents floating point data. For this reason, you may experience some loss of precision, and some floating-point operations may produce unexpected results.

    This behavior is the result of one of the following:

    The binary representation of the decimal number may not be exact.
    There is a type mismatch between the numbers used (for example, mixing float and double).
    To resolve the behavior, most programmers either ensure that the value is greater or less than what is needed, or they get and use a Binary Coded Decimal (BCD) library that will maintain the precision.

    Binary representation of floating-point values affects the precision and accuracy of floating-point calculations. Microsoft Visual C++ uses IEEE floating-point format.

    Example
    /* Compile options needed: none. Value of c is printed with a decimal
    point precision of 10 and 6 (printf rounded value by default) to
    show the difference
    */
    #include <stdio.h>
    #define EPSILON 0.0001 // Define your own tolerance
    #define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
    void main()
    {
    float a, b, c;
    a = 1.345f;
    b = 1.123f;
    c = a + b;
    // if (FLOAT_EQ(c, 2.468)) // Remove comment for correct result
    if (c == 2.468) // Comment this line for correct result
    printf("They are equal.\n");
    else
    printf("They are not equal! The value of c is %13.10f,or %f",c,c);
    }
    Output Result
    They are not equal! The value of c is 2.4679999352 or 2.468000.
    For EPSILON, you can use the constants FLT_EPSILON, which is defined for float as 1.192092896e-07F, or DBL_EPSILON, which is defined for double as 2.2204460492503131e-016. You need to include float.h for these constants. These constants are defined as the smallest positive number x, such that x+1.0 is not equal to 1.0. Because this is a very small number, you should employ user-defined tolerance for calculations involving very large numbers.

  3. #3
    Join Date
    Jun 1999
    Location
    San Diego, CA
    Posts
    600
    You asked the wrong question.

    Doubles are exact in themselves. 0.1 is NOT a double, 0.1 is a decimal point number. 0.1000001 is also a decimal number used by human, not a double used by the computer.

    The question you asked is how to represent a decimal number exactly using a double. Or the reverse question is how to represent a double exactly using decimal number. In most cases the answer is no. There is no exact conversion between the two.

  4. #4
    Join Date
    May 2002
    Location
    grenoble, france
    Posts
    5

    fpu problem

    To my mind, the problem is that the fpu works in binary

    In the most cases, there are problems of accuracy with float. It occurs when the number can't be represented by a sum of 1/(2^n)

    Some float numbers can be exactly represented such as 0.5 (1/2^2) or 0.3125 (1/2^3 + 1/2^5) for instance.

    That is not the case with 0.1, and the number will be between two possibles representations
    Unfortunately, the fpu have never been able to choose the closer value : they always whoose the upper value. That's why you have a 1 at the end of your 0.1000000000000000000000001

    It is shocking because with integer numbers, the problem does not exists, but everybody knows that the computer are bad calculators.

    Hope this help

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured