Need only 2 digits after decimal point - c#

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.

Related

How to get the next decimal given a decimal/precision

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

How to format numbers in scientific notation with powers in superscript

I need to write values like:
9.6 x 10²
9.6 x 10¹²
I need to know if there is a way to format numbers as above in a string.
You have to find the appropriate character from the code page you are using, for example UTF-8:
string superScript2 = "²";
There is no such thing as formatting in a string, it is just all data.
Try this:
public static string Eng(this double x, string format="g")
{
const string sup_signs = "⁺⁻⁼⁽⁾ⁿ";
const string sup_digits = "⁰¹²³⁴⁵⁶⁷⁸⁹";
if(double.IsNaN(x) || double.IsInfinity(x))
{
return x.ToString();
}
int num_sign = Math.Sign(x);
x = Math.Abs(x);
// group exponents in multiples of 3 (thousands)
int exp = (int)Math.Floor(Math.Log(x, 10)/3)*3;
// otherwise use:
// int exp = (int)Math.Floor(Math.Log(x, 10));
// and handle the exp==1 case separetly to avoid 10¹
x*= Math.Pow(10, -exp);
int exp_sign = Math.Sign(exp);
exp = Math.Abs(exp);
// Build the exponent string 'dig' from right to left
string dig = string.Empty;
while(exp>0)
{
int n = exp%10;
dig = sup_digits[n] + dig;
exp = exp/10;
}
// if has exponent and its negative prepend the superscript minus sign
if(dig.Length>0 && exp_sign<0)
{
dig = sup_signs[1] + dig;
}
// prepend answer with minus if number is negative
string sig = num_sign<0 ? "-" : "";
if(dig.Length>0)
{
// has exponent
return $"{sig}{x.ToString(format)}×10{dig}";
}
else
{
// no exponent
return $"{sig}{x.ToString(format)}";
}
}
As a test case run
static void Main(string[] args)
{
// Type code here.
double x = Math.PI/50e5;
for(int i = 0; i < 20; i++)
{
// Format output to 12 wide column, right aligned
Debug.WriteLine($"{ Eng(x, "g4"),12}");
x*=50;
}
}
with the output:
628.3×10⁻⁹
31.42×10⁻⁶
1.571×10⁻³
78.54×10⁻³
3.927
196.3
9.817×10³
490.9×10³
24.54×10⁶
1.227×10⁹
61.36×10⁹
3.068×10¹²
153.4×10¹²
7.67×10¹⁵
383.5×10¹⁵
19.17×10¹⁸
958.7×10¹⁸
47.94×10²¹
2.397×10²⁴
119.8×10²⁴
By no means optimized, but it does the job. The exponents are in engineering form (multiples of 3 only, in order to avoid things like 10¹). As a bonus, the number can be formatted to a specific number of significant digits by supplying a format code like g4 or g5 for 4 or 5 digits respectively.
It can handle negative or positive numbers
It can handle negative or positive exponents of 10
In can format the mantissa
It can handle NAN or Inf.
It's in extension form for re-usability
As a follow up to my comment above - does something like this do what you require :
public String FormatAs10Power(decimal val)
{
string SuperscriptDigits = "\u2070\u00b9\u00b2\u00b3\u2074\u2075\u2076\u2077\u2078\u2079";
string expstr = String.Format("{0:0.#E0}", val);
var numparts = expstr.Split('E');
char[] powerchars = numparts[1].ToArray();
for (int i = 0; i < powerchars.Length; i++)
{
powerchars[i] = (powerchars[i] == '-') ? '\u207b' : SuperscriptDigits[powerchars[i] - '0'];
}
numparts[1] = new String(powerchars);
return String.Join(" x 10",numparts);
}
See : https://dotnetfiddle.net/dX7LAF
As per my comment above - the number is first converted to an exponential format string (https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#EFormatString), that string is then split on the exponential separator 'E'. The first array is the numeric part, the second the power of 10 to which it is raised - this is converted to superscript characters using one of the techniques of the link I gave (Convert a string/integer to superscript in C#), converted back to a string & the two parts combined using "x 10" as the new separator.
I have assumed you want the value to single digit precision as per your example with no preceding + sign. If you need anything else you could pass the format as a parameter. The code for superscript + is '\u207A'. There is a link here (at the time of writing) giving the list of superscript codes : http://unicode.org/charts/PDF/U2070.pdf

Format Double to fixed Width C#

My requirements are as follows:
I have a double number. It can be positive as well as negative. I want to use String.Format() to format it.
The Output Number(positive(no sign)/negative(including sign)/zero) should be fixed width: 11
All numbers should have 2 places of decimal.
Examples:
1.2 00000001.20
.2 00000000.20
-.2 -0000000.20
12 00000012.00
0 00000000.00
-0 00000000.00
12.555 00000012.55
Basically, what I want is fixed width(11 digits). 2 Decimal points. No positive sign. Negative sign included in fixed width.
What I have tried:
{0:00000000.00;0:0000000.00;0:00000000.00}
Please tell me what is the right way to do this.
You can use section modifiers to give the output you need:
string format = "{0:00000000.00;-0000000.00}";
Console.WriteLine(string.Format(format, 1.2));
Console.WriteLine(string.Format(format, .2));
Console.WriteLine(string.Format(format, -.2));
Console.WriteLine(string.Format(format, 12.0));
Console.WriteLine(string.Format(format, -0.0));
Console.WriteLine(string.Format(format, 12.555));
Prints out:
00000001.20
00000000.20
-0000000.20
00000012.00
00000000.00
00000012.56
It's basically {position:postive format;negative format;zero format}
Note: position is only used for formatted strings, you can also use it with double.ToString(string) without the "position" element;
If zero format is not provided, format for positive format section is used to format Zero.
See https://msdn.microsoft.com/en-us/library/0c899ak8(v=vs.110).aspx for more detail about the ; section format.
string.Format("{0:00000000.00}", 1.2)
works fine for me
You'll need a second format section for negative numbers. Declaring it as a Func or extension method might be helpful if you need to reuse it. Like so:
using System;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Func<double, string> toFixedWidth = (d) => {
return string.Format("{0:00000000.00;-0000000.00}", d);
};
foreach (var d in new double[] { 1.2, 0.2, -0.2, 12, 0, -0, 12.555 })
{
Console.WriteLine(toFixedWidth(d));
}
}
}
}
00000001,20
00000000,20
-0000000,20
00000012,00
00000000,00
00000000,00
00000012,56
Press any key to continue . . .
double d = -12.365;
string s = d.ToString("0:00000000.00"); //-0:00000012.37
string sOut = d.ToString("00000000.00"); //-00000012.37
Here's a general function for this. It works the same as the other answers, but it builds the formatting string dynamically based on the length (total length) and decimals parameters.
public static string FormatDoubleAsFixedLengthString(double value, int length, int decimals)
{
int wholeDigits = length - decimals;
// Provide a spot for the negative sign if present.
if (value < 0)
{
wholeDigits--;
}
string wholeDigitsFormat = new String('0', wholeDigits);
string decimalDigitsFormat = new String('0', decimals);
string format = $"{{0:{wholeDigitsFormat}.{decimalDigitsFormat}}}";
return string.Format(format, value);
}
And while we're at it, here's the same function but for integers:
public static string FormatIntAsFixedLengthString(int value, int length)
{
// Provide a spot for the negative sign if present.
if (value < 0)
{
length--;
}
return string.Format($"{{0:D{length}}}", value);
}

How to implement a robust truncate method in C#?

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);

Getting Exact precision of decimal places from a double in .NET 3.5

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

Categories