Format string with decimal - c#

I am trying to take a string that may or may not contain a '.' to x amount of characters removing the "decimal point" as well. the result will ultimately be converted to a signed integer. I will also always need to the 1/10 decimal (ie 10 will become 100, 1 will become 10, etc...) I would like to just format the string without converting to an integer until the very end.
Example
if my incoming string is
9.86
I want 98 as a string ( i don't care about rounding up or anything)
if i get 9
I want 90
if i get -100
i want -1000
if i get -95.353
i want -953

string.Format("{0:d}", (int)9.015*10);
If you want a rounded result, replace the Cast
Edit: But I missed the "string" part. Verbose code below
var input = "9.86";
var len = input.IndexOf('.');
var result = "";
if (len > 0)
{
result = input.Substring(0, len);
result += input.Substring(len + 1, 1);
}
else
{
result = input + "0";
}

If you are essentially multiplying by ten the number contained in the string and dropping decimal places after the first, then you would be better off casting the string as a decimal and then doing the conversion and casting that number as an integer. Otherwise you will have to write a large set of mathematical rules on how to modify your string based on a particular type of input.
string[] input = {"9.86", "9", "-100", "-95.3"};
List<int> intNums = new List<int>();
foreach (string s in input)
{
decimal number;
if (Decimal.TryParse(s, out number))
{
number = number * 10;
intNums.Add((int)number);
}
}
Output:
[0] 98 int
[1] 90 int
[2] -1000 int
[3] -953 int

Related

Why is the output of my solution to PlusOne (LeetCode Problem) so different from what I expect?

I'm just starting out on LeetCode doing some of the 'easy' problems and I'm trying to solve a problem called 'PlusOne' where you're asked to do the following:
"You are given a large integer represented as an integer array digits, where each digits[i] is the i-th digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading 0's.
Increment the large integer by one and return the resulting array of digits."
Below is the solution I came up with. The input is digits = [1, 2, 3].
static int[] PlusOne(int[] digits)
{
string digitsToString = string.Join(string.Empty, digits);
int stringToInt = Convert.ToInt32(digitsToString);
stringToInt += 1;
string outputString = stringToInt.ToString();
int[] output = outputString.Select(x => Convert.ToInt32(x)).ToArray();
/*
Tried this as well, but just got the same result
char[] outputCharArr = stringToInt.ToString().ToCharArray();
int[] output = Array.ConvertAll(outputCharArr, Convert.ToInt32);
*/
return output;
}
The expected output is [1, 2, 4], but what I get is [49, 50, 52]. I'm completely baffled as to why this the output I'm getting so if someone could explain it to me I'd be extremely appreciative!
Yong's answer will solve the problem you're having with your approach. Your solution will work up until a point but for very large numbers it will fail once you get out of range for a 32 bit integer.
Alternatively you can increment the digits like Yong hinted at, however you need to handle rolling over to "10" back to 0 and incrementing the previous digit, which is possibly one of the goals of the exercise.
public static int[] PlusOne(int[] digits)
{
return incrementPosition(digits, digits.Length-1);
}
private static int[] incrementPosition(int[] digits, int position)
{
if (position < 0 || position > digits.Length)
throw new ArgumentException("Position falls outside of digit length.");
if (digits[position] < 0 || digits[position] > 9)
throw new ArgumentException($"The digit at position {position} was out of range.");
digits[position]++;
if (digits[position] >= 10)
{
digits[position] = 0;
if (position > 0)
digits = incrementPosition(digits, position - 1);
else
{
int[] updatedDigits = new int[digits.Length + 1];
updatedDigits[0] = 1;
digits.CopyTo(updatedDigits, 1);
digits = updatedDigits;
}
}
return digits;
}
This assumes that the array contains single-digit elements /w base-10 incrementing, and represents a positive value. There is a basic check for when a particular digit is incremented. This code handles when a digit rolls over, including when a "full" array (I.e. 9, 9, 9) rolls over, inserting a new digit converting 999 to 1000.
The problem was from here:
string outputString = stringToInt.ToString();
int[] output = outputString.Select(x => Convert.ToInt32(x)).ToArray();
Which you are converting a char to int.
According to here, you will get the result of 49 when casting from a '1' (char) [Known as ASCII].
char
int
'1'
49
'2'
50
'4'
52
If your int array with a guarantee with orders (smallest to largest), you can just update the last value of the array as below:
static int[] PlusOne(int[] digits)
{
digits[digits.Length - 1] += 1;
return digits;
}
Sample .NET Fiddle

How to convert from big number to short plus Exp?

Maybe I just didn't sleep enough today and can't think clearly enough today:
I have big numbers, and I have an array of Exp "big number names". I want to get the Exponent of the big number and then display the big number as a decimal value + big number label.
string[] exponent =
{
"Mil",
"Bil",
"Tri",
"Qua",
"Qui",
"Sex",
"Sep",
"Oct",
"Non",
};
double value = 1230000000;
if(value > 1000000)
{
int pow = (int)(value / 1000000);
res = value.ToString("#.##") + exponent[pow] ;
}
Expected output I want would be:
1.23Bil
but I'm clearly not converting value correctly.
Using the logarithm base 10 will get you the nearest power of 10 to the number, but you need to round to the nearest multiple of 3 of the power of ten (you really want the log base 1000).
Then you need to divide the value by that power of 1000 to get the matching mantissa:
string res;
if(value >= 1e6) {
int pow = ((int)Math.Log10(value))/3;
res = (value/Math.Pow(10, 3*pow)).Dump().ToString("#.##") + exponent[pow-2] ;
}
else
res = value.ToString();

Split an integer

I have been searching around the internet for a while but haven't found what I am looking for.
Let me start with some code example:
int a = 25;
int b;
int c;
What I want to do here is I want to split the a variable and give the two values to variable b and c. The result would be int b = 2 and int c = 5, or vice versa (doesn't matter in the purpose I'm going to use this).
How can you do this?
You can use integer division and modulo for that:
int b = a / 10;
int c = a % 10;
If the variable a contains a larger number, you would first determine how many digits you want in each variable. If you for example want two digits in c, you would use 100 as the second operand in both operations.
One way you could do it is with the following code:
int input = 123845;
var digits = input.ToString().Select(x=>int.Parse(x.ToString()));
This will first of all convert your input number to a string. It then treats this string as a character array when passing to Select. It then converts the char to a string and then parses it as an int, resulting in an IEnumerable<int>.
Of note is that this won't work if your input is a negative number (it will complain about the -). It wouldn't be too hard to check for the "-" at the beginning if you wanted to though.
The other way is to continually divide by 10 getting all the digits out one by one.
public IEnumerable<int> GetDigits(int input)
{
int currentNumber = input;
List<int> digits = new List<int>();
while (currentNumber !=0)
{
digits.Add(currentNumber%10);
currentNumber = currentNumber/10;
}
digits.Reverse();
return digits;
}
This will loop through the number adding the last digit to a list as it goes. It then returns the list reversed. This does deal with negative numbers and if the input is negative all output numbers iwll be negative.
An important note is that both of these methods will deal with more than two digits input numbers.
int a = 12345;
a = Math.Abs(a);
int length = a.ToString().Length;
int[] array = new int[length];
for (int i = 0; i < length; i++)
{
array[i] = a % 10;
a /= 10;
}

Format C# Double to Scientfic Notation in powers with multiples of three

I'm trying to format some large numbers in scientific format, but I need the power in multiples of three. Is there a recommended way to do this?
I have a range of numbers in a table and instead of true scientific format (with a single digit before the decimal point) I'm happy to have that change in order to have a power with a multiple of three, for example:
3.123e+003
19.523e+003
Rather than:
3.123e+003
1.952e+004
Having all the powers as multiples of three makes my table easier to scan, I believe.
Thanks in advance
I think you need to write your own function.
At first you can get the scientific representation of the number with the precision two digits larger than you need.
Then you should parse resulting string to get floating-point coefficient and 10's power index as numbers of type decimal. After that you analyse the remainder of division index by 3 and change the numbers in the appropriate way. Finally you generate output string.
static string Scientific3(double value, int precision)
{
string fstr1 = "{0:E" + (precision+2).ToString() + "}";
string step1 = string.Format(fstr1, value);
int index1 = step1.ToLower().IndexOf('e');
if (index1 < 0 || index1 == step1.Length - 1)
throw new Exception();
decimal coeff = Convert.ToDecimal(step1.Substring(0, index1));
int index = Convert.ToInt32(step1.Substring(index1 + 1));
while(index%3!=0)
{
index--;
coeff *= 10;
}
string fstr2 = "{0:F" + precision.ToString() + "}E{1}{2:D3}";
return string.Format(fstr2, coeff, ((index < 0) ? "-" : "+"), Math.Abs(index));
}

Dynamic number format in .NET?

I have a problem and cant find a solution. I have numbers (decimal) like 85.12343 or 100 or 1.123324. I want to format this in a way that the result is always 13 chars long including the separator.
100 --> 100.000000000
1.123324 --> 1.12332400000
I tried with toString, but failed. How could I do this?
Thanks :)
int digits = 13;
decimal d = 100433.2414242241214M;
int positive = Decimal.Truncate(d).ToString().Length;
int decimals = digits - positive - 1; //-1 for the dot
if (decimals < 0)
decimals = 0;
string dec = d.ToString("f" + decimals);
It will not remove digits from the whole part, only the fraction, when needed.
I'd go with Kobi's answer, unless it's possible you could have more than 13 digits to start with, in which case you might need to do something like this (warning: I have not even attempted to make this efficient; surely there are ways it could be optimized if necessary):
public static string ToTrimmedString(this decimal value, int numDigits)
{
// First figure out how many decimal places are to the left
// of the decimal point.
int digitsToLeft = 0;
// This should be safe since you said all inputs will be <= 100M anyway.
int temp = decimal.ToInt32(Math.Truncate(value));
while (temp > 0)
{
++digitsToLeft;
temp /= 10;
}
// Then simply display however many decimal places remain "available,"
// taking the value to the left of the decimal point and the decimal point
// itself into account. (If negative numbers are a possibility, you'd want
// to subtract another digit for negative values to allow for the '-' sign.)
return value.ToString("#." + new string('0', numDigits - digitsToLeft - 1));
}
Example inputs/output:
Input Output
---------------------------------------
100 100.000000000
1.232487 1.23248700000
1.3290435309439872321 1.32904353094
100.320148109932888473 100.320148110
0.000383849080819849081 .000383849081
0.0 .000000000000
Quick 'n' dirty:
return (value.ToString("0.#") + "0000000000000").Substring(0, 13);
string formatted = original.ToString("0.000000000000").Remove(13);
Besides simply padding the string you can do some more elaborate math to determine the number of digits:
String FormatField(Int32 fieldWidth, Decimal value) {
var integerPartDigits =
value != Decimal.Zero ? (int) Math.Log10((Double) value) + 1 : 1;
var fractionalPartDigits = Math.Max(0, fieldWidth - integerPartDigits - 1);
return value.ToString("F" + fractionalPartDigits);
}
Note that if the value is negative or has an integer part with one less digit than the field width you will not get the desired result. However, you can modify the code to accommodate these cases based on exactly how you want to format and align these numbers.
What about
string newString;
if (original.ToString().Length >= 13)
{
newString = original.ToString().Substring(13);
}
else
{
newString = original.ToString().PadRight(13, '0');
}
int noofdecimal=3;
double value=1567.9800
value.ToString("#." + new string('0', noofdecimal));
//Result=1567.980

Categories

Resources