Re: [Python-Dev] Floor division

2007-01-25 Thread Armin Rigo
Hi Tim,

On Tue, Jan 23, 2007 at 05:14:29PM -0500, Tim Peters wrote:
 For some reason `decimal` implemented __mod__ as the proposed
 standard's remainder operation.  That's the immediate source of your
 surprise.  IMO `decimal` should not have implemented __mod__ at all,
 as Python's number-theoretic mod is not part of the proposed standard,
 is a poor basis for a floating-point mod regardess, and it was a
 mistake to implement decimal % decimal in a way so visibly different
 from float % float and integer % integer:  it confuses the meaning of
 %.  That's your complaint, right?

Thanks for the clarification.  Yes, it makes sense that __mod__,
__divmod__ and __floordiv__ on float and decimal would eventually follow
the same path as for complex (where they make even less sense and
already raise a DeprecationWarning).


A bientot,

Armin.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Nick Maclaren
Armin Rigo [EMAIL PROTECTED] wrote:

 Thanks for the clarification.  Yes, it makes sense that __mod__,
 __divmod__ and __floordiv__ on float and decimal would eventually follow
 the same path as for complex (where they make even less sense and
 already raise a DeprecationWarning).

Yes.  Though them not doing so would also make sense.  The difference
is that they make no mathematical sense for complex, but the problems
with float are caused by floating-point (and do not occur for the
mathematical reals).

There is an argument for saying that divmod should return a long
quotient and a float remainder, which is what C99 has specified for
remquo (except that it requires only the last 3 bits of the quotient
for reasons that completely baffle me).  Linux misimplemented that
the last time I looked.

Personally, I think that it is bonkers, as it is fiendishly expensive
compared to its usefulness - especially with Decimal!  But it isn't
obviously WRONG.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QH, England.
Email:  [EMAIL PROTECTED]
Tel.:  +44 1223 334761Fax:  +44 1223 334679
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Problem with signals in a single threaded application

2007-01-25 Thread Gustavo Carneiro

On 1/24/07, Martin v. Löwis [EMAIL PROTECTED] wrote:


Gustavo Carneiro schrieb:
What about http://www.python.org/sf/1564547 ?  It tries to solve a
 different problem, but I think it also fixes this one; at least as much
 as possible with the braindead unix signal programming interface...

I'm sceptical. It is way too much code for me to review, so I'm unable
to comment whether it fixes the problem under discussion.



 Due to a bug, my patch  didn't fix this bug.  But I fixed the patch and it
now fixes both my problem and Ulisses'.

I feel that

this problem should find a much simpler solution.



  The problem is that if you apply Ulisses' patch then my patch, Ulisses'
changes will simply disappear because my patch handles signals and a much
safer way, completely bypassing the 'add/make pending calls' system, since
this system is patently *not* async safe, no matter how much you tweak it.

 Yes, I know my patch is not very small (though not that big either), but
the signal module was in dire need of refactoring.  And you can observe how
much simpler the signal module becomes after that patch.

 Regards.

--
Gustavo J. A. M. Carneiro
The universe is always one step beyond logic.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Guido van Rossum
The only thing I would miss about this is that I am used to write
certain timing loops that like to sync on whole seconds, by taking
time.time() % 1.0 which nicely gives me the milliseconds in the
current second. E.g.

while True:
  do_something_expensive_once_a_second_on_the_second()
  now = time.time()
  time.sleep(1.0 - (now % 1.0))

I guess I could use (now - int(now)) in a pinch, assuming int()
continues to truncate.

--Guido

On 1/25/07, Armin Rigo [EMAIL PROTECTED] wrote:
 Hi Tim,

 On Tue, Jan 23, 2007 at 05:14:29PM -0500, Tim Peters wrote:
  For some reason `decimal` implemented __mod__ as the proposed
  standard's remainder operation.  That's the immediate source of your
  surprise.  IMO `decimal` should not have implemented __mod__ at all,
  as Python's number-theoretic mod is not part of the proposed standard,
  is a poor basis for a floating-point mod regardess, and it was a
  mistake to implement decimal % decimal in a way so visibly different
  from float % float and integer % integer:  it confuses the meaning of
  %.  That's your complaint, right?

 Thanks for the clarification.  Yes, it makes sense that __mod__,
 __divmod__ and __floordiv__ on float and decimal would eventually follow
 the same path as for complex (where they make even less sense and
 already raise a DeprecationWarning).


 A bientot,

 Armin.
 ___
 Python-Dev mailing list
 Python-Dev@python.org
 http://mail.python.org/mailman/listinfo/python-dev
 Unsubscribe: 
 http://mail.python.org/mailman/options/python-dev/guido%40python.org



