# RFC: Add support for GMP floating point numbers

- Status: Inactive
- Authors: Sara Golemon, pollita@php.net
- Date: 2014-01-04
- Version: 1.1
- Original: https://wiki.php.net/rfc/gmp-floating-point
- Page: https://externals.io/rfc/gmp-floating-point
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Discussions on the mailing list

- [\[RFC\] Floating Point support in GMP extension](https://externals.io/message/70998.md) — started on 2014-01-04, 8 messages
- [GMP Floating Point Support - Will be implemented?](https://externals.io/message/73752.md) — started on 2014-04-21, 2 messages

---

## Introduction

@yohgaki suggested adding support for libgmp's arbitrary precision floating point numbers to the PHP extension, and I offered to implement it, so here's my proposal.

## Proposal #1

Extend &#96;gmp\_object&#96; struct to the following:

```
#define PHP_GMP_TYPE_INT 0
#define PHP_GMP_TYPE_FLOAT 1
typedef struct _gmp_object {
  zend_object std;
  char type;
  union {
     mpz_t inum;
     mpf_t fnum;
  }
} gmp_object;
```

The existing gmp\_init() function will create a gmp\_object with type == PHP\_GMP\_TYPE\_INT.

Add gmp\_init\_float(int\|string $number\[, $base = 0\]) to create a gmp\_object with type == PHP\_GMP\_TYPE\_FLOAT

Extend all other gmp\_\*() functions (and overload operators) to check type on the input object(s) and call the appropriate libgmp function and return the appropriate gmp\_object type.

Add gmp\_floatval(), gmp\_isint(), gmp\_isfloat(), and similar introspection functions.

## Proposal #2

Rather than overload the GMP class for integer/float representations, organize Integer and Floating-Point GMP objects into a class heirarchy as so:

```
abstract class GMPNumber {}
class GMPInt extends GMPNumber {}
class GMPFloat extends GMPNumber {}
```

The same open questions exist for this approach (i.e. should int/int yield float?)

## Backward Incompatible Changes

gmp\_init\_float() is being added to specifically avoid breakage in code currently supplying numbers which may (or may not) have decimal separators in them. Note that overloading gmp\_init() to detect floating point numbers would also present a challenge as GMP parses numbers based on system locale which may use '.', ',', or other separators. Having a unique initializer avoids that problem.

Actor functions and operator overloads should remain unaffected (with one exception, below) as code producing gmp\_objects now will continue to do so, with the single (invisible) addition of the type byte.

gmp\_div() (aka gmp\_div\_q()), may result in a non-integer result. This function currently has three modes: GMP\_ROUND\_ZERO, GMP\_ROUND\_PLUSINF, GMP\_ROUND\_MINUSINF which define what to do with the leftover fractional portion. This proposal suggests adding GMP\_ROUND\_NONE which will produce a floating point GMP object. The existing three modes will continue to produce integer results.

gmp\_div\_qr() would not be modified to handle GMP\_ROUND\_NONE as it is specifically designed to return a remainder. It would, however, still need to be extended to handle division of floating point numbers with integer 'q' and floating point 'r' results.

**Open Question**: The division operator overload uses the default division mode of GMP\_ROUND\_ZERO. It may coincide with “The PHP Way” to change to GMP\_ROUND\_NONE so that floating-point results may be produced from expressions such as: gmp\_init(3) / gmp\_init(2) This has limited BC issues since operator overloading for GMP is very new.

## Proposed PHP Version(s)

5.next (master branch)

## php.ini Defaults

Add INI setting: gmp.default\_precision=(libgmp-initial-default-precision)

## History

- Version 1.0: 2014-01-04 Initial Draft
- Version 1.1: 2014-01-05 Added proposal #2

## Implementation

Pending discussion to decide what direction we should go.
