Understanding C++ code - "Get the number of digits in an int" - c++

I am having trouble understanding how exactly this code works:
int length = 1;
int x = 234567545;
while (x /= 10)
length++;
It is supposed to count the number of digits in the int variable. I don't get how the while loop is working. Does the loop just go to zero and stop by default? Also, why is the length starting at 1?

There are three things that might be suspicious for you if you are a C++ beginner:
First thing might be operator /=, which combines an integral division (i.e. without remainder), with an assignment. So x /= 10 actually is the same as x = x / 10.
Second, each expression in C++ has - after having been evaluated - a value. For an assignment like (x = 0), the result is the value of x after the assignment, i.e. 0 in this case.
Third, a condition like if (x) ... with x being of integral type has in C++ the same meaning as if(x != 0), i.e. it is false if x equals 0, and it is true if x is anything else but 0.
All together: while ( x /= 10 ) means assign x the value of an integral division by 10 and then compare the value to 0. If 0 is reached, the loop ends.
BTW: length starts with 1, because any number, even 0, comprises at least one digit.

x /= 10 continuously divides x by 10, which will make it 0 eventually and cause the while loop to terminate due to 0 being interpreted as false (and any other value than 0 as true).
The reason it starts at length = 1 is because there is always at least 1 digit in the number: if x was from 0 to 9 inclusive, then x /= 10 would cause x to become 0 immediately, meaning nothing inside the loop would execute. Therefore, if length started at 0, it would never get to be incremented to 1 which would be wrong if x was a single digit large.
Manually calculating this example by hand:
234567545 / 10 = 23456754, which is true, so the while loop continues and length becomes 2.
23456754 / 10 = 2345675, true. length becomes 3.
2345675 / 10 = 234567, true. length becomes 4.
234567 / 10 = 23456, true. length becomes 5.
23456 / 10 = 2345, true. length becomes 6.
2345 / 10 = 234, true. length becomes 7.
234 / 10 = 23, true. length becomes 8.
23 / 10 = 2, true. length becomes 9.
2 / 10 = 0, false. The while loop stops with length equal 9.

The loop
while (x /= 10) {
length++;
}
will go until the result of x /= 10 evaluates to false, since 0 means false it will go until x /= 10 is 0. Integer division truncates, ensuring the condition will be reached. This can be illustrated by adding a simple debug statement, i.e.
while (x /= 10) {
length++;
std::cout << length << " " << x << std::endl;
}
Which outputs
2 23456754
3 2345675
4 234567
5 23456
6 2345
7 234
8 23
9 2

Integer division will truncate the remainder, so continually dividing a number with integer division will inevitably result in zero.
Dividing a number n by 10 while incrementing a counter i once for each time the resulting quotient (stored back into n) is not zero will result in the i containing the number of digits for the base-10 representation of n.

It helps to understand two parts:
what is "/="
when does the loop terminate
Explain "/="
This:
x /= 10
is the same as:
x = x / 10
Explain when the loop terminates
The while loop terminates, when the condition is false. And 0 is equivalent to false.
while (condition) {
length++;
}
So x is, with every pass through the loop, divided by 10, until is is 0. That terminates the loop.
So, the condition is two things at the same time:
it is a value, that is compared to 0. The loop continues until this
evaluates to 0.
it is an assignment: x gets a new value with every evaluation. It's divided by 10, so it converges to 0.

This is a bit of stupidity you'll often see in C/C++, taking advantage of the fact that TRUE is implemented as non-zero, and FALSE as zero*. So x is repeatedly divided by 10, and the expression eventually becomes zero, so the loop stops.
Though confusing, this works - until the day someone in a hurry changes x from an int to a double :-) Much clearer and less failure-prone to write "while (x /= 10 >= 1)", or even to put the math inside the loop body rather than in the condition.
*IMHO one of the few shortcomings of C is that it didn't have an explicit logical type, as FORTRAN did.

Related

To find the smallest number divisible by first n numbers [duplicate]

Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).

Codeblocks "project.exe has stopped working" for certain input numbers, C++ [duplicate]

Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).

Mechanics of 'x % y != 0' in C++

Can someone please explain the under-the-hood mechanics of x % y !=0 in C++? It evaluates to 0 if there is no remainder in integer division and it evaluates to 1 if there is any remainder of any amount. I find this to be quite useful, but I'd like to understand what is taking place, as the syntax is not intuitive to me.
I discovered this in a separate thread, which I do not have permissions to comment in:
Fast ceiling of an integer division in C / C++
Thank you.
(Please forgive any formatting faux pas; this is my first go here)
% is the integer remainder operator.
For example:
21 % 7 == 0
22 % 7 == 1
25 % 7 == 4
27 % 7 == 6
28 % 7 == 0
x % y != 0 is true if the integer division yields a non-zero remainder, false if it doesn't. x % y is simply that remainder; x % y != 0 tests whether that remainder is non-zero.
(Note that x % y != 0 can also be written as (x % y) != 0.)
It's slightly complicated when you consider negative operands.
The result of the expression is a Boolean (via the "not-equal-to" binary operator). So if the result of the modulus is non-zero, the full expression result is 1 (true). If the result of the modulus is zero, the full expression result is 0 (false)
Well it seems your problem is the modulo operater (%). So what this operator does is give you the remainder after we divide two numbers.
EX. 5 % 2 = 1 Because when we take 5/2 in integer division we get 2 however we clearly have 1 as a remainder. Another example is 22 % 4 = 2 Because 22/4 = 5 with 2 remainder.
Now that we understand this we can clearly see that if we get a non zero number the expression x % y != 0 will return true so we have two integers that dont divide each other. If we get this as false then we get two numbers that do divide each other. So you actually have it backwards because if the integer division is successful with no remainder x % y == 0 so 0 != 0 will be false.

