How can i truncate the leading digit of double value in C#,I have tried Math.Round(doublevalue,2) but not giving the require result. and i didn't find any other method in Math class.
For example i have value 12.123456789 and i only need 12.12.
EDIT: It's been pointed out that these approaches round the value instead of truncating. It's hard to genuinely truncate a double value because it's not really in the right base... but truncating a decimal value is more feasible.
You should use an appropriate format string, either custom or standard, e.g.
string x = d.ToString("0.00");
or
string x = d.ToString("F2");
It's worth being aware that a double value itself doesn't "know" how many decimal places it has. It's only when you convert it to a string that it really makes sense to do so. Using Math.Round will get the closest double value to x.xx00000 (if you see what I mean) but it almost certainly won't be the exact value x.xx00000 due to the way binary floating point types work.
If you need this for anything other than string formatting, you should consider using decimal instead. What does the value actually represent?
I have articles on binary floating point and decimal floating point in .NET which you may find useful.
What have you tried? It works as expected for me:
double original = 12.123456789;
double truncated = Math.Truncate(original * 100) / 100;
Console.WriteLine(truncated); // displays 12.12
double original = 12.123456789;
double truncated = Truncate(original, 2);
Console.WriteLine(truncated.ToString());
// or
// Console.WriteLine(truncated.ToString("0.00"));
// or
// Console.WriteLine(Truncate(original, 2).ToString("0.00"));
public static double Truncate(double value, int precision)
{
return Math.Truncate(value * Math.Pow(10, precision)) / Math.Pow(10, precision);
}
How about:
double num = 12.12890;
double truncatedNum = ((int)(num * 100))/100.00;
This could work (although not tested):
public double RoundDown(this double value, int digits)
{
int factor = Math.Pow(10,digits);
return Math.Truncate(value * factor) / factor;
}
Then you simply use it like this:
double rounded = number.RoundDown(2);
This code....
double x = 12.123456789;
Console.WriteLine(x);
x = Math.Round(x, 2);
Console.WriteLine(x);
Returns this....
12.123456789
12.12
What is your desired result that is different?
If you want to keep the value as a double, and just strip of any digits after the second decimal place and not actually round the number then you can simply subtract 0.005 from your number so that round will then work. For example.
double x = 98.7654321;
Console.WriteLine(x);
double y = Math.Round(x - 0.005, 2);
Console.WriteLine(y);
Produces this...
98.7654321
98.76
There are a lot of answers using Math.Truncate(double).
However, the approach using Math.Truncate(double) can lead to incorrect results.
For instance, it will return 5.01 truncating 5.02, because multiplying of double values doesn't work precisely and 5.02*100=501.99999999999994
If you really need this precision, consider, converting to Decimal before truncating.
public static double Truncate(double value, int precision)
{
decimal power = (decimal)Math.Pow(10, precision);
return (double)(Math.Truncate((decimal)value * power) / power);
}
Still, this approach is ~10 times slower.
I'm sure there's something more .netty out there but why not just:-
double truncVal = Math.Truncate(val * 100) / 100;
double remainder = val-truncVal;
If you are looking to have two points after the decimal without rounding the number, the following should work
string doubleString = doublevalue.ToString("0.0000"); //To ensure we have a sufficiently lengthed string to avoid index issues
Console.Writeline(doubleString
.Substring(0, (doubleString.IndexOf(".") +1) +2));
The second parameter of substring is the count, and IndexOf returns to zero-based index, so we have to add one to that before we add the 2 decimal values.
This answer is assuming that the value should NOT be rounded
For vb.net use this extension:
Imports System.Runtime.CompilerServices
Module DoubleExtensions
<Extension()>
Public Function Truncate(dValue As Double, digits As Integer)
Dim factor As Integer
factor = Math.Pow(10, digits)
Return Math.Truncate(dValue * factor) / factor
End Function
End Module
I use a little formatting class that I put together which can add gaps and all sorts.
Here is one of the methods that takes in a decimal and return different amounts of decimal places based on the decimal display setting in the app
public decimal DisplayDecimalFormatting(decimal input, bool valueIsWeightElseMoney)
{
string inputString = input.ToString();
if (valueIsWeightElseMoney)
{
int appDisplayDecimalCount = Program.SettingsGlobal.DisplayDecimalPlacesCount;
if (appDisplayDecimalCount == 3)//0.000
{
inputString = String.Format("{0:#,##0.##0}", input, displayCulture);
}
else if (appDisplayDecimalCount == 2)//0.00
{
inputString = String.Format("{0:#,##0.#0}", input, displayCulture);
}
else if (appDisplayDecimalCount == 1)//0.0
{
inputString = String.Format("{0:#,##0.0}", input, displayCulture);
}
else//appDisplayDecimalCount 0 //0
{
inputString = String.Format("{0:#,##0}", input, displayCulture);
}
}
else
{
inputString = String.Format("{0:#,##0.#0}", input, displayCulture);
}
//Check if worked and return if worked, else return 0
bool itWorked = false;
decimal returnDec = 0.00m;
itWorked = decimal.TryParse(inputString, out returnDec);
if (itWorked)
{
return returnDec;
}
else
{
return 0.00m;
}
}
object number = 12.123345534;
string.Format({"0:00"},number.ToString());
Related
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.
I have an interesting problem, I need to convert an int to a decimal.
So for example given:
int number = 2423;
decimal convertedNumber = Int2Dec(number,2);
// decimal should equal 24.23
decimal convertedNumber2 = Int2Dec(number,3);
// decimal should equal 2.423
I have played around, and this function works, I just hate that I have to create a string and convert it to a decimal, it doesn't seem very efficient:
decimal IntToDecConverter(int number, int precision)
{
decimal percisionNumber = Convert.ToDecimal("1".PadRight(precision+1,'0'));
return Convert.ToDecimal(number / percisionNumber);
}
Since you are trying to make the number smaller couldn't you just divide by 10 (1 decimal place), 100 (2 decimal places), 1000 (3 decimal places), etc.
Notice the pattern yet? As we increase the digits to the right of the decimal place we also increase the initial value being divided (10 for 1 digit after the decimal place, 100 for 2 digits after the decimal place, etc.) by ten times that.
So the pattern signifies we are dealing with a power of 10 (Math.Pow(10, x)).
Given an input (number of decimal places) make the conversion based on that.
Example:
int x = 1956;
int powBy=3;
decimal d = x/(decimal)Math.Pow(10.00, powBy);
//from 1956 to 1.956 based on powBy
With that being said, wrap it into a function:
decimal IntToDec(int x, int powBy)
{
return x/(decimal)Math.Pow(10.00, powBy);
}
Call it like so:
decimal d = IntToDec(1956, 3);
Going the opposite direction
You could also do the opposite if someone stated they wanted to take a decimal like 19.56 and convert it to an int. You'd still use the Pow mechanism but instead of dividing you would multiply.
double d=19.56;
int powBy=2;
double n = d*Math.Pow(10, powBy);
You can try create decimal explictly with the constructor which has been specially designed for this:
public static decimal IntToDecConverter(int number, int precision) {
return new decimal(Math.Abs(number), 0, 0, number < 0, (byte)precision);
}
E.g.
Console.WriteLine(IntToDecConverter(2423, 2));
Console.WriteLine(IntToDecConverter(1956, 3));
Outcome:
24.23
1.956
Moving the decimal point like that is just a function of multiplying/dividing by a power of 10.
So this function would work:
decimal IntToDecConverter(int number, int precision)
{
// -1 flips the number so its a fraction; same as dividing below
decimal factor = (decimal)Math.Pow(10, -1*precision)
return number * factor;
}
number/percisionNumber will give you an integer which you then convert to decimal.
Try...
return Convert.ToDecimal(number) / percisionNumber;
Convert your method like as below
public static decimal IntToDecConverter(int number, int precision)
{
return = number / ((decimal)(Math.Pow(10, precision)));
}
Check the live fiddle here.
I'm trying to output a percentage from a value imputed from a textbox. Here is my code;
int firstNumber;
double mydouble1 = 0.15;
int myint1 = (int)mydouble1;
int.TryParse(HouseValue.Text, out firstNumber);
int answer;
answer = (firstNumber) * (myint1);
prem1.Text = answer.ToString();
The problem is when I run the app and enter a value to calculate, the answer is 0. I cant seem to get it to display the correct amount for 0.15% of the value.
Try this: change your answer from an int to a double:
int firstNumber;
double mydouble1 = 0.15;
if (int.TryParse(HouseValue.Text, out firstNumber))
{
double answer = firstNumber * mydouble1;
prem1.Text = answer.ToString(); // you may want to round/format this
}
The problem is that casting 0.15 to int makes it 0
(int)0.15 == 0
The double type has primarily been made for scientific calculations. You should use decimal when dealing with money, since decimal fractions can often not be translated into binary numbers (used internally to store doubles) without loss of precision.
decimal percentage = 0.15m;
int houseValue;
if (Int32.TryParse(HouseValue.Text, out houseValue)) {
decimal result = Math.Round(percentage * houseValue);
prem1.Text = result.ToString();
} else {
prem1.Text = "Please enter valid house value!";
}
firstNumber, myint1 and mydouble1 are terrible names. Use speaking names!
Except error handling in converting string to int, use following code:
double mydouble1 = 0.15;
double percentage = int.Parse(ouseValue.Text) * mydouble1;
I know we can display decimals up to certain no of places (if that no of places is fixed). For example, we can display up to 2 places using String.Format:
String.Format("{0:0.00}", 123.4567);
But our requirement is, we have to fetch no of decimal places from database and display the decimal value up to that place. For example:
int n=no of decimal places
I want to write something like:
String.Format("{0:0.n}", 123.4567);
Any suggestions would be of great help.
Added Note: String.Format rounds off the digit. I am looking for something to omit the remaining digits.
Perhaps:
int n = 3;
string format = String.Format("{{0:0.{0}}}", new string('0', n));
Console.Write(String.Format(format, 123.4567)); // 123,457
as method:
public static string FormatNumber(double d, int decimalPlaces)
{
string format = String.Format("{{0:0.{0}}}", new string('0', decimalPlaces));
return String.Format(format, d);
}
or even simpler, using ToString + N format specifier:
public static string FormatNumber(double d, int decimalPlaces)
{
return d.ToString("N" + decimalPlaces);
}
if you don't want the default rounding behaviour but you just want to truncate the remaining decimal places:
public static string FormatNumberNoRounding(double d, int decimalPlaces)
{
double factor = Math.Pow(10, decimalPlaces);
double truncated = Math.Floor(d * factor) / factor;
return truncated.ToString();
}
If you prefer less string formatting, this is perhaps simpler:
decimal d = 123.4567
Console.Write("rounded: {0}", decimial.Round(d, 3));
Additionally, you can control the type of rounding used:
decimial.Round(d, 3, MidpointRounding.AwayFromZero)
Since not many people realise that .NET's default rounding method is ToEven, which rounds to the nearest even number. So values like 2.5 actually round to 2, not 3.
I have a double typed variable. This variable stores information that is part of a more complex formula. Importantly, this variable can only include information up to the tenths location, or one decimal position (i.e. 10.1, 100.2, etc). However, when determining this value, it must be calculated such that anything past the tenths location is truncated, not rounded. For instance:
if the value equals 10.44, The variable value should be 10.4.
if the value equals 10.45, The variable value should also be set to 10.4
How do I truncate values in C# with respect to a decimal place?
Using an extension method:
public static double RoundDown(this double value, int digits)
{
int factor = Math.Pow(10,digits);
return Math.Truncate(value * factor) / factor;
}
Then you simply use it like this:
double rounded = number.RoundDown(2);
You have to do that by your own:
public static decimal Truncate(decimal value, int decimals)
{
if ((decimals < 0) || (decimals > 28))
{
throw new ArgumentOutOfRangeException("decimals", "The number of fractional decimals must be between 0 and 28.");
}
decimal integral = Math.Truncate(value);
decimal fractional = value - integral;
decimal shift = (decimal)Math.Pow(10, decimals);
fractional = Math.Truncate(shift * fractional);
fractional = fractional / shift;
return (integral + fractional);
}
System.Math.Truncate (d * 10) / 10
Generally, if you're working with numbers where the precise decimal representation is important, you should use decimal - not double.
With decimal, you can do something like...
decimal d = ...;
d = decimal.Truncate(d*10)/10;
If you use a double value, your truncated number will not generally be precisely representable - you may end up with excess digits or minor rounding errors. For example Math.Truncate((4.1-4.0)*10) is not 1, but 0.
While I would probably use Phillippe's answer, if you wanted to avoid scaling the number up (unlikely to be a problem for 1dp), you could:
public static double RoundDown(this double x, int numPlaces)
{
double output = Math.Round(x, numPlaces, MidpointRounding.AwayFromZero);
return (output > x ? output - Math.Pow(10, -numPlaces) : output);
}