Python code to convert decimal to binary - python-2.7

I need to write a Python script that will convert and number x in base 10 to binary with up to n values after the decimal point. And I can't just use bin(x)! Here's what I have:
def decimal_to_binary(x, n):
x = float(x)
test_str = str(x)
dec_at = test_str.find('.')
#This section will work with numbers in front of the decimal
p=0
binary_equivalent = [0]
c=0
for m in range(0,100):
if 2**m <= int(test_str[0:dec_at]):
c += 1
else:
break
for i in range(c, -1, -1):
if 2**i + p <= (int(test_str[0:dec_at])):
binary_equivalent.append(1)
p = p + 2**i
else:
binary_equivalent.append(0)
binary_equivalent.append('.')
#This section will work with numbers after the decimal
q=0
for j in range(-1, -n-1, -1):
if 2**j + q <= (int(test_str[dec_at+1:])):
binary_equivalent.append(1)
q = q + 2**j
else:
binary_equivalent.append(0)
print float((''.join(map(str, binary_equivalent))))
So say you call the function by decimal_to_binary(123.456, 4) it should convert 123.456 to binary with 4 places after the decimal, yielding 1111011.0111.
The first portion is fine - it will take the numbers in front of the decimal, in this case 123, and convert it to binary, outputting 1111011
However, the second portion, which deals with values after the decimal, is not doing what I think it should. The output it gives is not .0111, but rather .1111
I ran through the code with pen and paper writing down the value for each variable and it should work. But it doesn't. Can anyone help me fix this?
I call the function as decimal_to_binary(123.456, 4) and it prints out 1111011.1111

You're close, but there's an issue with your comparison when you go beyond the decimal:
if 2**j + q <= (int(test_str[dec_at+1:])):
What you're doing here is comparing a fractional value (since j is always negative) to a whole integer value. This comparison will, for all practical purposes, always be true.
Based on the surrounding logic, my guess would be that you're attempting to compare it to the actual decimal value here. Using your data, that would be 0.4 on the first iteration, so you expect the statement to be evaluated as:
0.5 <= 0.4
The actual comparison in your code is:
0.5 <= 4
There are two separate issues here:
You're taking all of the numbers after the decimal point, but not actually including the decimal point itself in your extraction. This is primarily why you are getting whole numbers in your test incorrectly. This is fixed simply by referencing test_str[dec_at:] rather than test_str[dec_at+1:]
You're casting to int. Even if you applied the change in the first point, your code would still not run correctly. However, in that case it would be because the cast would truncate the value down to 0 on every iteration. Cast to a float instead: float(test_str[dec_at:])
Your comparison line thus becomes if 2**j + q <= (float(test_str[dec_at:])):, which provides the correct output on my machine.
Note that floating point comparisons can be "finicky" in some situations, depending on rounding and the like. There are ways to mitigate this if needed.

Related

log and rand() gives not a number

