Custom number to binary? - c#

I'm learning C# and im trying to get a custom number to convert to binary. I've looked up several forms here on stack overflow and they have similar code to this, but it doesn't work. Any ideas?
Console.WriteLine("You have chosen binary, input a number then it will be converted to binary.");
string num1input = Console.ReadLine();
double num1 = double.Parse(num1input);
var binary = Convert.ToString(num1, 2);
Console.WriteLine("{0} converted to binary is {1} " ,num1, binary);

It's not clear from your question if you are trying to convert an integer or a floating point value to a binary string representation.
For an integer, use this code:
void Main()
{
Console.WriteLine("You have chosen binary, input a number then it will be converted to binary.");
string num1input = Console.ReadLine();
int num1 = int.Parse(num1input);
var binary = Convert.ToString(num1, 2);
Console.WriteLine("{0} converted to binary is {1} ", num1, binary);
}
For a double, this code might be what you want:
void Main()
{
Console.WriteLine("You have chosen binary, input a number then it will be converted to binary.");
string num1input = Console.ReadLine();
double num1 = double.Parse(num1input);
long bits = BitConverter.DoubleToInt64Bits(num1);
var binary = Convert.ToString(bits, 2);
Console.WriteLine("{0} converted to binary is {1} ", num1, binary);
}

I found this exercise interesting, so here is what I did :
public IEnumerable<char> ConvertToBase2(int myNumber) {
while(myNumber != 0) {
var returnValue = (myNumber%2 == 0) ? '0' : '1';
myNumber = (myNumber % 2 == 0) ? myNumber / 2 :
(myNumber - 1) / 2;
yield return returnValue;
}
}
Console.Write(String.Concat(
ConvertToBase2(9).Reverse()
));
It works only for integers. I don't remember exactly how floating points numbers are implemented.
By the way, this is a better answer ;-)

Related

How to format floating point value with fix number of digits?

Is it possible in C# to format a double value with double.ToString in a way that I have always a fixed number of digits, no matter on which side of the decimal point?
Say I wish 6 digits, I want to have these results:
0.00123456789 gives "0.00123"
1.23456789 gives "1.23457"
123.456789 gives "123.457"
0.0000000123456789 gives "0.00000"
12345678.9 gives "12345679" (on overflow I want to see all digits left of decimalpoint)
4.2 gives "4.20000"
I'm experimenting with double.ToString, but cannot find any suitable format string.
Already tried "G6" (gives sometimes exponential format), "F6" (comes close, but 0.123456789 gives "0.123457" which are 7 digits).
I think some of your examples are wrong.
But I still think that I understand what you want to achieve.
I made an extension method.
public static class StringExtensionMethods
{
public static string ToString(this double d, int numberOfDigits)
{
var result = "";
// Split the number.
// Delimiter can vary depending on locale, should consider this and not use "."
string[] split = d.ToString().Split(new string[] { "." }, StringSplitOptions.None);
if(split[0].Count() >= numberOfDigits)
{
result = split[0].Substring(0, numberOfDigits);
}
else
{
result = split[0];
result += ".";
result += split[1];
// Add padding.
while(result.Count() < numberOfDigits +1)
result += "0";
result = result.Substring(0, numberOfDigits + 1);
}
return result;
}
}
I ran it with your examples:
double d0 = 0.00123456789;
double d1 = 1.23456789;
double d2 = 123.456789;
double d3 = 0.0000000123456789;
double d4 = 12345678.9;
double d5 = 4.2;
Console.WriteLine(d0.ToString(6));
Console.WriteLine(d1.ToString(6));
Console.WriteLine(d2.ToString(6));
Console.WriteLine(d3.ToString(6));
Console.WriteLine(d4.ToString(6));
Console.WriteLine(d5.ToString(6));
This is the output:
0.00123
1.23456
123.456
1.23456
123456
4.20000
I don't think this is the best way to solve it, but I like extension methods.
DoubleConverter class: http://1drv.ms/1yEbvL4
If your goal is to avoid "jumping" of the decimal point:
Use g formating, this does the most sensible thing to do
See where the decimal point is in your resulting string
pad with spaces at the beginning to align the column at the decimal point
As I understand, there is no predefined format that does what I need. So for everyone who is interested, here is the function I ended up with:
public string FormatValue(double d, int noOfDigits)
{
double abs = Math.Abs(d);
int left = abs < 1 ? 1 : (int)(Math.Log10(abs) + 1);
int usedDigits = 0;
StringBuilder sb = new StringBuilder();
for(; usedDigits < left; usedDigits++)
{
sb.Append("0");
}
if(usedDigits < noOfDigits)
{
sb.Append(".");
for(; usedDigits < noOfDigits; usedDigits++)
{
sb.Append("0");
}
}
return d.ToString(sb.ToString());
}