-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Having trouble committing

2007-01-25 Thread Brett Cannon
I am trying to commit to the 2.5 branch and I am getting an error:

svn: Commit failed (details follow):
svn: Can't create directory
'/data/repos/projects/db/transactions/53566-1.txn': Permission denied

Anyone know what is going on?

-Brett
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Having trouble committing

2007-01-25 Thread Tim Peters
[Brett Cannon]
 I am trying to commit to the 2.5 branch and I am getting an error:

 svn: Commit failed (details follow):
 svn: Can't create directory
 '/data/repos/projects/db/transactions/53566-1.txn': Permission denied

 Anyone know what is going on?

Did you do `svn info` in that directory to make sure you have a
writable (svn+ssh) checkout of that part?
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Having trouble committing

2007-01-25 Thread Martin v. Löwis
Brett Cannon schrieb:
 I am trying to commit to the 2.5 branch and I am getting an error:
 
 svn: Commit failed (details follow):
 svn: Can't create directory
 '/data/repos/projects/db/transactions/53566-1.txn': Permission denied
 
 Anyone know what is going on?

It's not clear to me. The permissions on the transactions folder look
good (pythondev has write permissions), so I can't see anything wrong.
Also, assuming that the error happened just before you sent the email,
I can't find anything suspicious in the log files around this time
(22:27 +0100)
Can you try again?

Regards,
Martin
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Tim Peters
[Guido]
 The only thing I would miss about this is that I am used to write
 certain timing loops that like to sync on whole seconds, by taking
 time.time() % 1.0 which nicely gives me the milliseconds in the
 current second. E.g.

 while True:
   do_something_expensive_once_a_second_on_the_second()
   now = time.time()
   time.sleep(1.0 - (now % 1.0))

Indeed, the only use of floating % in the standard library I recall is
the ancient

return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0

from the original Wichman-Hill random() generator.  Maybe we could
introduce % as a unary prefix operator, where %x means the
fractional part of x ;-)

Are you opposed to importing `math`?  The infix spelling had important
speed benefits in random.py (random() was the time-critical function
in that module), but the use above couldn't care less.

 time.sleep(1.0 - math.fmod(now, 1.0))

would do the same, except would be easier to reason about because it's
trivially guaranteed that 0.0 = math.fmod(x, 1.0)  1.0 for any
finite float x = 0.0.  The same may or may not be true of % (I would
have to think about that, and craft a proof one way or the other -- if
it is true, it would have to invoke something special about the
modulus 1.0, as the inequality doesn't hold for % for some other
modulus values).

Better, you could use the more obvious:

time.sleep(math.ceil(now) - now)

That says as directly as possible that you want the number of
seconds needed to reach the next integer value (or 0, if `now` is
already an integer).

 I guess I could use (now - int(now)) in a pinch,

That would need to be

time.sleep(1.0 - (now - int(now)))

I'd use the `ceil` spelling myself, even today -- but I don't suffer
it's better if it's syntax or __builtin__ disease ;-)

 assuming int() continues to truncate.

Has anyone suggested to change that?  I'm not aware of any complaints
or problems due to int() truncating.  There have been requests to add
new kinds of round-to-integer functions, but in addition to int().
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Having trouble committing

2007-01-25 Thread Brett Cannon
On 1/25/07, Tim Peters [EMAIL PROTECTED] wrote:
 [Brett Cannon]
  I am trying to commit to the 2.5 branch and I am getting an error:
 
  svn: Commit failed (details follow):
  svn: Can't create directory
  '/data/repos/projects/db/transactions/53566-1.txn': Permission denied
 
  Anyone know what is going on?

 Did you do `svn info` in that directory to make sure you have a
 writable (svn+ssh) checkout of that part?


