How to change a decimal value so it ends in a specified digit? - c#

I have a decimal value stored in 'amount' and another decimal value called 'roundTo'.
I'm trying to take whatever 'amount' is, round it to whatever 'roundTo' is set to and then set the final value in newAmount, but it should round to the closest value to roundTo.
Ex.
amount = 2.01
roundTo = 0.09
newAmount becomes 1.99
Ex.
amount = 2.07
roundTo = 0.09
newAmount becomes 2.09
I'm trying to get it to work with all possible values, so roundTo can be anything from 0.01 to 0.09
I've tried doing this like
newAmount = (Math.Round(amount * 10m) / 10m - 0.01m);
The above only really works for when roundTo is 0.09 (using a switch case where if roundTo was 0.09, the above would run).
I also tried
newAmount = Math.Round(amount / roundTo, MidpointRounding.AwayFromZero) * roundTo;
But didn't get any good data from this.
Can anyone point me in the right direction? Thanks!!

decimal amount = 2.06m;
decimal roundTo = 0.04m;
decimal newAmount = Math.Round(amount - roundTo, 1) + roundTo;

Related

C# Mathemathics

I wanted to ask a question about a calculation I had today in C#.
double expenses = (pricePen + priceMark + priceLitres) - discount / 100*(pricePen + priceMark + priceLitres); //Incorrect
double expenses = (pricePen + priceMark + priceLitres) - (pricePen + priceMark + priceLitres)* discount/100; //Correct
So as you can see at the end of the equation I had to multiply the brackets by the integer named "discount", which is obviously a discount percentage.
When I change the places of that value whether it would be in front of the brackets or behind the brackets the answer will always be different, but in Maths I even checked myself that I should get the same answer even if the value is placed in front of the brackets to multiply or placed behind the brackets to multiply again, but C# doesn't think so.
I wanted to ask people, how does C# actually calculate this and why am I getting different results at the end? (Result should be 28.5, not 38)
[Data: pricePen = 11.6; priceMark = 21.6; priceLitres = 4.8; discount = 25;]
(I know that the question is irrelevant.)
In first line after dividing by 100 the result is in an integer. For that the rest of division get lost. So the multiplication has a lower result.
In second line the multiplication has the correct result and the rest of devision is lower than one.
So I know its already answered but if you want to learn more about divisions with int
here it is:
for example:
float value = 3/4 you would expect it to be 0.75 but that's not the case.
Because when the Compiler goes through the values 3 and 4 he makes des Literal of the highest data type - in this case (int)-.
That means the result of this division will be "0".75 because int has no floating numbers and just cuts it off. Then the program just takes that value and puts it in the float value ...
so the result will be
"3/4" 0 ->"float value" 0.0 = 0.0
Some guys before me already told you the solution to that problem like making one divisor to float with .0
float value = 3.0/4
or you can tell the Compiler to store the value in a float Literal with the (float) "command"
float value = (float) 3/4
I hope it helped you explain why you did that :)
To avoid these problems makes sure you are doing math with floating point types, and not int types. In your case discount is an int and thus
x * (discount / 100) = x * <integer>
Best to define a function to do the calculation which forces the type
double DiscountedPrice(double price, double discount)
{
return price - (discount/100) * price;
}
and then call it as
var x = DiscountedPrice( pricePen + priceMark + priceLitres, 15);
In the above scenario, the compiler will force the integer 15 to be converted into an double as a widening conversion (double has more digits than integer).

C#. Strange behavior of double

Here is the code which made me post this question.
// int integer;
// int fraction;
// double arg = 110.1;
this.integer = (int)(arg);
this.fraction = (int)((arg - this.integer) * 100);
The variable integer is getting 110. That's OK.
The variable fraction is getting 9, however I am expecting 10.
What is wrong?
Update
It seems I have discovered that the source of the problem is subtraction
arg - this.integer
Its result is 0.099999999999994316.
Now I am wondering how I should correctly subtract so that the result was 0.1.
You have this:
fraction = (int)((110.1 - 110) * 100);
The inner part ((110.1 - 110) * 100), will be 9.999999
When you cast it to int, it will be round off to 9
This is because of "floating point" (see here) limitations:
Computers always need some way of representing data, and ultimately
those representations will always boil down to binary (0s and 1s).
Integers are easy to represent, but non-integers are a bit more
tricky. Consider the following var:
double x = 0.1d;
The variable x will actually store the closest available double to
that value. When you understand this, it becomes obvious why some
calculations seem to be "wrong".
If you were asked to add a third to a third, but could only use 3
decimal places, you'd get the "wrong" answer: the closest you could
get to a third is 0.333, and adding two of those together gives 0.666,
rather than 0.667 (which is closer to the exact value of two thirds).
Update:
In financial applications or where the numbers are so important to be exact, you can use decimal data type:
(int)((110.1m - 110) * 100) //will be 10 (m is decimal symbol)
or:
decimal arg = 110.1m;
int integer = (int)(arg); //110
decimal fraction = (int)((arg - integer) * 100); //will be 10
It is because you are using double, precision gets rounded, if you want it to be 10 use decimal type:
check the following:
int integer;
int fraction;
decimal arg = 110.1M;
integer = (int)(arg);
decimal diff = arg - integer;
decimal multiply = diff * 100;
fraction = (int)multiply;//output will be 10 as you expect

