Trimming a Float up to a certain decimal point [duplicate] - c#

This question already has answers here:
How do I display a decimal value to 2 decimal places?
(19 answers)
Closed 9 years ago.
I need a way to round down a float up to a specific number of decimal places. Math.Round will round up if the number after the cut is larger than 6, and Math.Floor does not work with decimal places.
Basically if I have 2.566321, I want the code to return 2.56. The only way I know that this can be done is to convert the float to a string and use string.format but I would rather not do that if possible.
Thanks.

A brute force way might be to multiply by 10^n where n is the number of decimal places you want, cast to int (which does truncation rather than rounding), then cast back to float and divide by 10^n again.
visually:
2.566321 * 10^2 = 2.566321 * 100 = 256.6321
(int) 256.6321 = 256
(float) 256 / 10^2 = (float) 256 / 100 = 2.56
Quick attempt at the code:
public float Truncate(float value, int decimalPlaces) {
int temp = (int) (value * Math.Pow(10, decimalPlaces));
return (float) temp / Math.Pow(10, decimalPlaces);
}
I haven't tested this, but that should get you going.

Related

C# round a number to any arbitrary digit of a double [duplicate]

This question already has answers here:
Round a double to x significant figures
(17 answers)
Round double in two decimal places in C#?
(8 answers)
Closed 1 year ago.
I am looking to round a double to any arbitrary digit to right or left of the decimal point.
Math.Round only works for digits to the right of the decimal point, and I need to be able to round to values the nearest 10s, 100s, 1000s, ...
Example of desired inputs/outputs:
Round(1234.56789, 0) == 1235
Round(1234.56789, -3) == 1234.568
Round(1234.56789, 3) == 1000
This problem differs from Round double in two decimal places in C#?
because I need to round values to positions to the left of the decimal point such as 1,2345,000 rounding to the nearest 10,000
If we take 10 to the power of the digit position, we can round the double to the arbitrary precision
public double RoundToDigit(double i, int digitPosition)
{
double precision = Math.Pow(10, digitPosition);
double result = Math.Round(i / precision, 0) * precision;
return result;
}

How to comparing two x significant doubles correctly [duplicate]