Damn it, I think that was it.  I did a framework build in there and
``make distclean`` didn't clean up all the Mac-related files (which
should get fixed at some point), so I nuked the directory (which
itself had permission stuff that required sudo) and did a fresh
checkout.  Must have accidentally done a read-only checkout.

Sorry for the false alarm.

-Brett
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Having trouble committing

2007-01-25 Thread Neal Becker
I've heard it claimed that men often have this problem.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Guido van Rossum
On 1/25/07, Tim Peters [EMAIL PROTECTED] wrote:
 [Guido]
  The only thing I would miss about this is that I am used to write
  certain timing loops that like to sync on whole seconds, by taking
  time.time() % 1.0 which nicely gives me the milliseconds in the
  current second. E.g.
 
  while True:
do_something_expensive_once_a_second_on_the_second()
now = time.time()
time.sleep(1.0 - (now % 1.0))

 Indeed, the only use of floating % in the standard library I recall is
 the ancient

 return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0

 from the original Wichman-Hill random() generator.  Maybe we could
 introduce % as a unary prefix operator, where %x means the
 fractional part of x ;-)

 Are you opposed to importing `math`?  The infix spelling had important
 speed benefits in random.py (random() was the time-critical function
 in that module), but the use above couldn't care less.

  time.sleep(1.0 - math.fmod(now, 1.0))

 would do the same, except would be easier to reason about because it's
 trivially guaranteed that 0.0 = math.fmod(x, 1.0)  1.0 for any
 finite float x = 0.0.  The same may or may not be true of % (I would
 have to think about that, and craft a proof one way or the other -- if
 it is true, it would have to invoke something special about the
 modulus 1.0, as the inequality doesn't hold for % for some other
 modulus values).

I don't care about the speed, but having to import math (which I
otherwise almost never need) is a distraction, and (perhaps more so) I
can never remember whether it's modf() or fmod() that I want.

 Better, you could use the more obvious:

 time.sleep(math.ceil(now) - now)

 That says as directly as possible that you want the number of
 seconds needed to reach the next integer value (or 0, if `now` is
 already an integer).

Yeah, once math is imported the possibilities are endless. :-)

  I guess I could use (now - int(now)) in a pinch,

 That would need to be

 time.sleep(1.0 - (now - int(now)))

 I'd use the `ceil` spelling myself, even today -- but I don't suffer
 it's better if it's syntax or __builtin__ disease ;-)

  assuming int() continues to truncate.

 Has anyone suggested to change that?  I'm not aware of any complaints
 or problems due to int() truncating.  There have been requests to add
 new kinds of round-to-integer functions, but in addition to int().

I thought those semantics were kind of poorly specified. But maybe
that was long ago (when int() just did whatever (int) did in C) and
it's part of the language now.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Tim Peters
[Guido]
 ...
 I don't care about the speed, but having to import math (which I
 otherwise almost never need) is a distraction, and (perhaps more so) I
 can never remember whether it's modf() or fmod() that I want.

fractional part of x == fmod(x, 1.0) == modf(x)[0], so you could use
either.  Since modf returns a tuple and fmod returns a float, you'll
get an exception quickly if you pick the wrong one :-)  The name
modf certainly sucks.

...

 assuming int() continues to truncate.

 Has anyone suggested to change that?  I'm not aware of any complaints
 or problems due to int() truncating.  There have been requests to add
 new kinds of round-to-integer functions, but in addition to int().

 I thought those semantics were kind of poorly specified. But maybe
 that was long ago (when int() just did whatever (int) did in C) and
 it's part of the language now.

(int)float_or_double truncates in C (even in KR C) /provided that/
the true result is representable as an int.  Else behavior is
undefined (may return -1, may cause a HW fault, ...).

So Python uses C's modf() for float-int now, which is always defined
for finite floats, and also truncates.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Tim Peters
[Armin]
 Thanks for the clarification.  Yes, it makes sense that __mod__,
 __divmod__ and __floordiv__ on float and decimal would eventually follow
 the same path as for complex (where they make even less sense and
 already raise a DeprecationWarning).

