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


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

Re: How to simulate C style integer division?

Started byBen Finney <ben+python@benfinney.id.au>
First post2016-01-21 20:11 +1100
Last post2016-01-21 15:22 +0100
Articles 11 — 8 participants

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

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: How to simulate C style integer division? Ben Finney <ben+python@benfinney.id.au> - 2016-01-21 20:11 +1100
    Re: How to simulate C style integer division? Paul Rubin <no.email@nospam.invalid> - 2016-01-21 01:43 -0800
      Re: How to simulate C style integer division? Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-21 11:58 +0200
    Re: How to simulate C style integer division? Steven D'Aprano <steve@pearwood.info> - 2016-01-21 23:42 +1100
      Re: How to simulate C style integer division? Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-21 16:00 +0200
        Re: How to simulate C style integer division? Marko Rauhamaa <marko@pacujo.net> - 2016-01-21 16:31 +0200
          Re: How to simulate C style integer division? Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-01-21 16:48 +0200
          Re: How to simulate C style integer division? Random832 <random832@fastmail.com> - 2016-01-21 14:52 -0500
            Re: How to simulate C style integer division? Marko Rauhamaa <marko@pacujo.net> - 2016-01-21 23:17 +0200
              Re: How to simulate C style integer division? Matt Wheeler <m@funkyhat.org> - 2016-01-22 00:51 +0000
        Re: How to simulate C style integer division? Wolfgang Maier <wolfgang.maier@biologie.uni-freiburg.de> - 2016-01-21 15:22 +0100

#101952 — Re: How to simulate C style integer division?

FromBen Finney <ben+python@benfinney.id.au>
Date2016-01-21 20:11 +1100
SubjectRe: How to simulate C style integer division?
Message-ID<mailman.143.1453367498.15297.python-list@python.org>
Shiyao Ma <i@introo.me> writes:

> I wanna simulate C style integer division in Python3.

I'm not sure I know exactly what behaviour you want (“C style” may mean
different things to each of us).

I'll point out that Python's ‘//’ operator specifies floor division
<URL:https://docs.python.org/3/reference/expressions.html#binary-arithmetic-operations>.

