[Patches] import floatdivision # 1/2==0.5

David Scherer dscherer@cmu.edu
Mon, 12 Jun 2000 13:57:43 -0400


This is a multi-part message in MIME format.

------=_NextPart_000_0009_01BFD476.2E3025C0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

This patch provides a way to make 1/2==0.5 optional without introducing any
backward incompatibilities.  It provides a pseudomodule "floatdivision"
that, when imported, changes the behavior of the importing script at compile
time:

import floatdivision
print 3/4             # 0.75

This behavior is already available in my 1.5.2-based Python distribution for
Windows (see http://sourceforge.net/projects/visualpython).  I would like to
see it generally available, particularly since I cannot easily provide a
replacement Python interpreter to UNIX users.

The attached patch is against the CVS 1.6 of this morning.  I believe the
changes are self-explanatory, but I will be happy to discuss them.  In my
original changes to 1.5.2, I implemented the BINARY_FRACTION opcode through
a new PyNumber_Fraction API call, but I thought it best to keep this patch
as simple as possible and let someone more familiar with the code base
reorganize it if they choose.

Optionally, the interpreter can be made to do floating-point division in
interactive mode.  The lines that do this are commented out in the patch:

  		c->c_interactive++;
+ 		/* c->c_floatdivision++; */

+ 		/* c->c_floatdivision--; */
  		c->c_interactive--;

Alternatively, this could be left to environments such as IDLE.

I confirm that, to the best of my knowledge and belief, this
contribution is free of any claims of third parties under
copyright, patent or other rights or interests ("claims").  To
the extent that I have any such claims, I hereby grant to CNRI a
nonexclusive, irrevocable, royalty-free, worldwide license to
reproduce, distribute, perform and/or display publicly, prepare
derivative versions, and otherwise use this contribution as part
of the Python software and its related documentation, or any
derivative versions thereof, at no cost to CNRI or its licensed
users, and to authorize others to do so.

I acknowledge that CNRI may, at its sole discretion, decide
whether or not to incorporate this contribution in the Python
software and its related documentation.  I further grant CNRI
permission to use my name and other identifying information
provided to CNRI by me for use in connection with the Python
software and its related documentation.

Dave

------=_NextPart_000_0009_01BFD476.2E3025C0
Content-Type: application/octet-stream;
	name="floatdivision.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="floatdivision.patch"

diff -c -r -x Entries* old\python/dist/src/Include/opcode.h =
python/dist/src/Include/opcode.h
*** old\python/dist/src/Include/opcode.h	Tue Mar 28 23:10:02 2000
--- python/dist/src/Include/opcode.h	Mon Jun 12 14:41:06 2000
***************
*** 76,81 ****
--- 76,82 ----
  #define BINARY_AND	64
  #define BINARY_XOR	65
  #define BINARY_OR	66
+ #define BINARY_FRACTION	67	/* 3/4 =3D=3D 0.75 */
 =20
 =20
  #define PRINT_EXPR	70
diff -c -r -x Entries* old\python/dist/src/Lib/dis.py =
python/dist/src/Lib/dis.py
*** old\python/dist/src/Lib/dis.py	Thu Mar 30 14:02:10 2000
--- python/dist/src/Lib/dis.py	Mon Jun 12 15:52:20 2000
***************
*** 186,191 ****
--- 186,192 ----
  def_op('BINARY_AND', 64)
  def_op('BINARY_XOR', 65)
  def_op('BINARY_OR', 66)
+ def_op('BINARY_FRACTION', 67)
 =20
  def_op('PRINT_EXPR', 70)
  def_op('PRINT_ITEM', 71)
diff -c -r -x Entries* old\python/dist/src/Python/ceval.c =
python/dist/src/Python/ceval.c
*** old\python/dist/src/Python/ceval.c	Mon May 08 14:06:50 2000
--- python/dist/src/Python/ceval.c	Mon Jun 12 14:52:02 2000
***************
*** 787,792 ****
--- 787,816 ----
  			PUSH(x);
  			if (x !=3D NULL) continue;
  			break;
+=20
+ 		case BINARY_FRACTION:
+ 			w =3D POP();
+ 			v =3D POP();
+ 			if (PyInt_Check(v) && PyInt_Check(w)) {
+ 				/* 3/4 =3D=3D 0.75 */
+ 				long vi, wi;
+ 				vi =3D PyInt_AS_LONG(v);
+ 				wi =3D PyInt_AS_LONG(w);
+ 				if (wi =3D=3D 0) {
+ 					PyErr_SetString(PyExc_ZeroDivisionError,
+ 							"integer division");
+ 					x=3DNULL;
+ 				}
+ 				else
+ 					x=3DPyFloat_FromDouble( (double)vi / (double)wi );
+ 			}
+ 			else
+ 				x =3D PyNumber_Divide(v, w);
+ 			Py_DECREF(v);
+ 			Py_DECREF(w);
+ 			PUSH(x);
+ 			if (x !=3D NULL) continue;
+ 			break;
  	=09
  		case BINARY_MODULO:
  			w =3D POP();
diff -c -r -x Entries* old\python/dist/src/Python/compile.c =
python/dist/src/Python/compile.c
*** old\python/dist/src/Python/compile.c	Wed May 03 23:44:38 2000
--- python/dist/src/Python/compile.c	Mon Jun 12 15:25:26 2000
***************
*** 329,334 ****
--- 329,335 ----
  #ifdef PRIVATE_NAME_MANGLING
  	char *c_private;	/* for private name mangling */
  #endif
+ 	int c_floatdivision;    /* generate BINARY_FRACTION; 3/4=3D=3D0.75 */
  };
 =20
 =20
