Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #101946 > unrolled thread

How to simulate C style integer division?

Started byShiyao Ma <i@introo.me>
First post2016-01-21 16:39 +0800
Last post2016-01-23 17:44 +0100
Articles 10 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  How to simulate C style integer division? Shiyao Ma <i@introo.me> - 2016-01-21 16:39 +0800
    Re: How to simulate C style integer division? "Peter Heitzer" <peter.heitzer@rz.uni-regensburg.de> - 2016-01-21 08:44 +0000
    Re: How to simulate C style integer division? Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-21 10:59 +0200
      Re: How to simulate C style integer division? Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-21 12:13 +0200
    Re: How to simulate C style integer division? Grobu <snailcoder@retrosite.invalid> - 2016-01-22 02:59 +0100
      Re: How to simulate C style integer division? Steven D'Aprano <steve@pearwood.info> - 2016-01-22 14:48 +1100
        Re: How to simulate C style integer division? Grobu <snailcoder@retrosite.invalid> - 2016-01-23 13:04 +0100
          Re: How to simulate C style integer division? Grobu <snailcoder@retrosite.invalid> - 2016-01-23 13:52 +0100
            Re: How to simulate C style integer division? Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-23 17:07 +0200
              Re: How to simulate C style integer division? Grobu <snailcoder@retrosite.invalid> - 2016-01-23 17:44 +0100

#101946 — How to simulate C style integer division?

FromShiyao Ma <i@introo.me>
Date2016-01-21 16:39 +0800
SubjectHow to simulate C style integer division?
Message-ID<mailman.139.1453365561.15297.python-list@python.org>
Hi,

I wanna simulate C style integer division in Python3.

So far what I've got is:
# a, b = 3, 4

import math
result = float(a) / b
if result > 0:
  result = math.floor(result)
else:
  result = math.ceil(result)


I found it's too laborious. Any quick way?

-- 

吾輩は猫である。ホームーページはhttps://introo.me <http://introo.me>。

[toc] | [next] | [standalone]


#101949

From"Peter Heitzer" <peter.heitzer@rz.uni-regensburg.de>
Date2016-01-21 08:44 +0000
Message-ID<dgbk3mF6045U1@mid.individual.net>
In reply to#101946
Shiyao Ma <i@introo.me> wrote:
>Hi,

>I wanna simulate C style integer division in Python3.

>So far what I've got is:
># a, b = 3, 4

>import math
>result = float(a) / b
>if result > 0:
>  result = math.floor(result)
>else:
>  result = math.ceil(result)


>I found it's too laborious. Any quick way?
In Python3 you have to use the floor division operator '//'
For example:
result=a//b


[toc] | [prev] | [next] | [standalone]


#101951

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-01-21 10:59 +0200
Message-ID<lf5k2n3l34h.fsf@ling.helsinki.fi>
In reply to#101946
Shiyao Ma writes:

> I wanna simulate C style integer division in Python3.
>
> So far what I've got is:
> # a, b = 3, 4
>
> import math
> result = float(a) / b
> if result > 0:
>   result = math.floor(result)
> else:
>   result = math.ceil(result)
>
> I found it's too laborious. Any quick way?

The general principle is to define a function when something is too
laborious to do inline. def truncdiv(a, b): ...

But math.trunc rounds towards 0. Maybe you want to use that here.

[toc] | [prev] | [next] | [standalone]


#101956

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-01-21 12:13 +0200
Message-ID<lf5bn8fkzou.fsf@ling.helsinki.fi>
In reply to#101951
Jussi Piitulainen writes:
> Shiyao Ma writes:
>
>> I wanna simulate C style integer division in Python3.
>>
>> So far what I've got is:
>> # a, b = 3, 4
>>
>> import math
>> result = float(a) / b
>> if result > 0:
>>   result = math.floor(result)
>> else:
>>   result = math.ceil(result)
>>
>> I found it's too laborious. Any quick way?
>
> The general principle is to define a function when something is too
> laborious to do inline. def truncdiv(a, b): ...
>
> But math.trunc rounds towards 0. Maybe you want to use that here.

It's actually best to avoid floating point altogether. The following
answer by Abhijit was linked from the StackOverflow page[1] where I
found out about C99 integer division:

def trunc_div(a,b):
    q, r = divmod(a,b)
    if  q < 0 and r:
        q += 1
    return q

It adjusts a negative floored quotient towards zero if there was a
remainder.

[1] http://stackoverflow.com/questions/15633787/truncated-versus-floored-division-in-python?rq=1

[toc] | [prev] | [next] | [standalone]


#101988