This question already has answers here:
Round a double to x significant figures
(17 answers)
Closed 4 years ago.
This is not a duplicate question. There is an answer posted in the question. Hope it can help.
There are two doubles with the same value with decimals.
(Sorry, this is not a good case. because it will return false sometimes, but I can't find the case. If you try this case, it may not have any problem. So don't waste time to test it.)
double a = 0.70448;
double b = 0.70441;
I want to compare them with only 4 decimals.
I have this helper function to round them down to 4 decimals first.
public static double RoundDown(this double value, int decimals)
{
var multiplier = Math.Pow(10, decimals);
return Math.Floor(value * multiplier) / multiplier;
}
And then I want to check if a is larger than b like this:
RoundDown(a, 4) > RoundDown(b, 4)
Sometimes, for some cases, it will return true even they look equal. I understand very well this is floating issue, so I would like to know if there any elegant solution to compare them.
Updates:
I have tried to multiply it and compare them in integer. However, for this solution, I need to handle double infinity and NAN.
private static CompareResult Compare(double a, double b, double decimals = 0)
{
var multiplier = Math.Pow(10, decimals);
var aInt = Convert.ToInt32(a * multiplier);
var bInt = Convert.ToInt32(b * multiplier);
return aInt > bInt ? CompareResult.Greater : aInt < bInt ? CompareResult.Less : CompareResult.Equal;
}
private enum CompareResult
{
Greater,
Less,
Equal
}
System.OverflowException is thrown if one of the double is larger than int max or infinity. Also, this is not an elegant way to compare double.
Importants:
I am not going to round down with x significant figures. I have already provide this solution in my question, my question is: Even round down to x significant figures, it will return true when comparing them.
Again
I am not finding a way to round down or truncate the doubles to x significant digits. I have no problem on this part.
Answer
Thanks for #m88 answer. But it still cannot solve my problem.
I finally solve this issue using sigma. (Reference: http://forums.codeguru.com/showthread.php?506300-float-double-value-comparison-significant-figures.)
Thanks to some people misunderstand the problem and vote it as a duplicated question. I can't post my answer for others facing the same problem. So I post the answer in my question. I hope it can help others.
public static int CompareTo(this double value1, double value2, int decimals)
{
var diff = value1 - value2;
var sigma = Math.Pow(10, -decimals - 1);
return Math.Abs(diff) < sigma ? 0 : diff > 0 ? 1 : -1;
}
If you use the Math.Round method to round a and b to 4 decimals, a (0.7045) will always be greater than b (0.7044):
const double a = 0.70448;
const double b = 0.70441;
if (Math.Round(a, 4) > Math.Round(b, 4))
...
If you want to truncate the values, you need to be aware of the fact that not all fractions can be accurately represented in a double. If you want "exact" truncating, you might consider converting the double value to a string, truncate the string and then convert the truncated string value back to double. Something like this:
private static double Truncate(double d, int decimals)
{
string s = d.ToString(System.Globalization.CultureInfo.InvariantCulture);
int index = s.IndexOf(System.Globalization.CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator);
if (index > -1)
return Convert.ToDouble($"{s.Substring(0, index + 1)}{s.Substring(index + 1, decimals)}", System.Globalization.CultureInfo.InvariantCulture);
return d;
}
Usage:
const double a = 0.70448;
const double b = 0.70441;
if (Truncate(a, 4) >= Truncate(b, 4))
....
Obviously, if you don't want any "floating issues" as you said in the chat, you cannot work with floating point data types.
You want to truncate, not round:
double a = Math.Truncate(100 * 0.70448) / 100;
double b = Math.Truncate(100 * 0.70441) / 100;
if (a > b)
{
// ...
}
Note that fractions cannot be accurately represented in a double, as per #mm8's comment.

failed/success percentage from total items [duplicate]

This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 7 years ago.
Let's assume I have 8 items.
From these 8, 5 are success and 3 failure.
If I want to get the success and failure in percentage with 2 decimals precission I will do like this:
int total = 8;
int success = 5;
int failure = 3;
string success =((decimal)((success * 100) / total)).FormatDecimal();
string failure = ((decimal)((failure * 100) / total)).FormatDecimal();
Format decimal is an extension that will convert decimal to string with x amount of decimals.
public static string FormatDecimal(this decimal value, int decimals = 2)
{
return value.ToString(string.Format("0.{0}", new string('0', decimals)));
}
Now if I take my calculator and I do this, the result is correct:
success: (5 * 100) / 8 = 62.5 %
failure: (3 * 100) / 8 = 37.5 %
However my solution return me 62.00 % and 37.00%
What's wrong with my code?
Because your code is running with integer division but you calculator can do floating-point division.
Your (5 * 100) / 8 returns 62, not 62.5 since both operand is int and this operation will always disregards fractional part.
From / Operator (C# Reference)
When you divide two integers, the result is always an integer. For
example, the result of 7 / 3 is 2.
If you change your total to double, you can fix this since you start doing floating-point division not integer division.
double total = 8.0;
Check out;
7.7.2 Division operator
That's because the division operator / for integers only return the integer part.
If need to cast to float, double or decimal.
var result = ((float)(5 * 100)) / 8;
If any of the values you are dividing is a float, double or decimal, the division operator will support the decimal part.
This is very basic mistake at C#. You have defined the calculation wrong.
(success * 100) / total
It means that after success * 100, the result will be parsed as integer. It is now 300 in integer. 300 / 8 = 37 in integer.
Instead, you can replace the 100 with 100m to force convert them to decimal.

How to divide an int to receive a decimal? [duplicate]

This question already has answers here:
How can I divide two integers to get a double?
(9 answers)
Closed 7 years ago.
I'm trying to calculate the area of a sector but when I divide angleParse by 360 and times it by radiusParse, I will sometimes receive a output of 0.
What happens and where do I need to fix it? (Sorry, if this is a weird question but I started learning C# yesterday, also I just started using StackOverflow today)
Frostbyte
static void AoaSc()
{
Console.WriteLine("Enter the radius of the circle in centimetres.");
string radius = Console.ReadLine();
int radiusParse;
Int32.TryParse(radius, out radiusParse);
Console.WriteLine("Enter the angle of the sector.");
string sectorAngle = Console.ReadLine();
int angleParse;
Int32.TryParse(sectorAngle, out angleParse);
double area = radiusParse * angleParse / 360;
Console.WriteLine("The area of the sector is: " + area + "cm²");
Console.ReadLine();
}
You've encountered integer division. If a and b are int, then a / b is also an int, where the non-integer part has been truncated (i.e. everything following the decimal point has been cut off).
If you want the "true" result, one or more of the operands in your division needs to be a floating point. Either of the following will work:
radiusParse * (double)angleParse / 360;
radiusParse * angleParse / 360.0;
Note that it's not sufficient to cast radiusParse to double, because the / operator has higher precedence than * (so the integer division happens first).
Finally, also note that decimal in .NET is its own type, and is distinct from float and double.
I think if you divide it by 360.0 it will work.
Alternatively declare a variable of type decimal and set this to 360.
private decimal degreesInCirle = 360;
// Other code removed...
double area = radiusParse * angleParse / degreesInCirle;

Division in C# to get exact value [duplicate]

This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 9 years ago.
If I divide 150 by 100, I should get 1.5. But I am getting 1.0 when I divided like I did below:
double result = 150 / 100;
Can anyone tell me how to get 1.5?
try:
double result = (double)150/100;
When you are performing the division as before:
double result = 150/100;
The devision is first done as an Int and then it gets cast as a double hence you get 1.0, you need to have a double in the equation for it to divide as a double.
Cast one of the ints to a floating point type. You should look into the difference between decimal and double and decide which you want, but to use double:
double result = (double)150 / 100;
Make the number float
var result = 150/100f
or you can make any of number to float by adding .0:
double result=150.0/100
or
double result=150/100.0
double result = (150.0/100.0)
One or both numbers should be a float/double on the right hand side of =
If you're just using literal values like 150 and 100, C# is going to treat them as integers, and integer math always "rounds down". You can add a flag like "f" for float or "m" for decimal to not get integer math. So for example result = 150m/100m will give you a different answer than result = 150/100.

Categories

Resources