C# convert large binary string to decimal string and divide - c#

I want to convert a large binary string to decimal string format and then divide by an integer. (The result must have at least 2 decimal places).
For example,
strBinary = "01010000010010110000001100000100000010100000000000000000000000000000000000000000101010000111100111011110010001100000101111000110110100101000101000011100010111000000000000000000000111000101110000000000000000000010011100000000000001110000000001100001011100110111001101100101011101000111001100101111011001000110010101110110011010010110001101100101011100110010111101100100011001010111011001101001011000110110010101011111011000010111001101110101011100110101111101111010011001010110111001110111011000010111010001100011011010000010111001101010011100000110011111111110110010100000000000000000000000000000000000000000111111111101100011111111111000010000000000011000010001010111100001101001011001100000000000000000010010010100100100101010000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111101100000000000001000101000100011101010110001101101011011110010000000000000001000000000000010000000000000000000000000001000110000000000000000011111111111000010000001100101101011010000111010001110100011100000011101000101111001011110110111001110011001011100110000101100100011011110110001001100101001011100110001101101111011011010010111101111000011000010111000000101111001100010010111000110000001011110000000000111100001111110111100001110000011000010110001101101011011001010111010000100000011000100110010101100111011010010110111000111101001000101110111110111011101111110010001000100000011010010110010000111101001000100101011100110101010011010011000001001101011100000100001101100101011010000110100101001000011110100111001001100101010100110111101001001110010101000110001101111010011010110110001100111001011001000010001000111111001111100010000000111100011110000011101001111000011011010111000001101101011001010111010001100001001000000111100001101101011011000110111001110011001110100111100000111101001000100110000101100100011011110110001001100101001110100110111001110011001110100110110101100101011101000110000100101111001000100010000001111000001110100111100001101101011100000111010001101011001111010010001001000001";
I want -
strDecimal = ConvertBinaryToDecimalString(strBinary);
Now I want to divide the decimal string by an integer and store the result -
strDivResult = DivideLargeNumber(strDecimal, 5);
I do not want to use BigInteger or BigDecimal for this purpose.
I referred these answers, however did not get what I am looking for, with a fast operation -
Convert a "big" Hex number (string format) to a decimal number (string format) without BigInteger Class
https://www.geeksforgeeks.org/divide-large-number-represented-string/
Appreciate your help. Thanks.

Related

Converting Long String to Double in C#

I have the following code to convert a very long numeric string.
using System;
class MainClass {
public static void Main (string[] args) {
string longString = "1000000000000000000000000000001";
double convertedString = Double.Parse(test);
Console.WriteLine(test2);
}
}
However, convertedString is outputted in scientific notation:
1E+30
Is there a way to retain the exact value of the double when I convert it from a string?
The format of the output and the precision of the variable itself have nothing to do with each other. You can get the format you want by changing the format string, e.g.
Console.WriteLine("{0:N}", test1);
As for the precision of the variable, you should be aware that floating point numbers are not precise. And your number is about ten digits too long to fit into a long.
You will either need to store that number as a custom data type or, if it is just an identifier and not actually a number on which you need to perform math, simply store it as a string.

How to use String.Format to format a number with comma separators and floating decimal point?

Suppose I have a list of decimal numbers that I must format with a comma every three places, plus the appropriate number of digits after the decimal point. I want to use the .net string.Format method.
I want it to work like this:
string format = ???;
string s1 = string.Format(format, "1500"); // "1,500"
string s2 = string.Format(format, "1500.25"); // "1,500.25"
string s3 = string.Format(format. "3.1415926358979"); // "3.1415926358979"
I have seen other answers where the digits after the decimal are either limited to a fixed number of digits or truncated entirely, but this doesn't work for my application. I want to add the comma-separator to the whole part of the number, but keep the digits after the decimal exactly as they are.
First problem, you need to parse your strings before you can format them. There maybe some lose of precision. Then you need to decide what your maximum amount of precision you need is. Then you can do something like this:
string format = "{0:#,##0.#############}";
string s1 = string.Format(format, double.Parse("1500")); // "1,500"
string s2 = string.Format(format, double.Parse("1500.25")); // "1,500.25"
string s3 = string.Format(format, double.Parse("3.1415926358979")); // "3.1415926358979"
The # after the decimal place is a place holder for a decimal digit. If there are no more digits it won't show trailing zeros.
If being limited to a number of decimal places or possibly losing precision when converting to double. You could do something really cludgy like this:
public static string DecimalFormatCludge(string original)
{
var split = original.Split('.');
return string.Join(".", (new [] { int.Parse(split[0]).ToString("#,##0")}).Concat(split.Skip(1)));
}
This will split on the . in the string, parse the first part as an int, convert it back to a string correctly formatted and then just stick the decimal part back on (if there is one)
something like this?
string s1 = format.ToString("#,##0.00");
The format is something like this:
string format = "{0:#,##.##################}";

