I'm trying to solve a simple question on leetcode.com (https://leetcode.com/problems/number-of-1-bits/) and I encounter a strange behavior which is probably my lack of understanding...
My solution to the question in the link is the following:
public int HammingWeight(uint n) {
int sum = 0;
while (n > 0) {
uint t = n % 10;
sum += t == 0 ? 0 : 1;
n /= 10;
}
return sum;
}
My solution was to isolate each number and if it's one increase the sum. When I ran this on my PC it worked (yes - I know it's not the optimal solution and there are more elegant solutions considering it's binary representation).
But when I tried running in the leetcode editor it returned a wrong answer for the following input (00000000000000000000000000001011).
No real easy way to debug other then printing to the console so I printed the value of n when entering the method and got the result of 11 instead of 1011 - on my PC I got 11. If I take a different solution - one that uses bitwise right shift or calculating mod by 2 then it works even when the printed n is still 11. And I would have expected those solutions to fail as well considering that n is "wrong" (different from my PC and the site as described).
Am I missing some knowledge regarding the representation of uint? Or binary number in a uint variable?
Your code appears to be processing it as base 10 (decimal), but hamming weight is about base 2 (i.e. binary). So: instead if doing % 10 and /= 10, you should be looking at % 2 and /= 2.
As for what uint looks like as binary: essentially like this, but ... the CPU is allowed to lie about where each of the octets actually is (aka "endianness"). The good news is: it doesn't usually expose that lie to you unless you cheat and look under the covers by looking at raw memory. As long as you use regular operators (include bitwise operators): the lie will remain undiscovered.
Side note: for binary work that is about checking a bit and shuffling the data down, & 1 and >> 1 would usually be preferable to % 2 and / 2. But as canton7 notes: there are also inbuilt operations for this specific scenario which uses the CPU intrinsic instruction when possible (however: using the built-in function doesn't help you increase your understanding!).
This Kata has a poor writing, in the examples the Inputs are printed in binary representation while the Outputs are in printed in decimal representation. And there is no clues to help understand that.
00000000000000000000000000001011b is 11 (in decimal, 8 + 2 + 1). That is why you get 11 as input for the first test case.
There is no numbers made of 0s and 1s in base 10 you have to decode as base 2 stuff here.
To solve the Kata, you just need to work in base 2 as you succeed to do and like #MarcGravell explained.
Please check below code, it will work for you.
Its very simple way to solve.
var result = 0;
for(var i = 0; i < 32; i++)
{
if ((n & 1) == 1) result++;
n = n >> 1;
}
return result;
Related
I'm working on the following practice problem from GeeksForGeeks:
Write a function Add() that returns sum of two integers. The function should not use any of the arithmetic operators (+, ++, ā, -, .. etc).
The given solution in C# is:
public static int Add(int x, int y)
{
// Iterate till there is no carry
while (y != 0)
{
// carry now contains common set bits of x and y
int carry = x & y;
// Sum of bits of x and y where at least one of the bits is not set
x = x ^ y;
// Carry is shifted by one so that adding it to x gives the required sum
y = carry << 1;
}
return x;
}
Looking at this solution, I understand how it is happening; I can follow along with the debugger and anticipate the value changes before they come. But after walking through it several times, I still don't understand WHY it is happening. If this was to come up in an interview, I would have to rely on memory to solve it, not actual understanding of how the algorithm works.
Could someone help explain why we use certain operators at certain points and what those totals are suppose to represent? I know there are already comments in the code, but I'm obviously missing something...
At each iteration, you have these steps:
carry <- x & y // mark every location where the addition has a carry
x <- x ^ y // sum without carries
y <- carry << 1 // shift the carry left one column
On the next iteration, x holds the entire sum except for the carry bits, which are in y. These carries are properly bumped one column to the left, just as if you were doing the addition on paper. Continue doing this until there are no more carry bits to worry about.
Very briefly, this does the addition much as you or I would do it on paper, except that, instead of working right to left, it does all the bits in parallel.
Decimal arithmetic is more complicated than binary arithmetic, but perhaps it helps to compare them.
The algorithm that is usually taught for addition is to go through the digits one by one, remembering to "carry a one" when necessary. In the above algorithm, that is not exactly what happens - rather, all digits are added and allowed to wrap, and all the carries are collected to be applied all at once in the next step. In decimal that would look like this:
123456
777777
------ +
890123
001111 << 1
011110
------ +
801233
010000 << 1
100000
------ +
901233
000000 done
In binary arithmetic, addition without carry is just XOR.
What you have here is a case of Binary Math on the Represenetation in memory:
https://www.wikihow.com/Add-Binary-Numbers
Generally when programming in C#, you do not bother with the "how is it represented in memory" level of things. 55% of the time it is not worth the effort, 40% it is worse then just using the builtin functions. And the remaing 5% you should ask yourself why you are not programming in Native C++, Assembler or something with similar low level capacities to begin with.
There have been many questions but i can't seem to find the why in the answers. It's usually: no, replace this with this or this should work.
My task is to create a program that asks the user to input a 3 digit positive integer (decimal) that converts it to octal.
For example, on paper: To convert the number 112 to octal. (8 is the base number for octal.)
These are the steps you would take:
112 / 8 = 14 remainder = 0
14 / 8 = 1 remainder = 6
1 / 8 = 0 remainder = 1
Remainder from bottom to up is the octal number that represents 112 in decimal.
So the octal number for 112 is 160.
I found the following program on the internet but i don't understand it fully.
The comments in the program are mine. Could anyone explain it to me please?
//declaration and initialization of variables but why is there an array?
int decimalNumber, quotient, i = 1, j;
int[] octalNumber = new int[100];
//input
Console.WriteLine("Enter a Decimal Number :");
decimalNumber = int.Parse(Console.ReadLine());
quotient = decimalNumber;
//as long as quotient is not equal to 0, statement will run
while (quotient != 0)
{
//this is how the remainder is calculated but it is then put in an array + 1, i don't understand this.
octalNumber[i++] = quotient % 8;
//divide the number given by the user with the octal base number
quotient = quotient / 8;
}
Console.Write("Equivalent Octal Number is ");
//i don't understand the code below here aswell.
for (j = i - 1; j > 0; j--)
Console.Write(octalNumber[j]);
Console.Read();
Any help is truly appreciated.
The first thing to understand is: this is a terrible way to solve this problem. The code is full of odd choices; it looks like someone took a bad C solution of this problem and translated it to C# without applying careful thought or using good practices. If you are trying to learn how to understand crappy code you find on the internet, this is a great example. If you are trying to learn how to design good code, this is a great example of what not to do.
//declaration and initialization of variables but why is there an array?
There's an array because we wish to store all the octal digits, and an array is a convenient mechanism for storing a number of data of the same type.
But we could ask some more pertinent questions here:
Why of size 100? It's not wrong, but that's enormously larger than necessary. What thought process led to 100 being chosen? Why wasn't that thought process documented anywhere?
Why an array of int? We're outputting text, which is a sequence of chars. It would seem more natural to have a bunch of chars.
Why an array? Since we are building a first-in-last-out data structure, a stack seems more appropriate. Or why not simply accumulate a string? That's inefficient if the string is large, but an octal string from a 32 bit integer is never large!
Why does the program produce output to the console? Surely a better factored program would have a method that takes an int and returns an octal string, which can then be printed.
Why do some of the variables have descriptive names and some have undescriptive names? Is the author of the code deliberately trying to confuse the reader? Or did they simply not think about it very carefully?
Why does i - apparently the current index into the array -- start at one?! This is simply bizarre. Arrays start at zero in C#.
What happens if you type in a negative number? Try it!
What happens if you type in zero?
We then go on to:
decimalNumber = int.Parse(Console.ReadLine());
This code presumes that the typed-in text is a legal integer, which is not guaranteed. So this program can crash. TryParse should be used, and the failure mode should be handled.
// this is how the remainder is calculated but it is
// then put in an array + 1, i don't understand this.
octalNumber[i++] = quotient % 8;
The author of the code thinks they are being clever. This is too much cleverness. Rewrite the code in your head to how it should have been implemented in the first place. First, rename i to currentIndex. Next, produce one side effect per statement, not two:
while (quotient != 0)
{
octalNumber[currentIndex] = quotient % 8;
currentIndex += 1;
quotient = quotient / 8;
}
Now it should be clear what is going on.
// I don't understand the code below here as well.
for (j = i - 1; j > 0; j--)
Console.Write(octalNumber[j]);
Do a little example. Suppose the number is 14, which is 16 in octal. First time through the loop we put 6 in slot 1. Next time through, we put 1 in slot 2. So the array is {0, 6, 1, 0, 0, 0, 0 ... } and i is 3. We wish to output 16. So we loop j from i-1 to 1, and print out 1 then 6.
So, exercise for you: write this program again, this time using the conventions of a well-designed C# program. Put your attempt on the code review site and people will be happy to give you tips on how to improve it.
This is already built into .NET, Convert.ToString already does this.
In your code, just after you have decimalNumber = int.Parse(...) you can do this:
Console.WriteLine(Convert.ToString(decimalNumber, 8));
Console.Read();
and then remove the rest of the code.
Now, if you're not asking how to do octal conversion in .NET but actually how that code works, here's how it works:
This loop does the heavy lifting:
1 while (quotient != 0)
{
//this is how the remainder is calculated but it is then put in an array + 1, i don't understand this.
2 octalNumber[i++] = quotient % 8;
//divide the number given by the user with the octal base number
3 quotient = quotient / 8;
}
I added some numbers to the lines to make it easier writing a description.
Basically, the loop does this (lines above correspond to points below).
As long as we have a number to convert (ie. we're still not done), loop.
Figure out the least significant digit, this is the remainder after dividing by 8, which is handled by the remainder operator, %, store this digit into the array in the next position.
Divide by 8 to get rid of that least significant digit and move all the other digits one up
Then loop back.
However, since we essentially found all the digits from the rightmost side towards the left, the loop at the end writes them back out in their opposite order.
As an exercise to the reader, try to figure out how the code in the question behaves if you:
Input a negative number
Input 0
(hint, it doesn't behave correctly but Convert.ToString does)
An array is used because they are calculating each digit every interation of the while loop. (e.g.) {0, 6, 1}
The last part of the program is printing each digit out, starting with the last item in the array and moving to the first. in this case it would print out:
160
On my TI-84 Plus (Silver Edition), I can enter the following without error: (-1)^(1/3) = -1
I also know that entering some expressions like the following would yield a non-real -imaginary- number like: (-1)^.5
Now, my problem is with C#'s Math object. If I send any fractions like these: {1.667, 109.667, 0.667, 120.667} OR {4/3, 111/3, 2/3, 122/3}, I would get: {NaN, NaN, NaN, NaN}.
Do I have to write a new object MathHelper that checks the rational value and returns an answer according to a limited input switch? Or is there a feature to the Math object I am missing. I can do this on the calculator...
PS, I did not come across any similar questions online yet; so if this is a duplicate, please inform me ;)
[My new views]
Thank you all for your help! I had finished upgrading the "Microsoft.Solver.Foundation.dll" to the 4.0 targeted framework and it turned out that the 'Rational' object seemed to return only -1's and 'Indeterminate'. Then after entering (-1)^(1/2) [nonreal ans] on Google, it dawned on me that I was working with nth-roots!! So, it turned out that I had already managed imaginary numbers in the past in C#, hence having solved my problem:
Any even root 2n of a negative number -m will always equal an imaginary number i. (2nā-m)=i
I can't believe I forgot this simple algebra property
You will have to write your own Math helper to do functions like this (at least for Math.Pow). EDIT: Or you can use the Rational library like mentioned in the comments.
According to the documentation:
Input: x < 0 but not NegativeInfinity; y is not an integer, NegativeInfinity, or PositiveInfinity.
Result: NaN
Review the docs here: http://msdn.microsoft.com/en-us/library/system.math.pow.aspx
In C#, (-1)^R isn't defined for non-integer values of R.
If you try to calculate (-1)^(1/3), C# will calculate 1/3 first, resulting in a non-integer floating point number for R.
Solution:
Use the mathematical identity:
a^(x/y) = a^x * a^(1/y) x,y integers
For negative a, use:
a^1/y = -(|a|^1/y) // only works if y is odd
Or put together:
if (a < 0) {
if (y % 2 = 1) {
result = a^x * -1 * (-a)^(1.0/y); // Replace ^ with the correct C# call.
} else {
// NaN
}
} else {
result = a^(x/y);
}
I'm trying to get the factorial value of number 66, but my method resulting me an output 0. But whenever I try to get the factorial of 5, it is resulting me an output 120. Could anyone please tell me why?
public static int factorial(int n)
{
if (n == 1)
return n;
return n * factorial(n - 1);
}
Sure - factorials get very big, very fast. You're overflowing the bounds of int very quickly... and at some point you'll have multiplied by enough factors to get an overflow to 0, which will then keep the value at 0 forever.
According to a quick Google search, 66 factorial is 5.44344939 Ć 1092 - which is considerably more than int can handle, or even long or decimal. You could get double to handle it - you'd lose a huge amount of precision, and that would accumulate really quickly too, but at least it wouldn't overflow...
Your method overflows. See the following example:
static void Main(string[] args)
{
Console.WriteLine(factorial(66));
}
public static int factorial(int n)
{
if (n == 1)
return n;
var result = n * factorial(n - 1);
Console.WriteLine("{0} : {1}", n, result);
return result;
}
With this example, the results of each iteration is printed.
You see that at one point, result becomes 0 and this means that every iteration from that point on becomes n * 0.
You can try using BigInteger. This will give the correct result. Calculate factorials in C# contains more information on this.
66! does not fit into an int. Use BigInteger.
The problem is that the factorial of 66 is way to large to fit into an int. I think it will also we way to large to fit into a long.
As an example, factorial(20) will return 2432902008176640000
The factorial of 50 is 3.0414093202Ć1064 which exeeds already what a int can contain.
Use long or BigInteger for this.
You get numeric overflow, 66! ~= 5e92 which is way larger than an int can handle. Also, factorials are better calculated using a for loop.
Approximately 13 or 14 is the largest number whose factorial fits in an int... If you switch to long, it'll be aroung 18 or 19 if I recall correctly. If you wish arbitraty big numbers you'd have to write your own big arithmetic library or use an existing one :)
You need to use the appropriate data type.
In this case the Big Integer data type is probably best seeing as how fast the numbers get real big.
Here is the way you use this data type.
Right click on your project, choose the add reference menu.
Look for the system.numerics library and add it.
You then add the using clause in your code.
And then you can initialise variable with the keyword as usual.
I have a very large number I need to calculate, and none of the inbuilt datatypes in C# can handle such a large number.
Basicly I want to solve this:
Project Euler 16:
2^15 = 32768 and the sum of its digits
is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the
number 2^1000?
I have already written the code, but, as said before, the number is too large for c# datatypes. The code has been tested and verified with small numbers (such as 2^15) and it works perfectly.
using System;
namespace _16_2E1000
{
class Program
{
static void Main(string[] args)
{
ulong sum = 0;
ulong i = 1 << 1000;
string s = i.ToString();
foreach (char c in s)
{
sum += (ulong) Convert.ToInt64(c.ToString());
}
Console.WriteLine(sum);
Console.ReadLine();
}
}
}
You can use BigInteger from the J# classes. First question in this article tells you how. It's a bit of pain b/c then you have to provide the J# redistributable when you roll out tho.
First to answerer you exact question, look for a BigInt or BigNum type
Second, from what I know of Project Euler, there will be a cool, tricky way to do it that is much easier.
As a first guess I'd compute the answerer for 2^1 -> 2^n (for whatever n you can get to work) and look for patterns. Also look for patterns in the sequences
V(0) = 2^p
V(n) = floor(V(n - 1) / 10)
D(n) = V(n) % 10
I hope this is not a homework problem, but to get to the answer of 2^1000, you'll have to divide it into smaller chunks,
try something like,
2^1000 = 2 * 2^999 = 2^999 + 2^999 = 2^ 998 + 2^ 998 + 2^ 998 + 2^ 998
breaking into smaller bits till you get to solvable a problem,
complete solution to project Euler is on following links.
http://blog.functionalfun.net/2008/07/project-euler-problem-16-calculating.html
http://code.msdn.microsoft.com/projecteuler
It is not necessary to have Big Integer capabilities in order to solve this problem.
One could just use the property that:
2^n = 2^(n-1) + 2^(n-1)
If Big Integer is really necessary for other tasks, I have been using the BigInt class from F# in my C# programs and am happy with it.
The necessary steps:
Install the F# CTP
In your C# (or other .NET language) application add a reference to the FSharp.Core dll.
Add: using Microsoft.FSharp.Math;
In the "Class View" window familiarize yourself with the members of the two classes: BigInt and BigNum
After executing these steps one is basically ready to use the BigInt class.
One last hint:
To avoid declaring variables with improper names to hold constants that makes the code unreadable, I am using a name that starts with _ (underscore), followed by the integer constant. In this way one will have expressions like:
N = _2 * N;
clearly much more readable than:
N = Two * N;
Here's a BigInteger (source code is available) that you can use; though, as already mentioned, there are more efficient ways to do this than brute force.
BigInteger on codeplex
Actually, while a biginteger utility might be of interest here, you don't need it, even for this. Yes, it looks like it does, but you don't. In fact, use of a biginteger form may even slow things down.
Since I don't want to solve the problem for you, I'll just suggest you think about this in a modular way.