This truly has nothing to do with complex.  All meanings for mod
(whether in Python, IEEE-754, C89, C99, or IBM's proposed decimal
standard) are instances of this mathematical schema:

[1]x%y = x - R(x/y)*y

by definition, where R(z) is a specific way of rounding z to an exact
mathematical (infinite precision) integer.

For int, long, and float, Python uses R=floor (and again it's
important to note that these are mathematical statements, not
statements about computer arithmetic).

For ints, longs, and (mathematical) reals, that's the usual
number-theoretic definition of mod, as, e.g., given by Knuth:

mod(x, y) = x - floor(x/y)*y

It's the only definition of all those mentioned here that guarantees
the result is non-negative when the modulus (y) is positive, and
that's a very nice property for integers.  It's /also/ the only
definition off all those mentioned here where the exact mathematical
result may /not/ be exactly representable as a computer float when x
and y are computer floats.

It's that last point that makes it a poor definition for working with
computer floats:  for any other plausible way of defining mod, the
exact result /is/ exactly representable as a computer float.  That
makes reasoning much easier, just as you don't have to think twice
about seeing abs() or unary minus applied to a float.  No information
is lost, and you can rely on expected invariants like

[2]0 = abs(x%y)  abs(y)if y != 0 and finite

provided one of the non- R=floor definitions of mod is used for computer floats.

For complex, Python uses R(z) = floor(real_part_of(z)).  AFAICT,
Python just made that up out of thin air.  There are no known use
cases, and it's bizarre.  For example, [2] isn't even approximately
reliable:

 x = 5000 + 100j
 y = 1j
 x % y
(5000+0j)
 print abs(x%y), abs(y)
5000.0 1.0

In short, while Python does something for complex % complex, what it
does seems more-than-less arbitrary.  That's why it was deprecated
years ago, and nobody complained.

But for computer floats, there are ways to instantiate R in [1] that
work fine, returning a result that is truly (exactly) congruent to x
modulo y, even though x, y and the result are all computer floats.
Two of those ways:

The C89 fmod = C99 fmod = C99 integral % = IBM spec remainder
picks R(z) = round z to the closest integer in the direction of 0.

The C99 remainder = IBM spec remainder-near = IEEE-754 REM picks
R(z) = round z to the nearest integer, or if z is exactly halfway
between integers to the nearest even integer.  This one has the nice
property (for floats!) that [2] can be strengthened to:

0 = abs(x%y) = abs(y)/2

That's often useful for argument reduction of periodic functions,
which is an important use case for a floating-point mod.  You
typically don't care about the sign of the result in that case, but do
want the absolute value as small as possible.  That's probably why
this was the only definition standardized by 754.

In contrast, I don't know of any use for complex %.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Tim Peters
...

[Tim]
 fractional part of x == fmod(x, 1.0) == modf(x)[0], so you could use
 either.

[Anders J. Munch]
 Actually, on the off chance that time.time() is negative, he can use
 neither.  It has to be math.ceil, float.__mod__ or divmod.

If time.time() is negative, I expect this would be the least of his worries :-)

Even on most Unixish boxes, Python's time.time() is immune to the
year 2038 problem anyway, since it uses POSIX's gettimeofday()
instead of C's time() when it can.
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Tim Peters
[Armin Rigo]
 Thanks for the clarification.  Yes, it makes sense that __mod__,
 __divmod__ and __floordiv__ on float and decimal would eventually follow
 the same path as for complex (where they make even less sense and
 already raise a DeprecationWarning).

[Nick Maclaren]
 Yes.  Though them not doing so would also make sense.  The difference
 is that they make no mathematical sense for complex, but the problems
 with float are caused by floating-point (and do not occur for the
 mathematical reals).

 There is an argument for saying that divmod should return a long
 quotient and a float remainder,

It could, but who would have a (sane) use for a possibly 2000-bit quotient?

 which is what C99 has specified for remquo (except that it requires
 only the last 3 bits of the quotient for reasons that completely baffle
 me).

C99 has no integral type capable of representing the full quotient,
but the last few bits may suffice for performing argument reduction in
the implementation of a periodic function.  Surely you did that for
trig functions in the bad old days?  For example, express input x as
N*(pi/2) + r, where |r| = pi/4.  Then N can be expressed as 4*n1 +
n2, with n2 in [0, 1, 2, 3], and:

