Digit grouping with two decimal places in c# - c#

I want to display a number which is of double datatype in C#, in grouped digits and with two decimal places only if it contains a decimal no.
e.g. If there is 2000.4567 and 2000.45, it must be displayed as 2,000.45 and if it is 2000 then it will displayed as 2,000 (grouped but without decimal).
I have tried this and it is working fine for digit grouping but it rounds off the decimal no. to an integer value either by floor or ceil:
DimensionLength.ToString("#,##0")
DimensionLength is of type double.

Try this Code
double s=123.345345;
string str=string.Empty;
str = s.ToString("#,0.##");
MessageBox.Show(str);

I think you are better off by creating your own custom condition
double _inputval=2000.4567
string _outputVal="";
if ((_inputval % 1) == 0)
{
_outputVal = _inputval.ToString("#,##");
}
else
{
_outputVal = _inputval.ToString("N2");
}
Hope it helps

Related

Replacing float with int - how do I do localized input/output?

This is one of those cases where I assume the solution is on google, but I have no idea what the search term even is. Or even which Tags to use on Stack Overflow.
Situation:
Floats are not precise. A common trick around it, is to use Integers for the math, then shift the decimal point during output:
If you need 4 decimal places of precision for € (not uncommon in finances), you effectively measure and calculate in milli-Euro. Then during output you shift the decimal left, and cut off the last 2 digits:
So a int 1234567 that is stored, retrieved and processes as a int, would print as/stand for "123.45 €" to the normal end user.
Problem:
But how would this interact with localisation? .NET has this awesome part where Parse() and ToString() look at the current Windows Users Culture setting, to figure out what the decimal separator, group separator and group size is today.
There seems to be no fixed point type in .NET, to do the work for me.
Is there some format string combination I could use to say "shift decimal point 4 left into the number, omit last 2 digits)"? F2 would only add two empty 0 past the decimal point for any int. and "1234567.00 €" is a few orders of magnitude off from "123.45 €"
My best idea thus far:
Building my own format string out of the NumberDecimalSeparator, NumberGroupSeparator and NumberGroupSizes from the users culture - but that is just ugly and seems like something I should not be doing. Is there a better day to do it, or is it one of those cases where I have to go for the ugly thing that works?
Maybe something like this
using System.Globalization;
int n = 123456;
string price = "";
string priceW = "";
int i = 0;
foreach(char c in n.ToString())
{
i++;
if(i == n.ToString().Length - 1)
price += ".";
price += c;
}
float rPrice = float.Parse(price, CultureInfo.InvariantCulture.NumberFormat);
priceW = price + "€";

How can I force a number to have 3 digits while keeping ALL decimal places?

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

Dataset adding values by decimal but returning 0

I have a data-set with 2 columns.
I'm adding the 2 values together, both are object(decimal) types.
private decimal CalculateCensusForChild(DataSet dsGADCensusDetails)
{
var total = 0.00M;
foreach (DataRow dr in dsGADCensusDetails.Tables[0].Rows)
{
total += WebUtility.Cast(dr["Male"], 0.00M) + WebUtility.Cast(dr["Female"], 0.00M);
}
return total;
}
public static decimal Cast(Object aValue, decimal aOnError)
{
decimal result;
try
{
result = decimal.Parse(aValue.ToString());
}
catch
{
result = aOnError;
}
return result;
}
The total returns fine when the values are whole int numbers but I'm looking for them to be decimal values and thus return a decimal value which I will later turn into a string with no decimal places.
e.g 0.65 + 0.25 returns 0.
The total will always equal a whole number but it's required on the UI to show decimal values to reduce rounding, so bit of workaround that may seem unnecessary but that's the world we live in.
So I think I'm messing up on syntax to convert it to a decimal while it's adding but any other ideas are very welcomed.
Cheers folks.

Round off in listview

I am trying to round off each row to the nearest 1.0 in a column of a listview, so meaning 1.58 should show 2.00 and 1.48 should be 1.00 -
Math.Round(listView1.Columns[2].ToString(), 10);
You need to use 0 in digits parameter. You expect no digits here, but you're passing 10 to digit parameter which says to round with 10 digits after decimal.
var res = Math.Round(1.58, 0);//2
var res = Math.Round(1.48, 0);//1
Just saw you try to Round the string, You'll have to convert it to Double or decimal or whatever.
var rounded = Math.Round(Double.Parse(listView1.Columns[2].ToString()), 0);
In case you want to get String as a final result (as far as you've put ToString() in your code), you may just use appropriate formatting string ("F0" in your case):
String result = (1.58).ToString("F0"); // <- "2"
...
String result = (1.48).ToString("F0"); // <- "1"
You can't round a string directly.
string val=listView1.Columns[2].ToString();
double i;
if(Double.TryParse(val, out i))
{
Console.WriteLine(Math.Round(i)); // you can use Math.Round without second
// argument if you need rounding to the
// nearest unit
}

An error occurred while updating the entries. xx.xxx Out of range

I have a table with the column
name: variant_markup
datatype: numeric(4,3)
I try to put value 10.000 into it
And I get the Error
An error occurred while updating the entries
10.000 Out of range
It shouldn't be, and I have other columns with same data type and the same process to add a number in, and they don't complain!
The code:
decimal strippedMarkRate = decimal.Round(0, 3);
if (MarkUpTextBox.Text != string.Empty)
strippedMarkRate = decimal.Round(decimal.Parse(toolbox.removeChars(MarkUpTextBox.Text)), 3);
variant_markup = strippedMarkRate;
toolbox.removeChars function just removes any character that isn't a digit or a decimal point from the box, is there a way to do this with regex by anychance?
If you want to insert 10.000 then your data type needs to be defined as numeric(5,3). The first digit in the numeric type declaration is the maximum number of digits in the number (precision). In the case of 10.000, there are 5.
decimal and numeric (Transact-SQL)
decimal [ (p[ ,s] )] and numeric[ (p[ ,s] )]
...
p (precision) The maximum total number of decimal digits that can be stored, both to the left and to the right of the decimal point. The precision
must be a value from 1 through the maximum precision of 38. The
default precision is 18.
s (scale) The maximum number of decimal digits that can be stored to the right of the decimal point. Scale must be a value from 0 through p.
Scale can be specified only if precision is specified. The default
scale is 0; therefore, 0 <= s <= p. Maximum storage sizes vary, based
on the precision.
Perhaps your remove chars isn't doing what you need it to? As to you last question, it would probably be faster to remove the disallowed chars with a foreach statement like so:
StringBuilder sb = new StringBuilder();
foreach(char c in value)
{
if(char.IsDigit(c) || c == '.')
{
sb.append(c);
}
}
return sb.ToString();

Categories