String/Int to double with precision defined onruntime

I have an input type integer that represents a number that needs to be converted to double between 1-100, and the rest is decimal precision.
Example: 1562 -> 15.62 ; 198912 -> 19.8912
Right now, I tried a conversion to string, count the number of characters, take 2 to check how many decimals I have and depending of the result "create" a composite string to get a valid double...
Any idea of there is a better way of resolving convert-precision on runtime.
What about this:
int value = 1562;
decimal d = value;
while (d > 100) {
d /= 10;
}
You can use LINQ Skip and Take like:
string str = "198912";
string newStr = string.Format("{0}.{1}", new string(str.Take(2).ToArray()), new string(str.Skip(2).ToArray()));
double d = double.Parse(newStr, CultureInfo.InvariantCulture);
You can add the checks for length on original string, and also use double.TryParse to see if you get valid values.
If you have an int to begin with then you can use decimal, which would provide you more accurate conversion. Like:
int number = 1562123123;
decimal decimalNumber = number;
while (decimalNumber > 100)
{
decimalNumber /= 10;
}
Here is a mathematical solution. The line lg = Math.Max(lg, 0); changes "2" to return "2.0" instead of "20.0" but I guess that depends on your needs for single digit numbers.
static double ToDoubleBetween1And100(int num)
{
var lg = Math.Floor(Math.Log10(num)) - 1;
lg = Math.Max(lg, 0);
return ((double)num) / Math.Pow(10, lg);
}

How to display just first 2 decimals unequal to 0

How can I display the number with just the 2 not=zero decimals?
Example:
For 0.00045578 I want 0.00045 and for 1.0000533535 I want 1.000053
There is no built in formatting for that.
You can get the fraction part of the number and count how many zeroes there are until you get two digits, and put together the format from that. Example:
double number = 1.0000533535;
double i = Math.Floor(number);
double f = number % 1.0;
int cnt = -2;
while (f < 10) {
f *= 10;
cnt++;
}
Console.WriteLine("{0}.{1}{2:00}", i, new String('0', cnt), f);
Output:
1.000053
Note: The given code only works if there actually is a fractional part of the number, and not for negative numbers. You need to add checks for that if you need to support those cases.
My solution would be to convert the number to a string. Search for the ".", then count zeroes till you find a non-zero digit, then take two digits.
It's not an elegant solution, but I think it will give you consistent results.
Try this function, using parsing to find the # of fractional digits rather than looking for zeros (it works for negative #s as well):
private static string GetTwoFractionalDigitString(double input)
{
// Parse exponential-notation string to find exponent (e.g. 1.2E-004)
double absValue = Math.Abs(input);
double fraction = (absValue - Math.Floor(absValue));
string s1 = fraction.ToString("E1");
// parse exponent peice (starting at 6th character)
int exponent = int.Parse(s1.Substring(5)) + 1;
string s = input.ToString("F" + exponent.ToString());
return s;
}
You can use this trick:
int d, whole;
double number = 0.00045578;
string format;
whole = (int)number;
d = 1;
format = "0.0";
while (Math.Floor(number * Math.Pow(10, d)) / Math.Pow(10, d) == whole)
{
d++;
format += "0";
}
format += "0";
Console.WriteLine(number.ToString(format));

How do I round doubles in human-friendly manner in C#?