Math.Floor to x digits after decimal

I need to display two digits after decimal point while rounding to floor as a percentage. I wrote out this code to do so, but this looks too complex, is there another more effecient way of doing this?
double decimalPlacesFactor =Math.Pow(10, numberOfDigits+2);
percentage = Math.Floor((NumA/NumB)*decimalPlacesFactor)/decimalPlacesFactor *100;
The output should look like
99.78 %
Use the ToString() methode to convert your number to a string. Display it as a floating point with X digits by using the argument "FX". e.g. "F2" for two digits
string percentage = Math.Floor(NumA/NumB).ToString("F"+numberOfDigits);
Depends on how you want to display the percentage value, but I am guessing you'll want to show string of the percentage? What about:
string percentage = Math.Floor(NumA/NumB).ToString("0.00");
Console.WriteLine(Math.Floor(2.3).ToString("0.00")); //this will output 2.00
If you want to make the number of digits after decimal configurable you could create the masking string beforehand, with something like this:
private string CreateMaskingString(int numberOfDigits)
{
var sb = new StringBuilder("0.");
sb.Append(new string('0', numberOfDigits));
return sb.ToString();
}
And usage would look like this:
Console.WriteLine(Math.Floor(2.3).ToString(CreateMaskingString(2))); //this will output 2.00
A much more simple and elegant solution looks like this, as has been pointed out by RomCoo:
string percentage = Math.Floor(NumA/NumB).ToString("F" + numberOfDigits);
What does the "F" mean here? You can read the explanation here. But basically:
The fixed-point ("F") format specifier converts a number to a string of
the form "-ddd.ddd…" where each "d" indicates a digit (0-9). The
string starts with a minus sign if the number is negative.

Format decimal number with custom amount of digits after comma

I have this custom extension that should format a decimal number with a custom amount of digits after comma.
public static decimal FormatDecimal(this decimal value, int decimalSeparator = 2)
{
decimal returnValue = Math.Round(value, decimalSeparator, MidpointRounding.AwayFromZero);
return returnValue;
}
The problem is that doesn't work as expected.
If I do like this:
decimal number = 12345;
and then:
decimal formatedNumber = number.FormatDecimal(2);
the result should be:
12345.00
instead the result is:
12345
What I am doing wrong?
Here's the extension function working
public static string FormatDecimal(this decimal value, int decimalSeparator = 2)
{
return value.ToString(string.Format("0.{0}", new string('0', decimalSeparator)));
}
I think the right way is to using The "0" custom format specifier;
Replaces the zero with the corresponding digit if one is present;
otherwise, zero appears in the result string.
For example;
decimal d = 12345;
Console.WriteLine(d.ToString("#.00")); // 12345.00
You're probably looking to format the string representation of your decimal instead. Try this:
decimal myNumber = 12345.67m;
string formattedNumber = myNumber.ToString("N3");
Console.WriteLine(formattedNumber); // Prints "12345.670"
See here for more information: https://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx
From MSDN:
Standard numeric format strings are used to format common numeric types. A standard numeric format string takes the form Axx, where:
A is a single alphabetic character called the format specifier. Any numeric format string that contains more than one alphabetic character, including white space, is interpreted as a custom numeric format string. For more information, see Custom Numeric Format Strings.
xx is an optional integer called the precision specifier. The precision specifier ranges from 0 to 99 and affects the number of digits in the result. Note that the precision specifier controls the number of digits in the string representation of a number. It does not round the number itself. To perform a rounding operation, use the Math.Ceiling, Math.Floor, or Math.Round method.
When precision specifier controls the number of fractional digits in the result string, the result strings reflect numbers that are rounded away from zero (that is, using MidpointRounding.AwayFromZero).
You should specify the formatting when you display the string.
What you need is to do the following, when you convert to string:
String.Format("{0:0.00}", formatedNumber);
Refer to This article for more details:

