Sign in to follow this  

Specyfing double precision

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! I need to be able to specify how many decimals a double should have. Does anybody know a way to do this using C++? So if I've got 1.5328 and want to change it to 3 decimals it would become 1.533. Thanks in advance

Share this post


Link to post
Share on other sites
Examples can be found in other users code. Assuming you're talking about printing variables via:

cout << "My Variable: " << variable << endl;


Then this google search is the one you should use on your path to elightenment:

http://www.google.com/search?q=double+precision+cout&sourceid=firefox&start=0&start=0&ie=utf-8&oe=utf-8

Copy 'n paste, and read what I put in as the query so you might learn how better to google the answer to your future questions.

-Mike

Share this post


Link to post
Share on other sites
nope, that's not what I'm looking for...I want to do calculations with the specified number of decimals. I have googled for it but only found what you described above...

Share this post


Link to post
Share on other sites
Quote:
Original post by petewood
multiply by 1000 and convert to integers.
The problem with this is that doubles have a larger range than integers.

The proper way would be:
double RoundToNearest(double number, double precision, double base = 0.0)
{
if(number >= base)
{
return floor((((number - base) / precision) + 0.5) * precision) + base;
}
else
{
return ceil((((number - base) / precision) - 0.5) * precision) + base;
}
}

To round to 3 decimals, you'd use RoundToNearest(number, 0.001)

It will always round 'away' from 'base' (with base = 0, negative numbers are rounded properly {I think}), and the numbers it will return should always be representable as (base + (int * precision))

You might have to play around with the above to get it working properly, but I think I have it correct.

To use this to properly do 3-decimal math, you'd have to put it around every operation you perform. Since that would be extremely tedious, I suggest making a number class that mimics double and automatically does the digit chopping constantly.

Also, if you want to do math via FPU assembly, there might be some mode you could change on there, but I'm not sure.

[Edited by - Extrarius on September 17, 2004 3:20:30 PM]

Share this post


Link to post
Share on other sites
You really really are better off using the computer's arithmetic internally and just chopping things to 3 decimals when you need to output a value. There is no datatype that will store things in base 10 with 3 decimal digits; the computer just doesn't think that way. If you try to limit the digits after every step of calculation, then you potentially throw away precision while also slowing things down.

On the other hand, if you really need things to work that way (i.e. your numbers are conceptually a fixed number of thousandths), and you don't need values greater than 2 million-odd ((2^31 - 1) / 1000), then I would go with petewood's suggestion. It will be efficient and avoid weird problems due to rounding.

Share this post


Link to post
Share on other sites
Well, multiplying and dividing fixed point numbers isn't quite trivial, and you'll constantly be converting between fixed point and floating if you're doing anything more complex like roots, trig, etc. Also, if you do it that way, you'll have a lot more error since you'll miss those 0.0005<= x < 0.001 parts that would effect proper rounding.

As far as using the round only for displaying numbers, I agree with that.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
The problem with this is that double precision cannot accurately represent pretty much any decimal number that isnt a whole number.

This problem also exists in a fixed point scheme that uses a fixed power-of-two exponent (basically, double precision floats use the same technique as power-of-two fixed point, but also store an exponent which indicates what power of two is being used)

Consider "16.16" fixed point - accurately representing 0.1 is not possible. How about "32.32" fixed point? Nope. Still not possible.

What you need is a power-of-ten exponent and IEEE floats do not have such a feature. Your only recourse is to use a strategy similar to microsofts Currency datatype, which is simply a 64-bit fixed point scheme with a power-of-ten exponent of E+4

Multiplication and division under your own fixed point scheme isnt very complicated, you just have to make sure that you square/unsquare your exponents after such operations. proper rounding would be a slight hassle.

- Rockoon

Share this post


Link to post
Share on other sites
Quote:
Original post by wall
nope, that's not what I'm looking for...I want to do calculations with the specified number of decimals. I have googled for it but only found what you described above...
Could you please elaborate a little on what you want to use this for, as it would help us all provide better answers. It's always difficult when people can't see an obvious reason for you wanting to do what you're wanting to do.

e.g. Do you need to be using doubles? How many digits do you need left of the decimal point? If you only need 6lhs + 3rhs then the preferred solution would probably be to use int's multiplied by 1000. I have done a similiar thing myself before when storing weights with a 0.1kg resolution (*10). (or pounds if you're american)

Share this post


Link to post
Share on other sites

This topic is 4839 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this