Search
ctrl/
Ask AI
Light
Dark
System

Numerical Types, Functions, and Operators

int16

16-bit integer

int32

32-bit integer

int64

64-bit integer

float32

32-bit floating point number

float64

64-bit floating point number

bigint

Arbitrary precision integer.

decimal

Arbitrary precision number.

anyreal + anyreal

Arithmetic addition.

anyreal - anyreal

Arithmetic subtraction.

-anyreal

Arithmetic negation.

anyreal * anyreal

Arithmetic multiplication.

anyreal / anyreal

Arithmetic division.

anyreal // anyreal

Floor division.

anyreal % anyreal

Remainder from division (modulo).

anyreal ^ anyreal

Power operation.

= != ?= ?!= < > <= >=

Comparison operators

sum()

Returns the sum of the set of numbers.

min()

Returns the smallest value in the given set.

max()

Returns the largest value in the given set.

round()

Rounds a given number to the nearest value.

random()

Returns a pseudo-random number in the range of 0.0 <= x < 1.0.

math::abs()

Returns the absolute value of the input.

math::ceil()

Rounds up a given value to the nearest integer.

math::floor()

Rounds down a given value to the nearest integer.

math::ln()

Returns the natural logarithm of a given value.

math::lg()

Returns the base 10 logarithm of a given value.

math::log()

Returns the logarithm of a given value in the specified base.

math::mean()

Returns the arithmetic mean of the input set.

math::stddev()

Returns the sample standard deviation of the input set.

math::stddev_pop()

Returns the population standard deviation of the input set.

math::var()

Returns the sample variance of the input set.

math::var_pop()

Returns the population variance of the input set.

bit_and()

Bitwise AND operator for 2 intergers.

bit_or()

Bitwise OR operator for 2 intergers.

bit_xor()

Bitwise exclusive OR operator for 2 intergers.

bit_not()

Bitwise negation operator for 2 intergers.

bit_lshift()

Bitwise left-shift operator for intergers.

bit_rshift()

Bitwise arithemtic right-shift operator for intergers.

bit_count()

Return the number of bits set in the bytes value.

to_bigint()

Returns a bigint value parsed from the given string.

to_decimal()

Returns a decimal value parsed from the given string.

to_int16()

Returns an int16 value parsed from the given input.

to_int32()

Returns an int32 value parsed from the given input.

to_int64()

Returns an int64 value parsed from the given input.

to_float32()

Returns a float32 value parsed from the given string.

to_float64()

Returns a float64 value parsed from the given string.

It’s possible to explicitly cast between all numeric types. All numeric types can also be cast to and from str and json.

type

int16
int16

A 16-bit signed integer.

int16 is capable of representing values from -32768 to +32767 (inclusive).

type

int32
int32

A 32-bit signed integer.

int32 is capable of representing values from -2147483648 to +2147483647 (inclusive).

type

int64
int64

A 64-bit signed integer.

int64 is capable of representing values from -9223372036854775808 to +9223372036854775807 (inclusive).

type

float32
float32

A variable precision, inexact number.

The minimal guaranteed precision is at least 6 decimal digits. The approximate range of a float32 spans from -3.4e+38 to +3.4e+38.

type

float64
float64

A variable precision, inexact number.

The minimal guaranteed precision is at least 15 decimal digits. The approximate range of a float64 spans from -1.7e+308 to +1.7e+308.

type

bigint
bigint

An arbitrary precision integer.

Our philosophy is that use of bigint should always be an explicit opt-in and should never be implicit. Once used, these values should not be accidentally cast to a different numerical type that could lead to a loss of precision.

In keeping with this philosophy, our mathematical functions are designed to maintain separation between big integer values and the rest of our numeric types.

All of the following types can be explicitly cast into a bigint type:

A bigint literal is an integer literal, followed by ‘n’:

Copy
db> 
select 42n is bigint;
{true}

To represent really big integers, it is possible to use the exponent notation (e.g. 1e20n instead of 100000000000000000000n) as long as the exponent is positive and there is no dot anywhere:

Copy
db> 
select 1e+100n is bigint;
{true}

When a float literal is followed by n it will produce a decimal value instead:

Copy
db> 
select 1.23n is decimal;
{true}
Copy
db> 
select 1.0e+100n is decimal;
{true}

Use caution when casting bigint values into json. The JSON specification does not have a limit on significant digits, so a bigint number can be losslessly represented in JSON. However, JSON decoders in many languages will read all such numbers as some kind of 32-bit or 64-bit number type, which may result in errors or precision loss. If such loss is unacceptable, then consider casting the value into str and decoding it on the client side into a more appropriate type.

