diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml
new file mode 100644
index aaf758d..da27874
*** a/doc/src/sgml/plpython.sgml
--- b/doc/src/sgml/plpython.sgml
*************** $$ LANGUAGE plpythonu;
*** 308,321 ****
        </para>
       </listitem>
  
       <listitem>
        <para>
!        PostgreSQL <type>real</type>, <type>double</type>,
!        and <type>numeric</type> are converted to
!        Python <type>float</type>.  Note that for
!        the <type>numeric</type> this loses information and can lead to
!        incorrect results.  This might be fixed in a future
!        release.
        </para>
       </listitem>
  
--- 308,326 ----
        </para>
       </listitem>
  
+ 	 <listitem>
+       <para>
+        PostgreSQL <type>real</type> and <type>double</type> are converted to
+        Python <type>float</type>.
+       </para>
+      </listitem>
+ 
       <listitem>
        <para>
!        PostgreSQL <type>numeric</type> is converted to
!        Python <type>Decimal</type>. This type is imported from 
! 	   <literal>cdecimal</literal> package if it is available. If cdecimal
! 	   cannot be used, then <literal>decimal.Decimal</literal> will be used.
        </para>
       </listitem>
  
diff --git a/src/pl/plpython/expected/plpython_types.out b/src/pl/plpython/expected/plpython_types.out
new file mode 100644
index 4641345..46308ed
*** a/src/pl/plpython/expected/plpython_types.out
--- b/src/pl/plpython/expected/plpython_types.out
*************** CONTEXT:  PL/Python function "test_type_
*** 213,248 ****
  (1 row)
  
  CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
! plpy.info(x, type(x))
  return x
  $$ LANGUAGE plpythonu;
! /* The current implementation converts numeric to float. */
  SELECT * FROM test_type_conversion_numeric(100);