C# convert string to decimal 4dp

I need to take a string object and convert it to a decimal to 4 dp.
So for example:
string val = "145.83011";
decimal sss = Math.Round(Convert.ToDecimal(val), 4);
bring back 145.8301 - good
However:
string val = "145.8300";
decimal sss = Math.Round(Convert.ToDecimal(val), 4);
brings back 145.83
I need it to be 145.8300
I need it in a decimal format so can't use string format options.
Thanks
rob
One option would be to use string manipulation three times:
Parse the original text to a decimal value (this will preserve the original number of decimal places)
Use string formatting to end up with a string with exactly 4 decimal places. (Math.Round ensures there are at most 4DP, but not exactly 4DP.)
Parse the result of the formatting to get back to a decimal value with exactly 4DP.
So something like this:
public static decimal Force4DecimalPlaces(string input)
{
decimal parsed = decimal.Parse(input, CultureInfo.InvariantCulture);
string intermediate = parsed.ToString("0.0000", CultureInfo.InvariantCulture);
return decimal.Parse(intermediate, CultureInfo.InvariantCulture);
}
I recoil from using string conversions like this, but the alternatives are relatively tricky. You could either get the raw bits, split out the different parts to find the mantissa and scale, then adjust appropriately... or you could potentially work out some sequence of arithmetic operations to get to the right scale. (Jeppe's approach of multiplying by 1.0000m may well be entirely correct - I just don't know whether it's documented to be correct. It would at least be worth adding in appropriate tests for the sorts of numbers you expect to see.)
Note that the above code will perform round up on halves, as far as I can tell, so 1.12345 will be converted to 1.1235 for example.
Sample with output in comments:
using System;
using System.Globalization;
class Test
{
static void Main()
{
Console.WriteLine(Force4DecimalPlaces("0.0000001")); // 0.0000
Console.WriteLine(Force4DecimalPlaces("1.000000")); // 1.0000
Console.WriteLine(Force4DecimalPlaces("1.5")); // 1.5000
Console.WriteLine(Force4DecimalPlaces("1.56789")); // 1.5679
}
public static decimal Force4DecimalPlaces(string input)
{
decimal parsed = decimal.Parse(input, CultureInfo.InvariantCulture);
string intermediate = parsed.ToString("0.0000", CultureInfo.InvariantCulture);
return decimal.Parse(intermediate, CultureInfo.InvariantCulture);
}
}
Both Convert.ToDecimal and decimal.Parse do preserve trailing zeroes in the string (a System.Decimal can have at most 28-29 digits in total, so in most cases there's still room for all the trailing zeroes).
And Math.Round(..., 4) preserves trailing zeroes up to the fourth place after the decimal period.
Therefore the premise of the question is wrong. Your example does bring back what you want.
In any case, consider specifying the overload that takes in an IFormatProvider as well, and give CultureInfo.InvariantCulture as argument. Then the conversion is independent of the local culture.
If instead you want to handle strings like "145.83" and append trailing zeroes that were not in the string, use:
string val = "145.83";
decimal sss = Math.Round(
decimal.Parse(val, CultureInfo.InvariantCulture) * 1.0000m,
4);
Epilog: If you don't like multiplying and dividing by numbers like 1.0000m, use decimal.GetBits to get the internal representation. Adjust the integer "part" by multiplying or dividing by the appropriate power of ten, and adjust the scale "part" by subtracting or adding the corresponding number. The scale counts the number of places to move the decimal point to the left, starting from the 96-bit integer.

Categories