In the following part of code:
I want to generate a random number "U" from the range 0 to 1,
then I calculate an equation having log
The error is: some value of U makes the log in the equation give "not a number"value
I tried casting the "U" to float or double or even round it to 2 decimal places but same error
vector <double>Xs;//random Xs
double x;
double U;
while (check_arr < 360)
{
U = ((rand() / RAND_MAX) * 100) / 100;
x = (log10(1 - U)) / (-1 / a);
Xs.push_back(x);
}
There are multiple problems with your code.
rand() returns an integer, and RAND_MAX is an integer, so when you divide them you get an integer which will almost always be zero (since rand() can produce the value RAND_MAX - one time in 2^31 on my computer - and that division will produce 1).
Next, multiplying then dividing by 100 is doing nothing. The result will be the same: an integer that's almost always 0, sometimes 1.
Finally, you must avoid taking the log10 of zero. This value is disallowed and will raise the divide-by-zero exception (also, negative values would raise the invalid floating point exception).
Perhaps you could use the following expression instead:
U = (rand() % 100)/100.0;
This will give you a value of U with a distribution from 0.00 up to 0.99 inclusive. When you then take log10(1-U) you won't get an exception.
log10() will return "not a number" when the parameter being passed to it is 0. When I ran the method on my machine the result that I got was "-1.#INF000000000000". log(0) is an invalid number. You can verify this by opening the calculator on your PC (if you are using windows), switch to scientific mode then try to do log 0.
Mathematical explanation:
The log base 10 function is used to help find the exponent y in 10^y=x. So when you are trying to plug in 0 in the function you are trying to find a solution to the following:
10^y=0
But there are no solution to this so instead the function will return an invalid number. It would be better if you set the range of the x value to 0 < x <= 1 so you will not have that same issue.
Since the rand function returns a value between 0 and RAND-MAX you can be able to use the following to ensure that you will not input 0 into the log function:
U = (rand() % 100 + 1)/100;
This will return a range of 0.01 and 1. You can mess around with the numbers to increase/decrease the range.

Python arithmetic operation returns 0

read = True
while read:
my_input = int(raw_input())
print my_input
result = (1/6) * my_input * (my_input + 1) * (my_input +2)
if result == 0:
print ''
read = False
break
else:
print result
I wrote this little code snippet to solve 1 + (1+2) + (1+2+3+)... without looping over anything but the result is always 0 for some reason. I am using PyDev on Eclipse but I do not think that's even remotely the issue
Thank you
Multiplying by zero always results in zero.
>>> a = (1/6)
>>> print a
0
This is happening because Python is casting the resulting operation to integer.
In order to get a float result you can specify the values in decimal notation.
>>> a = 1.0/6.0
>>> print a
0.166666666667
Integer division.
When you divide (1/6) it comes out to 0 because of integer division.
When two ints are divided, they come out to the normal answer, minus anything after the decimal point.
For example, 1/4 would usually equal 0.25.
However, everything after the decimal point is dropped, so it comes out to 0.

How can I find the amount of numbers in double?