Condition in "if" ignored in "for" loop

For below code, when input is:
first input = 0 1 2 3 4 5 6 7 8 9
second input = 1 2 3 4 5 6 7 8 9 10
it will produce output of:
first output = 0
second output = 1
instead of taking each input quartile it take its first element, and the problem is (after testing and such), it follow with the problem in code
for (vector<int>::size_type counter = 0; (quartiles < quadro) && (counter < numstore.size()); ++counter)
{
if (counter == (quartiles/quadro * numstore.size()))
{
quaele.push_back(numstore[counter]);
if ((quartiles == 2) && (numstore.size() / 2 == 0))
quaele[quartiles-1] = (numstore[counter]+numstore[counter-1]) / 2;
++quartiles;
}
// test
cout << quartiles;
}
where the conditional in "if function" doesn't work, I mean on first loop, counter == 0, how can 0 == 1(quartiles)/4(quadro) * 10(numstore.size()??
Because quartiles and quadro are both integers and the first is always less than the second (because that's what the for statement says), the expression:
quartiles / quadro * numstore.size()
will always be equal to zero, because quartiles / quadro is calculated first. Hence, the if statement will only ever be true the first time through the loop.
You may be able to get around this by re-arranging the calculation:
quartiles * numstore.size() / quadro
That's how integer arithmetic works. 1/4 is truncated to zero.
You can get the correct result (rounded down to the nearest integer) by multiplying first:
(quartiles * numstore.size()) / quadro
I've used parentheses to make the evaluation order clear - you could leave them out if you prefer.
Note that, for large values, you'll need to be careful that the multiplication doesn't overflow - perhaps by converting to a wider type, or to floating point, or by carefully multiplying and dividing by smaller factors. That is probably not an issue in this case.
The expression quartiles/quadro * numstore.size() will be 0 for the case where quartiles = 1 and quadro = 4. This is because 1/4 is rounded downwards to 0.
Maybe this is what you mean: (quartiles * numstore.size()) / quadro
In C++, the division operator can be thought of as two different operators: one that works on integer operands, and one that works on floating point operands. If the operands are of a floating point type, the division operator will return a floating point value.
http://www.learncpp.com/cpp-programming/eight-c-programming-mistakes-the-compiler-wont-catch/
Try:
float result = quartiles/quadro * numstore.size();
edit: correcting thanks to the comments.
float result = quartiles/(float)quadro * numstore.size();
It is enough to convert one of the operands to a floating point number.
quartiles/quadro is equal to 0.25 and because quartiles is type int quartiles/quadro == 0
In C++ when you divide two integer, you get integer division. Moreover, * and / have the same precedence, so the parser interprets it as (quartiles / quadro) * numstore.size(). And (1 / 4) is equal to 0.

Can't Mod Zero?

Why is X % 0 an invalid expression?
I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?
The C++ Standard(2003) says in §5.6/4,
[...] If the second operand of / or % is zero the behavior is undefined; [...]
That is, following expressions invoke undefined-behavior(UB):
X / 0; //UB
X % 0; //UB
Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),
[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.
This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).
Mathematicians: See here.
Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.
This represents division for positive X and D; it's made up of the integral part and fractional part:
(X / D) = integer + fraction
= floor(X / D) + (X % D) / D
Rearranging, you get:
(X % D) = D * (X / D) - D * floor(X / D)
Substituting 0 for D:
(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)
Since division by 0 is undefined:
(X % 0) = 0 * undefined - 0 * floor(undefined)
= undefined - undefined
= undefined
X % D is by definition a number 0 <= R < D, such that there exists Q so that
X = D*Q + R
So if D = 0, no such number can exists (because 0 <= R < 0)
I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this
REMAIN = Y ? X % Y : X
Another way that might be conceptually easy to understand the issue:
Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.
In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.
X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.
you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...
by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])
where [a*b]==your x-axis, over time
[b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function
https://www.shadertoy.com/view/MslfW8
I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.
However, the best solution in line with your thinking would be to do something like this,
ans = Y ? X % Y : X
Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.
How computers divide:
Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:
10 - 3 = 7
7 - 3 = 4
4 - 3 = 1
So
10 / 3 = 3
10 % 3 = 1
To divide 1 and 0:
1 / 0
1 - 0 = 1
1 - 0 = 1
1 - 0 = 1
...
So
1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN
If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).
This will never end so the remainder is undefined (which is NaN for computers).