# The decimals Reference Manual

Next: , Previous: , Up: (dir)   [Contents][Index]

# The decimals Reference Manual

This is the decimals Reference Manual, generated automatically by Declt version 3.0 "Montgomery Scott" on Fri Jun 26 10:09:01 2020 GMT+0.

Next: , Previous: , Up: Top   [Contents][Index]

# Decimals

A decimal number parser and formatting package for Common Lisp

## Introduction

This Common Lisp package offers functions for parsing and formatting decimal numbers. Package's main interface are functions `parse-decimal-number` and `format-decimal-number`. The former is for parsing strings for decimal numbers and the latter for pretty-printing them as strings. See section The Programming Interface for the full documentation of the public programming interface. Here are some examples.

### Parsing

``````DECIMALS> (parse-decimal-number "0.24")
6/25

DECIMALS> (parse-decimal-number "−12,345"
:decimal-separator #\,
:negative-sign #\−)
-2469/200
``````

### Formatting

``````DECIMALS> (format-decimal-number -100/6 :round-magnitude -3)
"-16.667"
("-" "16" "." "667")

DECIMALS> (loop for e from -5 upto 5
do (print (format-decimal-number
(expt 10 e) :round-magnitude -5
:decimal-separator ","
:integer-minimum-width 7
:integer-group-separator " "
:fractional-minimum-width 7
:fractional-group-separator " ")))

"      0,000 01"
"      0,000 1 "
"      0,001   "
"      0,01    "
"      0,1     "
"      1       "
"     10       "
"    100       "
"  1 000       "
" 10 000       "
"100 000       "
NIL

DECIMALS> (loop for m from -3 upto 3
do (print (format-decimal-number
2000/3 :round-magnitude m
:integer-minimum-width 4
:fractional-minimum-width 4)))

" 666.667"
" 666.67 "
" 666.7  "
" 667    "
" 670    "
" 700    "
"1000    "
NIL
``````

Author: Teemu Likonen <tlikonen@iki.fi>

License: Creative Commons CC0 (public domain dedication)

The source code repository: https://github.com/tlikonen/cl-decimals

## The Programming Interface

### Condition: `decimal-parse-error`

Function `parse-decimal-number` signals this condition when it couldn't parse a decimal number from string. Function `decimal-parse-error-string` can be used to read the input string from the condition object.

### Function: `format-decimal-number`

The lambda list:

`````` (number &key (round-magnitude 0)
(rounder #'round-half-away-from-zero) (decimal-separator #\.)
(integer-group-separator nil) (integer-group-digits 3)
(fractional-group-separator nil) (fractional-group-digits 3)
(show-trailing-zeros nil) (positive-sign nil) (negative-sign #\-)
(zero-sign nil))
``````

Apply specified decimal number formatting rules to number and return a formatted string.

The second return value is (almost) the same formatted string divided into four strings. It's a list of four strings: sign, integer part, decimal separator and fractional part. Formatting arguments integer-minimum-width and fractional-minimum-width do not apply to the second return value. Everything else does.

Number must be of type `real`. This function uses `rational` types internally. If the given number is a `float` it is first turned into `rational` by calling `cl:rational`.

Formatting rules are specified with keyword arguments, as described below. The default value is in parentheses.

• `round-magnitude (0)`

This is the order of magnitude used for rounding. The value must be an integer and it is interpreted as a power of 10.

• `show-trailing-zeros (nil)`

If the value is non-nil print all trailing zeros in fractional part. Examples:

``````(format-decimal-number 1/5 :round-magnitude -3
:show-trailing-zeros nil)
=> "0.2"

(format-decimal-number 1/5 :round-magnitude -3
:show-trailing-zeros t)
=> "0.200"
``````
• `rounder (#'round-half-away-from-zero)`

The value must be a function (or a symbol naming a function). It is used to round the number to the specified round magnitude. The function must work like `cl:truncate`, `cl:floor`, `cl:ceiling` and `cl:round`, that is, take two arguments, a number and a divisor, and return the quotient as the first value.

This package introduces another rounding function, `round-half-away-from-zero`, which is used by default. See its documentation for more information.

• `decimal-separator (#\.)`

If the value is non-nil the `princ` output of the value will be added between integer and fractional parts. Probably the most useful types are `character` and `string`.

• `integer-group-separator (nil)`

• `fractional-group-separator (nil)`

If the value is non-nil the digits in integer or fractional parts are put in groups. The `princ` output of the value will be added between digit groups.

• `integer-group-digits (3)`

• `fractional-group-digits (3)`

The value is a positive integer defining the number of digits in groups.

• `integer-minimum-width (0)`

• `fractional-minimum-width (0)`

Format integer or fractional part using minimum of this amount of characters, possibly using some padding characters (see below). positive-sign, negative-sign or zero-sign (see below) is included when calculating the width of the integer part. Similarly decimal-separator is included when calculating the width of the fractional part.

• `integer-pad-char (#\Space)`

• `fractional-pad-char (#\Space)`

The value is the padding character which is used to fill integer-minimum-width or fractional-minimum-width.

• `positive-sign (nil)`

• `negative-sign (#\-)`

• `zero-sign (nil)`

If values are non-nil these are used as the leading sign for positive, negative and zero numbers. The `princ` output of the value is used.

### Function: `parse-decimal-number`

The lambda list:

`````` (string &key (decimal-separator #\.) (positive-sign #\+)
(negative-sign #\-) (start 0) (end nil))
``````

Examine string (or its substring from start to end) for a decimal number. Assume that the decimal number is exact and return it as a rational number.

Rules for parsing: First all leading and trailing `#\Space` characters are stripped. The resulting string may start with a positive-sign or a negative-sign character. The latter causes this function to assume a negative number. The following characters in the string must include one or more digit characters and it may include one decimal-separator character which separates integer and fractional parts. All other characters are illegal.

If the parsing rules are not met a `decimal-parse-error` condition is signaled. Function `decimal-parse-error-string` can be used to read the string from the condition object.

Examples:

``````(parse-decimal-number "0.2")  => 1/5
(parse-decimal-number ".2")   => 1/5
(parse-decimal-number "+3.")  => 3
(parse-decimal-number " -7 ") => -7

(parse-decimal-number "−12,345"
:decimal-separator #\,
:negative-sign #\−)
=> -2469/200
``````

### Function: `round-half-away-from-zero`

The lambda list:

`````` (number &optional (divisor 1))
``````

Divide number by divisor and round the result to the nearest integer. If the result is half-way between two integers round away from zero. Two values are returned: quotient and remainder.

This is similar to `cl:round` function except that `cl:round` rounds to an even integer when number is exactly between two integers. Examples:

``````(round-half-away-from-zero 3/2) => 2, -1/2
(round 3/2)                     => 2, -1/2

(round-half-away-from-zero 5/2) => 3, -1/2
(round 5/2)                     => 2, 1/2
``````

### Macro: `define-decimal-formatter`

The lambda list:

`````` (name &body keyword-arguments)
``````

Define a decimal number formatter function to use with the `~/` directive of `cl:format`. The valid format is this:

``````(define-decimal-formatter name
(:keyword form)
...)
``````

Name is the symbol that names the function. Keyword must be a valid keyword argument for the `format-decimal-number` function (see its documentation for more information). Form is evaluated and the value is used with the keyword argument. Macro's side effect is that global function name is defined. It can be used with the `~/` directive of `cl:format` function.

Examples:

``````(define-decimal-formatter my-formatter
(:round-magnitude -6)
(:decimal-separator ",")
(:integer-group-separator " ")
(:integer-minimum-width 4)
(:fractional-group-separator " ")
(:fractional-minimum-width 10)
(:show-trailing-zeros t))
=> MY-FORMATTER

(format nil "~/my-formatter/" 10/6)
=> "   1,666 667  "

(format nil "~/my-formatter/" 100/8)
=> "  12,500 000  "
``````

The `~/` directive function call can optionally take up to three arguments to override the defaults:

``````~round-magnitude,integer-minimum-width,fractional-minimum-width/FUNCTION/
``````

For example:

``````(format nil "~-2,3,4/my-formatter/" 10/6)
=> "  1
``````

Next: , Previous: , Up: Top   [Contents][Index]

## 2 Systems

The main system appears first, followed by any subsystem dependency.

Previous: , Up: Systems   [Contents][Index]

### 2.1 decimals

Author

Teemu Likonen <tlikonen@iki.fi>

Creative Commons CC0 (public domain dedication)

Description

Decimal number parser and formatter

Source

decimals.asd (file)

Component

decimals.lisp (file)

Next: , Previous: , Up: Top   [Contents][Index]

## 3 Files

Files are sorted by type and then listed depth-first from the systems components trees.

Previous: , Up: Files   [Contents][Index]

### 3.1 Lisp

Next: , Previous: , Up: Lisp files   [Contents][Index]

#### 3.1.1 decimals.asd

Location

decimals.asd

Systems

decimals (system)

Previous: , Up: Lisp files   [Contents][Index]

#### 3.1.2 decimals/decimals.lisp

Parent

decimals (system)

Location

decimals.lisp

Packages
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

## 4 Packages

Packages are listed by definition order.

Previous: , Up: Packages   [Contents][Index]

### 4.1 decimals

Source

decimals.lisp (file)

Use List

common-lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

## 5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.

Next: , Previous: , Up: Definitions   [Contents][Index]

### 5.1 Exported definitions

Next: , Previous: , Up: Exported definitions   [Contents][Index]

#### 5.1.1 Macros

Macro: define-decimal-formatter NAME &body KEYWORD-ARGUMENTS

Define a decimal number formatter function to use with the ‘~/‘
directive of ‘cl:format‘. The valid format is this:

(define-decimal-formatter name
(:keyword form)
...)

_Name_ is the symbol that names the function. _Keyword_ must be a valid keyword argument for the ‘format-decimal-number‘ function (see its documentation for more information). _Form_ is evaluated and the value
is used with the _keyword_ argument. Macro’s side effect is that global function _name_ is defined. It can be used with the ‘~/‘ directive of ‘cl:format‘ function.

Examples:

(define-decimal-formatter my-formatter
(:round-magnitude -6)
(:decimal-separator ",")
(:integer-group-separator " ")
(:integer-minimum-width 4)
(:fractional-group-separator " ")
(:fractional-minimum-width 10)
(:show-trailing-zeros t))
=> MY-FORMATTER

(format nil "~/my-formatter/" 10/6)
=> " 1,666 667 "

(format nil "~/my-formatter/" 100/8)
=> " 12,500 000 "

The ‘~/‘ directive function call can optionally take up to three arguments to override the defaults:

~round-magnitude,integer-minimum-width,fractional-minimum-width/FUNCTION/

For example:

(format nil "~-2,3,4/my-formatter/" 10/6)
=> " 1,67 "

Package
Source

decimals.lisp (file)

Next: , Previous: , Up: Exported definitions   [Contents][Index]

#### 5.1.2 Functions

Function: format-decimal-number NUMBER &key ROUND-MAGNITUDE ROUNDER DECIMAL-SEPARATOR INTEGER-GROUP-SEPARATOR INTEGER-GROUP-DIGITS INTEGER-MINIMUM-WIDTH INTEGER-PAD-CHAR FRACTIONAL-GROUP-SEPARATOR FRACTIONAL-GROUP-DIGITS FRACTIONAL-MINIMUM-WIDTH FRACTIONAL-PAD-CHAR SHOW-TRAILING-ZEROS POSITIVE-SIGN NEGATIVE-SIGN ZERO-SIGN

Apply specified decimal number formatting rules to _number_ and return a formatted string.

The second return value is (almost) the same formatted string divided into four strings. It’s a list of four strings: sign, integer part, decimal separator and fractional part. Formatting arguments _integer-minimum-width_ and _fractional-minimum-width_ do not apply to the second return value. Everything else does.

_Number_ must be of type ‘real‘. This function uses ‘rational‘ types internally. If the given _number_ is a ‘float‘ it is first turned into ‘rational‘ by calling ‘cl:rational‘.

Formatting rules are specified with keyword arguments, as described below. The default value is in parentheses.

* ‘round-magnitude (0)‘

This is the order of magnitude used for rounding. The value must be an integer and it is interpreted as a power of 10.

* ‘show-trailing-zeros (nil)‘

If the value is non-nil print all trailing zeros in fractional part. Examples:

(format-decimal-number 1/5 :round-magnitude -3 :show-trailing-zeros nil)
=> "0.2"

(format-decimal-number 1/5 :round-magnitude -3 :show-trailing-zeros t)
=> "0.200"

* ‘rounder (#’round-half-away-from-zero)‘

The value must be a function (or a symbol naming a function). It is used to round the number to the specified round magnitude. The function must work like ‘cl:truncate‘, ‘cl:floor‘, ‘cl:ceiling‘ and ‘cl:round‘, that is, take two arguments, a number and a divisor, and return the quotient as the first value.

This package introduces another rounding function, ‘round-half-away-from-zero‘, which is used by default. See its documentation for more information.

* ‘decimal-separator (#\.)‘

If the value is non-nil the ‘princ‘ output of the value will be added between integer and fractional parts. Probably the most useful types are ‘character‘ and ‘string‘.

* ‘integer-group-separator (nil)‘
* ‘fractional-group-separator (nil)‘

If the value is non-nil the digits in integer or fractional parts are put in groups. The ‘princ‘ output of the value will be added between digit groups.

* ‘integer-group-digits (3)‘
* ‘fractional-group-digits (3)‘

The value is a positive integer defining the number of digits in groups.

* ‘integer-minimum-width (0)‘
* ‘fractional-minimum-width (0)‘

Format integer or fractional part using minimum of this amount of characters, possibly using some padding characters (see below). _positive-sign_, _negative-sign_ or _zero-sign_ (see below) is included when calculating the width of the integer part. Similarly _decimal-separator_ is included when calculating the width of the fractional part.

The value is the padding character which is used to fill _integer-minimum-width_ or _fractional-minimum-width_.

* ‘positive-sign (nil)‘
* ‘negative-sign (#\-)‘
* ‘zero-sign (nil)‘

If values are non-nil these are used as the leading sign for positive, negative and zero numbers. The ‘princ‘ output of the value is used.

Package
Source

decimals.lisp (file)

Function: parse-decimal-number STRING &key DECIMAL-SEPARATOR POSITIVE-SIGN NEGATIVE-SIGN START END

Examine _string_ (or its substring from _start_ to _end_) for a decimal number. Assume that the decimal number is exact and return it as a rational number.

Rules for parsing: First all leading and trailing ‘#\Space‘ characters are stripped. The resulting string may start with a _positive-sign_ or a _negative-sign_ character. The latter causes this function to assume a negative number. The following characters in the string must include one or more digit characters and it may include one _decimal-separator_ character which separates integer and fractional parts. All other characters are illegal.

If the parsing rules are not met a ‘decimal-parse-error‘ condition is signaled. Function ‘decimal-parse-error-string‘ can be used to read the string from the condition object.

Examples:

(parse-decimal-number "0.2") => 1/5
(parse-decimal-number ".2") => 1/5
(parse-decimal-number "+3.") => 3
(parse-decimal-number " -7 ") => -7

(parse-decimal-number "−12,345"
:decimal-separator #\,
:negative-sign #\−)
=> -2469/200

Package
Source

decimals.lisp (file)

Function: round-half-away-from-zero NUMBER &optional DIVISOR

Divide _number_ by _divisor_ and round the result to the nearest integer. If the result is half-way between two integers round away from zero. Two values are returned: quotient and remainder.

This is similar to ‘cl:round‘ function except that ‘cl:round‘ rounds to an even integer when number is exactly between two integers. Examples:

(round-half-away-from-zero 3/2) => 2, -1/2
(round 3/2) => 2, -1/2

(round-half-away-from-zero 5/2) => 3, -1/2
(round 5/2) => 2, 1/2

Package
Source

decimals.lisp (file)

Next: , Previous: , Up: Exported definitions   [Contents][Index]

#### 5.1.3 Generic functions

Generic Function: decimal-parse-error-string CONDITION
Package
Methods
Method: decimal-parse-error-string (CONDITION decimal-parse-error)
Source

decimals.lisp (file)

Previous: , Up: Exported definitions   [Contents][Index]

#### 5.1.4 Conditions

Condition: decimal-parse-error ()

Function ‘parse-decimal-number‘ signals this condition when it couldn’t parse a decimal number from string. Function ‘decimal-parse-error-string‘ can be used to read the input string from the condition object.

Package
Source

decimals.lisp (file)

Direct superclasses

parse-error (condition)

Direct methods

decimal-parse-error-string (method)

Direct slots
Slot: string
Initargs

:string

decimal-parse-error-string (generic function)

Previous: , Up: Definitions   [Contents][Index]

### 5.2 Internal definitions

Previous: , Up: Internal definitions   [Contents][Index]

#### 5.2.1 Functions

Function: decimal-round-split NUMBER &key ROUND-MAGNITUDE ROUNDER POSITIVE-SIGN NEGATIVE-SIGN ZERO-SIGN
Package
Source

decimals.lisp (file)

Function: divide-into-groups STRING &key SEPARATOR FROM-END GROUP-DIGITS
Package
Source

decimals.lisp (file)

Function: number-string-to-fractional STRING
Package
Source

decimals.lisp (file)

Function: number-string-to-integer STRING
Package
Source

decimals.lisp (file)

Function: string-align STRING WIDTH &key SIDE CHAR
Package
Source

decimals.lisp (file)

Previous: , Up: Top   [Contents][Index]

## Appendix A Indexes

Next: , Previous: , Up: Indexes   [Contents][Index]

### A.1 Concepts

Next: , Previous: , Up: Indexes   [Contents][Index]

### A.2 Functions

Next: , Previous: , Up: Indexes   [Contents][Index]

### A.3 Variables

Index Entry Section `Slot, string`: Exported conditions `string`: Exported conditions