***************
*** 463,468 ****
--- 464,470 ----
  	c->c_last_addr =3D 0;
  	c->c_last_line =3D 0;
  	c-> c_lnotab_next =3D 0;
+ 	c->c_floatdivision =3D 0;
  	return 1;
  =09
    fail:
***************
*** 1482,1488 ****
  			op =3D BINARY_MULTIPLY;
  			break;
  		case SLASH:
! 			op =3D BINARY_DIVIDE;
  			break;
  		case PERCENT:
  			op =3D BINARY_MODULO;
--- 1484,1493 ----
  			op =3D BINARY_MULTIPLY;
  			break;
  		case SLASH:
! 			if (c->c_floatdivision)
! 				op =3D BINARY_FRACTION;
! 			else
! 				op =3D BINARY_DIVIDE;
  			break;
  		case PERCENT:
  			op =3D BINARY_MODULO;
***************
*** 2179,2188 ****
  		/* 'import' ... */
  		for (i =3D 1; i < NCH(n); i +=3D 2) {
  			REQ(CHILD(n, i), dotted_name);
! 			com_addopname(c, IMPORT_NAME, CHILD(n, i));
! 			com_push(c, 1);
! 			com_addopname(c, STORE_NAME, CHILD(CHILD(n, i), 0));
! 			com_pop(c, 1);
  		}
  	}
  }
--- 2184,2200 ----
  		/* 'import' ... */
  		for (i =3D 1; i < NCH(n); i +=3D 2) {
  			REQ(CHILD(n, i), dotted_name);
!=20
! 			if (NCH( CHILD(n,i) )=3D=3D1 &&=20
! 			    !strcmp("floatdivision", STR(CHILD(CHILD(n,i),0))))
! 			{
! 				c->c_floatdivision++;
! 			} else {
! 				com_addopname(c, IMPORT_NAME, CHILD(n, i));
! 				com_push(c, 1);
! 				com_addopname(c, STORE_NAME, CHILD(CHILD(n, i), 0));
! 				com_pop(c, 1);
! 			}
  		}
  	}
  }
***************
*** 3306,3311 ****
--- 3318,3324 ----
  	case single_input: /* One interactive command */
  		/* NEWLINE | simple_stmt | compound_stmt NEWLINE */
  		c->c_interactive++;
+ 		/* c->c_floatdivision++; */
  		n =3D CHILD(n, 0);
  		if (TYPE(n) !=3D NEWLINE)
  			com_node(c, n);
***************
*** 3313,3318 ****
--- 3326,3332 ----
  		com_push(c, 1);
  		com_addbyte(c, RETURN_VALUE);
  		com_pop(c, 1);
+ 		/* c->c_floatdivision--; */
  		c->c_interactive--;
  		break;
  =09
***************
*** 3482,3487 ****
--- 3496,3503 ----
  	else
  		sc.c_private =3D NULL;
  #endif
+ 	if (base)
+ 		sc.c_floatdivision =3D base->c_floatdivision;
  	compile_node(&sc, n);
  	com_done(&sc);
  	if ((TYPE(n) =3D=3D funcdef || TYPE(n) =3D=3D lambdef) && sc.c_errors =
=3D=3D 0) {

------=_NextPart_000_0009_01BFD476.2E3025C0--