! INFO:  (100.0, <type 'float'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                         100.0
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(-100);
! INFO:  (-100.0, <type 'float'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                        -100.0
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(5000000000.5);
! INFO:  (5000000000.5, <type 'float'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
                   5000000000.5
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(null);
! INFO:  (None, <type 'NoneType'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
--- 213,264 ----
  (1 row)
  
  CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
! plpy.info(str(x))
  return x
  $$ LANGUAGE plpythonu;
! /* The current implementation converts numeric to decimal.Decimal. */
  SELECT * FROM test_type_conversion_numeric(100);
! INFO:  100
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                           100
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(-100);
! INFO:  -100
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                          -100
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(5000000000.5);
! INFO:  5000000000.5
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
                   5000000000.5
  (1 row)
  
+ SELECT * FROM test_type_conversion_numeric(1234567890.0987654321);
+ INFO:  1234567890.0987654321
+ CONTEXT:  PL/Python function "test_type_conversion_numeric"
+  test_type_conversion_numeric 
+ ------------------------------
+         1234567890.0987654321
+ (1 row)
+ 
+ SELECT * FROM test_type_conversion_numeric(-1234567890.0987654321);
+ INFO:  -1234567890.0987654321
+ CONTEXT:  PL/Python function "test_type_conversion_numeric"
+  test_type_conversion_numeric 
+ ------------------------------
+        -1234567890.0987654321
+ (1 row)
+ 
  SELECT * FROM test_type_conversion_numeric(null);
! INFO:  None
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
diff --git a/src/pl/plpython/expected/plpython_types_3.out b/src/pl/plpython/expected/plpython_types_3.out
new file mode 100644
index 511ef5a..d791fb6
*** a/src/pl/plpython/expected/plpython_types_3.out
--- b/src/pl/plpython/expected/plpython_types_3.out
*************** CONTEXT:  PL/Python function "test_type_
*** 213,248 ****
  (1 row)
  
  CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
! plpy.info(x, type(x))
  return x
  $$ LANGUAGE plpython3u;
! /* The current implementation converts numeric to float. */
  SELECT * FROM test_type_conversion_numeric(100);
! INFO:  (100.0, <class 'float'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                         100.0
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(-100);
! INFO:  (-100.0, <class 'float'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                        -100.0
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(5000000000.5);
! INFO:  (5000000000.5, <class 'float'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
                   5000000000.5
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(null);
! INFO:  (None, <class 'NoneType'>)
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
--- 213,264 ----
  (1 row)
  
  CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
! plpy.info(str(x))
  return x
  $$ LANGUAGE plpython3u;
! /* The current implementation converts numeric to decimal.Decimal. */
  SELECT * FROM test_type_conversion_numeric(100);
! INFO:  100
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                           100
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(-100);
! INFO:  -100
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
!                          -100
  (1 row)
  
  SELECT * FROM test_type_conversion_numeric(5000000000.5);
! INFO:  5000000000.5
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
                   5000000000.5
  (1 row)
  
+ SELECT * FROM test_type_conversion_numeric(1234567890.0987654321);
+ INFO:  1234567890.0987654321
+ CONTEXT:  PL/Python function "test_type_conversion_numeric"
+  test_type_conversion_numeric 
+ ------------------------------
+         1234567890.0987654321
+ (1 row)
+ 
+ SELECT * FROM test_type_conversion_numeric(-1234567890.0987654321);
+ INFO:  -1234567890.0987654321
+ CONTEXT:  PL/Python function "test_type_conversion_numeric"
+  test_type_conversion_numeric 
+ ------------------------------
+        -1234567890.0987654321
+ (1 row)
+ 
  SELECT * FROM test_type_conversion_numeric(null);
! INFO:  None
  CONTEXT:  PL/Python function "test_type_conversion_numeric"
   test_type_conversion_numeric 
  ------------------------------
diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c
new file mode 100644
index 6a9a2cb..e04c2f9
*** a/src/pl/plpython/plpy_typeio.c
--- b/src/pl/plpython/plpy_typeio.c
***************
*** 18,23 ****
--- 18,24 ----
  #include "utils/memutils.h"
  #include "utils/syscache.h"
  #include "utils/typcache.h"
+ #include "utils/numeric.h"
  
  #include "plpython.h"
  
*************** static void PLy_output_datum_func2(PLyOb
*** 35,41 ****
  static PyObject *PLyBool_FromBool(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyFloat_FromFloat4(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyFloat_FromFloat8(PLyDatumToOb *arg, Datum d);
! static PyObject *PLyFloat_FromNumeric(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyInt_FromInt16(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyInt_FromInt32(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyLong_FromInt64(PLyDatumToOb *arg, Datum d);
--- 36,42 ----
  static PyObject *PLyBool_FromBool(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyFloat_FromFloat4(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyFloat_FromFloat8(PLyDatumToOb *arg, Datum d);
! static PyObject *PLyDecimal_FromNumeric(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyInt_FromInt16(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyInt_FromInt32(PLyDatumToOb *arg, Datum d);
  static PyObject *PLyLong_FromInt64(PLyDatumToOb *arg, Datum d);
*************** PLy_input_datum_func2(PLyDatumToOb *arg,
*** 450,456 ****
  			arg->func = PLyFloat_FromFloat8;
  			break;
  		case NUMERICOID:
! 			arg->func = PLyFloat_FromNumeric;
  			break;
  		case INT2OID:
  			arg->func = PLyInt_FromInt16;
--- 451,457 ----
  			arg->func = PLyFloat_FromFloat8;
  			break;
  		case NUMERICOID:
! 			arg->func = PLyDecimal_FromNumeric;
  			break;
  		case INT2OID:
  			arg->func = PLyInt_FromInt16;
*************** PLyFloat_FromFloat8(PLyDatumToOb *arg, D
*** 516,531 ****
  }
  
  static PyObject *
! PLyFloat_FromNumeric(PLyDatumToOb *arg, Datum d)
  {
! 	/*
! 	 * Numeric is cast to a PyFloat: This results in a loss of precision Would
! 	 * it be better to cast to PyString?
! 	 */
! 	Datum		f = DirectFunctionCall1(numeric_float8, d);
! 	double		x = DatumGetFloat8(f);
  
! 	return PyFloat_FromDouble(x);
  }
  
  static PyObject *
--- 517,549 ----
  }
  
  static PyObject *
! PLyDecimal_FromNumeric(PLyDatumToOb *arg, Datum d)
  {
! 	char *x;
! 	PyObject *pvalue, *value, *decimal, *decimal_dict;
! 	static PyObject *decimal_ctor;
  
! 	/* Try to import cdecimal, if it doesnt exist, fallback to decimal */
! 	if (decimal_ctor == NULL)
! 	{
! 		decimal = PyImport_ImportModule("cdecimal");
! 		if (decimal == NULL)
! 		{
! 			PyErr_Clear();
! 			decimal = PyImport_ImportModule("decimal");
! 		}
! 		if (decimal == NULL)
! 			PLy_elog(ERROR, "could not import module 'decimal'");
! 
! 		decimal_dict = PyModule_GetDict(decimal);
! 		decimal_ctor = PyDict_GetItemString(decimal_dict, "Decimal");
! 		Py_DECREF(decimal_dict);
! 	}
! 
! 	x = DatumGetCString(DirectFunctionCall1(numeric_out, d));
! 	pvalue = PyString_FromString(x);
! 	value = PyObject_CallFunctionObjArgs(decimal_ctor, pvalue, NULL);
! 	return value;
  }
  
  static PyObject *
diff --git a/src/pl/plpython/sql/plpython_types.sql b/src/pl/plpython/sql/plpython_types.sql
new file mode 100644
index 6a50b42..83a8ef9
*** a/src/pl/plpython/sql/plpython_types.sql
--- b/src/pl/plpython/sql/plpython_types.sql
*************** SELECT * FROM test_type_conversion_int8(
*** 86,99 ****
  
  
  CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
! plpy.info(x, type(x))
  return x
  $$ LANGUAGE plpythonu;
  
! /* The current implementation converts numeric to float. */
  SELECT * FROM test_type_conversion_numeric(100);
  SELECT * FROM test_type_conversion_numeric(-100);
  SELECT * FROM test_type_conversion_numeric(5000000000.5);
  SELECT * FROM test_type_conversion_numeric(null);
  
  
--- 86,101 ----
  
  
  CREATE FUNCTION test_type_conversion_numeric(x numeric) RETURNS numeric AS $$
! plpy.info(str(x))
  return x
  $$ LANGUAGE plpythonu;
  
! /* The current implementation converts numeric to decimal.Decimal. */
  SELECT * FROM test_type_conversion_numeric(100);
  SELECT * FROM test_type_conversion_numeric(-100);
  SELECT * FROM test_type_conversion_numeric(5000000000.5);
+ SELECT * FROM test_type_conversion_numeric(1234567890.0987654321);
+ SELECT * FROM test_type_conversion_numeric(-1234567890.0987654321);
  SELECT * FROM test_type_conversion_numeric(null);
  
  
