Sign in to follow this  
coderWalker

1 decimal point floats

Recommended Posts

I want to keep my floats as 1 1.2 1.4 1.6 1.8 however somtimes i get things like 1.79999999.
This data will be output to the user and must stay to 1 decimal place.

Best way to do this?

I was thinking *10 then static cast int then /10. that doesnt work though.

Share this post


Link to post
Share on other sites
if you want to do it that way, you'd do it like so.

float i = 1.78;
i * 10;
i = static_cast<float>( static_cast<int>(i) / 10);

I didn't test it but that should work... that or stringstream can take the float and I believe you can set the width or decimal precision.

something like

std::Stringstream ss;
ss << std::decprec(1) << i;
ss >> i;

I cant remember of the top of my head.

Share this post


Link to post
Share on other sites
Assuming you are using C++, it might be better to set the precision of the output formatting instead of modifying the number in memory. Streams have a [url="http://www.cplusplus.com/reference/iostream/manipulators/setprecision/"]setprecision[/url] manipulator you can use. Otherwise, something like double d = (int)(num * 10 + 0.5) / 10.0; should do what you want. You may have missed dividing back by a double instead of an integer.

Share this post


Link to post
Share on other sites
Considering that most numbers divided by ten cannot be exactly represented by a floating point, the (x*10)/10 is not a great idea (this is probably what is causing your problem). You should use the output formatting options in whatever language you are using instead.

Share this post


Link to post
Share on other sites
I am using C++.

However I am not using string stream.

This is for the inventory system in my game.
I draw the amount of that item that they have to a texture then draw that.
So any rounding has to be done by me.

Also it needs 1 decimal place to make my math correct and if statements work.

Share this post


Link to post
Share on other sites
In that case you probably do want to switch to a fixed-point representation as Hodgman suggested. Essentially, you use an integer and always know that it really represents 10 times what the actual value is. There is an implementation of a fixed point number [url="http://wiki.yak.net/675"]here[/url], but you may be able to find better with a little searching.

Share this post


Link to post
Share on other sites
If you're using C-style format specifiers, you could use something like this to show only one digit after the decimal point: "%.1f"

Fixed-point representation is a good idea if your internal representation need to be precise, though output does get a little more complicated--especially if you have negative numbers.

Share this post


Link to post
Share on other sites
Go with the approach of storing the value multiplied by 10. It's simple fast and accurate. I've worked on production code that has made good use of this for the last 10 years.
When you output the value, you could do something like this, if you've having trouble with any other methods:[code]cout << (value/10) << "." << (value%10) << endl;[/code]

Share this post


Link to post
Share on other sites
Actually, whether or not the modulus operator returns a negative given a negative input is implementation defined. Your compiler may return a negative, but another compiler is perfectly free to return a positive. See section 5.6 paragraph 4 in the C++ standard.

Share this post


Link to post
Share on other sites
Actually I only need 1 decimal place.

So I multiplited everything by 10.
Store it in an int.

Then when I ouptut i just output number/10

works perfect!
The game shouldn't allow negatives so no prob.

112 11.2
224 22.4
1000 100


Thanks for the help

Share this post


Link to post
Share on other sites
[quote name='freeworld' timestamp='1297822843' post='4774768']
if you want to do it that way, you'd do it like so.

float i = 1.78;
i * 10;
i = static_cast<float>( static_cast<int>(i) / 10);

I didn't test it but that should work... that or stringstream can take the float and I believe you can set the width or decimal precision.

something like

std::Stringstream ss;
ss << std::decprec(1) << i;
ss >> i;

I cant remember of the top of my head.
[/quote]

That doesn't work because the compiler sees a integer division and then a cast to float to assign it to a float variable, if you use 10.0f as the divider it should cast the integer to a float first and do a float division instead. Don't type 10.0 as the compiler interpretes that as a double

Share this post


Link to post
Share on other sites

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