Skip to content

Commit 06d4f99

Browse files
committed
Add bitwise NOT
Closes Blake-Madden#15 Blake-Madden#13
1 parent 7e041d0 commit 06d4f99

File tree

6 files changed

+452
-83
lines changed

6 files changed

+452
-83
lines changed

TinyExprChanges.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ The following are changes from the original TinyExpr C library:
3434
- `and`: returns true (i.e., non-zero) if all conditions are true (accepts 1-7 arguments).
3535
- `average`: returns the mean for a range of values (accepts 1-7 arguments).
3636
- `bitand`: bitwise AND.
37-
- `bitlrotate64`: bitwise (`uint64_t`) left rotate. (Only available if compiled as C++20.)
37+
- `bitlrotate`: bitwise left rotate. Versions of this are available for 8-, 16-, 32-, and 64-bit integers (if supported by the platform). (Only available if compiled as C++20.)
3838
- `bitlshift`: left shift.
3939
Negative shift amount arguments (similar to *Excel*) are supported.
40+
- `bitnot`: bitwise NOT. Versions of this are available for 8-, 16-, 32-, and 64-bit integers (if supported by the platform).
4041
- `bitor`: bitwise OR.
41-
- `bitrrotate64`: bitwise (`uint64_t`) right rotate. (Only available if compiled as C++20.)
42+
- `bitrrotate`: bitwise right rotate. Versions of this are available for 8-, 16-, 32-, and 64-bit integers (if supported by the platform). (Only available if compiled as C++20.)
4243
- `bitrshift`: right shift.
4344
Negative shift amount arguments (similar to *Excel*) are supported.
4445
- `bitxor`: bitwise XOR.
@@ -87,6 +88,7 @@ The following are changes from the original TinyExpr C library:
8788
- `<<<` left (`uint64_t`) rotation operator.
8889
- `>>>` right (`uint64_t`) rotation operator.
8990
- `**` exponentiation (alias for `^`).
91+
- `~` bitwise NOT.
9092
- `round` now supports negative number of digit arguments, similar to *Excel*.
9193
For example, `ROUND(-50.55,-2)` will yield `-100`.
9294
- Custom variables and functions are now stored in a `std::set`

docs/manual/compile-time-options.qmd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ If compiling as C++20 (and `TE_FLOAT` is not defined), then the following functi
6767
- `BITLROTATE16`
6868
- `BITLROTATE32`
6969
- `BITLROTATE64`
70+
- `BITLROTATE`
7071
- `BITRROTATE8`
7172
- `BITRROTATE16`
7273
- `BITRROTATE32`
7374
- `BITRROTATE64`
75+
- `BITRROTATE`
7476
- `<<<` (unsigned 64-bit left rotation)
7577
- `>>>` (unsigned 64-bit right rotation)

docs/manual/functions.qmd

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,26 @@ Table: Math Functions\index{functions!math}
5252
| BITLROTATE8(Number, RotateAmount) | Returns *Number* left rotated left to the most significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 8-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
5353
| BITLROTATE16(Number, RotateAmount) | Returns *Number* left rotated left to the most significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 16-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
5454
| BITLROTATE32(Number, RotateAmount) | Returns *Number* left rotated left to the most significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 32-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
55-
| BITLROTATE(Number, RotateAmount) | Returns *Number* left rotated left to the most significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 53-bit (or 64-bit) integer.<br>\linebreak Note, however, that values beyond the range of `double` should not be used as they will wrap around.<br>\linebreak (Only available if compiled as C++20.) |
56-
| BITLSHIFT(Number, ShiftAmount) | Returns *Number* left shifted by the specified number (*ShiftAmount*) of bits.<br>\linebreak *Number* cannot exceed `(2^48)-1` and *ShiftAmount* cannot exceed `53` (or `64`, if supported). |
55+
| BITLROTATE64(Number, RotateAmount) | Returns *Number* left rotated left to the most significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 64-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
56+
| BITLROTATE(Number, RotateAmount) | Returns *Number* left rotated left to the most significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as either a 32- or 64-bit integer (depending on what is supported by the compiler).<br>\linebreak (Only available if compiled as C++20.) |
57+
| BITLSHIFT(Number, ShiftAmount) | Returns *Number* left shifted by the specified number (*ShiftAmount*) of bits.<br>\linebreak *Number* cannot exceed `(2^48)-1` and *ShiftAmount* cannot exceed `53` (or `63`, if 64-bit is supported). |
58+
| BITNOT8(Number) | Returns a bitwise 'NOT' of a 8-bit integer. |
59+
| BITNOT16(Number) | Returns a bitwise 'NOT' of a 16-bit integer. |
60+
| BITNOT32(Number) | Returns a bitwise 'NOT' of a 32-bit integer. |
61+
| BITNOT64(Number) | Returns a bitwise 'NOT' of a 64-bit integer (if 64-bit integers are supported). |
62+
| BITNOT(Number) | Returns a bitwise 'NOT' of a 32- or 64-bit integer (depending on whether 64-bit is supported). |
5763
| BITOR(Number1, Number2) | Returns a bitwise 'OR' of two (integral) numbers. (Both numbers must be positive and cannot exceed `(2^48)-1`.) |
5864
| BITRROTATE8(Number, RotateAmount) | Returns *Number* right rotated right to the least significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 8-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
5965
| BITRROTATE16(Number, RotateAmount) | Returns *Number* right rotated right to the least significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 16-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
6066
| BITRROTATE32(Number, RotateAmount) | Returns *Number* right rotated right to the least significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 32-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
61-
| BITRROTATE(Number, RotateAmount) | Returns *Number* right rotated right to the least significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 53-bit (or 64-bit) integer.<br>\linebreak Note, however, that values beyond the range of `double` should not be used as they will wrap around.<br>\linebreak (Only available if compiled as C++20.) |
62-
| BITRSHIFT(Number, ShiftAmount) | Returns *Number* right shifted by the specified number (*ShiftAmount*) of bits.<br>\linebreak *Number* cannot exceed `(2^48)-1` and *ShiftAmount* cannot exceed `53` (or `64`, if supported). |
67+
| BITRROTATE64(Number, RotateAmount) | Returns *Number* right rotated right to the least significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as an unsigned 64-bit integer.<br>\linebreak (Only available if compiled as C++20.) |
68+
| BITRROTATE(Number, RotateAmount) | Returns *Number* right rotated right to the least significant bit by the specified number (*RotateAmount*) of bits.<br>\linebreak *Number* is rotated as either a 32- or 64-bit integer (depending on what is supported by the compiler).<br>\linebreak (Only available if compiled as C++20.) |
69+
| BITRSHIFT(Number, ShiftAmount) | Returns *Number* right shifted by the specified number (*ShiftAmount*) of bits.<br>\linebreak *Number* cannot exceed `(2^48)-1` and *ShiftAmount* cannot exceed `53` (or `63`, if 64-bit is supported). |
6370
| BITXOR(Number1, Number2) | Returns a bitwise 'XOR' of two (integral) numbers. (Both numbers must be positive and cannot exceed `(2^48)-1`.) |
6471
| SUPPORTS32BIT() | Returns true if 32-bit integers are supported. This will affect the supported range of values for bitwise operations. |
6572
| SUPPORTS64BIT() | Returns true if 64-bit integers are supported. This will affect the supported range of values for bitwise operations. |
6673