Let's say I have an input 1.251564.
How can I find how many elements are after "." to have an output as follows:
int numFloating;
// code to go here that leads to
// numFloating == 6
p.s. Sorry for not providing any code, I just have no idea how that should be implemented :(
Thanks for your answers!
Let us consider your number, 1.251564. When you store this in a double, it is stored in the binary IEEE754 format. And you might find that the number is not representable. So, let us check for this number. The closest representable double is:
1.25156 39999 99999 89880 45035 73046 53152 82344 81811 52343 75
This probably comes as something of a surprise to you. There are 52 decimal digits following the decimal point.
The lesson that you need to take away from this is that if you want to ask questions about decimal representations, you need to use a decimal data type rather than double. Once you can actually represent the value exactly, then you will be able to reason about it in a manner that matches your expectations.
Simplest way would be to store it in string.
std::string str("1.1234");
size_t length = str.length();
size_t found = str.find('.', 0 );
size_t count = length-found-1;
int finallyGotTheCount = static_cast<int>(count);
This won't end up well. The problem is that sometimes there are float errors when representing numbers in binary (which is what your computer does).
For example, when adding 1 / 3 + 1 / 3 + 1 / 3 you might get 0.999999... and the number of decimal places varies greatly.
ravi already provided a good way to calculate it, so I'll provide a different one:
double number = 0; // should be equal to the number you want to check
int numFloating = 0;
while ((double)(int)number != number){
number *= 10;
numFloating++;
}
number is a double variable that holds the number you want to check for decimal places.
If you have a fractional number. Lets say .1234
Repeatedly multiply by 10 and throw away the integer portion of the number until you get zero. The number of steps will be the number of decimals. e.g:
.1234 * 10 = 1.234
.234 * 10 = 2.34
.34 * 10 = 3.4
.4 * 10 = 4.0
Problems will however occur when you have a number that is "floating" like 1.199999999.
int numFloating = 0;
double orgin = 1.251564;
double value = orgin - floor(orgin);
while(value == 0)
{
value *= 10;
value = value - floor(value);
numFloating ++;
}
By using this code sometimes answer is wrong. exp: zero in floating point is equal to (2^31)-1.
Obviously output depends on how it realy stored.

Can't divide a smaller number by a larger number in Python

In python, i cannot divide 5 by 22. When I try this, it gives me zero-even when i use float?!!
>>> print float(5/22)
0.0
It's a problem with order of operations. What's happening is this:
* First python takes 5/22. Since 5 and 22 are integers, it returns an integer result, rounding down. The result is 0
* Next you're converting to a float. So float(0) results in 0.0
What you want to do is force one (or both) operands to floats before dividing. e.g.
print 5.0/22 (if you know the numbers absolutely)
print float(x)/22 (if you need to work with a variable integer x)
Right now you're casting the result of integer division (5/22) to float. 5/22 in integer division is 0, so you'll be getting 0 from that. You need to call float(5)/22.

Differentiate between a number (of type double) with decimal places and one without - c++

I am trying to implement a simple decimation algorithm in c++. I have two arrays, say p & q, where the subscripts are related to each other by the following relation:
p[k] = q[0.5*k]. This means that the following sequence should hold valid:
p[0] = q[0]
p[1] = 0
p[2] = q[1]
p[3] = 0
p[4] = q[2]
and so on...
Please note that p[k] takes on a value only and only when the result of (0.5*k) contains no decimal places (or has 0 in decimal) and does not use any rounding off etc.
My question is: Is there a way to distinguish between an integer (a number with no decimal places or only 0 in decimal, say 2.0) and a number with decimal places in C++, provided both are cast to double?
eg.) 2.0 is an integer cast to double. 2.1 is a number with decimal places.
eg. 2) * 0.9*2 should put 0 into array p while 0.9*10 should put q[9] into array p.*
If I use the statement, (int) (0.5*k), then I end up with an integer in every case, irrespective of the value of k.
Edit: The 0.5 in the above case is only illustrative. It could be any number, say 2, 2.5, 0.9, 0.95 etc.)
Any help is most welcome,
Thanks,
Sriram.
Assuming k is of an integer type, you could use if (k % 2 == 0) ... to check if kis divisible by two:
if (k % 2 == 0)
p[k] = q[k / 2];
else
p[k] = 0;
This can also be expressed using the ternary operator:
p[k] = (k % 2 == 0) ? q[k / 2] : 0;
Presuming that the coef can be anything else,
p[floor(coef*k)] = (fabs(coef*k-floor(coef*k))<1E-6)?q[k]:0;
The short syntax for what you want to do could be this:
p[k] = k % 2 ? 0 : q[k/2];
Is there a way to distinguish between a whole number and an integer in C++?
Define whole number, and define integer in this context. I'm confused!
Are you taking about the difference as explained here?
If you want to detect whether a number is integer or not, then probably this may help:
#include<cmath>
bool IsInteger(double d)
{
double intpart;
return std::modf(double number, &intpart) == 0.0;
}
k % 2 is in a couple of answers in this thread.
However, this is not useful in answering the OP's question. Note the edit:
"Edit: The 0.5 in the above case is only illustrative. It could be any number, say 2, 2.5, 0.9, 0.95 etc.)"
k % 2 only works because the value chosen was 0.5. It won't hold true for any other values.
Therefore, unless I'm missing something entirely, the simplest approach I can think of is the following:
Subtract the floor of the number from the number itself. If the result is > 0, it is not an integer.
Unless you have expressions that result in irrational numbers, you could use Boost.Rational to represent your indizes.
#Aix's suggestion of k%2 looks like it'd combine nicely with the ?: operator:
p[k] = (k%2) ? 0 : q[k/2];