How to ignore Decimal - c#

I have tried to do this - Making any float value to int value. What I tried to achieve is make it 2.00-2.99 goes to 2.
Note: Im not trying to do Approximation (lower than 2.49 goes to 2, and those 2.50+ goes to 3).
I have done this so far
public int RemoveDecimal(float value)
{
string TempText = (string)value;
TempText.Remove(IndexOf('.'));
return int.parse(TempText);
}
But this will get an error when the float value ends with .00
How can I achieve this?
Thanks for any help

Math.Floor is the function you need.
It:
Returns the largest integer less than or equal to the specified number.
Example:
var val = Math.Floor(value);
Or, you could simply cast to an integer - this will simply ignore the decimal portion, so long as the range of the decimal is within the range of an int (otherwise you will get an exception):
int noDecimals = (int)value;

you can't always convert a float to an int because most of the values in float are out of range for int. you should return a string.
the following will do just that.
public string RemoveDecimal(float value)
{
string TempText = value.ToString("#");
return TempText;
}

Simply casting a floating point number to int does what you want.
i = (int)myFloat;
It truncates the fractional digits, i.e. it always goes in the direction of 0.
(int)2 == 2
(int)1.9 == 1
(int)-1.5 == -1
This will obviously not work correctly if the result is outside the valid range of int. If you want to achieve the same thing, but with a floating point number as result, Math.Truncate is what you need.

Related

converting int to decimal choosing where to put decimal place

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.

custom method for returning decimal places shows odd behavior

