Using fractions in equations using python - python

I'm trying to write this equation with python:
(1/100)*((102/65520)*x - 1)*10
wolfram alpha link
But I don't know how to apply the fractions in order to get the right result.
Does anyone know how I should write it?

You are using 'integer' division, which is default in python 2, so results are being rounded (1/100 is equal to 0, nooooo!).
You have too make the division 'floaty'. I can think of two solutions:
1) Make the dividends become floats directly
(1.0/100)*((102.0/65520)*x - 1)*10
You can cast integers into floats with float(), too. Then, float(102) is equivalent to 102.0
(float(1)/100)*(float(102)/65520)*x - 1)*10
2) Use float division (default in Python 3):
from future import __division__
Now / is float division and your code line works as it is.
Note: You should use '//' for integer division, just in case.
Credits on the second one for:
How can I force division to be floating point? Division keeps rounding down to 0

Related

Python numerical calculation concerns

I computed the following 2 values in python and got different results! It would be great if someone could reason it why it is happening like this.
(111 - (111 + 2*17)*3375)/(-14) gives 34947 as output.
(111 - (111 + 2*17)*3375)/(14)*-1 gives 34948 as output.
Both terms are mathematically equivalent.
This has to do with the rounding rules. Consider a simpler example:
>>> -3/(-2)
1
>>> -3/2*-1
2
1.5 is rounded down to 1, and -1.5 is rounded down to -2. Consistent, in a way.
Doc reference:
Plain or long integer division yields an integer of the same type; the
result is that of mathematical division with the ‘floor’ function
applied to the result.
If you want a floating point result in Python 2.x, you need either an explicit conversion (or just use float literals), or do from __future__ import division. In Python 3.x, division always produces a float (ref).
You're doing integer math, which rounds the fractional result differently depending on whether it's negative or positive. Using floating point division:
>>> (111 - (111 + 2*17)*3375)/(14.)*(-1)
34947.42857142857
>>> (111 - (111 + 2*17)*3375)/(-14.)
34947.42857142857
It comes down to the way that python handles integer division.
If iether the numerator(top) or divisor(bottom) of your division is negative then python will round away from zero. A simple way to convince yourself of this is to compare two simpler fractions: 25/6 and 25/(-6). These will yield 4 and -5 respectively.
In order to get the same results you could us a float ie 14.0 to shift to floating point arithmatic.
If you are interested in more of the mathematics this seemed to be a pretty good article:
http://python-history.blogspot.co.nz/2010/08/why-pythons-integer-division-floors.html
As mentioned earlier python division and rounding seems issue
Here is how to fix it
In [10]: int((111 - (111 + 2*17)*3375)/(-14.0))
Out[10]: 34947
In [11]: int((111 - (111 + 2*17)*3375)/(14.0)*-1 )
Out[11]: 34947

Two forward slashes in Python

