Sign in to follow this  

[C#] How can I speed up float truncation?

This topic is 2544 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

I'm currently trying to truncate a float to a certain number of digits. I've come up with two methods:

1) Convert the float to a string and truncate that
2) Use the decimal.Round method

I've set up a test environment as follows:


private void SpeedTest()
{
// [Method 1]
debugUtilities.StopwatchStart();

float value = 1.0023378734f;

for (int i = 0; i < 10000; ++i)
{
string truncated = StringTools.Truncate(value.ToString(), 4);
}

debugUtilities.StopwatchStop();

// [Method 2]
debugUtilities.StopwatchStart();

for (int i = 0; i < 10000; ++i)
{
float truncated = (float)decimal.Round((decimal)value, 4);
}

debugUtilities.StopwatchStop();
}



The ToString() method (method 1) is always faster.

How can I truncate a float faster (in a similar way to method 2) rather than using method 1?

It seems a little odd that converting it to a string is so much quicker.

Share this post


Link to post
Share on other sites

float value = 1.0023378734f;

int truValue = (int)(value + 0.0005)*10000;
value = truValue/10000;




Give that a try. Did it quick so there might be a lil error in it.

theTroll

Share this post


Link to post
Share on other sites
I've changed the method slightly to accommodate n decimal places:


for (int i = 0; i < 10000; ++i)
{
//float truncated = (float)decimal.Round((decimal)value, 4);
float truncated = Truncate(value, 4);
}


private float Truncate(float value, int decimals)
{
float pow = 10;
decimals -= 1;

for (int i = 0; i < decimals; ++i)
{
pow *= 10;
}

int t = (int)(value * pow);

return t / pow;
}




It's a tiny bit faster but still not as fast as the string method.

Share this post


Link to post
Share on other sites
These are also not correct. Try 12.345678 for example. The multiplier depends on where the decimal point is. Even the string truncation version does not take that into account, and is incorrect.

Share this post


Link to post
Share on other sites
Is it truly necessary to truncate the numbers for your calculations?

Even a simple calculation like (int)(0.000101010f * 10000.0f) / 10000.0f can give you a result like "0.000099899898898," which is precisely not what you want.

Usually, truncation is done when you're outputting the number to the screen or a file; you don't force the float's value to conform to human readable standards, only the output.

Share this post


Link to post
Share on other sites
- You don't include parsing the string back to a float in method 1, which will take up its fair share of time.
- Beware of potential behind-the-scenes caching mechanisms/optimizations. Use different values of each iteration and see if that makes a difference.

Share this post


Link to post
Share on other sites
The truncation is there to shorten the length of the output before displaying on the screen. This means that the string will not be converted back to a float in method 1 but the float will need to be converted to a string in method 2. Apologies for not mentioning this sooner.

Quote:

These are also not correct. Try 12.345678 for example. The multiplier depends on where the decimal point is. Even the string truncation version does not take that into account, and is incorrect.


That is true but it is a string that will be displayed so it will need to be of a certain length. What improvements would you suggest?

Share this post


Link to post
Share on other sites
string s = string.Format("{0:0.0000}", number);


This will be fast enough until it becomes a bottleneck. If this output will be used for rendering on screen, then emitting single glyph of resulting string will take much more time than formatting itself.

Share this post


Link to post
Share on other sites
Thanks Antheus.

Is there any way I can use your method to limit the number of digits it displays (significant figures)?

E.g.

48003.0032 (5 s.f.) would display 48003

48.0030032 would display 48.003

EDIT:

Never mind, I've got it:


string truncated = string.Format("{0:G5}", value);




Thanks again.

Share this post


Link to post
Share on other sites

This topic is 2544 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