2019-06-27 01:03:04 +08:00
|
|
|
#RUN: %fish %s
|
2021-06-25 02:07:54 +08:00
|
|
|
# OpenBSD doesn't do hex numbers in str/wcstod (like C99 requires).
|
|
|
|
# So let's skip this.
|
|
|
|
#REQUIRES: test "$(uname)" != OpenBSD
|
2019-06-27 01:03:04 +08:00
|
|
|
# Validate basic expressions
|
|
|
|
math 3 / 2
|
|
|
|
# CHECK: 1.5
|
|
|
|
math 10/6
|
|
|
|
# CHECK: 1.666667
|
|
|
|
math -s0 10 / 6
|
|
|
|
# CHECK: 1
|
|
|
|
math 'floor(10 / 6)'
|
|
|
|
# CHECK: 1
|
|
|
|
math -s3 10/6
|
|
|
|
# CHECK: 1.667
|
|
|
|
math '10 % 6'
|
|
|
|
# CHECK: 4
|
|
|
|
math -s0 '10 % 6'
|
|
|
|
# CHECK: 4
|
|
|
|
math '23 % 7'
|
|
|
|
# CHECK: 2
|
|
|
|
math --scale=6 '5 / 3 * 0.3'
|
|
|
|
# CHECK: 0.5
|
|
|
|
math --scale=max '5 / 3'
|
|
|
|
# CHECK: 1.666666666666667
|
|
|
|
math "7^2"
|
|
|
|
# CHECK: 49
|
|
|
|
math -1 + 1
|
|
|
|
# CHECK: 0
|
|
|
|
math '-2 * -2'
|
|
|
|
# CHECK: 4
|
|
|
|
math 5 \* -2
|
|
|
|
# CHECK: -10
|
|
|
|
math -- -4 / 2
|
|
|
|
# CHECK: -2
|
|
|
|
math -- '-4 * 2'
|
|
|
|
# CHECK: -8
|
|
|
|
|
2021-03-28 23:58:41 +08:00
|
|
|
# Validate max and min
|
|
|
|
math 'max(1,2)'
|
|
|
|
math 'min(1,2)'
|
|
|
|
# CHECK: 2
|
|
|
|
# CHECK: 1
|
|
|
|
|
2019-06-27 01:03:04 +08:00
|
|
|
# Validate some rounding functions
|
2020-01-14 03:34:22 +08:00
|
|
|
math 'round(3/2)'
|
|
|
|
math 'floor(3/2)'
|
|
|
|
math 'ceil(3/2)'
|
2019-06-27 01:03:04 +08:00
|
|
|
# CHECK: 2
|
|
|
|
# CHECK: 1
|
|
|
|
# CHECK: 2
|
2020-01-14 03:34:22 +08:00
|
|
|
math 'round(-3/2)'
|
|
|
|
math 'floor(-3/2)'
|
|
|
|
math 'ceil(-3/2)'
|
2019-06-27 01:03:04 +08:00
|
|
|
# CHECK: -2
|
|
|
|
# CHECK: -2
|
|
|
|
# CHECK: -1
|
|
|
|
|
|
|
|
# Validate some integral computations
|
|
|
|
math 1
|
|
|
|
math 10
|
|
|
|
math 100
|
|
|
|
math 1000
|
|
|
|
# CHECK: 1
|
|
|
|
# CHECK: 10
|
|
|
|
# CHECK: 100
|
|
|
|
# CHECK: 1000
|
|
|
|
math '10^15'
|
|
|
|
math '-10^14'
|
|
|
|
math '-10^15'
|
|
|
|
# CHECK: 1000000000000000
|
|
|
|
# CHECK: 100000000000000
|
|
|
|
# CHECK: -1000000000000000
|
|
|
|
|
2019-11-09 13:54:33 +08:00
|
|
|
math 3^0.5^2
|
|
|
|
math -2^2
|
|
|
|
# CHECK: 1.316074
|
|
|
|
# CHECK: 4
|
|
|
|
|
2019-06-27 01:03:04 +08:00
|
|
|
math -s0 '1.0 / 2.0'
|
|
|
|
math -s0 '3.0 / 2.0'
|
|
|
|
math -s0 '10^15 / 2.0'
|
|
|
|
# CHECK: 0
|
|
|
|
# CHECK: 1
|
|
|
|
# CHECK: 500000000000000
|
|
|
|
|
|
|
|
# Validate how variables in an expression are handled
|
|
|
|
math $x + 1
|
|
|
|
set x 1
|
|
|
|
math $x + 1
|
|
|
|
set x 3
|
|
|
|
set y 1.5
|
|
|
|
math "-$x * $y"
|
|
|
|
math -s0 "-$x * $y"
|
|
|
|
# CHECK: 1
|
|
|
|
# CHECK: 2
|
|
|
|
# CHECK: -4.5
|
|
|
|
# CHECK: -4
|
|
|
|
|
|
|
|
# Validate math error reporting
|
|
|
|
# NOTE: The leading whitespace for the carets here is ignored
|
|
|
|
# by littlecheck.
|
|
|
|
not math '2 - '
|
|
|
|
# CHECKERR: math: Error: Too few arguments
|
|
|
|
# CHECKERR: '2 - '
|
|
|
|
# CHECKERR: ^
|
|
|
|
not math 'ncr(1)'
|
|
|
|
# CHECKERR: math: Error: Too few arguments
|
|
|
|
# CHECKERR: 'ncr(1)'
|
|
|
|
# CHECKERR: ^
|
2020-11-26 19:35:56 +08:00
|
|
|
|
2022-09-09 02:45:20 +08:00
|
|
|
math "min()"
|
|
|
|
# CHECKERR: math: Error: Too few arguments
|
|
|
|
# CHECKERR: 'min()'
|
|
|
|
# CHECKERR: ^
|
|
|
|
|
2021-03-28 23:58:41 +08:00
|
|
|
# There is no "blah" function.
|
|
|
|
not math 'blah()'
|
2020-11-26 19:35:56 +08:00
|
|
|
# CHECKERR: math: Error: Unknown function
|
2021-03-28 23:58:41 +08:00
|
|
|
# CHECKERR: 'blah()'
|
2022-09-08 23:54:45 +08:00
|
|
|
# CHECKERR: ^~~^
|
2020-11-26 19:35:56 +08:00
|
|
|
|
|
|
|
math n + 4
|
|
|
|
# CHECKERR: math: Error: Unknown function
|
|
|
|
# CHECKERR: 'n + 4'
|
|
|
|
# CHECKERR: ^
|
|
|
|
|
|
|
|
|
2019-06-27 01:03:04 +08:00
|
|
|
not math 'sin()'
|
|
|
|
# CHECKERR: math: Error: Too few arguments
|
|
|
|
# CHECKERR: 'sin()'
|
|
|
|
# CHECKERR: ^
|
|
|
|
not math '2 + 2 4'
|
2021-12-01 23:55:19 +08:00
|
|
|
# CHECKERR: math: Error: Missing operator
|
2019-06-27 01:03:04 +08:00
|
|
|
# CHECKERR: '2 + 2 4'
|
2021-12-30 20:26:44 +08:00
|
|
|
# This regex to check whitespace - the error appears between the second 2 and the 4!
|
|
|
|
# (right after the 2)
|
|
|
|
# CHECKERR: {{^}} ^
|
2022-09-09 00:45:41 +08:00
|
|
|
printf '<%s>\n' (math '2 + 2 4' 2>&1)
|
|
|
|
# CHECK: <math: Error: Missing operator>
|
|
|
|
# CHECK: <'2 + 2 4'>
|
|
|
|
# CHECK: < ^~~~~^>
|
|
|
|
|
2021-12-01 20:38:42 +08:00
|
|
|
not math '(1 2)'
|
2021-12-01 23:55:19 +08:00
|
|
|
# CHECKERR: math: Error: Missing operator
|
2021-12-01 20:38:42 +08:00
|
|
|
# CHECKERR: '(1 2)'
|
2021-12-01 23:55:19 +08:00
|
|
|
# CHECKERR: ^
|
2021-12-01 20:38:42 +08:00
|
|
|
not math '(1 pi)'
|
2021-12-01 23:55:19 +08:00
|
|
|
# CHECKERR: math: Error: Missing operator
|
2021-12-01 20:38:42 +08:00
|
|
|
# CHECKERR: '(1 pi)'
|
2021-12-01 23:55:19 +08:00
|
|
|
# CHECKERR: ^
|
2021-12-01 20:38:42 +08:00
|
|
|
not math '(1 pow 1,2)'
|
2022-01-13 06:27:17 +08:00
|
|
|
# CHECKERR: math: Error: Missing operator
|
2021-12-01 20:38:42 +08:00
|
|
|
# CHECKERR: '(1 pow 1,2)'
|
2022-01-13 06:27:17 +08:00
|
|
|
# CHECKERR: ^
|
2019-06-27 01:03:04 +08:00
|
|
|
not math
|
2021-11-04 13:52:17 +08:00
|
|
|
# CHECKERR: math: expected >= 1 arguments; got 0
|
2019-06-27 01:03:04 +08:00
|
|
|
not math -s 12
|
2021-11-04 13:52:17 +08:00
|
|
|
# CHECKERR: math: expected >= 1 arguments; got 0
|
|
|
|
# XXX FIXME these two should be just "missing argument" errors, the count is not helpful
|
2019-06-27 01:03:04 +08:00
|
|
|
not math 2^999999
|
|
|
|
# CHECKERR: math: Error: Result is infinite
|
|
|
|
# CHECKERR: '2^999999'
|
2023-08-06 02:54:39 +08:00
|
|
|
not math 'sqrt(-1)'
|
|
|
|
# CHECKERR: math: Error: Result is not a number
|
|
|
|
# CHECKERR: 'sqrt(-1)'
|
|
|
|
math 'sqrt(-0)'
|
|
|
|
# CHECK: -0
|
|
|
|
not math 2^53 + 1
|
|
|
|
# CHECKERR: math: Error: Result magnitude is too large
|
|
|
|
# CHECKERR: '2^53 + 1'
|
|
|
|
not math -2^53 - 1
|
|
|
|
# CHECKERR: math: Error: Result magnitude is too large
|
|
|
|
# CHECKERR: '-2^53 - 1'
|
2022-09-08 22:50:18 +08:00
|
|
|
printf '<%s>\n' (not math 1 / 0 2>&1)
|
|
|
|
# CHECK: <math: Error: Division by zero>
|
|
|
|
# CHECK: <'1 / 0'>
|
|
|
|
# CHECK: < ^>
|
|
|
|
printf '<%s>\n' (math 1 % 0 - 5 2>&1)
|
|
|
|
# CHECK: <math: Error: Division by zero>
|
|
|
|
# CHECK: <'1 % 0 - 5'>
|
|
|
|
# CHECK: < ^>
|
2022-09-09 03:32:09 +08:00
|
|
|
printf '<%s>\n' (math min 1 / 0, 5 2>&1)
|
|
|
|
# CHECK: <math: Error: Division by zero>
|
|
|
|
# CHECK: <'min 1 / 0, 5'>
|
|
|
|
# CHECK: < ^>
|
2019-06-27 01:03:04 +08:00
|
|
|
|
|
|
|
# Validate "x" as multiplier
|
|
|
|
math 0x2 # Hex
|
|
|
|
math 5 x 4
|
|
|
|
math 2x 4
|
|
|
|
math 2 x4 # ERROR
|
2020-01-31 04:46:22 +08:00
|
|
|
# CHECKERR: math: Error: Unknown function
|
2019-06-27 01:03:04 +08:00
|
|
|
# CHECKERR: '2 x4'
|
2022-09-08 23:54:45 +08:00
|
|
|
# CHECKERR: ^^
|
2019-06-27 01:03:04 +08:00
|
|
|
math 0x 3
|
|
|
|
# CHECK: 2
|
|
|
|
# CHECK: 20
|
|
|
|
# CHECK: 8
|
|
|
|
# CHECK: 0
|
2019-11-01 15:40:56 +08:00
|
|
|
|
|
|
|
math "42 >= 1337"
|
|
|
|
# CHECKERR: math: Error: Logical operations are not supported, use `test` instead
|
|
|
|
# CHECKERR: '42 >= 1337'
|
|
|
|
# CHECKERR: ^
|
2020-08-25 22:45:31 +08:00
|
|
|
|
|
|
|
math "bitand(0xFE, 1)"
|
|
|
|
# CHECK: 0
|
|
|
|
math "bitor(0xFE, 1)"
|
|
|
|
# CHECK: 255
|
|
|
|
math "bitxor(5, 1)"
|
|
|
|
# CHECK: 4
|
|
|
|
math "bitand(5.5, 2)"
|
|
|
|
# CHECK: 0
|
|
|
|
math "bitand(5.5, 1)"
|
|
|
|
# CHECK: 1
|
|
|
|
|
|
|
|
math "bitor(37 ^ 5, 255)"
|
|
|
|
# CHECK: 69343999
|
2020-10-26 04:28:49 +08:00
|
|
|
|
|
|
|
math 'log 16'
|
2021-03-30 23:21:28 +08:00
|
|
|
# CHECK: 1.20412
|
2020-10-26 04:28:49 +08:00
|
|
|
|
|
|
|
math 'log(16'
|
|
|
|
# CHECKERR: math: Error: Missing closing parenthesis
|
|
|
|
# CHECKERR: 'log(16'
|
|
|
|
# CHECKERR: ^
|
2020-10-08 01:03:19 +08:00
|
|
|
|
2021-12-01 20:38:42 +08:00
|
|
|
math '(2'
|
|
|
|
# CHECKERR: math: Error: Missing closing parenthesis
|
|
|
|
# CHECKERR: '(2'
|
|
|
|
# CHECKERR: ^
|
|
|
|
|
2020-10-08 01:03:19 +08:00
|
|
|
math --base=16 255 / 15
|
|
|
|
# CHECK: 0x11
|
|
|
|
math -bhex 16 x 2
|
|
|
|
# CHECK: 0x20
|
|
|
|
math --base hex 12 + 0x50
|
|
|
|
# CHECK: 0x5c
|
2021-11-08 08:41:47 +08:00
|
|
|
math --base hex 0
|
|
|
|
# CHECK: 0x0
|
|
|
|
math --base hex -1
|
|
|
|
# CHECK: -0x1
|
|
|
|
math --base hex -15
|
|
|
|
# CHECK: -0xf
|
|
|
|
math --base hex 'pow(2,40)'
|
|
|
|
# CHECK: 0x10000000000
|
|
|
|
math --base octal 0
|
|
|
|
# CHECK: 0
|
|
|
|
math --base octal -1
|
|
|
|
# CHECK: -01
|
|
|
|
math --base octal -15
|
|
|
|
# CHECK: -017
|
|
|
|
math --base octal 'pow(2,40)'
|
|
|
|
# CHECK: 020000000000000
|
2020-10-08 01:03:19 +08:00
|
|
|
math --base octal --scale=0 55
|
|
|
|
# CHECK: 067
|
|
|
|
math --base notabase
|
2021-11-04 13:52:17 +08:00
|
|
|
# CHECKERR: math: notabase: invalid base value
|
2020-10-08 01:03:19 +08:00
|
|
|
echo $status
|
|
|
|
# CHECK: 2
|
2021-02-21 15:48:38 +08:00
|
|
|
|
|
|
|
math 'log2(8)'
|
|
|
|
# CHECK: 3
|
2021-03-30 23:21:28 +08:00
|
|
|
|
|
|
|
# same as sin(cos(2 x pi))
|
|
|
|
math sin cos 2 x pi
|
|
|
|
# CHECK: 0.841471
|
|
|
|
# Inner function binds stronger, so this is interpreted as
|
|
|
|
# pow(sin(3,5))
|
|
|
|
|
|
|
|
math pow sin 3, 5
|
|
|
|
# CHECKERR: math: Error: Too many arguments
|
|
|
|
# CHECKERR: 'pow sin 3, 5'
|
|
|
|
# CHECKERR: ^
|
|
|
|
|
2022-09-09 02:41:02 +08:00
|
|
|
math pow sin 3, 5 + 2
|
|
|
|
# CHECKERR: math: Error: Too many arguments
|
|
|
|
# CHECKERR: 'pow sin 3, 5 + 2'
|
|
|
|
# CHECKERR: ^~~~^
|
|
|
|
|
2021-03-30 23:21:28 +08:00
|
|
|
math sin pow 3, 5
|
|
|
|
# CHECK: -0.890009
|
|
|
|
|
|
|
|
math pow 2, cos -pi
|
|
|
|
# CHECK: 0.5
|
|
|
|
|
|
|
|
# pow(2*cos(-pi), 2)
|
|
|
|
# i.e. 2^2
|
|
|
|
# i.e. 4
|
|
|
|
math pow 2 x cos'(-pi)', 2
|
|
|
|
# CHECK: 4
|
2021-07-27 00:39:09 +08:00
|
|
|
|
|
|
|
# This used to take ages, see #8170.
|
|
|
|
# If this test hangs, that's reintroduced!
|
|
|
|
math 'ncr(0/0, 1)'
|
2022-09-08 22:50:18 +08:00
|
|
|
# CHECKERR: math: Error: Division by zero
|
2021-07-27 00:39:09 +08:00
|
|
|
# CHECKERR: 'ncr(0/0, 1)'
|
2022-09-08 22:50:18 +08:00
|
|
|
# CHECKERR: ^
|
2022-01-20 06:12:30 +08:00
|
|
|
|
|
|
|
# Variadic functions require at least one argument
|
|
|
|
math min
|
|
|
|
# CHECKERR: math: Error: Too few arguments
|
|
|
|
# CHECKERR: 'min'
|
|
|
|
# CHECKERR: ^
|
|
|
|
math min 2
|
|
|
|
# CHECK: 2
|
|
|
|
math min 2, 3, 4, 5, -10, 1
|
|
|
|
# CHECK: -10
|
|
|
|
|
|
|
|
# Parentheses are required to disambiguate function call nested in argument list,
|
|
|
|
# except when the call is the last argument.
|
|
|
|
math 'min 5, 4, 3, ncr 2, 1, 5'
|
|
|
|
# CHECKERR: math: Error: Too many arguments
|
|
|
|
# CHECKERR: 'min 5, 4, 3, ncr 2, 1, 5'
|
|
|
|
# CHECKERR: {{^}} ^
|
|
|
|
math 'min 5, 4, 3, ncr(2, 1), 5'
|
|
|
|
# CHECK: 2
|
|
|
|
math 'min 5, 4, 3, 5, ncr 2, 1'
|
|
|
|
# CHECK: 2
|
|
|
|
# Variadic function consumes all available arguments,
|
|
|
|
# so it is always the last argument unless parenthesised.
|
|
|
|
# max(1, 2, min(3, 4, 5))
|
|
|
|
math 'max 1, 2, min 3, 4, 5'
|
|
|
|
# CHECK: 3
|
|
|
|
# max(1, 2, min(3, 4), 5)
|
|
|
|
math 'max 1, 2, min(3, 4), 5'
|
|
|
|
# CHECK: 5
|
2022-03-13 18:23:35 +08:00
|
|
|
math 0_1
|
|
|
|
# CHECK: 1
|
|
|
|
math 0x0_A
|
|
|
|
# CHECK: 10
|
|
|
|
math 1_000 + 2_000
|
|
|
|
# CHECK: 3000
|
|
|
|
math 1_0_0_0
|
|
|
|
# CHECK: 1000
|
|
|
|
math 0_0.5_0 + 0_1.0_0
|
|
|
|
# CHECK: 1.5
|
|
|
|
math 2e0_0_2
|
|
|
|
# CHECK: 200
|
|
|
|
math -0_0.5_0_0E0_0_3
|
|
|
|
# CHECK: -500
|
|
|
|
math 20e-0_1
|
|
|
|
# CHECK: 2
|
|
|
|
math 0x0_2.0_0_0P0_2
|
|
|
|
# CHECK: 8
|
|
|
|
math -0x8p-0_3
|
|
|
|
# CHECK: -1
|
2023-04-17 23:27:39 +08:00
|
|
|
|
|
|
|
echo 5 + 6 | math
|
|
|
|
# CHECK: 11
|
2023-08-20 17:19:52 +08:00
|
|
|
|
|
|
|
# Historical: If we have arguments on stdin and argv,
|
|
|
|
# the former takes precedence and the latter is ignored entirely.
|
|
|
|
echo 7 + 6 | math 2 + 2
|
|
|
|
# CHECK: 13
|
|
|
|
|
|
|
|
# It isn't checked at all.
|
|
|
|
echo 7 + 8 | math not an expression
|
|
|
|
# CHECK: 15
|
2023-08-25 22:15:52 +08:00
|
|
|
|
|
|
|
math (string repeat -n 1000 1) 2>| string shorten -m50 --char=""
|
|
|
|
# CHECK: math: Error: Number is too large
|
|
|
|
# CHECK: '1111111111111111111111111111111111111111111111111
|
|
|
|
# CHECK: ^
|
|
|
|
|
|
|
|
math 0x0_2.0P-0x3
|
|
|
|
# CHECKERR: math: Error: Unknown function
|
|
|
|
# CHECKERR: '0x0_2.0P-0x3'
|
|
|
|
# CHECKERR: ^^
|
|
|
|
math 0x0_2.0P-f
|
|
|
|
# CHECKERR: math: Error: Unexpected token
|
|
|
|
# CHECKERR: '0x0_2.0P-f'
|
|
|
|
# CHECKERR: ^
|