CARVIEW |
Extended Numbers
This document registers tags for serializing extended numbers in Concise Binary Object Representation (CBOR), which is specified in RFC 7049 at the time of this writing.
- Tag: 268
- Data item: array
- Semantics: Extended decimal fraction
- Tag: 269
- Data item: array
- Semantics: Extended bigfloat
- Tag: 270
- Data item: array
- Semantics: Extended rational number
Introduction
This document introduces new CBOR tags that extend the expressiveness of decimal fractions, bigfloats, and rational numbers by allowing them to express negative zero, infinities, and NaN values of various kinds. For example, decimal fractions given here are as expressive as numbers specified in the General Decimal Arithmetic Specification version 1.70.
Detailed Semantics
An item with tag 268 is an array of three items in the following order: exponent, mantissa, and options. The exponent and mantissa have the same semantics given in section 2.4.3 of RFC 7049 (or a successor to that section) for decimal fractions, except the exponent can also be a bignum (major type 6, tag 2 or 3) and the mantissa may not be negative.
An item with tag 269 is an array of three items in the following order: exponent, mantissa, and options. The exponent and mantissa have the same semantics given in section 2.4.3 of RFC 7049 (or a successor to that section) for bigfloats, except the exponent can also be a bignum (major type 6, tag 2 or 3) and the mantissa may not be negative.
An item with tag 270 is an array of three items in the following order: numerator, denominator, and options. The numerator and denominator have the same semantics given in the CBOR tag 30 specification for rational numbers, except the numerator may not be negative.
For all three tags, the third item (options) is an integer (major type 0) with one of the following values: 0 = finite nonnegative; 1 = finite negative; 2 = positive infinity; 3 = negative infinity; 4 = quiet NaN nonnegative; 5 = quiet NaN negative; 6 = signaling NaN nonnegative; 7 = signaling NaN negative.
For tags 268 and 269: If the third item indicates infinity, the first item (exponent) and the second item (mantissa) have to be 0. If the third item indicates NaN, the first item (exponent) has to be 0 and the second item expresses diagnostic information rather than a mantissa (but is still limited to the same data types as the mantissa).
For tag 270: If the third item indicates infinity, the first item (numerator) has to be 0 and the second item (denominator) has to be 1. If the third item indicates NaN, the second item (denominator) has to be 1 and the first item expresses diagnostic information rather than a numerator (but is still limited to the same data types as the numerator).
A CBOR decoder can treat data items with tags 268, 269, or 270 that don't meet the criteria above as an error, but this specification doesn't define how a CBOR implementation ought to behave in this case. Section 3.4 of RFC 7049 details this kind of error-handling behavior. The semantics of positive and negative zero, infinity, and quiet and signaling NaN are not further specified here.
Security Considerations
Decimal fractions and bigfloats allow encoding numbers with exponents that are extremely large (tens of thousands or more) or extremely small (negative tens of thousands or less), so large to be unreasonable for most applications.
There are several security concerns with such numbers:
- A decimal fraction or bigfloat with an extremely large exponent resolves to an arbitrary-precision integer with at least as many decimal digits or bits, respectively, and thus often requires as much memory to store. If such a number is converted to an arbitrary-precision integer (such as `BigInteger` in Java, or CBOR's bignum tags), the decoder or application might need to allocate much more memory than usual. Generally, for extremely large exponents, a decimal fraction with a positive exponent requires at least about 3/10 the value of the exponent in bytes of memory to store, so that, for example, the decimal fraction 75e+9000000 requires about 3 megabytes of storage to an arbitrary-precision integer. A similar concern is present when the decimal fraction or bigfloat is converted to a rational number. Applications or protocols that support decimal fractions and/or bigfloats might wish to—
- limit the supported range of exponents,
- treat numbers with extremely large exponents as infinity or raise an overflow error on such numbers,
- treat numbers with extremely small exponents as zero or raise an underflow error on such numbers, and/or
- raise a subnormal warning on numbers with exponents close to the minimum supported exponent.
- Operations on decimal fractions and/or bigfloats (such as addition and division) can cause unreasonable memory allocation when a number with a small exponent and a number with an extremely large or extremely small exponent are involved. For example, adding the two numbers 75e+9000000 and 125 results in the exact value of 750000...000125, a number with a mantissa of 750000...000125 and an exponent of 0, thus requiring at least 3 megabytes of storage. To mitigate this problem, applications or protocols that support decimal fractions and/or bigfloats might wish to limit the range of precisions (number of decimal digits or bits) the mantissa can have, and round numbers, if necessary, to fit the precision limits.
Author
Peter Occil (poccil14 at gmail dot com)
My CBOR home page.
Any copyright to this specification is released to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/