In my C# program I have a double obtained from some computation and its value is something like 0,13999 or 0,0079996 but this value has to be presented to a human so it's better displayed as 0,14 or 0,008 respectively.
So I need to round the value, but have no idea to which precision - I just need to "throw away those noise digits".
How could I do that in my code?
To clarify - I need to round the double values to a precision that is unknown at compile time - this needs to be determined at runtime. What would be a good heuristic to achieve this?
You seem to want to output a value which is not very different to the input value, so try increasing numbers of digits until a given error is achieved:
static double Round(double input, double errorDesired)
{
if (input == 0.0)
return 0.0;
for (int decimals = 0; decimals < 17; ++decimals)
{
var output = Math.Round(input, decimals);
var errorAchieved = Math.Abs((output - input) / input);
if (errorAchieved <= errorDesired)
return output;
}
return input;
}
}
static void Main(string[] args)
{
foreach (var input in new[] { 0.13999, 0.0079996, 0.12345 })
{
Console.WriteLine("{0} -> {1} (.1%)", input, Round(input, 0.001));
Console.WriteLine("{0} -> {1} (1%)", input, Round(input, 0.01));
Console.WriteLine("{0} -> {1} (10%)", input, Round(input, 0.1));
}
}
private double PrettyRound(double inp)
{
string d = inp.ToString();
d = d.Remove(0,d.IndexOf(',') + 1);
int decRound = 1;
bool onStartZeroes = true;
for (int c = 1; c < d.Length; c++ )
{
if (!onStartZeroes && d[c] == d[c - 1])
break;
else
decRound++;
if (d[c] != '0')
onStartZeroes = false;
}
inp = Math.Round(inp, decRound);
return inp;
}
Test:
double d1 = 0.13999; //no zeroes
double d2 = 0.0079996; //zeroes
double d3 = 0.00700956; //zeroes within decimal
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 + "<br/><br/>");
d1 = PrettyRound(d1);
d2 = PrettyRound(d2);
d3 = PrettyRound(d3);
Response.Write(d1 + "<br/>" + d2 + "<br/>" + d3 +"<br/><br/>");
Prints:
0,13999
0,0079996
0,00700956
0,14
0,008
0,007
Rounds your numbers as you wrote in your example..
I can think of a solution though it isn't very efficient...
My assumption is that you can tell when a number is in the "best" human readable format when extra digits make no difference to how it is rounded.
eg in the example of 0,13999 rounding it to various numbers of decimal places gives:
0
0.1
0.14
0.14
0.14
0.13999
I'd suggest that you could loop through and detect that stable patch and cut off there.
This method seems to do this:
public double CustomRound(double d)
{
double currentRound = 0;
int stability = 0;
int roundLevel = 0;
while (stability < 3)
{
roundLevel++;
double current = Math.Round(d, roundLevel);
if (current == currentRound)
{
stability++;
}
else
{
stability = 1;
currentRound=current;
}
}
return Math.Round(d, roundLevel);
}
This code might be cleanable but it does the job and is a sufficient proof of concept. :)
I should emphasise that that initial assumption (that no change when rounding) is the criteria we are looking at which means that something like 0.3333333333 will not get rounded at all. With the examples given I'm unable to say if this is correct or not but I assume if this is a double issues that the problem is with the very slight variations from the "right" value and the value as a double.
Heres what I tried:
public decimal myRounding(decimal number)
{
double log10 = Math.Log10((double) number);
int precision = (int)(log10 >= 0 ? 0 : Math.Abs(log10)) + (number < 0.01m ? 1 : 2);
return Math.Round(number, precision);
}
test:
Console.WriteLine(myRounding(0.0000019999m)); //0.000002
Console.WriteLine(myRounding(0.0003019999m)); //0.0003
Console.WriteLine(myRounding(2.56777777m)); //2.57
Console.WriteLine(myRounding(0.13999m)); //0.14
Console.WriteLine(myRounding(0.0079996m)); //0.008
You can do it without converting to string. This is what I created fast:
private static double RoundDecimal(double number)
{
double temp2 = number;
int temp, counter = 0;
do
{
temp2 = 10 * temp2;
temp = (int)temp2;
counter++;
} while (temp < 1);
return Math.Round(number, counter < 2 ? 2 : counter);
}
or
private static double RoundDecimal(double number)
{
int counter = 0;
if (number > 0) {
counter = Math.Abs((int) Math.Log10(number)) + 1;
return Math.Round(arv, counter < 2 ? 2 : counter);
}
After giving it another thought I did the following and looks like it does what I want so far.
I iterate over the number of digits and compare Round( value, number ) and Round( value, number + 1 ). Once they are equal (not == of course - I compare the difference against a small number) then number is the number of digits I'm looking for.
Double.ToString() can take a string format as an argument. This will display as many characters as you require, rounding to the decimal place. E.G:
double Value = 1054.32179;
MessageBox.Show(Value.ToString("0.000"));
Will display "1054.322".
Source
Generic formats (i.e, pre-generated)
How to generate custom formats
You can use no of digits with Math.Round Function
Double doubleValue = 4.052102;
Math.Round(doubleValue, 2);
This will return 4.05 as your required answer.
This is tested code, can u explain me how i am wrong. So i need to change.

Parse decimal and filter extra 0 on the right?

From a XML file I receive decimals on the format:
1.132000
6.000000
Currently I am using Decimal.Parse like this:
decimal myDecimal = Decimal.Parse(node.Element("myElementName").Value, System.Globalization.CultureInfo.InvariantCulture);
How do print myDecimal to string
to look like below ?
1.132
6
I don't think there are any standard numeric format strings which will always omit trailing insignificant zeroes, I'm afraid.
You could try to write your own decimal normalization method, but it could be quite tricky. With the BigInteger class from .NET 4 it would be reasonably feasible, but without that (or something similar) it would be very hard indeed.
EDIT: Okay, I think this is what you want:
using System;
using System.Numerics;
public static class DecimalExtensions
{
// Avoiding implicit conversions just for clarity
private static readonly BigInteger Ten = new BigInteger(10);
private static readonly BigInteger UInt32Mask = new BigInteger(0xffffffffU);
public static decimal Normalize(this decimal input)
{
unchecked
{
int[] bits = decimal.GetBits(input);
BigInteger mantissa =
new BigInteger((uint) bits[0]) +
(new BigInteger((uint) bits[1]) << 32) +
(new BigInteger((uint) bits[2]) << 64);
int sign = bits[3] & int.MinValue;
int exponent = (bits[3] & 0xff0000) >> 16;
// The loop condition here is ugly, because we want
// to do both the DivRem part and the exponent check :(
while (exponent > 0)
{
BigInteger remainder;
BigInteger divided = BigInteger.DivRem(mantissa, Ten, out remainder);
if (remainder != BigInteger.Zero)
{
break;
}
exponent--;
mantissa = divided;
}
// Okay, now put it all back together again...
bits[3] = (exponent << 16) | sign;
// For each 32 bits, convert the bottom 32 bits into a uint (which won't
// overflow) and then cast to int (which will respect the bits, which
// is what we want)
bits[0] = (int) (uint) (mantissa & UInt32Mask);
mantissa >>= 32;
bits[1] = (int) (uint) (mantissa & UInt32Mask);
mantissa >>= 32;
bits[2] = (int) (uint) (mantissa & UInt32Mask);
return new decimal(bits);
}
}
class Program
{
static void Main(string[] args)
{
Check(6.000m);
Check(6000m);
Check(6m);
Check(60.00m);
Check(12345.00100m);
Check(-100.00m);
}
static void Check(decimal d)
{
Console.WriteLine("Before: {0} - after: {1}", d, d.Normalize());
}
}
}
This will remove all the trailing zeros from the decimal and then you can just use ToString().
public static class DecimalExtensions
{
public static Decimal Normalize(this Decimal value)
{
return value / 1.000000000000000000000000000000000m;
}
}
Or alternatively, if you want an exact amount of precision, say 5 decimal places, first Normalize() and then multiply by 1.00000m.
This meets the example given but POORLY. (I THINK)
myDecimal.ToString("#.######")
What other requirements are there? Are you going to manipulate the values and show the manipulated values to this number of decimals?
Alternate answer involves recursiveness, like so:
//use like so:
myTextbox.Text = RemoveTrailingZeroes( myDecimal.ToString() );
private string RemoveTrailingZeroes(string input) {
if ( input.Contains( "." ) && input.Substring( input.Length - 1 ) == "0" ) { //test the last character == "0"
return RemoveTrailingZeroes( input.Substring( 0, input.Length - 2 ) )
//drop the last character and recurse again
}
return input; //else return the original string
}
And if you wanted an extension method, then this is an option
//use like so:
myTextbox.Text = myDecimal.ToString().RemoveTrailingZeroes();
private string RemoveTrailingZeroes(this string input) {
if ( input.Contains( "." ) && input.Substring( input.Length - 1 ) == "0" ) { //test the last character == "0"
return RemoveTrailingZeroes( input.Substring( 0, input.Length - 2 ) )
//drop the last character and recurse again
}
return input; //else return the original string
}
Added input.Contains( "." ) && per comment from Jon Skeet, but bear in mind this is going to make this incredibly slow. If you know that you'll always have a decimal and no case like myDecimal = 6000; then you could drop that test, or you could make this into a class and have several private methods based on whether the input contained a decimal, etc. I was going for simplest and "it works" instead of Enterprise FizzBuzz
If you only need to do this for display then how about using a custom format string?
// decimal has 28/29 significant digits so 30 "#" symbols should be plenty
public static readonly string TrimmedDecimal = "0." + new string('#', 30);
// ...
decimal x = 1.132000m;
Console.WriteLine(x.ToString() + " - " + x.ToString(TrimmedDecimal)); // 1.132
decimal y = 6.000000m;
Console.WriteLine(y.ToString() + " - " + y.ToString(TrimmedDecimal)); // 6
What about using toString("G29") on your decimal?
this does exactly what you're trying to achieve !

Categories