2

I want to understand the following code. What kinda shifting 3rd line is doing?

number = 1.265
bits = 8
shifted_no = 1.265 * (2** bits)

If I check the binary format of the results of number and shifted_no :

0011 1111 1010 0001 1110 1011 1000 0101
0100 0001 0010 0001 1110 1011 1000 0101

Thanks.

blackbug
  • 1,098
  • 3
  • 13
  • 40

2 Answers2

5

If i is an integer,

i * 2**bits

is equal to

i << bits

As an example :

>>> 1 * 2**8
256
>>> 1 << 8
256
>>> 2 * 2**8
512
>>> 2 << 8
512

But << isn't defined for floats :

>>> 1.265 << 8
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for <<: 'float' and 'int'

You can think of :

* 2**bits

as being an extension of << bits to floats. :

>>> 1.0 * 2**8
256.0
>>> 1.00000000001 * 2**8
256.00000000256
>>> 1.265 * 2**8
323.84
>>> 1.99999999999 * 2**8
511.99999999744
>>> 2.0 * 2**8
512.0

As a comparison, n! is only defined for non-negative integers but Γ(z) is defined for any complex number and coincides with the factorial function when plugging in a natural number. See this thread.

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • 1
    A nit: n! is only defined for non-negative integers. Γ(z) is defined for any complex number (except a countable infinity of poles) and is defined such that for non-negative integers, n!=Γ(n+1). See https://en.wikipedia.org/wiki/Gamma_function – Scott Centoni Sep 02 '21 at 21:04
4

Here number is a 32-bit floating point. A floating point has the structure:

+-+--------+-----------------------+
|s|  exp   |       mantisse        |
+-+--------+-----------------------+
 1    8             23

This represents a value (-1)1-2×s×2e-127×1.m with s the value of s, e the value of exp and m the value of mantisse.

With the number of bits underneath each component. If you multiply a float with a power of two, the exponent part is incremented with that power. So since you multiply with eight (there is probably an error in your question), you increment the exponent with three and obtain.

Original floating point:

+-+--------+-----------------------+
|0|01111111|01000011110101110000101|
+-+--------+-----------------------+
 1    8             23

Final floating point:

+-+--------+-----------------------+
|0|10000010|01000011110101110000101|
+-+--------+-----------------------+
 1    8             23

What you here do however is not shifting. Shifting means you see the data as a sequence of bits and move them to the left or the right. You do this (usually) regardless of the semantical interpretation of that sequence. Shifts are usually done with the << and >> operators.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Thanks, it's quite descriptive. I have one query though. The above operation modifies the exp part. What one has to do to modify the mantisse part or signed part? – blackbug Feb 08 '17 at 10:43
  • 1
    @blackbug: well if you multiply with `-1`, the sign bit will of course swap. If you do not multiply with a number that is a power of two the mantisse (and probably the exponent will change). – Willem Van Onsem Feb 08 '17 at 10:44
  • This is a great answer: I think the part clarifying that this is 'Not Shifting' should come first, because the original question is a little misleading as it doesn't use the bit shift operators. – Hansang Jun 25 '22 at 01:15