FromGrobu <snailcoder@retrosite.invalid>
Date2016-01-22 02:59 +0100
Message-ID<n7s28p$7ub$1@dont-email.me>
In reply to#101946
On 21/01/16 09:39, Shiyao Ma wrote:
> Hi,
>
> I wanna simulate C style integer division in Python3.
>
> So far what I've got is:
> # a, b = 3, 4
>
> import math
> result = float(a) / b
> if result > 0:
>    result = math.floor(result)
> else:
>    result = math.ceil(result)
>
>
> I found it's too laborious. Any quick way?
>

math.trunc( float(a) / b )

[toc] | [prev] | [next] | [standalone]


#101991

FromSteven D'Aprano <steve@pearwood.info>
Date2016-01-22 14:48 +1100
Message-ID<56a1a698$0$1612$c3e8da3$5496439d@news.astraweb.com>
In reply to#101988
On Fri, 22 Jan 2016 12:59 pm, Grobu wrote:

> On 21/01/16 09:39, Shiyao Ma wrote:
>> Hi,
>>
>> I wanna simulate C style integer division in Python3.
>>
>> So far what I've got is:
>> # a, b = 3, 4
>>
>> import math
>> result = float(a) / b
>> if result > 0:
>>    result = math.floor(result)
>> else:
>>    result = math.ceil(result)
>>
>>
>> I found it's too laborious. Any quick way?
>>
> 
> math.trunc( float(a) / b )


That fails for sufficiently big numbers:


py> a = 3**1000 * 2
py> b = 3**1000
py> float(a)/b  # Exact answer should be 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to float


Note that Python gets the integer division correct:

py> a//b
2L


And even gets true division correct:

py> from __future__ import division
py> a/b
2.0


so it's just the intermediate conversion to float that fails.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#102034

FromGrobu <snailcoder@retrosite.invalid>
Date2016-01-23 13:04 +0100
Message-ID<n7vq24$a71$1@dont-email.me>
In reply to#101991
On 22/01/16 04:48, Steven D'Aprano wrote:
[ ... ]

>> math.trunc( float(a) / b )
>
>
> That fails for sufficiently big numbers:
>
>
> py> a = 3**1000 * 2
> py> b = 3**1000
> py> float(a)/b  # Exact answer should be 2
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> OverflowError: long int too large to convert to float
>
>
> Note that Python gets the integer division correct:
>
> py> a//b
> 2L
>
>
> And even gets true division correct:
>
> py> from __future__ import division
> py> a/b
> 2.0
>
>
> so it's just the intermediate conversion to float that fails.
>

Thanks! I did see recommandations to avoid floats throughout the thread, 
but didn't understand why.

Following code should be exempt from such shortcomings :

def intdiv(a, b):
     return (a - (a % (-b if a < 0 else b))) / b

[toc] | [prev] | [next] | [standalone]


#102035

FromGrobu <snailcoder@retrosite.invalid>
Date2016-01-23 13:52 +0100
Message-ID<n7vsta$kph$1@dont-email.me>
In reply to#102034
> def intdiv(a, b):
>      return (a - (a % (-b if a < 0 else b))) / b
>
>

Duh ... Got confused with modulos (again).

def intdiv(a, b):
     return (a - (a % (-abs(b) if a < 0 else abs(b)))) / b

[toc] | [prev] | [next] | [standalone]


#102048

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-01-23 17:07 +0200
Message-ID<lf5mvrwz651.fsf@ling.helsinki.fi>
In reply to#102035
Grobu writes:

>> def intdiv(a, b):
>>      return (a - (a % (-b if a < 0 else b))) / b
>>
>>
>
> Duh ... Got confused with modulos (again).
>
> def intdiv(a, b):
>     return (a - (a % (-abs(b) if a < 0 else abs(b)))) / b

You should use // here to get an exact integer result.

[toc] | [prev] | [next] | [standalone]


#102054

FromGrobu <snailcoder@retrosite.invalid>
Date2016-01-23 17:44 +0100
Message-ID<n80aem$7d1$1@dont-email.me>
In reply to#102048
On 23/01/16 16:07, Jussi Piitulainen wrote:
> Grobu writes:
>
>>> def intdiv(a, b):
>>>       return (a - (a % (-b if a < 0 else b))) / b
>>>
>>>
>>
>> Duh ... Got confused with modulos (again).
>>
>> def intdiv(a, b):
>>      return (a - (a % (-abs(b) if a < 0 else abs(b)))) / b
>
> You should use // here to get an exact integer result.
>

You're totally right, thanks! It isn't an issue for Python 2.x's 
"classic division", but it becomes one with Python 3's "True division", 
and '//' allows to play it safe all along.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web