I came across this sample of code from a radix sort:
def getDigit(num, base, digit_num):
# pulls the selected digit
return (num // base ** digit_num) % base
What does the // do in Python?
// is the floor division operator. It produces the floor of the quotient of its operands, without floating-point rounding for integer operands. This is also sometimes referred to as integer division, even though you can use it with floats, because dividing integers with / used to do this by default.
In Python 3, the ordinary / division operator returns floating point values even if both operands are integers, so a different operator is needed for floor division. This is different from Python 2 where / performed floor division if both operands were integers and floating point division if at least one of the operands was a floating point value.
The // operator was first introduced for forward-compatibility in Python 2.2 when it was decided that Python 3 should have this new ability. Together with the ability to enable the Python 3 behavior via from __future__ import division (also introduced in Python 2.2), this enables you to write Python 3-compatible code in Python 2.
You can just try it:
In []: 5/2
Out[]: 2
In []: 5.0/2
Out[]: 2.5
In []: 5.0//2
Out[]: 2.0
This should be self-explanatory.
(This is in Python 2.7.)
Python3 supports two types of division, floating point (/) and integer (//).
Floating point: 45/2 = 22.5
Integer: 45//2 = 22

How to implement division with round-towards-infinity in Python

I want 3/2 to equal 2 not 1.5
I know there's a mathematical term for that operation(not called rounding up), but I can't recall it right now.
Anyway, how do i do that without having to do two functions?
ex of what I do NOT want:
answer = 3/2 then math.ceil(answer)=2 (why does math.ceil(3/2)=1?)
ex of what I DO want:
"function"(3/2) = 2
To give a short answer...
Python only offers native operators for two types of division: "true" division, and "round down" division. So what you want isn't available as a single function. However, it is possible to easily implement a number of different types of division-with-rounding using some short expressions.
Per the title's request: given strictly integer inputs, "round up" division can be implemented using (a+(-a%b))//b, and "round away from zero" division can be implemented using the more complex a//b if a*b<0 else (a+(-a%b))//b. One of those is probably what you want. As to why...
To give a longer answer...
First, let me answer the subquestion about why 3/2==1 and math.ceil(3/2)==1.0, by way of explaining how the Python division operator works. There are two main issues at play...
float vs int division: Under Python 2, division behaves differently depending on the type of the inputs. If both a and b are integers, a/b performs "round down" or "floor integer" division (eg 3/2==1, but -3/2==-2). This is equivalent to int(math.floor(float(a)/b)) .
But if at least one of a and b are floats, Python performs "true" division, and gives you a float result (eg 3.0/2==1.5, and -3.0/2==-1.5). This is why you'll sometimes see the construction float(a)/b: it's being used to force true division even both inputs are integers (eg float(3)/2==1.5). This is why your example math.ceil(3/2) returns 1.0, whereas math.ceil(float(3)/2) returns 2.0. The result has already been rounded down before it even reaches math.ceil().
"true division" by default: In 2001, it was decided (PEP 238) that Python's division operator should be changed so that it always performs "true" division, regardless of whether the inputs are floats or integers (eg, this would make 3/2==1.5). In order to not break existing scripts, the change in default behavior was deferred until Python 3.0; in order to get this behavior under Python 2.x, you have to enable it per-file by adding from __future__ import division to the top of the file. Otherwise the old type-dependant behavior is used.
But "round down" division is still frequently needed, so the PEP didn't do way with it entirely. Instead, it introduced a new division operator: a//b, which always performs round down division, even if the inputs include floats. This can be used without doing anything special under both Python 2.2+ and 3.x.
That out of that way, division-with-rounding:
In order to simplify things, the following expressions all use the a//b operator when working on integers, since it will behave the same under all python versions. As well, I'm making an assumption that 0<=a%b<b if b is positive, and b<=a%b<=0 if b is negative. This is how Python behaves, but other languages may have slightly different modulus operators.
The four basic types of integer division with rounding:
"round down" aka "floor integer" aka "round to minus infinity" divsion: python offers this natively via a//b.
"round up" aka "ceiling integer" aka "round to positive infinity" division: this can be achieved via int(math.ceil(float(a)/b)) or (a+(-a%b))//b. The latter equation works because -a%b is 0 if a is a multiple of b, and is otherwise the amount we need to add to a to get to the next highest multiple.
"round towards zero" aka "truncated" division - this can be achieved via int(float(a)/b). Doing this without using floating point is trickier... since Python only offers round-down integer division, and the % operator has a similar round-down bias, we don't have any non-floating-point operators which round symmetrically about 0. So the only way I can think of is to construct a piecewise expression out of round-down and round-up: a//b if a*b>0 else (a+(-a%b))//b.
"round away from zero" aka "round to (either) infinity" division - unfortunately, this is even trickier than round-towards-zero. We can't leverage the truncating behavior of the int operator anymore, so I can't think of a simple expression even when including floating-point ops. So I have to go with the inverse of the round-to-zero expression, and use a//b if a*b<0 else (a+(-a%b))//b.
Note that if you're only using positive integers, (a+b-1)//b provides round up / away from zero even more efficiently than any of the above solutions, but falls apart for negatives.
Hope that helps... and happy to make edits if anyone can suggest better equations for round to/away from zero. I find the ones I have particularly unsatisfactory.
Integral division in Python 3:
3 // 2 == 1
Non-integral division in Python 3:
3 / 2 == 1.5
What you're talking about is not a division by all means.
The intent of the OP's question is "How to implement division with round-towards-infinity in Python" (suggest you change the title).
This is a perfectly legitimate rounding mode as per the IEEE-754 standard (read this overview), and the term for it is "round towards infinity" (or "round away from zero"). Most of the 9 downvotes were beating up on the OP unfairly. Yes, there is no single-function way to do this in native Python, but we can use round(float(a)/b) or else subclass numbers.Number and override __div__().
The OP would need to clarify whether they want -3/2 to round to -2 or -1 (or don't-care for negative operands). Since they already said they don't want round-upwards, we can infer -3/2 should round to -2.
Enough theory. For implementations:
If you just want the fast-and-dirty one-line solution for round-towards-infinity , use round(float(a)/b)
math.ceil(float(a)/b) gives you round-upwards, which you said you don't want
But if this is your default division operation, or you are doing a lot of this, then do like the pseudocode below: inherit from one of the subclasses of numbers.Number Real, Rational or Integral (new in 2.6), redefine __div__() or else define a non-default alternative __divra__() operation. You could define a class member or classmethod rounding_mode and look it up during divisions. Be careful of __rdiv__() and mixing with ordinary floats though.
.
import numbers
class NumberWithRounding(numbers.Integral):
# Here you could implement a classmethod setRoundingMode() or member rounding_mode
def __div__(self,other):
# here you could consider value of rounding_mode, or else hardwire it like:
return round(float(self)/other)
# You also have to raise ImplementationError/ pass/ or implement the other 31
# methods for Float: __abs__(),...,__xor__() Just shortcut that for now...
When you divide two integers, the result is an integer.
3 / 2 equals 1, not 1.5.
See the documentation, note 1:
For (plain or long) integer division, the result is an integer. The result is always rounded towards minus infinity: 1/2 is 0, (-1)/2 is -1, 1/(-2) is -1, and (-1)/(-2) is 0. Note that the result is a long integer if either operand is a long integer, regardless of the numeric value.
Once you get 1 from the division, there is no way to turn that into 2.
To get 1.5, you need floating-point division: 3.0 / 2.
You can then call math.ceil to get 2.
You are mistaken; there is no mathematical function that divides, then rounds up.
The best you can do is write your own function that takes two floats and calls math.ceil.
What you probably want is something like:
math.ceil(3.0/2.0)
# or
math.ceil(float(3)/float(2))
You could also do an import from future:
from __future__ import division
math.ceil(3/2) # == 2
But, if you do this, to get the current behavior of integer division you need to use the double slash:
3 // 2 == 1 # True
Integer division with ceiling rounding (to +Inf), floor rounding (to -Inf), and truncation (to 0) is available in gmpy2.
>>> gmpy2.c_div(3,2)
mpz(2)
>>> help(gmpy2.c_div)
Help on built-in function c_div in module gmpy2:
c_div(...)
c_div(x,y): returns the quotient of x divided by y. The quotient
is rounded towards +Inf (ceiling rounding). x and y must be integers.
>>> help(gmpy2.f_div)
Help on built-in function f_div in module gmpy2:
f_div(...)
f_div(x,y): returns the quotient of x divided by y. The quotient
is rounded towards -Inf (floor rounding). x and y must be integers.
>>> help(gmpy2.t_div)
Help on built-in function t_div in module gmpy2:
t_div(...)
t_div(x,y): returns the quotient of x divided by y. The quotient
is rounded towards 0. x and y must be integers.
>>>
gmpy2 is available at http://code.google.com/p/gmpy/
(Disclaimer: I'm the current maintainer of gmpy and gmpy2.)
I think that what you're looking for is this:
assuming you have x (3) and y (2),
result = (x + y - 1) // y;
this is the equivalent of a ceiling without the use of floating points.
Of course, y cannot be 0.
Firstly, you want to be using floating-point division in the arguments. Use:
from __future__ import division
If you always want to round up, so f(3/2)==2 and f(1.4)==2, then you want f to be math.trunc(math.ceil(x)).
If you want to get the closest integer, but have ties round up, then you want math.trunc(x + 0.5). That way f(3/2)==2 and f(1.4)==1.

Negative integer division surprising result

In my application I encountered the following and was surprised by the results:
8/-7=-2 (both integers).
What does this mean?
For the actual values, i.e. 8.0/(-7.0), the result is roughly -1.143.
Your result using integer division is being rounded down toward the more negative value of -2. (This is also known as "Floor division")
This is why you will get the somewhat perplexing answers of:
>>> 8/(-7)
-2
>>> 8/7
1
Note: This is "fixed" in Python 3, where the result of 8/(-7) would be -1.143. So if you have no reason to be using Python 2, you should upgrade. ;)
In Python 3, if you still want integer division, you can use the // operator. This will give you the same answer as 8/(-7) would in Python 2.
Here's a Python Enhancement Proposal on the subject: PEP 238 -- Changing the Division Operator
Python always does the "floor division" for both negative numbers division and positive numbers division.
That is
1/10 = 0
1/-10 = -1
But sometime we need 1/-10 to be 0
I figure out it can be done by using the float division first then cast result to int, e.g.
int(float(1)/-10) = 0
That works fine for me, no need to import the future division or upgrade to Python 3
Hope it can help you~
To have Python automatically convert integer division to float, you can use:
from __future__ import division
Now:
8/-7=-1.1428571428571428
This feature is not in the standard Python 2 not to break existing code that relied on integer division.
However, this is the default behavior for Python 3.
When both values are integers when dividing Python uses Floor division.
In Python, / operator is for integer division. You can look at it as float division followed by a floor operation.
For example,
8/7 == floor(8.0/7.0) == 1
8/-7 == floor(8.0/-7.0) == -2

How can I write this without so many floats?

float(float(1)/float(i) * float(score))
Assuming Python 2.x: 1.0 / i * score
The main case you need to worry about is the division because in Python 2.x, division is defaulted to integer division. In order to have floating-point division, either the dividend or divisor needs to be a float, hence the 1.0. Thus, 1.0/i will be a float, and multiplying a float by score (which can either be an integer or float) will result in another floating-point number.
In python 3.x, however, division defaults to floating-point division, so 1 / i * score would work.
What you want is simply float(score)/i in Python2. If one operand is a float, then the result will be a float too ,so code like score/float(i) or 1.0*score/i works as well.
You can also put from __future__ import division at the top of your .py file and you have float division by default. This means you can write score/i and it will be a float, like in Python3.
1.0 * score / i; should do it
Unless I'm totally wrong, a simple 1.0 / i * score should result in a float. I'm not sure if that's Python 3 only.

Categories