I want to determine the next decimal after a certain decimal programmatically.
For example, I have the decimal 0.0000041
I want to programmatically generate 0.0000042 in a function.
If I ran the function again after running it with 0.0000042 the new number would be 0.0000043
If I ran the function with the decimal being 0.0000049 the new number would be 0.0000050 etc....
Is there a way to do this?
I do not know where to start or what references to look at to do something like this.
Thank you.
You seem to be looking for something like this: (Check below if you want to specify the precision manually)
static decimal GetNextDecimal(decimal input)
{
int count = BitConverter.GetBytes(decimal.GetBits(input)[3])[2];
return input + (1m / (decimal)Math.Pow(10, count));
}
Usage:
decimal num1 = 0.0000041m;
decimal num2 = 0.00002m;
decimal next = GetNextDecimal(num1);
decimal next2 = GetNextDecimal(num2);
Console.WriteLine(next);
Console.WriteLine(next2);
Output:
0.0000042
0.00003
I used a little help of this answer to get the number of the decimal places.
If you originally wanted to specify the precision manually, you can use the following instead:
static decimal GetNextDecimal(decimal input, int precision)
{
return input + (1m / (decimal)Math.Pow(10, precision));
}
..which allows you to do something like this:
decimal num1 = 0.003m;
decimal next = GetNextDecimal(num1, 3);
decimal next2 = GetNextDecimal(num1, 4);
Console.WriteLine(next);
Console.WriteLine(next2);
Output:
0.004
0.0031
Related
I want my function to return value with only 2 decimal places. I have tried following code :
private static double CalculateSlabTax(int nSlabStartTaxable,
int nSlabEndTaxable,
float fSlabRate)
{
double dblSlabResult = 0;
try
{
dblSlabResult = (nSlabStartTaxable - nSlabEndTaxable) * fSlabRate;
dblSlabResult = Math.Round(dblSlabResult , 2);
return dblSlabResult;
}
catch (Exception)
{
return -1;
}
}
Expected output is : dblSlabResult = ####.## - two digits (eg. 1002.05)
Getting output as : eg. dblSlabResult = 1002.1
To represent use formatting. In your case exactly two digits after decimal point means "F2" format string
double source = 1234.56789;
// 1234.57
var result = source.ToString("F2");
Very simple. Try this
public double UptoTwoDecimalPoints(double num)
{
var totalCost = Convert.ToDouble(String.Format("{0:0.00}", num));
return totalCost;
}
The # character is an optional digit placeholder. Use 0 to enforce digits when converting to string:
string.Format("{0:#.##}", 1002.1) == "1002.1"
string.Format("{0:0.00}", 1002.1) == "1002.10"
Don't expect a specific count of digits when rounding float or double. They are just numbers, independent of their string format.
What inputs are you using? Math.Round should be working correctly, which suggests that the line above is returning a double with only 1 significant figure.
In c#, I want to force 0s when converting from double to string in case a number is lower than 100, the only challenge is that I want to keep all decimal places. Examples
58.3434454545 = 058.3434454545
8.343 = 008.343
I tried with ToString + a format provider but I'm not certain what's the correct provider for keeping all decimal places
You can use formatter strings for .ToString(), documented here.
To do what you want you can use this as example, noting the maximum digits for double is 17:
double numberA = 58.3434454545;
numberA.ToString("000.##############"); //058.3434454545
double numberB = 8.343;
numberB.ToString("000.##############"); //008.343
This is a rather ass ugly solution but if you wanted the number of decimals to be dynamic you could try something like this:
private string FormatDouble(double dbl)
{
int count = BitConverter.GetBytes(decimal.GetBits((decimal)dbl)[3])[2];
var fmt = string.Concat("000.", new string('#', count));
return dbl.ToString(fmt);
}
Call it like this:
Console.WriteLine(FormatDouble(58.3434454545123123));
Console.WriteLine(FormatDouble(8.3431312323));
And your output would be this:
058.3434454545123
008.3431312323
I'm sure there is a much better way to do this and I'm not sure about performance, but hey it works and you don't have to guess the number of decimals you need, so that's a plus
// Calculating and diplaying pricing in list.
for (double MAX = 4.25; MAX >= MIN; MAX -= 0.05)
{
Price = (X * MAX);
prices = Price.ToString("c");
listFinances.Items.Add(prices);
}
---
private void listFinances_SelectedIndexChanged(object sender, EventArgs e)
{
string TotalPrice = listFinances.SelectedItem.ToString();
double stateIncentive = (Convert.ToDouble(TotalPrice) / 4);
txtStateTax.Text = stateIncentive.ToString();
}
So I'm trying to take a ListBox of string currency values, turn them into a double, divide them by 4, and display the result in a TextBox. The user will select the ListBox value and the program should automatically divide by 4 and display.
It's not working however. The program always does an exception throw when you click the ListBox item. The exception is thrown at:
double stateIncentive = (Convert.ToDouble(TPrice) / 4);
saying that:
It's not in the correct format.
Can someone help me out here?
You add your strings with the currency symbol. If you want to parse the string back to a double (but it is better use a decimal) you need to tell the conversion that you have that symbol and ignore it
private void listFinances_SelectedIndexChanged(object sender, EventArgs e)
{
string TotalPrice = listFinances.SelectedItem.ToString();
decimal stateIncentive = decimal.Parse(TotalPrice, NumberStyles.Currency, CultureInfo.CurrentCulture) / 4);
txtStateTax.Text = stateIncentive.ToString();
}
I have used decimal instead of double because the decimal type is more adapt to handle money values. I suggest to make the same change in the for..loop that fill the list (Just use the suffix m to specify constant decimal values (IE. 4.25m and 0.05m)
You are trying to convert a currency string to double so you should Try like this:
double stateIncentive = (Double.Parse(TotalPrice, System.Globalization.NumberStyles.Currency) / 4);
Or would be better if using decimal (Read this to know why):
decimal stateIncentive = (decimal.Parse(TotalPrice, System.Globalization.NumberStyles.Currency) / 4);
The style parameter defines the style elements (such as white space, thousands separators, and currency symbols) refer to MSDN:Double.Parse Method (String, NumberStyles)
I know .NET has one built-in but it's an external call. Anyone knows why?
But the actual question is how to implement a truncate from scratch where the user will be able to specify how many digits to keep? Is multiplying a number by say 100 and then dividing it by the same amount enough? Or is there a better implementation?
Something like:
Truncate(12.3456789, 3);
// returns 12.345
The classic way:
var x = 1.2345678;
var tr = 4;
var truncated = (int) (x * Math.Pow(10, tr)) / Math.Pow(10, tr);
would give 1.2345;
You'd probably want to look at IEEE floating-point integers.
You can then use unsafe code to modify the numbers, like:
unsafe
{
double* pValue = &value;
var asLong = *(long*)pValue;
do whatever you want with asLong, e.g. bit-masking it, etc.;
}
As to the 'why': I have no idea, though the Shared Source CLI may provide clues. My guess would be that it might be because of performance optimizations.
Here is how I would do it. In C++, and I think in C# as well, you could get the integer part of a floating point number by casting it to an integer type.
double Truncate (double num, int dig)
{
if (dig > 15) dig = 15; // Don't overflow
long p = Math.Pow (10, dig);
// Save the integer part, so that we don't overflow
long integer_part = (long)num;
// Fractional part * 10^dig
double frac = (num - Convert.ToDouble(integer_part)) * p;
long frac_trunc = (long)frac;
// Final result
double result = Convert.ToDouble(integer_part) + (Convert.ToDouble(frac_trunc) / p);
return result;
}
Is multiplying a number by say 100 and then dividing it by the same
amount enough?
That should work, but be careful because with large numbers, or high number of digits, you can easily overflow, and it will give you weird results.
var result = Math.Round(12.3456789, 3);
Math.Round Method (Double, Int32)
It is not clear the reason you think that Truncate should keep the decmial value.
The default method within .NET is described by the following statement:
The integral part of d; that is, the number that remains after any
fractional digits have been discarded.
It seems like what you want to use is either to format the output string of an double/decmial value and/or use the Math.Round(double, int) function instead.
You could just use:
double num = 2.22939393; num = Convert.ToDouble(num.ToString("#0.000"));
From one of the duplicate questions:
public static decimal TruncateToDecimalPlace(this decimal numberToTruncate, int decimalPlaces)
{
decimal power = (decimal)(Math.Pow(10.0, (double)decimalPlaces));
return Math.Truncate((power * numberToTruncate)) / power;
}
I understand this still uses the Truncate method. I only provided this code since you wanted a Truncate method that would keep the decmial value of a number and the default built-in Truncate method does not.
You could always just use this:
Math.Round does NOT call the SplitFractionDouble from what I can tell
private static unsafe double InternalRound(double value, int digits, MidpointRounding mode) {
if (Abs(value) < doubleRoundLimit) {
Double power10 = roundPower10Double[digits];
value *= power10;
if (mode == MidpointRounding.AwayFromZero) {
double fraction = SplitFractionDouble(&value);
if (Abs(fraction) >= 0.5d) {
value += Sign(fraction);
}
}
else {
// On X86 this can be inlined to just a few instructions
value = Round(value);
}
value /= power10;
}
return value;
}
public static double Round(double value, int digits)
{
if ((digits < 0) || (digits > maxRoundingDigits))
throw new ArgumentOutOfRangeException("digits", Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
return InternalRound(value, digits, MidpointRounding.ToEven);
}
public static double Round(double value, MidpointRounding mode) {
return Round(value, 0, mode);
}
public static double Round(double value, int digits, MidpointRounding mode) {
if ((digits < 0) || (digits > maxRoundingDigits))
throw new ArgumentOutOfRangeException("digits", Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, "MidpointRounding"), "mode");
}
return InternalRound(value, digits, mode);
}
public static Decimal Round(Decimal d) {
return Decimal.Round(d,0);
}
public static Decimal Round(Decimal d, int decimals) {
return Decimal.Round(d,decimals);
}
public static Decimal Round(Decimal d, MidpointRounding mode) {
return Decimal.Round(d, 0, mode);
}
public static Decimal Round(Decimal d, int decimals, MidpointRounding mode) {
return Decimal.Round(d, decimals, mode);
}
public static Decimal Floor(Decimal d) {
return Decimal.Floor(d);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Floor(double d);
Due to a requirement I need very exact precision of a double value to a 4 decimal places as follows:
double myDoubleValue = 50234.9489898997952932;
From the above, I need the output as 50234.9489. I DON'T want Rounding the number in this requirement.
I came across with "Math.Truncate(a * 100) / 100;". But really i'm not interested with this approach.
I'm looking for better approach very simple way something like using String.Format or with Regular Expressions etc.
double d = 50234.94895345345345;
var Expected_result = Double.Parse((Regex.Match(d.ToString(), "[+-]?\\d*.\\d{0,4}")).Value);
You would need to do this yourself. One of the possible solutions would be to use an extension method
public static class DoubleEx
{
public static double TruncateFraction(this double value, int fractionRound)
{
double factor = Math.Pow(10, fractionRound);
return Math.Truncate(value * factor) / factor;
}
}
And this is how to use it
double foo = 50234.9489898997952932;
double bar = foo.TruncateFraction(4);
Console.WriteLine(foo); //50234.9489898997952932
Console.WriteLine(bar); //50234.9489
Without regexes:
This works very much fine for any double combinations
using System.Globalization;
class Program
{
static void Main(string[] args)
{
double d = 50234.9489898997952932;
char probablyDot = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
string[] number = d.ToString().Split(probablyDot);
//Console.WriteLine(number[0] + probablyDot + number[1].Remove(4));
Console.WriteLine(number[0] + probablyDot + (number.Length >1 ? (number[1].Length>4? number[1].Substring(0,4):number[1]): "0000"));
//Output: 50234.9489
Console.ReadKey();
}
}
There are a lot of answers here that work with the input given in the question, but on testing them with a range of values, they all have limitations (see comments).
The only way I can see to achieve this with any decimal input is the following. It might not be a one liner, but it seems robust to me.
private static string TrimDecimalPlaces(double value, int numberOfDecimalPlaces)
{
string valueString = value.ToString();
if (!valueString.Contains(".")) return valueString;
int indexOfDot = valueString.IndexOf(".");
if ((indexOfDot + numberOfDecimalPlaces + 1) < valueString.Length)
{
return valueString.Remove(indexOfDot + numberOfDecimalPlaces + 1);
}
return valueString;
}
I've tested this with the following test data and the results are as expected:
1
1.1
1.11
1.111
1.1111
1.11111
1.111111
-1
-1.1
-1.11
-1.111
-1.1111
-1.11111
-1.111111