|
helpfull thx
|
|
|
|
|
string Calculate(string Input, double FromBase, double ToBase)
{
double NativeForm;
string Output;
if (textBox1.Text == "" || textBox2.Text == "" || textBox3.Text == "")
throw new Exception("Empty Field");
int Decimal1;
if (Input.Contains('.'))
{
Decimal1 = Input.IndexOf('.');
Input = Input.Remove(Decimal1, 1);
if (Input.Contains('.'))
throw new Exception("Multiple Decimal Points");
}
else
{
Decimal1 = Input.Length;
}
Decimal1--;
NativeForm = 0.0;
for (int Position1 = 0; Position1 < Input.Length; Position1++)
{
int Place = Decimal1 - Position1;
double PlaceValue = Math.Pow(FromBase, Place);
char DigitRepresentation = Input[Position1];
int Digit = digits.IndexOf(char.ToUpper(DigitRepresentation));
if (Digit > FromBase)
throw new Exception("Symbol '" + DigitRepresentation + "' Exceeds Maximum");
double DigitValue = Digit * PlaceValue;
NativeForm += DigitValue;
}
int Position2 = 0;
int Decimal2 = (int)Math.Floor(Math.Log(NativeForm, ToBase));
double Remainder = NativeForm;
Output = "";
while (Remainder > 0.0 && Output.Length < 17)
{
int Place = Decimal2 - Position2;
double PlaceValue = Math.Pow(ToBase, Place);
int Digit = (int)Math.Floor(Remainder / PlaceValue);
char DigitRepresentation = digits[Digit];
Output += DigitRepresentation;
Remainder -= Digit * PlaceValue;
if (Position2 == 0)
Output += '.';
Position2++;
}
Output += "×" + ToBase.ToString() + "^" + Decimal2.ToString();
return Output;
}
}
|
|
|
|
|
Can a Fractional number be converted to Binary ? For Instance
Can you convert the following number to binary ?
10.93
|
|
|
|
|
It's about 1010.1110111...
|
|
|
|
|
I'm using your code to help make it easier to cache virtual earth tiles locally, the are numbered in a base 4 system.
|
|
|
|
|
|
static readonly char[] m_sDigit = new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static string DecimalToBase(int decimalNumber, int baseNumber)
{
if (baseNumber != 2)
if(baseNumber != 8)
if(baseNumber != 16)
return string.Empty;
uint val = (uint)decimalNumber;
StringBuilder binaryHolder = new StringBuilder();
int mask = 0, bits = 0;
if (baseNumber == 2)
{
mask = 1;
bits = 31;
}
else if (baseNumber == 8)
{
mask = 3;
bits = 30;
}
else if (baseNumber == 16)
{
mask = 4;
bits = 28;
}
baseNumber -=1;
for (; bits >= 0; bits -= mask)
{
binaryHolder.Append(m_sDigit[(val >> bits) & (baseNumber)]);
}
return binaryHolder.ToString();
}
DC
dciobanu2007@gmail.com
modified on Saturday, April 25, 2009 12:17 PM
|
|
|
|
|
Thank you for your worthy program.
I am new in C# and I need to do this conversion in one of my programs, but I am working with big numbers. i.e. 10^120 or bigger. Could you help me and say that how can I manage it while using this algorithm?
Thank you.
|
|
|
|
|
For any base from 2 to 62, handles negatives and zeroes:
public static int BaseToDecimal(string input, int nBase)
{
string characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
if (nBase < 2 || nBase > characters.Length)
{
throw new ArgumentOutOfRangeException("nBase", nBase, "Range: 2.." + characters.Length);
}
int result = 0;
bool negative = false;
if (input.StartsWith("-"))
{
negative = true;
input = input.Substring(1);
}
for (int i = 0; i < input.Length; i++)
{
int value = characters.IndexOf(input[i]);
if (value >= nBase || value < 0)
{
throw new ArgumentOutOfRangeException("input[" + i + "]", input[i], "This character is not valid for base " + nBase);
}
result += value * (int)Math.Pow(nBase, input.Length - i - 1);
}
if (negative)
{
result *= -1;
}
return result;
}
public static string DecimalToBase(int input, int nBase)
{
string characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
if (nBase < 2 || nBase > characters.Length)
{
throw new ArgumentOutOfRangeException("nBase", nBase, "Range: 2.." + characters.Length);
}
if (input == 0)
{
return characters[0].ToString();
}
bool negative = false;
if (input < 0)
{
negative = true;
input *= -1;
}
StringBuilder sb = new StringBuilder();
while (input != 0)
{
sb.Insert(0, (characters[input % nBase]));
input /= nBase;
}
if (negative)
{
sb.Insert(0, "-");
}
return sb.ToString();
} Converts 1 to million to hex and back again in .841 seconds.
No zero padding though, that's what we have String.Format for.
|
|
|
|
|
Hi,
exactly what I was looking for. Many thanks.
Volker
|
|
|
|
|
|
This is good but has one fatal flaw.
Try calling it like this:
DecimalToBase(int.MinValue, 16);
This causes an error due to the attempt to support negative signs on the final string. The problem is that the MinValue for Int has no corresponding positive value so doing this:
input *= -1;
doesn't actually change the sign. To get around this one would have to use uint and determine if the number should be negative or not. Like so:
<br />
public static string DecimalToBase(int input, uint nBase) {<br />
string characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";<br />
if (nBase < 2 || nBase > characters.Length) {<br />
throw new ArgumentOutOfRangeException("nBase", nBase, "Range: 2.." + characters.Length);<br />
}<br />
if (input == 0) {<br />
return characters[0].ToString();<br />
}<br />
<br />
uint uInput = unchecked((uint)input);<br />
bool negative = uInput > (uint)int.MaxValue;<br />
<br />
if (negative) {<br />
uint diff = uInput - (uint)int.MaxValue - 2;<br />
Console.WriteLine(diff);<br />
uInput = (uint)int.MaxValue - diff;<br />
}<br />
<br />
StringBuilder sb = new StringBuilder();<br />
while (uInput != 0) {<br />
sb.Insert(0, (characters[(int)(uInput % nBase)]));<br />
uInput /= nBase;<br />
}<br />
<br />
if (negative) {<br />
sb.Insert(0, "-");<br />
}<br />
return sb.ToString();<br />
}<br />
This will work for all the various bases supported. Also for larger numbers use long and ulong in place of int and uint.
|
|
|
|
|
Follow-Up.
Working with this more, I've added a means by which to get either the signed or unsigned equivalent of the number sent in.
Using HEX for example the integer value -2147483647 would come out as -7FFFFFFF if you wanted the negative sign appended (like the above method does). But what if you didn't want the signed version and wanted how it would actually be represented in the system or (if not using HEX how it'd be if not signed). It should be 80000001 (hex).
Here's the modified code to do both:
<br />
public static string DecimalToBase(int input, uint nBase, bool signed) {<br />
string characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";<br />
if (nBase < 2 || nBase > characters.Length) {<br />
throw new ArgumentOutOfRangeException("nBase", nBase, "Range: 2.." + characters.Length);<br />
}<br />
if (input == 0) {<br />
return characters[0].ToString();<br />
}<br />
<br />
uint uInput = unchecked((uint)input);<br />
bool negative = false;<br />
<br />
if (signed) {<br />
negative = uInput > (uint)int.MaxValue;<br />
<br />
if (negative) {<br />
uint diff = uInput - (uint)int.MaxValue - 2;<br />
uInput = (uint)int.MaxValue - diff;<br />
}<br />
}<br />
<br />
StringBuilder sb = new StringBuilder();<br />
while (uInput != 0) {<br />
sb.Insert(0, (characters[(int)(uInput % nBase)]));<br />
uInput /= nBase;<br />
}<br />
<br />
if (negative) {<br />
sb.Insert(0, "-");<br />
}<br />
return sb.ToString();<br />
}<br />
|
|
|
|
|
Thanks, works great
|
|
|
|
|
Hi,
This was very helpful to me.
Thank you very much.
jack
|
|
|
|
|
This was good. Helped me a lot.
Thanks...!
Nothing is impossible.....even impossible has the word possible
|
|
|
|
|
Thanks for the article - I just made use of the DecimalToBase method but found it doesn't give "0" - it gives "" instead. Also it doesn't do negative numbers.
I have made a few changes including:
fixing the 0 problem,
Support for negative numbers,
adding a zeroPadding parameter - set to 1 to get "0", 0 to get "" as before and 4 to get "0001" etc.
Improvement to the speed - to do all numbers 0 to 1 million in hex was taking 33 seconds, with this new version it takes 0.8 seconds.
private string DecimalToBase(int iDec, int numberBase, int zeroPadding)
{
if (numberBase > 16 || numberBase < 2) throw new System.ArgumentOutOfRangeException ("numberBase", numberBase, "numberBase - Range: 2..16") ;
if (zeroPadding < 0) throw new System.ArgumentOutOfRangeException ("zeroPadding", zeroPadding, "zeroPadding should be positive") ;
System.Text.StringBuilder str = new System.Text.StringBuilder() ;
bool negative ;
if (iDec < 0)
{
negative = true ;
iDec *=-1 ;
}
else
{
negative = false ;
}
int MaxBit = 32;
int max = MaxBit ;
int[] result = new int[MaxBit];
for(; iDec > 0; iDec/=numberBase)
{
int rem = iDec % numberBase;
result[--max] = rem;
}
if (iDec > 0) throw new System.ArgumentOutOfRangeException ("iDec", iDec, "iDec - Too large") ;
for (int i=max;i<MaxBit;i++)
{
str.Append(cHexa[result[i]]);
}
int zeroPaddingRequired = zeroPadding - (MaxBit - max) ;
if (zeroPaddingRequired > 0) str.Insert (0, new string('0',zeroPaddingRequired)) ;
if (negative) str.Insert (0, '-') ;
return str.ToString();
}
[NonSerialized()]private char[] cHexa = new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Hope someone finds it usefull
Team Leader - Team Code Project[^]
|
|
|
|
|
Hey Nigel
I think you have a typo error at "if (int i=max;i {str.Append(cHexa[result[i]]); }"...
_
modified on Tuesday, June 3, 2008 5:44 AM
|
|
|
|
|
Oops,
Appologies for loosing a bit
But it looks like you have fixed it now anyway
|
|
|
|
|
Anyway, I debugged it and below is the result. I just had to renamed all the variables to follow my coding standard. Thanks to you and to Balamurali, because I used this routine in my project.
[NonSerialized()]
private char[] hexCharacters = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private string DecimalToBase(int decimal_number, int number_base, int zero_padding)
{
if (number_base > 16 || number_base < 2)
{
throw new System.ArgumentOutOfRangeException (
"number_base", number_base, "number_base - Range: 2..16");
}
if (zero_padding < 0)
{
throw new System.ArgumentOutOfRangeException (
"zero_padding", zero_padding, "zero_padding should be positive");
}
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
bool isNegative = false;
if (decimal_number < 0)
{
isNegative = true ;
decimal_number *=-1 ;
}
else
{
isNegative = false ;
}
const int MAX_BIT = 32;
int max = MAX_BIT;
int[] remainders = new int[MAX_BIT];
for(; decimal_number > 0; decimal_number /= number_base)
{
remainders[--max] = decimal_number % number_base;
}
if (decimal_number > 0)
{
throw new System.ArgumentOutOfRangeException (
"decimal_number", decimal_number, "decimal_number - Too large") ;
}
for (int i = max; i < MAX_BIT; i++)
{
stringBuilder.Append(hexCharacters[remainders[i]]);
}
string s = stringBuilder.ToString();
int zero_padding_required = zero_padding - (MAX_BIT - max);
if (zero_padding_required > 0)
{
stringBuilder.Insert(0, new string('0', zero_padding_required));
}
s = stringBuilder.ToString();
if (isNegative)
{
stringBuilder.Insert(0, '-');
}
return stringBuilder.ToString();
}
_
modified on Tuesday, June 3, 2008 5:46 AM
|
|
|
|
|