Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com To: Marco Craveiro Cc: cygwin AT cygwin DOT com Subject: Re: atof returns a value that is slightly greater than the original string References: <1000153353 DOT 1101 DOT 8 DOT camel AT darkroom> From: James Youngman Date: 10 Sep 2001 22:12:00 +0100 In-Reply-To: <1000153353.1101.8.camel@darkroom> Message-ID: Lines: 67 User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Marco Craveiro writes: > int main (void) > { > float f = atof ("695.40"); > > cout << f; > } > > (gdb) p f > $2 = 695.400024 ----> after assignment > > since I need this the data to generate a sum, the sum ends up a bit off > because of this. and unfortunatelly, because there is so many people > with the #include problem, its impossible to search the web properly. > I'm sure its something i'm doing (or not doing), just can't see > what... This is not a bug in Cygwin. This is because of the fact that a float is almost never an exact representation of a decimal number. Each bit in a float represents a power of two which is either added to the total value, or not. Hence 695 can be represented exactly in binary as 1010110111, but the extra 0.4 is a problem. Using a fairly large number of binary digits, you can get quite close :- shell $ ( echo obase=2; echo scale=30; echo 6954/10 ) | bc 1010110111.011001100110011001100110011001100110011001100110011001100\ 1100110011001100110011001100110011001100110 ...but of course this is not exact (the backslashes here are just for readability). Unfortunately there are only 32 bits of data in a float, so the approximation used in a float is even less. If we change your program to use more precise types we get the following results :- float 695.400024 double 695.39999999999998 long double 695.39999999999997726263245567679405 If you want more precision still, you can use Bruno Haible's excellent CLN library (which is written in C++ and provides a good C++ API for extended precision arithmetic, and was originally written in order to provide Common Lisp bignum support). If you need "infinite" precision, CLN also offers a 'rational' representation which would represent "695.4" as "6954/10". However, as you continue to calculate with rational values, the large number of digits used on the top and bottom of the fraction can use lots of RAM up. There are also lots of things you can't use rational arithmetic for, for example trigonometry or root extraction. The other place to look for an explanation of this problem is the FAQ lists for the comp.lang.c and comp.lang.c++ newsgroups. See ftp://rtfm.mit.edu/. -- James Youngman Manchester, UK. +44 161 226 7339 PGP (GPG) key ID for is 64A95EE5 (F1B83152). -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/