type

decimal
decimal

Any number of arbitrary precision.

Our philosophy is that use of decimal should always be an explicit opt-in and should never be implicit. Once used, these values should not be accidentally cast to a different numerical type that could lead to a loss of precision.

In keeping with this philosophy, our mathematical functions are designed to maintain separation between decimal values and the rest of our numeric types.

All of the following types can be explicitly cast into decimal:

A decimal literal is a float literal, followed by n:

The EdgeDB philosophy is that using a decimal type should be an explicit opt-in, but once used, the values should not be accidentally cast into a numeric type with less precision.

In accordance with this the mathematical functions are designed to keep the separation between decimal values and the rest of the numeric types.

All of the following types can be explicitly cast into decimal: str, json, int16, int32, int64, float32, float64, and bigint.

A decimal literal is a float literal followed by ‘n’:

Copy
db> 
select 1.23n is decimal;
{true}
Copy
db> 
select 1.0e+100n is decimal;
{true}

Note that an integer literal (without a dot or exponent) followed by n produces a bigint value. A literal without a dot and with a positive exponent makes a bigint, too:

Copy
db> 
select 42n is bigint;
{true}
Copy
db> 
select 12e+34n is bigint;
{true}

Use caution when casting decimal values into json. The JSON specification does not have a limit on significant digits, so a decimal number can be losslessly represented in JSON. However, JSON decoders in many languages will read all such numbers as some kind of floating point values, which may result in precision loss. If such loss is unacceptable, then consider casting the value into a str and decoding it on the client side into a more appropriate type.

operator

anyreal + anyreal
anyreal + anyreal -> anyreal

Arithmetic addition.

Copy
db> 
select 2 + 2;
{4}

operator

anyreal - anyreal
anyreal - anyreal -> anyreal

Arithmetic subtraction.

Copy
db> 
select 3 - 2;
{1}

operator

-anyreal
- anyreal -> anyreal

Arithmetic negation.

Copy
db> 
select -5;
{-5}

operator

anyreal * anyreal
anyreal * anyreal -> anyreal

Arithmetic multiplication.

Copy
db> 
select 2 * 10;
{20}

operator

anyreal / anyreal
anyreal / anyreal -> anyreal

Arithmetic division.

Copy
db> 
select 10 / 4;
{2.5}

Division by zero will result in an error:

Copy
db> 
select 10 / 0;
DivisionByZeroError: division by zero

operator

anyreal // anyreal
anyreal // anyreal -> anyreal

Floor division.

In floor-based division, the result of a standard division operation is rounded down to its nearest integer. It is the equivalent to using regular division and then applying math::floor() to the result.

Copy
db> 
select 10 // 4;
{2}
Copy
db> 
select math::floor(10 / 4);
{2}
Copy
db> 
select -10 // 4;
{-3}

It also works on float, bigint, and decimal types. The type of the result corresponds to the type of the operands:

Copy
db> 
select 3.7 // 1.1;
{3.0}
Copy
db> 
select 3.7n // 1.1n;
{3.0n}
Copy
db> 
select 37 // 11;
{3}

Regular division, floor division, and % operations are related in the following way: A // B = (A - (A % B)) / B.

operator

anyreal % anyreal
anyreal % anyreal -> anyreal

Remainder from division (modulo).

This is commonly referred to as a “modulo” operation.

This is the remainder from floor division. Just as is the case with // the result type of the remainder operator corresponds to the operand type:

Copy
db> 
select 10 % 4;
{2}
Copy
db> 
select 10n % 4;
{2n}
Copy
db> 
select -10 % 4;
{2}
Copy
db> 
... 
... 
# floating arithmetic is inexact, so
# we get 0.3999999999999999 instead of 0.4
select 3.7 % 1.1;
{0.3999999999999999}
Copy
db> 
select 3.7n % 1.1n;
{0.4n}
Copy
db> 
select 37 % 11;
{4}

Regular division, // and % operations are related in the following way: A // B = (A - (A % B)) / B.

Modulo division by zero will result in an error:

Copy
db> 
select 10 % 0;
DivisionByZeroError: division by zero

operator

anyreal ^ anyreal
anyreal ^ anyreal -> anyreal

Power operation.

Copy
db> 
select 2 ^ 4;
{16}

function

round()
std::round(value: int64) -> float64std::round(value: float64) -> float64std::round(value: bigint) -> bigintstd::round(value: decimal) -> decimalstd::round(value: decimal, d: int64) -> decimal