67-
Table: Bitwise Functions\index{functions!bitwise}
74+
Table: Engineering Functions\index{functions!engineering}
6875
:::
6976

7077
::: {.notesection data-latex=""}
@@ -96,3 +103,8 @@ Table: Logic Functions\index{functions!logical}
96103
The first argument to any logic function must be valid (i.e., not NaN). If the first argument evaluates to NaN, then NaN will be returned.
97104
Any subsequent arguments that evaluate to NaN will be ignored.
98105
:::
106+
107+
## Compatibility Note {-}
108+
109+
`BITNOT` will call either `BITNOT32` or `BITNOT64`, depending on whether 64-bit integers are supported.
110+
This differs from *Excel*, which only works with 16-bit integers. To match the behavior of *Excel*, explicitly call `BITNOT16`.

docs/manual/operators.qmd

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The following operators\index{operators} are supported within math expressions:
1010
| % | Modulus: Divides two values and returns the remainder. |
1111
| + | Addition. |
1212
| \- | Subtraction. |
13-
| ^ | Either exponentiation or bitwise XOR. Exponentiation is the default; define `TE_BITWISE_OPERATORS` to enable bitwise behavior. For exponentiation, the number in front of ^ is the base, the number after it is the power to raise it to. |
13+
| ^ | Either exponentiation (the default) or bitwise XOR. For exponentiation, the number in front of ^ is the base, the number after it is the power to raise it to. |
1414
| ** | Exponentiation. (This is an alias for ^) |
1515
| < | Less than. |
1616
| \> | Greater than. |
@@ -20,26 +20,31 @@ The following operators\index{operators} are supported within math expressions:
2020
| \=\= | Equals. (This is an alias for \=) |
2121
| <> | Not equal to. |
2222
| \!\= | Not equal to. (This is an alias for <>) |
23-
| & | Either logical or bitwise conjunction (AND). Logical is the default, define `TE_BITWISE_OPERATORS` to enable bitwise behavior. |
24-
| && | Either logical conjunction (AND). |
25-
| \| | Logical or bitwise alternative (OR). Logical is the default, define `TE_BITWISE_OPERATORS` to enable bitwise behavior. |
26-
| \|\| | Logical alternative (OR). |
23+
| & | Either logical (the default) or bitwise conjunction (AND). |
24+
| && | Logical conjunction (AND). |
25+
| \| | Either Logical (the default) or bitwise alternative (OR). |
26+
| \|\ | | Logical alternative (OR). |
2727
| ( ) | Groups sub-expressions, overriding the order of operations. |
28-
| << | Bitwise left shift. |
29-
| >> | Bitwise right shift. |
28+
| ~ | Bitwise NOT. |
29+
| << | Bitwise left shift. |
30+
| >> | Bitwise right shift. |
3031
| <<< | Bitwise left rotate. (Only available if compiled as C++20.) |
3132
| >>> | Bitwise right rotate. (Only available if compiled as C++20.) |
3233

3334
Table: Operators
3435
:::
3536

37+
::: {.tipsection data-latex=""}
38+
Define `TE_BITWISE_OPERATORS` to enable bitwise behavior for `&`, `|`, and `^`.
39+
:::
40+
3641
::: {.minipage data-latex="{\textwidth}"}
3742
For operators, the order of precedence is:
3843

3944
| Operator | Description |
4045
| :-- | :-- |
4146
| ( ) | Instructions in parentheses are executed first. (If `TE_BRACKETS_AS_PARENS` is defined, then `[]` are treated the same way.) |
42-
| \+ and - | Positive or negative sign for a value. |
47+
| \+, -, ~ | Positive or negative sign for a value, and bitwise NOT. |
4348
| ^ | Exponentiation. |
4449
| \*, /, and % | Multiplication, division, and modulus. |
4550
| \+ and - | Addition and subtraction. |

0 commit comments

Comments
 (0)