Python - substr - php

I need to be able to get the last digit of a number.
i.e., I need 2 to be returned from: 12.
Like this in PHP: $minute = substr(date('i'), -1) but I need this in Python.
Any ideas

last_digit = str(number)[-1]

Use the % operator:
x = 12 % 10 # returns 2
y = 25 % 10 # returns 5
z = abs(-25) % 10 # returns 5

Python distinguishes between strings and numbers (and actually also between numbers of different kinds, i.e., int vs float) so the best solution depends on what type you start with (str or int?) and what type you want as a result (ditto).
Int to int: abs(x) % 10
Int to str: str(x)[-1]
Str to int: int(x[-1])
Str to str: x[-1]

Related

Understanding something more about the % Modulus operator

I am learning to work with some math like PHP query and just got to the modulo, I am not quite sure in what situations to use this because of something i stumbled on and yes I did already read one of the posts here about the modulo :
Understanding The Modulus Operator %
(This explanation is only for positive numbers since it depends on the language otherwise)
The quote above is in the top answer there. But if I focus on PHP only and i use the modulo like this:
$x = 8;
$y = 10;
$z = $x % $y;
echo $z; // this outputs 8 and I semi know why.
Calculation: (8/10) 0 //times does 10 fit in 8.
0 * 10 = 0 //So this is the number that has to be taken off of the 8
8 - 0 = 8 //<-- answer
Calculation 2: (3.2/2.4) 1 //times does this fit
1 * 2.4 = 2.4 //So this is the number that has to be taken off of the 3.2
3.2 - 2.4 = 0.8 // but returns 1?
So my question is why does this exactly happen. my guess would be that in the first phase it would get 8/10 = 0,8 but this doesn't happen. So can someone explain a bit about why this happens. I understand the modulo's basics like if I do 10 % 8 = 2 and I semi understand why it doesn't return something like this: 8 % 10 = -2.
Also, is there a way to modify how the modulo works? so it would return a - value or a decimal value in the calculation? or would I need to use something else for this
Little shortened: why does this happen when I get a negative number in return and is there some other way or operator that can actually do the same and get in the negative numbers.
Modulus (%) only works for integers, so your calculation at the bottom of your example is correct...
8/10 = 0 ( integer only ), remainder = 8-(0*10) = 8.
If you instead had -ve 12 - -12%10...
-12/10 = -1 (again integer only), remainder = -12 - (10*-1) = -2
For floats - you can use fmod(http://php.net/manual/en/function.fmod.php)
<?php
$x = 5.7;
$y = 1.3;
$r = fmod($x, $y);
// $r equals 0.5, because 4 * 1.3 + 0.5 = 5.7
(Example from manual)

PHP idiom for a counter over non-negative ints

In trying to make a counter that returns to 0 when the int range is exhausted. Essentially, 0, 1, ..., MAX_INT - 1, MAX_INT, 0, 1, ...
The idiomatic C is
x = ((x + 1) & MAX_INT);
But this won't work in PHP because the int gets promoted to a double when it overflows. The cleanest I can come up with is x = x == PHP_INT_MAX ? 0 : x + 1, but it's messier.
This seems to work:
$x = ($x + 1) % (PHP_INT_MAX+1);
You can use intval() to force using integers:
$x = intval($x + 1) & PHP_INT_MAX;
Try it out: echo intval(PHP_INT_MAX + 1): https://3v4l.org/7jlPN
Update:
The manual on Converting to integer states:
If the float is beyond the boundaries of integer (usually +/- 2.15e+9 = 2^31 on 32-bit platforms and +/- 9.22e+18 = 2^63 on 64-bit platforms other than Windows), the result is undefined, since the float doesn't have enough precision to give an exact integer result. No warning, not even a notice will be issued when this happens!
So you are right, while this is consistent for current implementations, the result is specified to be undefined and you should not rely on it.
That leaves you with more verbose solutions, either with % modulus or the ternary conditional as you already have it (which I would prefer for clarity and robustness).

Is there a clever way to do this with pure math

I've got this spot of code that seems it could be done cleaner with pure math (perhaps a logarigthms?). Can you help me out?
The code finds the first power of 2 greater than a given input. For example, if you give it 500, it returns 9, because 2^9 = 512 > 500. 2^8 = 256, would be too small because it's less than 500.
function getFactor($iMaxElementsPerDir)
{
$aFactors = range(128, 1);
foreach($aFactors as $i => $iFactor)
if($iMaxElementsPerDir > pow(2, $iFactor) - 1)
break;
if($i == 0)
return false;
return $aFactors[$i - 1];
}
The following holds true
getFactor(500) = 9
getFactor(1000) = 10
getFactor(2500) = 12
getFactor(5000) = 13
You can get the same effect by shifting the bits in the input to the right and checking against 0. Something like this.
i = 1
while((input >> i) != 0)
i++
return i
The same as jack but shorter. Log with base 2 is the reverse function of 2^x.
echo ceil(log(500, 2));
If you're looking for a "math only" solution (that is a single expression or formula), you can use log() and then take the ceiling value of its result:
$factors = ceil(log(500) / log(2)); // 9
$factors = ceil(log(5000) / log(2)); // 13
I seem to have not noticed that this function accepts a second argument (since PHP 4.3) with which you can specify the base; though internally the same operation is performed, it does indeed make the code shorter:
$factors = ceil(log(500, 2)); // 9
To factor in some inaccuracies, you may need some tweaking:
$factors = floor(log($nr - 1, 2)) + 1;
There are a few ways to do this.
Zero all but the most significant bit of the number, maybe like this:
while (x & x-1) x &= x-1;
and look the answer up in a table. Use a table of length 67 and mod your power of two by 67.
Binary search for the high bit.
If you're working with a floating-point number, inspect the exponent field. This field contains 1023 plus your answer, except in the case where the number is a perfect power of two. You can detect the perfect power case by checking whether the significand field is exactly zero.
If you aren't working with a floating-point number, convert it to floating-point and look at the exponent like in 3. Check for a power of two by testing (x & x-1) == 0 instead of looking at the significand; this is true exactly when x is a power of two.
Note that log(2^100) is the same double as log(nextafter(2^100, 1.0/0.0)), so any solution based on floating-point natural logarithms will fail.
Here's (nonconformant C++, not PHP) code for 4:
int ceillog2(unsigned long long x) {
if (x < 2) return x-1;
double d = x-1;
int ans = (long long &)d >> 52;
return ans - 1022;
}

Unexpected bitwise operation result [duplicate]

This question already has answers here:
What's the function of the ~ bitwise operator (Tilde) [duplicate]
(3 answers)
Closed 9 years ago.
Consider:
php > $a = 12; // 1100
php > echo ~$a;
-13
I would expect the inverse of 1100 to be either 0011 (direct) or 11110011 (an entire byte). That would give a result to either 3 or 243. Whence cometh -13?
Again, for good measure, another unexpected result of the same type and explanation:
php > $b = 6; // 0110
php > echo ~$b;
-7
Why -7?
Look at this code:
<?php
$val = 6;
print "$val = ".decbin($val);
print "\n";
$val = ~$val;
print "$val = ".decbin($val);
It prints
6 = 110
-7 = 11111111111111111111111111111001
At first you have 110. As my php uses 32 bits, after inverting all the bits, we get this huge number. As the 1-st bit is 1, php interprets it as a negative value, stored, using two's-complement representation. To find out, the modulus of the negative value, stored in this notation, we
invert the digits:
110
add one to the result:
111
which gives us 7
So, the value is -7
http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html
Why -7?
6 is 00000000000000000000000000000110, so ~6 is ~00000000000000000000000000000110, and that's equal to 11111111111111111111111111111001. Because a signed datatype is used, the first bit indicates whether the number is positive or negative (positive = 0 and negative = 1). Because it is Two's complement, you should convert the binary number to decimal using this way:
Invert the binary number. You get 00000000000000000000000000000110
Convert 00000000000000000000000000000110 (a positive binary number) to a decimal number. You get 6
Add 6 up with one: you get 7
Make it negative: you get -7

Why does “$temp = 0; echo ~$temp;” print -1?

Can anybody tell the internal procedure of the below code
<? $temp = 0; echo ~$temp; ?>
//instead of 1 it displays -1
echo ~$temp;
^bitwise not operator
Assuming 32-bit, Bitwise inverse of 0000 is FFFF (All 1's) which is -1, in signed int's case.
Another way to look at it: What ~ did is to give you the (One's complement)
In order to get the negative of a number, you take the 2's complement, which is just the
1's complement + 1
So,
(1's complement of 0) + 1 = 0 //negative 0 is 0
hence, 1's complement of 0 = -1
Bitwise-not (~):
This inverts each bit of its operand. If the operand is a floating point value, it is truncated to an integer prior to the calculation. If the operand is between 0 and 4294967295 (0xffffffff), it will be treated as an unsigned 32-bit value. Otherwise, it is treated as a signed 64-bit value
Its because you're actually dealing with a full 32-bit unsigned integer with NOT. What that means is you're not simply inverting 0001 but inverting 00000000000000000000000000000001
which becomes 11111111111111111111111111111110
essentially this is the number + 1 and negated. so 1 becomes -(num+1) which is -1 or
1111111111111111111111111111110
in binary (unsigned)
for example:-
$temp=1; echo~$temp; print -2 //-(n++)
Because ~0 is -1.
~ operator reverts every bit of 0.
The relation is: -$temp === ~$temp + 1

Categories