Rounds a given number to the nearest value.

The function will round a .5 value differently depending on the type of the parameter passed.

The float64 tie is rounded to the nearest even number:

Copy
db> 
select round(1.2);
{1}
Copy
db> 
select round(1.5);
{2}
Copy
db> 
select round(2.5);
{2}

But the decimal tie is rounded away from zero:

Copy
db> 
select round(1.2n);
{1n}
Copy
db> 
select round(1.5n);
{2n}
Copy
db> 
select round(2.5n);
{3n}

Additionally, when rounding a decimal value, you may pass the optional argument d to specify the precision of the rounded result:

Copy
db> 
select round(163.278n, 2);
{163.28n}
Copy
db> 
select round(163.278n, 1);
{163.3n}
Copy
db> 
select round(163.278n, 0);
{163n}
Copy
db> 
select round(163.278n, -1);
{160n}
Copy
db> 
select round(163.278n, -2);
{200n}

function

random()
std::random() -> float64

Returns a pseudo-random number in the range of 0.0 <= x < 1.0.

Copy
db> 
select random();
{0.62649393780157}

function

bit_and()
std::bit_and(l: int16, r: int16) -> int16std::bit_and(l: int32, r: int32) -> int32std::bit_and(l: int64, r: int64) -> int64

Bitwise AND operator for 2 intergers.

Copy
db> 
select bit_and(17, 3);
{1}

function

bit_or()
std::bit_or(l: int16, r: int16) -> int16std::bit_or(l: int32, r: int32) -> int32std::bit_or(l: int64, r: int64) -> int64

Bitwise OR operator for 2 intergers.

Copy
db> 
select bit_or(17, 3);
{19}

function

bit_xor()
std::bit_xor(l: int16, r: int16) -> int16std::bit_xor(l: int32, r: int32) -> int32std::bit_xor(l: int64, r: int64) -> int64

Bitwise exclusive OR operator for 2 intergers.

Copy
db> 
select bit_xor(17, 3);
{18}

function

bit_not()
std::bit_not(r: int16) -> int16std::bit_not(r: int32) -> int32std::bit_not(r: int64) -> int64

Bitwise negation operator for 2 intergers.

Bitwise negation for integers ends up similar to mathematical negation because typically the signed integers use “two’s complement” representation. In this represenation mathematical negation is achieved by aplying bitwise negation and adding 1.

Copy
db> 
select bit_not(17);
{-18}
Copy
db> 
select -17 = bit_not(17) + 1;
{true}

function

bit_lshift()
std::bit_lshift(val: int16, n: int64) -> int16std::bit_lshift(val: int32, n: int64) -> int32std::bit_lshift(val: int64, n: int64) -> int64

Bitwise left-shift operator for intergers.

The integer val is shifted by n bits to the left. The rightmost added bits are all 0. Shifting an integer by a number of bits greater than the bit size of the integer results in 0.

Copy
db> 
select bit_lshift(123, 2);
{492}
Copy
db> 
select bit_lshift(123, 65);
{0}

Left-shifting an integer can change the sign bit:

Copy
db> 
select bit_lshift(123, 60);
{-5764607523034234880}

In general, left-shifting an integer in small increments produces the same result as shifting it in one step:

Copy
db> 
select bit_lshift(bit_lshift(123, 1), 3);
{1968}
Copy
db> 
select bit_lshift(123, 4);
{1968}

It is an error to attempt to shift by a negative number of bits:

Copy
db> 
select bit_lshift(123, -2);
edgedb error: InvalidValueError: bit_lshift(): cannot shift by
negative amount

function

bit_rshift()
std::bit_rshift(val: int16, n: int64) -> int16std::bit_rshift(val: int32, n: int64) -> int32std::bit_rshift(val: int64, n: int64) -> int64

Bitwise arithemtic right-shift operator for intergers.

The integer val is shifted by n bits to the right. In the arithmetic right-shift, the sign is preserved. This means that the leftmost added bits are 1 or 0 depending on the sign bit. Shifting an integer by a number of bits greater than the bit size of the integer results in 0 for positive numbers or -1 for negative numbers.

Copy
db> 
select bit_rshift(123, 2);
{30}
Copy
db> 
select bit_rshift(123, 65);
{0}
Copy
db> 
select bit_rshift(-123, 2);
{-31}
Copy
db> 
select bit_rshift(-123, 65);
{-1}

In general, right-shifting an integer in small increments produces the same result as shifting it in one step:

