Solved

_fcvt returns wrong number?  What else can I use.

Posted on 1998-07-13
4
307 Views
Last Modified: 2008-02-01
Hi.  This short program has been puzzling me.  the _fcvt function adds a 2 to my number during
conversion.  I'm using Microsoft Visual C++ 4.0.  What else can I use to convert to a string. I tried evct and I
get the same result.  Thanks.

#include <stdlib.h>

void main(){

int sign, decimal_spot;
char* answer;
double startNo = 999999999999.9;

answer = _fcvt(startNo, 15, &decimal_spot, &sign) ;
// answer = 99999999999990020000000000
//  the answer has a 2 in it, why?  Is there a work around
}
0
Comment
Question by:cconis
  • 2
4 Comments
 

Author Comment

by:cconis
ID: 1167709
Edited text of question
0
 

Author Comment

by:cconis
ID: 1167710
Adjusted points to 100
0
 
LVL 6

Accepted Solution

by:
alamo earned 100 total points
ID: 1167711
Unfortunately, floating point numbers aren't always precise. This fact is often hidden by the fact that you don't usually need numbers with that many digits of precision - you are asking for 26 digits of precision! It is giving you 12. There is no way around this without going to a floating point number with more precision than a double, and even then there are cases where you can't solve it completely.

The number after the decimal point is effectively stored as a fraction with the denominator being a power of 2. Change .9 to .5 or .75 or a fraction that can be respresented as something over a power of 2 (.5=1/2,  .75=3/4, etc) and you'll find the fraction will be prescise. But .9 doesn't divide evenly into any powers of two until the powers get large, so when it converts it to a fraction there's a rounding error. I am not certain what fraction your .9 is, but here's an example that is close:
9 * 2^13 is 7372.8 / 8192,
which it rounds off to 7373 / 8192 for storage,
which when you convert back to decimal is 0.900024414

Changing the total value of the entire number also affects this: making the number smaller means more space is available to store the fraction, so the better the chance there's  be a large power of two which can represent the fraction exactly, or at least more precisely.

The reason you don't normally see rounding errors like this is that programs usually set the digits of precision much smaller.... so that _fcvt rounds off properly when converting back to decimal. So maybe that's the real answer as to how you can avoid this problem.

Programs which need absolute precison, such as financial programs where being off by a penny is a problem, don't use floating point because of the above. They use integers, sometimes building their own math packages so that they can get 100s of digits of precision.

Hope this explains it, let me know if anything isn't clear!
0
 
LVL 22

Expert Comment

by:nietod
ID: 1167712
Note one an Intel based computer (IBM compatible) a float will store approximately 7 decimal digits accurately.  Then you will see rounding errors after the first 7 digits.  (sometimes 6, sometimes 8).

double will store about 15 digits accurately.  (That is precisely what you have above!)
long double will store about 19 digits accurately.  That gives you about 4 more digits than you have now.

mainframes have larger floating points with even more accuracy, but you probably need a cray computer for 26 digits of floating point accuracy.  
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Visual c++ and text files 7 60
returning a dereferenced pts in C++ 10 142
Would like to move button in a function 3 73
Should CArray be used for a list of pointers in C++? 19 97
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

861 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now