I want to write a function that takes a string of Binary and returns the result as Decimal.
I've written some code but if I didn't know it needed to be a string of Binary instead of just the numbers. Is there a way to change the code so it takes the string? I don't want to turn the binary to float, I want to turn it into decimal.
#Binary to Decimal
def bi_to_dec(binary):
binary1 = binary
decimal, i, n = 0, 0, 0
while(binary != 0):
dec = binary % 10
decimal = decimal + dec * pow(2, i)
binary = binary//10
i += 1
return decimal
I'm going to assume this is an exercise where you have to write the algorithm yourself. Otherwise, you should just use the built-in function int(binary, 2) to parse the string binary in base 2 as an int.
If binary is a string, then the parts of your code you need to change are those which get the individual bits from the string. You can iterate over the bits in the string by writing for bit in reversed(binary):. This gives you a variable bit which is the current bit as a string, and because you reversed the string you get the bits in order from least-significant to most-significant as your algorithm requires. From there, you can simply convert the bit to an int using dec = int(bit).
Related
I can't quite find a solution for this.
Basically what I've done so far is created a string which represents the binary version of x amount of characters padded to show all 8 bits.
E.g. if x = 2 then I have 0101100110010001 so 8 digits in total. Now I have 2 strings of the same length which I want to XOR together, but python keeps thinking it's a string instead of binary. If I use bin() then it throws a wobbly thinking it's a string which it is. So if I cast to an int it then removes the leading 0's.
So I've already got the binary representation of what I'm after, I just need to let python know it's binary, any suggestions?
The current function I'm using to create my binary string is here
for i in origAsci:
origBin = origBin + '{0:08b}'.format(i)
Thanks in advance!
Use Python's int() function to convert the string to an integer. Use 2 for the base parameter since binary uses base 2:
binary_str = '10010110' # Binary string
num = int(binary_str, 2)
# Output: 150
Next, use the bin() function to convert the integer to binary:
binary_num = bin(num)
# Output: 0b10010110
how do I convert Convert 32 bit binary to a decimal in python
this
00011110001101110110110000001000
to
506948616
this
use in-built function int():
a = '00011110001101110110110000001000'
a_dec = int(a, 2)
use int for conversion of a string (just give the correct base as parameter):
int('00011110001101110110110000001000', 2)
Another way is to add 0b as a prefix for the number (same as 0x for hex values or 0o for octal values):
x=0b00011110001101110110110000001000
x will be an integer with decimal value of 506948616
I believe that 17 decimal places should be enough to correctly represent an 8-byte float, such that it is round-trip safe (converted to a string and back without any loss).
But in this test, the number can go as high as 23, and probably higher if you increase the number of iterations.
Is this a flawed test and why?
And how do you ensure a round-trip integrity of a float in Python?
def TestLoop():
sFormat = ''
success = True
ff = [1.0/i for i in range(1,10000000)]
for n in range(17, 31):
sFormat = '{{:.{:d}f}}'.format(n)
success = True
for f in ff:
if f != float(sFormat.format(f)):
success = False
break
if success:
return(n)
return(-1)
n = TestLoop()
print('Lossless with ', n, ' decimal places.')
If an IEEE 754 double precision is converted to a decimal string with at least 17 significant digits and then converted back to double, then the final number must match the original.
In my original test, I was operating on small numbers, so there were a lot of leading zeros, which are not significant digits. Floats require 17 significant digits to be represented correctly. By changing one line like so, I made the numbers larger and was able to succeed with only 16 digits after the decimal point.
ff = [10000000.0/i for i in range(1,10000000)]
The best approach seems to be to not use the format() at all, but use repr() or str() instead.
This code here succeeds:
def TestLoop():
for i in range(1, 10000000):
f = 1.0 / i
if f != float(repr(f)):
print('Failed.')
return
print('Succeeded.')
return
TestLoop()
Another way that worked was to use 17 digits after the decimal point, but use the g formatter instead of f. This uses an exponent, so the leading zeros are eliminated.
if f != float('{:.17g}'.format(f)):
There is an unexpected output when I am dealing with binary number in Python 3.
We can easily convert any integer to binary by built-in bin() function. For example:
>>>bin(4243125)
Here's the issue when I try to add 2 binary function:
>>>bin(x)+bin(y)
The output is concatenation of two binary number, not addition of binary number. The output of binary function has become a string.
Addition in a binary function works fine:
>>>bin(x+y)
And try to add two binary number without bin() is viable too:
>>>0b100+0b10111
What is the reasons/purposes of setting a bin() output to a string?
bin, like hex, converts a decimal to a string literal representing the number in that base.
If you want to add 2 numbers together simply do so:
x = 10
y = 2
x + y
If you want to take binary strings as input and add them together convert them back from string literals with int base 2, like this:
x = bin(10)
y = bin(2)
int(x, 2) + int(y, 2)
If you're looking to do bitwise operations look at the Python bitwise operators:
https://wiki.python.org/moin/BitwiseOperators
I have some number 0.0000002345E^-60. I want to print the floating point value as it is.
What is the way to do it?
print %f truncates it to 6 digits. Also %n.nf gives fixed numbers. What is the way to print without truncation.
Like this?
>>> print('{:.100f}'.format(0.0000002345E-60))
0.0000000000000000000000000000000000000000000000000000000000000000002344999999999999860343602938602754
As you might notice from the output, it’s not really that clear how you want to do it. Due to the float representation you lose precision and can’t really represent the number precisely. As such it’s not really clear where you want the number to stop displaying.
Also note that the exponential representation is often used to more explicitly show the number of significant digits the number has.
You could also use decimal to not lose the precision due to binary float truncation:
>>> from decimal import Decimal
>>> d = Decimal('0.0000002345E-60')
>>> p = abs(d.as_tuple().exponent)
>>> print(('{:.%df}' % p).format(d))
0.0000000000000000000000000000000000000000000000000000000000000000002345
You can use decimal.Decimal:
>>> from decimal import Decimal
>>> str(Decimal(0.0000002345e-60))
'2.344999999999999860343602938602754401109865640550232148836753621775217856801120686600683401464097113374472942165409862789978024748827516129306833728589548440037314681709534891496105046826414763927459716796875E-67'
This is the actual value of float created by literal 0.0000002345e-60. Its value is a number representable as python float which is closest to actual 0.0000002345 * 10**-60.
float should be generally used for approximate calculations. If you want accurate results you should use something else, like mentioned Decimal.
If I understand, you want to print a float?
The problem is, you cannot print a float.
You can only print a string representation of a float. So, in short, you cannot print a float, that is your answer.
If you accept that you need to print a string representation of a float, and your question is how specify your preferred format for the string representations of your floats, then judging by the comments you have been very unclear in your question.
If you would like to print the string representations of your floats in exponent notation, then the format specification language allows this:
{:g} or {:G}, depending whether or not you want the E in the output to be capitalized). This gets around the default precision for e and E types, which leads to unwanted trailing 0s in the part before the exponent symbol.
Assuming your value is my_float, "{:G}".format(my_float) would print the output the way that the Python interpreter prints it. You could probably just print the number without any formatting and get the same exact result.
If your goal is to print the string representation of the float with its current precision, in non-exponentiated form, User poke describes a good way to do this by casting the float to a Decimal object.
If, for some reason, you do not want to do this, you can do something like is mentioned in this answer. However, you should set 'max_digits' to sys.float_info.max_10_exp, instead of 14 used in the answer. This requires you to import sys at some point prior in the code.
A full example of this would be:
import math
import sys
def precision_and_scale(x):
max_digits = sys.float_info.max_10_exp
int_part = int(abs(x))
magnitude = 1 if int_part == 0 else int(math.log10(int_part)) + 1
if magnitude >= max_digits:
return (magnitude, 0)
frac_part = abs(x) - int_part
multiplier = 10 ** (max_digits - magnitude)
frac_digits = multiplier + int(multiplier * frac_part + 0.5)
while frac_digits % 10 == 0:
frac_digits /= 10
scale = int(math.log10(frac_digits))
return (magnitude + scale, scale)
f = 0.0000002345E^-60
p, s = precision_and_scale(f)
print "{:.{p}f}".format(f, p=p)
But I think the method involving casting to Decimal is probably better, overall.