-- 
 \       “Timid men prefer the calm of despotism to the boisterous sea |
  `\                                    of liberty.” —Thomas Jefferson |
_o__)                                                                  |
Ben Finney

[toc] | [next] | [standalone]


#101954

FromPaul Rubin <no.email@nospam.invalid>
Date2016-01-21 01:43 -0800
Message-ID<87io2np8rw.fsf@nightsong.com>
In reply to#101952
Ben Finney <ben+python@benfinney.id.au> writes:
> I'm not sure I know exactly what behaviour you want (“C style” may mean
> different things to each of us).

I thought he meant trunc-division, so -5 / 2 = -2 and -5 % 2 = -1.
Python specifies floor division but C leaves it unspecified, I thought.

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


#101955

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-01-21 11:58 +0200
Message-ID<lf5fuxrl0em.fsf@ling.helsinki.fi>
In reply to#101954
Paul Rubin writes:

> Ben Finney writes:
>> I'm not sure I know exactly what behaviour you want (“C style” may mean
>> different things to each of us).
>
> I thought he meant trunc-division, so -5 / 2 = -2 and -5 % 2 = -1.
> Python specifies floor division but C leaves it unspecified, I thought.

I found a statement that it's specified to be truncating since C99.
Before that it was flooring or truncating.

Reading OP's code, the intention seemed clear to me.

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


#101961

FromSteven D'Aprano <steve@pearwood.info>
Date2016-01-21 23:42 +1100
Message-ID<56a0d24f$0$1614$c3e8da3$5496439d@news.astraweb.com>
In reply to#101952
On Thu, 21 Jan 2016 08:11 pm, Ben Finney wrote:

> Shiyao Ma <i@introo.me> writes:
> 
>> I wanna simulate C style integer division in Python3.
> 
> I'm not sure I know exactly what behaviour you want (“C style” may mean
> different things to each of us).

Surely is means "whatever the C standard defines integer division to mean".

Are their any C programmers here who can tell us what the C standard says?

According to this:

http://stackoverflow.com/questions/3602827/what-is-the-behavior-of-integer-division-in-c

the behaviour of integer division was implementation dependent in C89, but
has now been specified in detail since C99. The answer is that a/b for
integers a and b *truncate towards zero*. That is, it returns the integer
part with no fractional part:

Both arguments are positive, or both negative:

    11/2 = 5.5 so throw away the 0.5 and return 5

    -11/-2 = 5.5 so throw away the 0.5 and return 5

One argument is positive and the other negative:

    -11/2 = -5.5 so throw away the 0.5 and return -5

    11/-2 = -5.5 so throw away the 0.5 and return -5


Python's integer division // performs flooring, not truncating, so it
disagrees in the case that exactly one of the arguments are negative:

py> 11//2
5
py> -11//-2
5

py> 11//-2
-6
py> -11//2
-6


So my guess is that the fastest, and certainly the most obvious, way to get
the same integer division behaviour as C99 would be:

def intdiv(a, b):
    # C99 style integer division with truncation towards zero.
    n = a//b
    if (a < 0) != (b < 0):
        n += 1
    return n



-- 
Steven

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


#101962

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-01-21 16:00 +0200
Message-ID<lf5mvrzuj5z.fsf@ling.helsinki.fi>
In reply to#101961
Steven D'Aprano writes:

> So my guess is that the fastest, and certainly the most obvious, way
> to get the same integer division behaviour as C99 would be:
>
> def intdiv(a, b):
>     # C99 style integer division with truncation towards zero.
>     n = a//b
>     if (a < 0) != (b < 0):
>         n += 1
>     return n

You should only increment if there is a (non-zero) remainder.

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


#101965

FromMarko Rauhamaa <marko@pacujo.net>
Date2016-01-21 16:31 +0200
Message-ID<87mvrzc8bx.fsf@elektro.pacujo.net>
In reply to#101962
Jussi Piitulainen <jussi.piitulainen@helsinki.fi>:

> Steven D'Aprano writes:
>
>> So my guess is that the fastest, and certainly the most obvious, way
>> to get the same integer division behaviour as C99 would be:
>>
>> def intdiv(a, b):
>>     # C99 style integer division with truncation towards zero.
>>     n = a//b
>>     if (a < 0) != (b < 0):
>>         n += 1
>>     return n
>
> You should only increment if there is a (non-zero) remainder.

Maybe:

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


Marko

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


#101967

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-01-21 16:48 +0200
Message-ID<lf5egdbugxm.fsf@ling.helsinki.fi>
In reply to#101965
Marko Rauhamaa writes:

> Jussi Piitulainen writes:
>
>> Steven D'Aprano writes:
>>
>>> So my guess is that the fastest, and certainly the most obvious, way
>>> to get the same integer division behaviour as C99 would be:
>>>
>>> def intdiv(a, b):
>>>     # C99 style integer division with truncation towards zero.
>>>     n = a//b
>>>     if (a < 0) != (b < 0):
>>>         n += 1
>>>     return n
>>
>> You should only increment if there is a (non-zero) remainder.
>
> Maybe:
>
>    def intdiv(a, b):
>        return a // b if (a < 0) == (b < 0) else -(-a // b)

Nice.

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


#101985

FromRandom832 <random832@fastmail.com>
Date2016-01-21 14:52 -0500
Message-ID<mailman.155.1453405932.15297.python-list@python.org>
In reply to#101965
On Thu, Jan 21, 2016, at 09:31, Marko Rauhamaa wrote:
> Maybe:
> 
>    def intdiv(a, b):
>        return a // b if (a < 0) == (b < 0) else -(-a // b)

Personally, I like a // b + (a % b and a ^ b < 0) - I've done the
opposite in C to get python-style division.

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


#101986

FromMarko Rauhamaa <marko@pacujo.net>
Date2016-01-21 23:17 +0200
Message-ID<877fj263aj.fsf@elektro.pacujo.net>
In reply to#101985
Random832 <random832@fastmail.com>:

> On Thu, Jan 21, 2016, at 09:31, Marko Rauhamaa wrote:
>> Maybe:
>> 
>>    def intdiv(a, b):
>>        return a // b if (a < 0) == (b < 0) else -(-a // b)
>
> Personally, I like a // b + (a % b and a ^ b < 0) - I've done the
> opposite in C to get python-style division.

Well, then there's:

    def intdiv(a, b):
        return int(a / b)


Marko

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


#101987

FromMatt Wheeler <m@funkyhat.org>
Date2016-01-22 00:51 +0000
Message-ID<mailman.156.1453424217.15297.python-list@python.org>
In reply to#101986
On 21 January 2016 at 21:17, Marko Rauhamaa <marko@pacujo.net> wrote:
> Well, then there's:
>
>     def intdiv(a, b):
>         return int(a / b)

That depends on how accurate you need it to be

>>> def intdiv(a, b):
...  return a//b if (a < 0) == (b < 0) else -(-a//b)
...
>>> num = 3**171
>>> num
3870210234510307998744588107535211184800325224934979257430349324033792477926791547
>>> num2 = 4**80
>>> num2
1461501637330902918203684832716283019655932542976
>>> intdiv(num, num2)
2648105301871818722187687529062555
>>> int(num/num2)
2648105301871818477801931416797184



-- 
Matt Wheeler
http://funkyh.at

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


#101966

FromWolfgang Maier <wolfgang.maier@biologie.uni-freiburg.de>
Date2016-01-21 15:22 +0100
Message-ID<mailman.149.1453386144.15297.python-list@python.org>
In reply to#101962
On 1/21/2016 15:00, Jussi Piitulainen wrote:
> Steven D'Aprano writes:
>
>> So my guess is that the fastest, and certainly the most obvious, way
>> to get the same integer division behaviour as C99 would be:
>>
>> def intdiv(a, b):
>>      # C99 style integer division with truncation towards zero.
>>      n = a//b
>>      if (a < 0) != (b < 0):
>>          n += 1
>>      return n
>
> You should only increment if there is a (non-zero) remainder.
>

Right. Merging Steven's suggestion and fractions.Fraction.__trunc__ 
implementation I think the right answer may be:

def intdiv2(a,b):
     # C99 style integer division with truncation towards zero.
     if (a < 0) != (b < 0):
         return -(-a // b)
     else:
         return a // b

Cheers,
Wolfgang


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

[toc] | [prev] | [standalone]


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


csiph-web