Re: [Python-Dev] Floor division
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
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
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
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
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
[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
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
[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
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
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
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
[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
[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
... [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
[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
[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