cos(x) =
cos((4*n1+n2)*(pi/2) + r) =
cos(n1*(2*pi) + n2*pi/2 + r) =  [can ignore integral multiples of 2*pi]
cos(n2*pi/2 + r)

Then the combination of n2 and the sign of r tell you which quadrant
you're in, and various cos-specific rules can deliver the result from
that and cos(r) or sin(r).

The point is that only the last 2 bits of the quotient are needed to
determine n2, and all other bits in N are irrelevant to the result.

 Linux misimplemented that the last time I looked.

 Personally, I think that it is bonkers, as it is fiendishly expensive
 compared to its usefulness - especially with Decimal!

Ah, but the IBM spec weasels out:  it raises an exception if you try
to compute remainder or remainder-near of inputs when the
exponents differ by too much.

This is a bit peculiar to me, because there are ways to compute
remainder using a number of operations proportional to the log of
the exponent difference.  It could be that people who spend their life
doing floating point forget how to work with integers ;-)

For example, what about 9e9 % 3.14?

9e9 = q*3.14 + r

if and only if (multiplying both sides by 100)

9e11 = 314*q + 100*r

So what's mod(9 * 10**11, 314)?  Binary-method modular
exponentiation goes fast:

 pow(10, 11, 314)
148
 _ * 9 % 314
76

So

9e11 = 314*q + 76

exactly for some integer q, so (dividing both sides by 100)

9e9 = 3.14*q + 0.76

exactly for the same integer q.  Done.  It doesn't require 10
long-division steps, it only requires about two dozen modular
multiplications wrt the relatively tiny modulus 314.

OTOH, I don't know how to get the last bit of `q` with comparable
efficiency, and that's required to implement the related
remainder-near in halfway cases.

 But it isn't obviously WRONG.

For floats, fmod(x, y) is exactly congruent to x modulo y -- I don't
think it's possible to get more right than exactly right ;-)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Floor division

2007-01-25 Thread Tim Peters
[Tim Peters]
 ...
 Maybe we could introduce % as a unary prefix operator, where
 %x means the fractional part of x ;-)

[Anders J. Munch]
 What'ya talking about?  Obviously it should be a suffix operator ;-)

Na -- that would be confusing ;-)

...

  time.sleep(1.0 - math.fmod(now, 1.0))

 would do the same, except would be easier to reason about because it's
 trivially guaranteed that 0.0 = math.fmod(x, 1.0)  1.0 for any
 finite float x = 0.0.  The same may or may not be true of % (I would
 have to think about that, and craft a proof one way or the other -- if
 it is true, it would have to invoke something special about the
 modulus 1.0, as the inequality doesn't hold for % for some other
 modulus values).

And as you note later, x%y == fmod(x, y) whenever x and y have the
same sign (well, given the way CPython implements float.__mod__
today), so there's actually an easy proof.

 Other modulus values are important:

On an importance scale of 1 to 10, 9 or 10 ;-) ?

 The attraction of Guido's formula is that he could just as easily have
 used 60.0 or 0.001 if minute or millisecond intervals were desired, or
 even som user-specified arbitrary dt.  Then we're comparing dt-now%dt
 to (1.0-int(now/dt))*dt or (math.ceil(now/dt)-now/dt)*dt.

time.time() is never negative in Python (see other reply), so the
trivial respelling dt-fmod(now, dt) does the same.

 Fortunately, for all a,b0, mathematically math.fmod(a,b) is equal to
 a%b, so if the former is exactly representable, so is the latter.

Yup.  Also when `a` and `b` both less than 0.  This /follows/ from
that when `a` and `b` have the same sign, the mathematical a/b is =
0, so truncation is the same as the floor.  Therefore the mathematical

a - floor(a/b)*b   # Python __mod__
and
a - truncate(a/b)*b  # C fmod

are exactly the same whenever a and b have the same sign.

 Which is borne out in floatobject.c: float_rem and float_divmod just
 pass on the C fmod result if (a  0) == (b  0).

Yes.  In fact, I wrote all that code :-)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com