|
From: Sven Peeters on 9 Feb 2006 04:42 Hi, I've got a problem with the atof function when using a certain string. Example Code ( We use VS6 ) : /* atof example */ #include <stdio.h> #include <stdlib.h> #include <math.h> int main () { double n; char *s; s = "0.2100000"; n = atof(s); return 0; } If you look in the watch window, the value of n is 0.20999999 instead if 0.21. This gives me some rounding errors further down in my program. Unfortunately 21 is the most common used VATrate in my country. How can I sove this that atof converts correctly. Sven Peeters Belgium
From: Bruno van Dooren on 9 Feb 2006 05:29 > If you look in the watch window, the value of n is 0.20999999 instead if > 0.21. > This gives me some rounding errors further down in my program. > Unfortunately 21 is the most common used VATrate in my country. you get 0.20999999 because 0.21 simply does not exist as a floating point number. everything behind the decimal symbol is an approximation that is guaranteed to be correct up to n digits behind the decimal place, where n depends on your format. double is more precise than float. search google for 'what every programmer needs to know about float arithmetic' and you'll get a whole lot of articles with precise explanations. -- Kind regards, Bruno. bruno_nos_pam_van_dooren(a)hotmail.com Remove only "_nos_pam"
From: Alex Blekhman on 9 Feb 2006 08:09 Sven Peeters wrote: > If you look in the watch window, the value of n is > 0.20999999 instead if 0.21. This gives me some rounding > errors further down in my program. Floating point calculations are inexact due to binary floating point representation in computers. You have sevearal choices: 1. Manage all calculations in floating point and round results from time to time. 2. Use integers to represent currency values. Look for CURRENCY and VARIANT in MSDN. You can take source of COleCurrency MFC class as example. 3. Buy expensive third party library for financial calculations. HTH Alex
From: David Webber on 9 Feb 2006 09:03 "Sven Peeters" <SvenPeeters(a)discussions.microsoft.com> wrote in message news:245352A2-4FEF-407A-B208-2DBAD3455046(a)microsoft.com... > If you look in the watch window, the value of n is 0.20999999 instead if > 0.21. > This gives me some rounding errors further down in my program. > Unfortunately 21 is the most common used VATrate in my country. > > How can I sove this that atof converts correctly. It *is* converting correctly. If you use doubles, you will get it right to around 16 sig figs, and it can't do better. When you print the final answer just round everything to two decimal places. Unless you are doing extremely long winded calculations, the rounding error won't propagate that far. Schematically something like: double result = ...; int n = nearest_integer( result * 100 ); printf( "%d.%02d", n/100, n%100 ); It's much easier than trying to hold floating point numbers to an accuracy greater than the format can manage! Dave -- David Webber Author MOZART the music processor for Windows - http://www.mozart.co.uk For discussion/support see http://www.mozart.co.uk/mzusers/mailinglist.htm
From: David Webber on 9 Feb 2006 09:27 "Alex Blekhman" <tkfx.N05P4M(a)yahoo.com> wrote in message news:eVqjgoXLGHA.904(a)TK2MSFTNGP10.phx.gbl... > Floating point calculations are inexact due to binary floating point > representation in computers. You have sevearal choices: Let me just add that floating point representations of numbers are intrinsically inexact - not just because of the computer representation. 1/3 is a precise number 0.333333333... to any finite number of places is an approximation. [Of course only rational numbers can be stored exactly as fractions. Irrationals like sqrt(2) cannot be.] The normal scientific convention is that 0.21 is a number somewhere between 0.205 and 0.215 And that 0.210 is a number between 0.2095 and 0.2105 And that successive trailing zeroes imply a greater and greater precision. The computer's error of 1 in the last stored sig fig is entirely consistent with this. The problem arises if you try to interpret 0.21 as meaning 0.21 followed by an infinite number of trailing zeroes (or the exact rational number 21/100). This spurious exactness is not invariant under a change of arithmetic base. For example in a ternary representation, where we use digits 0,1,2, to count 1, 2, 10, 11, 12, 20, ... the number 0.10000000000000000000... is a representation of one third, which is in decimal: 0.33333333333333333333... In the first case the trailing zeroes go on for ever, and in the second the trailing threes go on forever. There's no essential difference. But if you (foolishly) take the view that 0.1 is "exactly one third" in the first case, then you have a number which you believe to be "exact" in ternary but which cannot be represented "exactly" in decimal. So (I imagine) it is that if you assume 0.21 is "exact" in decimal, it ghas no "exact" hexademial representation. Much better to come to terms with floating point representations as being inexact in *all* cases, and *not* just because of the binary representation used by computers. It derives from the fact that for any pair of different real numbers there is always another one, different from both, between them (which is not a property of the integers). It is a subject which predated computers by a long long way! Dave -- David Webber Author MOZART the music processor for Windows - http://www.mozart.co.uk For discussion/support see http://www.mozart.co.uk/mzusers/mailinglist.htm
|
Next
|
Last
Pages: 1 2 Prev: Linking Problems (libc on VS2005) Next: serial port WriteFile() error 997 overlap |