Copy
db> 
select bit_rshift(bit_rshift(123, 1), 3);
{7}
Copy
db> 
select bit_rshift(123, 4);
{7}
Copy
db> 
select bit_rshift(bit_rshift(-123, 1), 3);
{-8}
Copy
db> 
select bit_rshift(-123, 4);
{-8}

It is an error to attempt to shift by a negative number of bits:

Copy
db> 
select bit_rshift(123, -2);
edgedb error: InvalidValueError: bit_rshift(): cannot shift by
negative amount

function

bit_count()
std::bit_count(val: int16) -> int64std::bit_count(val: int32) -> int64std::bit_count(val: int64) -> int64std::bit_count(bytes: bytes) -> int64

Return the number of bits set in the bytes value.

This is also known as the population count.

Copy
db> 
select bit_count(255);
{8}
Copy
db> 
select bit_count(b'\xff\xff');
{16}

function

to_bigint()
std::to_bigint(s: str, fmt: optional str={}) -> bigint

Returns a bigint value parsed from the given string.

The function will use an optional format string passed as fmt. See the number formatting options for help writing a format string.

Copy
db> 
select to_bigint('-000,012,345', 'S099,999,999,999');
{-12345n}
Copy
db> 
select to_bigint('31st', '999th');
{31n}

function

to_decimal()
std::to_decimal(s: str, fmt: optional str={}) -> decimal

Returns a decimal value parsed from the given string.

The function will use an optional format string passed as fmt. See the number formatting options for help writing a format string.

Copy
db> 
select to_decimal('-000,012,345', 'S099,999,999,999');
{-12345.0n}
Copy
db> 
select to_decimal('-012.345');
{-12.345n}
Copy
db> 
select to_decimal('31st', '999th');
{31.0n}

function

to_int16()
std::to_int16(s: str, fmt: optional str={}) -> int16std::to_int16(val: bytes, endian: Endian) -> int16

Returns an int16 value parsed from the given input.

The string parsing function will use an optional format string passed as fmt. See the number formatting options for help writing a format string.

Copy
db> 
select to_int16('23');
{23}
Copy
db> 
select to_int16('23%', '99%');
{23}

The bytes conversion function expects exactly 2 bytes with specified endianness.

Copy
db> 
select to_int16(b'\x00\x07', Endian.Big);
{7}
Copy
db> 
select to_int16(b'\x07\x00', Endian.Little);
{7}

Due to underlying implementation details using big-endian encoding results in slightly faster performance of to_int16.

function

to_int32()
std::to_int32(s: str, fmt: optional str={}) -> int32std::to_int32(val: bytes, endian: Endian) -> int32

Returns an int32 value parsed from the given input.

The string parsin function will use an optional format string passed as fmt. See the number formatting options for help writing a format string.

Copy
db> 
select to_int32('1000023');
{1000023}
Copy
db> 
select to_int32('1000023%', '9999999%');
{1000023}

The bytes conversion function expects exactly 4 bytes with specified endianness.

Copy
db> 
select to_int32(b'\x01\x02\x00\x07', Endian.Big);
{16908295}
Copy
db> 
select to_int32(b'\x07\x00\x02\x01', Endian.Little);
{16908295}

Due to underlying implementation details using big-endian encoding results in slightly faster performance of to_int32.

function

to_int64()
std::to_int64(s: str, fmt: optional str={}) -> int64std::to_int64(val: bytes, endian: Endian) -> int64

Returns an int64 value parsed from the given input.

The string parsing function will use an optional format string passed as fmt. See the number formatting options for help writing a format string.

Copy
db> 
select to_int64('10000234567');
{10000234567}
Copy
db> 
select to_int64('10000234567%', '99999999999%');
{10000234567}

The bytes conversion function expects exactly 8 bytes with specified endianness.

Copy
db> 
... 
select to_int64(b'\x01\x02\x00\x07\x11\x22\x33\x44',
                Endian.Big);
{72620574343574340}
Copy
db> 
... 
select to_int64(b'\x44\x33\x22\x11\x07\x00\x02\x01',
                Endian.Little);
{72620574343574340}

Due to underlying implementation details using big-endian encoding results in slightly faster performance of to_int64.

function

to_float32()
std::to_float32(s: str, fmt: optional str={}) -> float32

Returns a float32 value parsed from the given string.

The function will use an optional format string passed as fmt. See the number formatting options for help writing a format string.

function

to_float64()
std::to_float64(s: str, fmt: optional str={}) -> float64

Returns a float64 value parsed from the given string.

The function will use an optional format string passed as fmt. See the number formatting options for help writing a format string.