I am writing a simple method that will calculate the number of decimal places in a decimal value. The method looks like this:
public int GetDecimalPlaces(decimal decimalNumber) {
try {
int decimalPlaces = 1;
double powers = 10.0;
if (decimalNumber > 0.0m) {
while (((double)decimalNumber * powers) % 1 != 0.0) {
powers *= 10.0;
++decimalPlaces;
}
}
return decimalPlaces;
I have run it against some test values to make sure that everything is working fine but am getting some really weird behavior back on the last one:
int test = GetDecimalPlaces(0.1m);
int test2 = GetDecimalPlaces(0.01m);
int test3 = GetDecimalPlaces(0.001m);
int test4 = GetDecimalPlaces(0.0000000001m);
int test5 = GetDecimalPlaces(0.00000000010000000001m);
int test6 = GetDecimalPlaces(0.0000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001m);
Tests 1-5 work fine but test6 returns 23. I know that the value being passed in exceeds the maximum decimal precision but why 23? The other thing I found odd is when I put a breakpoint inside the GetDecimalPlaces method following my call from test6 the value of decimalNumber inside the method comes through as the same value that would have come from test5 (20 decimal places) yet even though the value passed in has 20 decimal places 23 is returned.
Maybe its just because I'm passing in a number that has way too many decimal places and things go wonky but I want to make sure that I'm not missing something fundamentally wrong here that might throw off calculations for the other values later down the road.
The number you're actually testing is this:
0.0000000001000000000100000000
That's the closest exact decimal value to 0.0000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001.
So the correct answer is actually 20. However, your code is giving you 23 because you're using binary floating point arithmetic, for no obvious reason. That's going to be introducing errors into your calculations, completely unnecessarily. If you change to use decimal consistently, it's fine:
public static int GetDecimalPlaces(decimal decimalNumber) {
int decimalPlaces = 1;
decimal powers = 10.0m;
if (decimalNumber > 0.0m) {
while ((decimalNumber * powers) % 1 != 0.0m) {
powers *= 10.0m;
++decimalPlaces;
}
}
return decimalPlaces;
}
(Suggestion) You could calculate that this way:
public static int GetDecimalPlaces(decimal decimalNumber)
{
var s = decimalNumber.ToString();
return s.Substring(s.IndexOf(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator) + 1).Length;
}
There is another way to do this and probably it works faster because it uses remainder operation only if the decimal number has a "trailing zeros" problem.
The basic idea:
In .NET any decimal is stored in memory in the form
m * Math.Power(10, -p)
where m is mantissa (96 bit size) and p is order (value from 0 to 28).
decimal.GetBits method retrieves this representation from decimal struct and returns it as array of int (of length 4).
Using this data we can construct another decimal. If we will use only mantissa, without "Math.Power(10, -p)" part, the result will be an integral decimal. And if this integral decimal number is divisible by 10, then our source number has one or more trailing zeros.
So here is my code
static int GetDecimalPlaces(decimal value)
{
// getting raw decimal structure
var raw = decimal.GetBits(value);
// getting current decimal point position
int decimalPoint = (raw[3] >> 16) & 0xFF;
// using raw data to create integral decimal with the same mantissa
// (note: it always will be absolute value because I do not analyze
// the sign information of source number)
decimal integral = new decimal(raw[0], raw[1], raw[2], false, 0);
// disposing from trailing zeros
while (integral > 0 && integral % 10 == 0)
{
decimalPoint--;
integral /= 10;
}
// returning the answer
return decimalPoint;
}

c# forcing a numeric updown to only accept positive integers with try-parse

I've only been doing this a few days and I'm pretty confused.
Everything else works fine, and the box only displays integers, but it still calculates with decimal values.
You should be able to do a int myInt = Convert.ToInt32(numBox.Value);
numBox.Value is a decimal, but that code will cause it to get converted to an integer.
Just know that IF you do get a decimal value back, it will round it up or down.
EDIT:
Aghilas Yakoub's solution might be better if you want only positive values. My solution will convert the decimal to an int, but it could still allow for negatives. Really what you should do is set your numBox.Minimum to 0 so it can't go below 0.
EDIT 2:
If you want to warn when the value is negative, try this:
int myInt = Convert.ToInt32(numBox.Value);
if (myInt < 0)
{
MessageBox.Show("Warning, your number must be 0 or greater");
}
Do you want to warn if the value isn't a whole number (has decimal values)?
You can try with
UInt32 result = 0;
UInt32.TryParse("...",
new CultureInfo(""),
out result);
if(result == 0)
{
Console.WriteLine("No parsing");
}
else
{
Console.WriteLine("result={0}", result);
}
A more elegant solution would be:
If you have access to DevExpress controls, you should use a SpinEdit control.
To limit its range from 0 to 999 (only integer number) set its:
Properties.Mask.EditMask to "##0;"
Properties.MaxValue to 999
Then the following line should work well without exceptions:
int myInt = Convert.ToInt32(numBox.Value);

Finding the number of places after the decimal point of a Double

I have a Double value:
double a = 4.5565;
What is the easiest way to calculate the number of digits after the decimal point (4 in this case).
I know that I can convert to string and do a split and take the length. But is there an easier way?
There's no easy way, especially since the number of digits mathematically speaking might be far more than displayed. For example, 4.5565 is actually stored as 4.556499999999999772626324556767940521240234375 (thanks to harold for calculating that). You're very unlikely to find a useful solution to this problem.
EDIT
You could come up with some algorithm that works like this: if, as you calculate the decimal representation, you find a certain number of 9s (or zeros) in succession, you round up (or down) to the last place before the series of 9s (or zeros) began. I suspect that you would find more trouble down that road than you would anticipate.
var precision = 0;
var x = 1.345678901m;
while (x*(decimal)Math.Pow(10,precision) !=
Math.Round(x*(decimal)Math.Pow(10,precision)))
precision++;
precision will be equal to the number of significant digits of the decimal value (setting x to 1.23456000 will result in a precision of 5 even though 8 digits were originally specified in the literal). This executes in time proportional to the number of decimal places. It counts the number of fractional digits ONLY; you can count the number of places to the left of the decimal point by taking the integer part of Math.Log10(x). It works best with decimals as they have better value precision so there is less rounding error.
Write a function
int CountDigitsAfterDecimal(double value)
{
bool start = false;
int count = 0;
foreach (var s in value.ToString())
{
if (s == '.')
{
start = true;
}
else if (start)
{
count++;
}
}
return count;
}
I think this might be a solution:
private static int getDecimalCount(double val)
{
int i=0;
while (Math.Round(val, i) != val)
i++;
return i;
}
double val9 = 4.5565d; int count9 = getDecimalCount(val9);//result: 4
Sorry for the duplication -> https://stackoverflow.com/a/35238462/1266873
base on james answer bat much clearer:
int num = dValue.ToString().Length - (((int)dValue).ToString().Length + 1);
num is the exact number of digits after the decimal point.
without including 0 like this(25.520000)
in this case, you will get num= 2
I Think String solution is best : ((a-(int)a)+"").length-2
I'll perhaps use this code if I needed,
myDoubleNumber.ToString("R").Split('.')[1].Length
"R" here is Round Trip Format Specifier
We need to check for the index bounds first of course.
Another solution would be to use some string functions:
private int GetSignificantDecimalPlaces(decimal number, bool trimTrailingZeros = true)
{
var stemp = Convert.ToString(number);
if (stemp.IndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator) < 0)
return 0;
if (trimTrailingZeros)
stemp = stemp.TrimEnd('0');
return stemp.Length - 1 - stemp.IndexOf(Application.CurrentCulture.NumberFormat.NumberDecimalSeparator);
}
Remember to use System.Windows.Forms to get access to Application.CurrentCulture

Truncate number of digit of double value in C#

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

Categories

Resources