I'm writing a number converter. How can I convert a integer to a binary string in C# WITHOUT using built-in functions (Convert.ToString does different things based on the value given)?
Binary -> Sign magnitude
Binary -> One's complement
Binary > Two's complement
Simple soution:
IntToBinValue = Convert.ToString(6, 2);
Almost all computers today use two's complement representation internally, so if you do a straightforward conversion like this, you'll get the two's complement string:
public string Convert(int x) {
char[] bits = new char[32];
int i = 0;
while (x != 0) {
bits[i++] = (x & 1) == 1 ? '1' : '0';
x >>= 1;
}
Array.Reverse(bits, 0, i);
return new string(bits);
}
That's your basis for the remaining two conversions. For sign-magnitude, simply extract the sign beforehand and convert the absolute value:
byte sign;
if (x < 0) {
sign = '1';
x = -x;
} else {
sign = '0';
}
string magnitude = Convert(x);
For one's complement, subtract one if the number is negative:
if (x < 0)
x--;
string onec = Convert(x);
At least part of the answer is to use decimal.GetBits(someValue) to convert the decimal to its binary representation.
BitConverter.GetBytes can be used, in turn, on the elements returned from decimal.GetBits() to convert integers into bytes.
You may find the decimal.GetBits() documentation useful.
I'm not sure how to go from bytes to decimal, though.
Update: Based on Author's update:
BitConverter contains methods for converting numbers to bytes, which is convenient for getting the binary representation. The GetBytes() and ToInt32() methods are convenient for conversions in each direction. The ToString() overloads are convenient for creating a hexadecimal string representation if you would find that easier to interpret as 1's and 0's.
var a = Convert.ToString(4, 2).PadLeft(8, '0');
Here's mine:
(The upper part convert 32-char binary string to 32-bit integer, the lower part convert 32-bit integer back to 32-char binary string).
Hope this helps.
string binaryString = "011100100111001001110011";
int G = 0;
for (int i = 0; i < binaryString.Length; i++)
G += (int)((binaryString[binaryString.Length - (i + 1)] & 1) << (i % 32));
Console.WriteLine(G); //7500403
binaryString = string.Empty;
for (int i = 31; i >= 0; i--)
{
binaryString += (char)(((G & (1 << (i % 32))) >> (i % 32)) | 48);
}
Console.WriteLine(binaryString); //00000000011100100111001001110011
You can construct the representations digit by digit from first principles.
Not sure what built-in functions you don't want to use, but presumably you can construct a string character by character?
Start with the highest power of two greater than the number.
Push a "1" into your string.
Subtract that power of two from your number.
Take the next-lowest power of two. If you've reached one-half, stop. You're done.
If the number that's left is greater than this power of two, go back to step 2. If not, push a "0" into the string and go back to step 4.
For one's complement and two's complement, calculate those with an additional step.
Or is this way too basic for what you need?
This is an unsafe implementation:
private static unsafe byte[] GetDecimalBytes(decimal d)
{
byte* dp = (byte*) &d;
byte[] result = new byte[sizeof(decimal)];
for (int i = 0; i < sizeof(decimal); i++, dp++)
{
result[i] = *dp;
}
return result;
}
And here is reverting back:
private static unsafe decimal GetDecimal(Byte[] bytes)
{
if (bytes == null)
throw new ArgumentNullException("bytes");
if (bytes.Length != sizeof(decimal))
throw new ArgumentOutOfRangeException("bytes", "length must be 16");
decimal d = 0;
byte* dp = (byte*)&d;
byte[] result = new byte[sizeof(decimal)];
for (int i = 0; i < sizeof(decimal); i++, dp++)
{
*dp = bytes[i];
}
return d;
}
Here is an elegant solution:
// Convert Integer to binary and return as string
private static string GetBinaryString(Int32 n)
{
char[] b = new char[sizeof(Int32) * 8];
for (int i = 0; i < b.Length; i++)
b[b.Length-1 - i] = ((n & (1 << i)) != 0) ? '1' : '0';
return new string(b).TrimStart('0');
}
Related
The problem is asking :
The user gives me integer n,
I convert it to binary in 16 bits,
inverse the binary,
then decode the inverse binary into a new integer.
example:
14769 is 0011100110110001 (the 2 zeros in the front are the problem for me)
inverse the binary:
1000110110011100
Decode:
36252
I wrote the code but when I convert to binary it only gives me
11100110110001 without 00 in front, so the whole inverse binary will change and the new integer will be different.
This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace HelloWorld
{
public class Program
{
public static void Main(string[] args)
{
long n, n1, p, i, r, sum, inv, inv1, newint;
Console.WriteLine("give n:");
n=long.Parse(Console.ReadLine());
n1=n;
p=1;
sum=0;
i=n;
//for below is for the binary representation of n
for(i=n;i!=0;i=i/2)
{
r=i%2;
sum=sum+r*p;
p=p*10;
}
inv=0;
//for below is to inverse the above binary representation
for(i=sum;i!=0;i=i/10)
{
r=i%10;
inv=10*inv+r;
}
inv1=inv;
newint=0;
p=0;
//for below is to decode the inverse binary to its decimal representation
for(i=inv;i!=0;i=i/10)
{
r=i%10;
newint=newint+r*(long)Math.Pow(2,p);
p=p+1;
}
Console.WriteLine("The number that you gave = {0} \nIts binary
representation = {1} \n\nThe inverse binary representation = {2} \nThe integer corresponding to the inverse binary number = {3}", n1, sum, inv1, newint);
}
}
}
So how can i encode on 16 bits?
Edit:
1)We didn't learn built in functions
2)We didn't learn padding or
Convert.Int...
3)We only know the for loop (+ while loop but better not use it)
4)We can't use strings either
You could reverse the bits using some simple bitwise operators.
ushort num = 14769;
ushort result = 0;
// ushort is 16 bits, therefore exactly 16 iterations is required
for (var i = 0; i < 16; i++, num >>= 1){
// shift result bits left by 1 position
result <<= 1;
// add the i'th bit in the first position
result |= (ushort)(num & 1);
}
Console.WriteLine(result); //36252
You can try using Convert to obtain binary representation and Aggregate (Linq) to get back decimal:
using System.Linq;
...
int value = 14769;
int result = Convert
.ToString(value, 2) // Binary representation
.PadLeft(16, '0') // Ensure it is 16 characters long
.Reverse() // Reverse
.Aggregate(0, (s, a) => s * 2 + a - '0'); // Back to decimal
Console.Write($"{value} => {result}");
Output:
14769 => 36252
Edit: Loop solution (if you are not allowed to use the classes above...)
int value = 14769;
int result = 0;
for (int i = 0, v = value; i < 16; ++i, v /= 2)
result = result * 2 + v % 2;
Console.Write($"{value} => {result}");
Explanation (how for above works):
First of all how can we get all 16 bits of the number? We can use standard algorithm based on remainder:
14769 / 1 % 2 == 1,
14769 / 2 % 2 == 0,
14769 / 4 % 2 == 0,
14769 / 8 % 2 == 0,
14769 / 16 % 2 == 1,
...
these are the bits from right to left: 11100110110001. Typical code can be
int v = value; // we don't want to change value, let's work with its copy - v
for (int i = 0; i < 16; ++i) {
// rightmost bit
int bit = v % 2;
// we divide v by to to get rid of the rightmost bit
v = v / 2;
}
Note that we compute bits from right to left - in reverse order - the very order we are looking for! How can we build result from these bits?
result = bit0 + 2 * (bit1 + 2 * (bit2 + ...))))..)
So we can easily modify our loop into
int result = 0;
int v = value; // we don't want to change value, let's work with its copy - v
for (int i = 0; i < 16; ++i) {
// rightmost bit
int bit = v % 2;
result = result * 2 + bit;
// we divide v by to to get rid of the rightmost bit
v = v / 2;
}
Finally, if we get rid of bit and make v declared within loop we can get my loop solution
I have no problem converting a double to such a string: 7.8746137240E-008
I don't know how to force the first digit to always be zero: 0.7874613724E-007
How to achieve that using a custom string format in C#?
Maybe do it yourself ;)
double foo = 7.8746137240E-008;
var numOfDigits = foo == 0 ? 0 : (int)Math.Ceiling(Math.Log10(Math.Abs(foo)));
string formatString = string.Format("{0:0.000000}E{1:+000;-000;+000}", foo / Math.Pow(10, numOfDigits), numOfDigits);
I found a simple solution:
value.ToString("\\0.0000000000E+000;-\\0.0000000000E+000")
You can do this by formatting with standard exponential notation followed by some post-processing:
public static string FormatNumberExpZero(double value, IFormatProvider format = null) {
if (!double.IsFinite(value)) // Infinity and NaN
return value.ToString(format);
// Format the number to a temporary buffer.
// "E10" means exponential notation with 10 decimal places.
Span<char> buffer = stackalloc char[24];
value.TryFormat(buffer, out int charCount, "E10", format);
// Don't touch any negative sign.
Span<char> bufferNoSign = (buffer[0] == '-') ? buffer.Slice(1) : buffer;
// Move everything after '.' one character forward to make space for the additional zero.
bufferNoSign.Slice(2, charCount - 2).CopyTo(bufferNoSign.Slice(3));
charCount++;
// Change 'X.' to '0.X'
bufferNoSign[2] = bufferNoSign[0];
bufferNoSign[1] = '.';
bufferNoSign[0] = '0';
// Read the exponent from the buffer.
Span<char> expChars = buffer.Slice(charCount - 4, 4);
int exponent = (expChars[1] - '0') * 100 + (expChars[2] - '0') * 10 + expChars[3] - '0';
if (expChars[0] == '-')
exponent = -exponent;
// Add 1 to the exponent to compensate.
exponent++;
// Write the new exponent back.
expChars[0] = (exponent < 0) ? '-' : '+';
int expAbs = (exponent < 0) ? -exponent : exponent;
int expDigit1 = expAbs / 100;
int expDigit2 = (expAbs - expDigit1 * 100) / 10;
int expDigit3 = expAbs - expDigit1 * 100 - expDigit2 * 10;
Console.WriteLine((expDigit1, expDigit2, expDigit3));
expChars[1] = (char)(expDigit1 + '0');
expChars[2] = (char)(expDigit2 + '0');
expChars[3] = (char)(expDigit3 + '0');
// Create the string.
return new string(buffer.Slice(0, charCount));
}
This solution is better than the one by #MarkSouls because it does not suffer from floating-point inaccuracy and/or overflow to infinity of doing value * 10. This requires .NET Standard 2.1 and so doesn't work with .NET Framework, though it can be modified to work with it (at the cost of allocating an additional string and char array).
I know no fancy way of achieving what you want but you can do it by writing your own function.
public static class Extender
{
public static string MyToString(this double value)
{
string s = (value * 10).ToString("E");
s = s.Replace(".", "");
return "0." + s;
}
}
It's just modifying exponential count and moving . front then adding 0.
public static void Main(string[] args)
{
Console.WriteLine(1d.MyToString());
Console.WriteLine(3.14159.MyToString());
Console.WriteLine(0.0033.MyToString());
Console.WriteLine(999414128.0.MyToString());
}
/* Output
0.1000000E+001
0.3141590E+001
0.3300000E-002
0.9994141E+009
*/
Not super cool code but it works, though I didn't check edge cases.
I wonder if there's more formal way to do it.
Can anybody help me with the of bit swapping in c#. It actually goes like this that the function accepts a number then it will convert it into binary and then swap its any bits and then convert it into decimal and the return the number.
Here is what I have tried:
DectoBin(int num) {
stringBuilder strBin = new StringBuilder();
while (num / 2 ! =1) {
strBin.Append((num % 2).ToString());
num = num / 2;
}
String str = strBin.ToString();
int BinDec(string str)
int DecNum = 0;
for (int i = str.length - 1; i >= 0; i++) {
DecNum = +DecNum
int.parse(str[k++] * pow(2, i);
}
return DecNum;
}
I need c# code of this problem soon. If anybody can provide me the code, I would be really thankful.
Your question is vague one, however, I can provide some suggestions. First, let's represent the initial int as a convenient string:
int value = ...
// Meanful bits only : 5 -> "101" (without leading zeroes)
string bits = Convert.ToString(unchecked((uint) value), 2);
// All 32 bits : 5 -> "00000000000000000000000000000101"
string allBits = Convert.ToString(unchecked((uint) value), 2).PadLeft(32, '0');
Time to query; let's use Linq whcih can be very convenient. Depending on what does swap mean it can be
using System.Linq;
...
// reversed bits: "101" -> "101", "100" -> "001", etc.
// but either "bits" or "allBits" as an argument
string result = string.Concat(bits.Reverse());
Or
// each '0' truns into "1" and vice versa: "101" -> "010", "100" -> "011" etc
// but either "bits" or "allBits" as an argument
string result = string.Concat(bits.Select(b => b == '1' ? '0' : '1'));
Finally, let's take int back with a help of Convert:
int outcome = unchecked((int)Convert.ToUInt32(result, 2));
I ran into this question when watching the twit.tv show coding 101 (episode 2). The code was pre written, but we were asked to change it in order to print out all the values of the while loop that converted an integer to a binary number.
I was able to print out everything with a simple "Console.WriteLine(number);" line. When doing so, it returns all the values for the 32-bit int 0's included.
My question, is there a way to trim or remove all the extra 0's in the division of the loop (not in the final binary number) so they are not printed? Here is the code of the program:
public static string ConvertIntToBinary(int number)
{
int bits = (sizeof(int) * 16); //32bits
char[] result = new char[bits]; //Array to hold the binary numbers http://msdn.microsoft.com/en-us/library/aa288453(v=vs.71).aspx
while (bits > 0)
{
bits = bits - 1;
int remainder = number % 2; //% called mod or modulo which computes the remainder after dividing http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx
if (remainder == 1) //If remainder is 1, store it as 1
result[bits] = '1';
else
result[bits] = '0'; //Otherwise store it as 0
number = number / 2; //Take the original number, divide it by 2
Console.WriteLine(number);
}
return new string(result).TrimStart('0'); //return the result as a string ,removing extra 0's
}
Terminate the loop when number reaches 0. At that point there are no more non-zero bits to pull off:
public static string ConvertIntToBinary(uint value)
{
int totalbits = sizeof(int) * 8;
char[] result = new char[totalbits];
int bits = totalbits;
uint number = value;
while (bits > 0)
{
bits--;
uint remainder = number % 2;
result[bits] = remainder == 0 ? '0' : '1';
number /= 2;
if (number == 0)
break;
}
return new string(result, bits, totalbits - bits);
}
I fixed an error in the code: there are 8 bits in a byte, and not 16 as per your code. I also simplified a few parts of the code. I used a conditional expression which is more concise than the if. And I introduced another local variable to hold the working value to avoid modifying the actual parameter. This is generally good practise that makes debugging easier. I also used uint for the input parameter since the entire approach depends on the value being positive.
Note that the termination is inside the loop rather than in the while test. If you test for number equal to 0 in the while condition then you will end up returning the empty string for an input of 0.
Just ignore all the Zero bits as you loop until you hit a '1' bit.
This works with negative numbers as well.
public static string ConvertIntToBinary(int number)
{
if (number == 0) return "0";
var bits = (sizeof(int) * 8); // 8bits per byte
var sb = new StringBuilder();
var print = false;
var mask = (uint)(1 << bits - 1);
while (bits-->0)
{
var bit = (number & mask) == mask;
if (bit) print = true;
if (print) sb.Append(bit ? '1' : '0');
mask = mask >> 1;
}
return sb.ToString();
}
I have very long 5 strings (the number of strings may change).There is no fixed format for these strings. I will provide a number which will indicate the length of the substring. I want to find the matching substrings with the given length. For example the strings are:
1. abcabcabc
2. abcasdfklop
string length: 3
Given these values the output will be something like this:
Match #1:
Matched string : "abc"
Matches in first string: 3
Matching positions: 0,3,6
Matches in second string: 1
Match positions: 0
Match #2:
Matched string : "bca"
Matches in first string: 2
Matching positions: 1,4
Matches in second string: 1
Match positions: 1
I managed to do it in 4 foreach statement. But it seemed to me too unefficient. Especially if the input sizes are very big.Is there any suggestion or short way to manage this more efficient in c#?
You can do this with a suffix array. (Suffix trees will work fine too, but they require a bit more space, time, and care in implementation.)
Concatenate your two strings, separating them with a character that occurs in neither one. Then build a suffix array. Then you can read off your answer.
Standard suffix arrays give you a lexicographically sorted array of pointers to suffixes of the string together with a "longest common prefix length" array telling you how long the longest common prefix of two lexicographically consecutive suffixes is.
It is fairly straightforward to use the longest common prefix length array to get the information you want; find all maximal subarrays of the longest common prefix length array for which the longest common prefix length is at least the query length, then, for each one that has a match both in the first string and in the second string, report the appropriate prefix and report that it occurs K+1 times, where K is the length of the maximal subarray.
Another approach that's easier to code is to hash all substrings of the appropriate length. You can do this easily with any rolling hash function. Store a dynamic array of pointers into the strings for each hash; once you've hashed all the strings, iterate over all of the hashes that came up and look for matches. You'll need to deal with the false positives somehow; one (probabilistic) approach is to use several hash functions until the false positive probability is acceptably small. Another approach, which is likely only acceptable in the case where you have few matches, is to compare the strings directly.
If you managed to do this in 4 foreach statements that are not nested then you should be good and you probably don’t need to optimize.
Here is something I’d try.
Create a structure that looks something like this
class SubString
{
string str;
int position;
}
Divide both strings into all possible substrings and store these into one array. This has a O(n2) complexity.
Now sort these arrays by string length ( O(n*log(n)) complexity) and go through both of these to identify matches.
You’ll need additional structure to hold the results and this probably needs some more tweaking but you see where this is going.
You could use a variant of suffix tree to solve this problem. http://en.wikipedia.org/wiki/Longest_common_substring_problem
Also check this out: Algorithm: Find all common substrings between two strings where order is preserved
If using very large strings, memory may become a problem. The code below finds the longest common substring and writes over the variable containing smaller common substrings, but could easily be altered to push the index and length to a list which is then returned as an array of strings.
This is refactored C++ code from Ashutosh Singh at https://iq.opengenus.org/longest-common-substring-using-rolling-hash/ - this will find the substring in O(N * log(N)^2) time and O(N) space
using System;
using System.Collections.Generic;
public class RollingHash
{
private class RollingHashPowers
{
// _mod = prime modulus of polynomial hashing
// any prime number over a billion should suffice
internal const int _mod = (int)1e9 + 123;
// _hashBase = base (point of hashing)
// this should be a prime number larger than the number of characters used
// in my use case I am only interested in ASCII (256) characters
// for strings in languages using non-latin characters, this should be much larger
internal const long _hashBase = 257;
// _pow1 = powers of base modulo mod
internal readonly List<int> _pow1 = new List<int> { 1 };
// _pow2 = powers of base modulo 2^64
internal readonly List<long> _pow2 = new List<long> { 1L };
internal void EnsureLength(int length)
{
if (_pow1.Capacity < length)
{
_pow1.Capacity = _pow2.Capacity = length;
}
for (int currentIndx = _pow1.Count - 1; currentIndx < length; ++currentIndx)
{
_pow1.Add((int)(_pow1[currentIndx] * _hashBase % _mod));
_pow2.Add(_pow2[currentIndx] * _hashBase);
}
}
}
private class RollingHashedString
{
readonly RollingHashPowers _pows;
readonly int[] _pref1; // Hash on prefix modulo mod
readonly long[] _pref2; // Hash on prefix modulo 2^64
// Constructor from string:
internal RollingHashedString(RollingHashPowers pows, string s, bool caseInsensitive = false)
{
_pows = pows;
_pref1 = new int[s.Length + 1];
_pref2 = new long[s.Length + 1];
const long capAVal = 'A';
const long capZVal = 'Z';
const long aADif = 'a' - 'A';
unsafe
{
fixed (char* c = s)
{
// Fill arrays with polynomial hashes on prefix
for (int i = 0; i < s.Length; ++i)
{
long v = c[i];
if (caseInsensitive && capAVal <= v && v <= capZVal)
{
v += aADif;
}
_pref1[i + 1] = (int)((_pref1[i] + v * _pows._pow1[i]) % RollingHashPowers._mod);
_pref2[i + 1] = _pref2[i] + v * _pows._pow2[i];
}
}
}
}
// Rollingnomial hash of subsequence [pos, pos+len)
// If mxPow != 0, value automatically multiply on base in needed power.
// Finally base ^ mxPow
internal Tuple<int, long> Apply(int pos, int len, int mxPow = 0)
{
int hash1 = _pref1[pos + len] - _pref1[pos];
long hash2 = _pref2[pos + len] - _pref2[pos];
if (hash1 < 0)
{
hash1 += RollingHashPowers._mod;
}
if (mxPow != 0)
{
hash1 = (int)((long)hash1 * _pows._pow1[mxPow - (pos + len - 1)] % RollingHashPowers._mod);
hash2 *= _pows._pow2[mxPow - (pos + len - 1)];
}
return Tuple.Create(hash1, hash2);
}
}
private readonly RollingHashPowers _rhp;
public RollingHash(int longestLength = 0)
{
_rhp = new RollingHashPowers();
if (longestLength > 0)
{
_rhp.EnsureLength(longestLength);
}
}
public string FindCommonSubstring(string a, string b, bool caseInsensitive = false)
{
// Calculate max neede power of base:
int mxPow = Math.Max(a.Length, b.Length);
_rhp.EnsureLength(mxPow);
// Create hashing objects from strings:
RollingHashedString hash_a = new RollingHashedString(_rhp, a, caseInsensitive);
RollingHashedString hash_b = new RollingHashedString(_rhp, b, caseInsensitive);
// Binary search by length of same subsequence:
int pos = -1;
int low = 0;
int minLen = Math.Min(a.Length, b.Length);
int high = minLen + 1;
var tupleCompare = Comparer<Tuple<int, long>>.Default;
while (high - low > 1)
{
int mid = (low + high) / 2;
List<Tuple<int, long>> hashes = new List<Tuple<int, long>>(a.Length - mid + 1);
for (int i = 0; i + mid <= a.Length; ++i)
{
hashes.Add(hash_a.Apply(i, mid, mxPow));
}
hashes.Sort(tupleCompare);
int p = -1;
for (int i = 0; i + mid <= b.Length; ++i)
{
if (hashes.BinarySearch(hash_b.Apply(i, mid, mxPow), tupleCompare) >= 0)
{
p = i;
break;
}
}
if (p >= 0)
{
low = mid;
pos = p;
}
else
{
high = mid;
}
}
// Output answer:
return pos >= 0
? b.Substring(pos, low)
: string.Empty;
}
}