I have a value of €1850.50. I want a calculation to round this to €1851
My formula is
ToNumber(Round(Replace([Item Data.LHC Part Anaes Rate 2019 (No Rounding)],"€","")))
Currently, it is bringing back €1850. It seems to round values of .5 downwards instead of upwards? This issue is only happening when the value is .50
The reason you're seeing this odd behavior is because .NET (the framework Blue Prism is based on) uses Banker's Rounding to perform rounding functions by default. From the linked page:
Bankers Rounding is an algorithm for rounding quantities to integers, in which numbers which are equidistant from the two nearest integers are rounded to the nearest even integer. Thus, 0.5 rounds down to 0; 1.5 rounds up to 2.
Thus, when leveraging the rounding functionality in a typical calculation stage, 0.5 will round to 0.
To counter this implementation of rounding, you can use one of two methods:
Method #1 - Processing of 0.5 as a separate case
Use decision stages to determine whether or not the number you're attempting to round has five tenths at the end. If yes, add another .5 to "round up". If there's any other decimal number, proceed with the rounding as normal.
Method #2 - Custom rounding implementation
Create a new custom object with an action that takes your number as an input. Write a code stage to implement the rounding as you see fit. This SO question body has some good code you can start with.
Why not use the RndUp function instead? Although I would expect .5 to be rounded up as well.
Also, the order of the functions in your code is not correct, you are first rounding and then converting to number. The Round function performs (or tries to) do the conversion automatically.
It could look like this:
RndUp(ToNumber(Replace("€1850.50","€","")))
Related
The value is the result of dividing the sum of 2.01 and 2.52 by 2 (2.01 + 2.52) / 2. Excel displays this value as 2.265 and when formatted to 2 digits, it's 2.27. However, the value stored in the file is 2.2649999999999997. When I recreate this is C#, I also get that value in my variable, not 2.265. I understand this is due to floating point precision issues with the division of 4.53 by 2.
double result = (2.01 + 2.52) / 2;
Console.WriteLine(result);
The Console displays 2.265 but the value shown in the QuickWatch debugger shows 2.264999999999997. I suspect the conversion of the value to a string on the in the WriteLine method is correcting for the floating point precision error.
When I apply Math.Round(result, 2, MidpointRounding.AwayFromZero), the result comes back as 2.26 not 2.27 as I expected. It seems like it looks at the first number to the right of the digit I want rounded, sees it's a 4 and ignores everything else to the right of it. The problem is that those 9's are only there because of the precision problem and need to be included, or better yet, the value should be 2.265.
What I have done in my code, is to read the text value from the Excel spreadsheet "2.2649999999999997", convert that to a double 2.264999999999999 and then to a string, which gives me "2.265". I then convert that back to a double 2.265 so that I can apply the Math.Round to it and get the expected result of 2.27. Here's the full code:
double result = Convert.ToDouble(((2.01 + 2.52) / 2).ToString());
Console.WriteLine(Math.Round(result, 2, MidpointRounding.AwayFromZero));
Is my approach for floating point precision and rounding issues, relying on ToString to clean it up, the correct one? If not, how should I have done it?
First: The problem is hard. Because 4.53/2 = 2.265. This rounds to 2.27. However the tiniest rounding error in the calculation resulting in a smaller result (2.264999999....) will lead to a rounding to 2.26. This is what is happening here.
To solve this problem you need to have a floating point arithmetic which has the same internal rounding errors as Excel does.
From this document https://en.wikipedia.org/wiki/Numeric_precision_in_Microsoft_Excel it appears as if Excel uses a modified version of IEEE 754, while C# uses IEEE 754. I do not know where the differences are, but it appears as if internally Excel generates different rounding errors.
This document describes the differences: https://support.microsoft.com/en-us/kb/78113/en-us
(For example, Excel does not use denormalized numbers. This implies a different behavior for rounding errors for numbers < 2).
So I assume you cannot solve this using "double"
Update
However, now that I understand that the issue is not the arithmetic, but the way Excel displays the number, maybe this is a solution
Math.Round(Math.Round(result, 3, MidpointRounding.AwayFromZero), 2, MidpointRounding.AwayFromZero)
First round to 3, then to 2 digits. It appears to me that Excel is doing this.
Excel is rounding numbers inconsistently that is causing me issues. When using ROUND(), sometimes it rounds a specific number up, while at other times it rounds the same value down.
I've tried setting Excel to show exact values in settings, but it doesn't change anything.
This is an example of what is happening.
This is the simple formula ROUND((A1-B1)/2,4)
For one record I have the values (.3159 - .3152) which evaluate to .0007 then divide by 2 to get .00035.
For the next record I have the values (.3554 - .3547) which also evaluates to .0007 and divided by 2 results in .00035
So, even though both values are .00035 when I round off to 4 decimal places I am getting .0003 for one and .0004 for another. Same number, rounding to the same number of places, two different results. How can I fix this?
This is an issue with floating point numbers that is inherent and cannot be solved, only avoided.
Try these tests in Excel:
=(0,3159-0,3152)=(0,3554-0,3547) gives you FALSE.
=(0,3159-0,3152)-(0,3554-0,3547) gives you something like 5.55112E-17.
If you cannot accept the differences, you should round already in the middle of the calculation, not only at the end:
=ROUND(0.3159-0.3152,4)=ROUND(0.3554-0.3547,4) is TRUE
=ROUND(0.3159-0.3152,4)-ROUND(0.3554-0.3547,4) is 0
further reading: Is floating point arithmetic stable? and Binary floating point and .NET, by highly regarded Jon Skeet.
A friend of mine discovered a really weird thing in MS Excel. Excel rounds down some specific numbers the wrong way, actually it rounds down a number that shouldn't need rounding.
As far as I have tested, it happens in most versions of MS Excel 2007+
Eg. the number 10358.165790 will be rounded down to 10358.1657899999.
Apparently it only happens in this interval: 8192.165790 - 65535.165790.
It is really weird - it doesn't happen with eg. .165890 or .165690, only with .165790.
Do any of you know why this happens and why it only accounts to certain numbers?
Excel uses an IEEE754 64 bit double precision floating point type to represent numeric data; with some clever formatting and roundup tricks to get sums like 1/3 + 1/3 + 1/3 correct.
What you are observing is a natural consequence of that numeric scheme only being accurate to 15 significant figures. Unless the number happens to be a dyadic rational, in which case it can be stored exactly, the closest representable number is chosen to the one you actually want. This may be below or above a rounding cutoff.
It will occur in other ranges other than the one you cite too.
Here in Kuwait (Arab country) we used three decimals after comma such as (100.523, 50.978, 340.143, 76.552, 414,081... etc).
How can rounding only the decimals to 0 or 5 or 1, for example:
1. 50.231 rounding to **50.230** Keeping same
2. 50.232 rounding to **50.230**
3. 50.233 rounding to **50.230**
4. 50.234 rounding to **50.230**
5. 50.235 rounding to **50.235** Keeping same
Another type of example for rounding to 1:
1. 50.236 rounding to **50.235**
2. 50.237 rounding to **50.235**
3. 50.238 rounding to **50.235**
4. 50.239 rounding to **50.235**
5. 50.240 rounding to **50.240** Keeping same.
If it possible can solve this issue in excel by using a formula or no?
You seem do be doing a FLOOR operation, not a round. The difference is that floor always rounds downwards, to the precision decided, while ROUND rounds to the nearest, either up or down.
With excel, you can do the following and set the precision:
=FLOOR(A1, 0.005)
For reference, see https://support.office.com/en-sg/article/FLOOR-function-14bb497c-24f2-4e04-b327-b0b4de5a8886
If using ROUND, your examples
3. 50.238 rounding to **50.235**
4. 50.239 rounding to **50.235**
Would instead round to 50.240 since that is the nearest multiple of 0.005.
You can use this:
=FLOOR.MATH(A1, 0.005)
or
=ROUNDDOWN(A1 * 200; 0) / 200
It looks like you are rounding down to the nearest 0.005. For that, try this formula, which gives the results you show in your example:
=ROUNDDOWN(A1/0.005,0)*0.005
Check that the formula also gives your desired results for negative numbers.
The FLOOR function would need to be modified to work for negative numbers in versions of Excel prior to 2010.
EDIT: In your Comment below, you have changed the results for Example 2. It now appears that you want to perform a simple ROUND, unless the value is nn.nn5 (e.g. exactly on the .005 boundary).
It is not clear what level of precision you require for this, and the IEEE standard for double-precision floating point arithmetic allows for a bit of "slop". So you will need to adjust the comparison exponent depending on your desired level of precision.
Here are the results, showing both your original Examples in your Question, and the different set of Examples in your Comment:
I need to convert floats into numbers that resemble measurements from a ruler. For example: 3.75 needs to be converted into 3 and 3/4. However, this is harder than it would seem at first, because I need to keep the denominator in a form that is easily translated into a ruler measurement by a human. Essentially, the denominator should only be powers of 2, up to 16. I don't want a fraction like 3/5 because 5'ths aren't marked on a ruler. I have figured out how to limit the denominator from going above 16, but I can't figure out how to keep the denominator a power of 2.
Answers in python or c++ is preferred.
extract integer part, so you have fraction part less than 1.
find nearest 16th of fraction: multiply by 16 and round to nearest integer. Have some policy to break ties (e.g. round to even). I believe this step can't introduce floating point arithmetic error because you are multiplying by a power of 2.
reduce n/16 to lowest terms (cancel out common multiples of 2). I guess you need to compute the greatest common divisor. In Python that's fractions.gcd, dunno about C++.
I did what Jhecht said because it seemed easy to do with python dictionary.