Round decimal value to nearest 5 or 0 amount

I have a web application that will apply a percentage markup to a product, but the percentage will be specified by a user. For example, the user can indicate they want to mark up a product 5%, 9%, 23%, etc. My problem is, the product price will change as well, and in doing so, end up giving ugly values ($1462.72)
As a result, my users are hoping that we can round the value to the nearest 5\0 value. So if my marked up product price is $1462.72, it would round up to $1465. $1798.02 on the other hand would round up to an even $1800.
Using VB\C#, how can I go about rounding these values?
Thanks!
To round to an arbitrary modulus you can create a function like:
public decimal Round(decimal source, decimal modulus)
{
return (Math.Round(source / modulus) * modulus);
}
and use it in this way:
decimal rounded = Round(1798.02m , 5.0m); // yields 1800.0
decimal rounded = Round(1462.72m , 5.0m); // yields 1465.0
decimal rounded = Round(2481.23m , 5.0m); // yields 2480.0
Note that Math.Round by default rounds midpoint values to the closest even number (e.g. 1.5 and 2.5 would both "round" to 2. In your case, the effect is that any numbers that are exactly between a 0 and 5 number (i.e. 2.5, 7.5) would be rounded to the closest 10:
decimal rounded = Round(1697.50m , 5.0m); // yields 1700.0
decimal rounded = Round(1702.50m , 5.0m); // yields 1700.0
If you want to always round UP on the midpoint just specify that in Round:
return (Math.Round(source / modulus, MidpointRounding.AwayFromZero) * modulus);
You can use the modulus operator to calculate the adjustment needed.
decimal price = 1798.02;
decimal adjustment = price % 5.0;
if(adjustment != 0) //so we don't round up already round numbers
{
price = (price - adjustment) + 5;
}
This will bring it up to the next multiple of 5.

How to round decimal value in c#?

Am calculating small values in decimal, Expected result is = 345.00 but Result getting is = 345.0000
my code is this decimal temp= 6900 * ( 5 / 100);
temp = 345.0000 how to round this ? I want to show 345.00 ? whats my mistake here ?
I tried this code Math.Round(tempdiscountprice, 2); also but it wont work here. Help me
I don't think you're showing your real code. The following will give a result of 0, because (5 / 100) is evaluated using integer arithmetic:
decimal temp = 6900 * (5 / 100);
Console.WriteLine(temp.ToString()); // result is 0
If you use decimal, you will get the following:
decimal temp = 6900 * (5M / 100);
Console.WriteLine(temp.ToString()); // result is 345.00
However the decimal type does preserve trailing zeroes:
decimal temp = 6900 * (5.0000M / 100);
Console.WriteLine(temp.ToString()); // result is 345.0000
Preserving trailing zeroes like this was introduced in .NET 1.1 for more strict conformance with the ECMA CLI specification.
But there's nothing to stop you formatting the output with two decimals, e.g.:
decimal temp = 6900 * (5.0000M / 100);
Console.WriteLine(temp.ToString("N2")); // result is 345.00
As user2864740 has pointed out above, the problem is not with your rounding, but with displaying the value as a string. Try:
decimal temp = 345.0000m;
String.Format("{0:0.00}", temp)
I think you showing us wrong code because this doesn't get 345.00 or 345.0000 as a result. It always gets 0.
Your temp should be 0 because since you doing integer division, your 5 / 100 is always 0. That's why your temp will 6900 * 0 then it will be 0.
If you show us the right code, your problem looks like showing problem instead of rounding problem.
If you want to format your number as a string, take a look at;
Custom Numeric Format Strings

C# midpointrounding down to zero

I know about MidpointRounding.AwayFromZero and MidpointRounding.ToEven, but I think I want something inbetween. It is for a promotions module, so discounted prices must round down if the value is .5.
For example, I would like:
£1.244 to round to £1.24
£1.245 to round to £1.24
£1.246 to round to £1.25
As I understand it, .AwayFromZero would round the middle value to £1.25 and .ToEven would round correctly to £1.24, but £1.335 would be rounded to £1.34, rather than £1.33 which is what I want.
Does anyone know how to accomplish this?
Thanks, Jon
There is a lot of unspecified behavior. Let's keep it safe and do the rounding explicitly, ignoring negatives since this is about money:
public static decimal Promotion(decimal value) {
decimal unround = decimal.Floor(value * 100m);
decimal fraction = value * 100m - unround;
if (fraction <= 0.5m) return unround / 100m;
else return (unround + 1m) / 100m;
}
Math.ceiling(x - 0.5)
Should do the trick.
Ussually to do something like this you subtract .001 from your value, then round normally.
1.244 - .001 = 1.243 = 1.24
1.245 - .001 = 1.244 = 1.24
1.246 - .001 = 1.245 = 1.25
1.300 - .001 = 1.299 = 1.3
In this case, you REALLY want to put this in it's own function/extrension method, whatever, and document with a function WHY you subtract .001 before rounding.

Categories

Resources