discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

bitwise arithmetic

JB
Jordan Brown
Sun, Mar 16, 2025 6:43 PM

My PR#4833 just merged, adding hexadecimal constants and bitwise
arithmetic to the language.  I think it appears first in 2025.03.14.

If you're not interested in bitwise arithmetic, here's what you might
need to know:

  • Historically, OpenSCAD allowed identifiers (variable names, module
    names, et cetera) that start with digits.  (I can't think of any
    other language that allows this.)  These are now deprecated and will
    yield a warning - except for ones starting with 0x and a hex digit;
    they will be interpreted as hexadecimal constants.
  • Very large numbers, larger than approximately 10^16 , have always
    been imprecise.  The 64-bit floating point representation that
    OpenSCAD uses can only represent about 16 decimal digits.  (Check it
    out:  echo(9007199254740992 == 9007199254740993); yields true.) 
    Integers that cannot be represented precisely (like
    9007199254740993) will now yield warning messages.  In the unlikely
    event that you actually want to work with numbers that large, add a
    period on the end so that it's no longer an integer.

If you are interested in bitwise arithmetic:

  • As noted above, OpenSCAD numbers have only 53 significant bits.  You
    can do bitwise operations on larger values than that, up to 64 bits,
    but the results will be imprecise.

  • As in C, the prefix "0x" introduces a hexadecimal constant.  Thus,
    e.g., 0xC0 is 192 decimal.
    o The "x" must be lower case; the digits are allowed to be either
    upper or lower case.
    o You can specify up to 64 bits (16 hexadecimal digits), but as
    noted above only 53 bits are significant.
    o As mentioned above, values that cannot be represented precisely
    yield warnings.

  • Bitwise arithmetic is done internally on 64-bit signed values. 
    Negative values are allowed and behave in obvious two's-complement ways.

  • Five operators are supported.  The semantics should be unsurprising,
    as long as you stay within the 53-bit limit.
    o A & B
    + Bitwise AND
    + For each bit, the result bit is on if both input bits are on.
    o A | B
    + Bitwise OR
    + For each bit, the result bit is on if either input bit is on.
    o A << B
    + Shift A left by B bits
    + This can shift bits off into the sign bit
    + It can shift bits off the left side of the 64-bit value.
    o A >> B
    + Shift A right by B bits
    + This is an "arithmetic" shift; the sign bit is replicated
    and so the sign of A is preserved.
    + It can shift bits off the right side of a value.
    o ~A
    + Bitwise NOT
    + For each bit, the result bit is on if the input bit is off,
    and vice versa.
    + Note that because the values are signed this makes positive
    numbers negative, and negative numbers positive.

  • Unlike C, the bitwise operators are higher priority than comparison
    operators.  Like C, they are lower priority than other arithmetic
    operators.  Like C, shift is higher priority than AND, and AND is
    higher priority than OR.

  • There is no XOR operator (^ in C).  This is because ^ is already
    used for exponentiation in OpenSCAD.  You can readily define an XOR
    function:
    o

    function XOR(a,b) = (a | b) & ~(a & b);
    
  • Other operators (NAND, NOR, implication, et cetera) are left as an
    exercise for the reader.

  • There is no way to convert a value to a string in hexadecimal.  It's
    a little tedious, but you can write your own conversion.

  • 53 bits is the limit today.  It's not impossible that it will get
    larger in the future.  Similarly, bitwise arithmetic is currently
    done on 64-bit values; it is not impossible that they will get wider
    in the future.

  • Fractions are truncated toward zero.

If you have any questions, just ask.

My PR#4833 just merged, adding hexadecimal constants and bitwise arithmetic to the language.  I think it appears first in 2025.03.14. If you're not interested in bitwise arithmetic, here's what you might need to know: * Historically, OpenSCAD allowed identifiers (variable names, module names, et cetera) that start with digits.  (I can't think of any other language that allows this.)  These are now deprecated and will yield a warning - except for ones starting with 0x and a hex digit; they will be interpreted as hexadecimal constants. * Very large numbers, larger than approximately 10^16 , have always been imprecise.  The 64-bit floating point representation that OpenSCAD uses can only represent about 16 decimal digits.  (Check it out:  echo(9007199254740992 == 9007199254740993); yields true.)  Integers that cannot be represented precisely (like 9007199254740993) will now yield warning messages.  In the unlikely event that you actually want to work with numbers that large, add a period on the end so that it's no longer an integer. If you *are* interested in bitwise arithmetic: * As noted above, OpenSCAD numbers have only 53 significant bits.  You can do bitwise operations on larger values than that, up to 64 bits, but the results will be imprecise. * As in C, the prefix "0x" introduces a hexadecimal constant.  Thus, e.g., 0xC0 is 192 decimal. o The "x" must be lower case; the digits are allowed to be either upper or lower case. o You can specify up to 64 bits (16 hexadecimal digits), but as noted above only 53 bits are significant. o As mentioned above, values that cannot be represented precisely yield warnings. * Bitwise arithmetic is done internally on 64-bit signed values.  Negative values are allowed and behave in obvious two's-complement ways. * Five operators are supported.  The semantics should be unsurprising, as long as you stay within the 53-bit limit. o A & B + Bitwise AND + For each bit, the result bit is on if both input bits are on. o A | B + Bitwise OR + For each bit, the result bit is on if either input bit is on. o A << B + Shift A left by B bits + This can shift bits off into the sign bit + It can shift bits off the left side of the 64-bit value. o A >> B + Shift A right by B bits + This is an "arithmetic" shift; the sign bit is replicated and so the sign of A is preserved. + It can shift bits off the right side of a value. o ~A + Bitwise NOT + For each bit, the result bit is on if the input bit is off, and vice versa. + Note that because the values are signed this makes positive numbers negative, and negative numbers positive. * Unlike C, the bitwise operators are higher priority than comparison operators.  Like C, they are lower priority than other arithmetic operators.  Like C, shift is higher priority than AND, and AND is higher priority than OR. * There is no XOR operator (^ in C).  This is because ^ is already used for exponentiation in OpenSCAD.  You can readily define an XOR function: o function XOR(a,b) = (a | b) & ~(a & b); * Other operators (NAND, NOR, implication, et cetera) are left as an exercise for the reader. * There is no way to convert a value to a string in hexadecimal.  It's a little tedious, but you can write your own conversion. * 53 bits is the limit today.  It's not impossible that it will get larger in the future.  Similarly, bitwise arithmetic is currently done on 64-bit values; it is not impossible that they will get wider in the future. * Fractions are truncated toward zero. If you have any questions, just ask.
NH
nop head
Sun, Mar 16, 2025 7:05 PM

I need identifiers that begin with digits for my libraries of parts some of
which begin with digits.

On Sun, 16 Mar 2025, 18:43 Jordan Brown via Discuss, <
discuss@lists.openscad.org> wrote:

My PR#4833 just merged, adding hexadecimal constants and bitwise
arithmetic to the language.  I think it appears first in 2025.03.14.

If you're not interested in bitwise arithmetic, here's what you might need
to know:

- Historically, OpenSCAD allowed identifiers (variable names, module
names, et cetera) that start with digits.  (I can't think of any other
language that allows this.)  These are now deprecated and will yield a
warning - except for ones starting with 0x and a hex digit; they will be
interpreted as hexadecimal constants.
- Very large numbers, larger than approximately 1016, have always been
imprecise.  The 64-bit floating point representation that OpenSCAD uses can
only represent about 16 decimal digits.  (Check it out:  echo(9007199254740992
== 9007199254740993); yields true.)  Integers that cannot be
represented precisely (like 9007199254740993) will now yield warning
messages.  In the unlikely event that you actually want to work with
numbers that large, add a period on the end so that it's no longer an
integer.

If you are interested in bitwise arithmetic:

- As noted above, OpenSCAD numbers have only 53 significant bits.  You
can do bitwise operations on larger values than that, up to 64 bits, but
the results will be imprecise.
- As in C, the prefix "0x" introduces a hexadecimal constant.  Thus,
e.g., 0xC0 is 192 decimal.
   - The "x" must be lower case; the digits are allowed to be either
   upper or lower case.
   - You can specify up to 64 bits (16 hexadecimal digits), but as
   noted above only 53 bits are significant.
   - As mentioned above, values that cannot be represented precisely
   yield warnings.
   - Bitwise arithmetic is done internally on 64-bit signed values.
Negative values are allowed and behave in obvious two's-complement ways.
- Five operators are supported.  The semantics should be unsurprising,
as long as you stay within the 53-bit limit.
- A & B
   - Bitwise AND
      - For each bit, the result bit is on if both input bits are on.
      - A | B
      - Bitwise OR
      - For each bit, the result bit is on if either input bit is on.
   - A << B
   - Shift A left by B bits
      - This can shift bits off into the sign bit
      - It can shift bits off the left side of the 64-bit value.
      - A >> B
      - Shift A right by B bits
      - This is an "arithmetic" shift; the sign bit is replicated and
      so the sign of A is preserved.
      - It can shift bits off the right side of a value.
      - ~A
      - Bitwise NOT
      - For each bit, the result bit is on if the input bit is off,
      and vice versa.
      - Note that because the values are signed this makes positive
      numbers negative, and negative numbers positive.
   - Unlike C, the bitwise operators are higher priority than
comparison operators.  Like C, they are lower priority than other
arithmetic operators.  Like C, shift is higher priority than AND, and AND
is higher priority than OR.
- There is no XOR operator (^ in C).  This is because ^ is already
used for exponentiation in OpenSCAD.  You can readily define an XOR
function:
   -

   function XOR(a,b) = (a | b) & ~(a & b);

   - Other operators (NAND, NOR, implication, et cetera) are left as
an exercise for the reader.
- There is no way to convert a value to a string in hexadecimal.  It's
a little tedious, but you can write your own conversion.
- 53 bits is the limit today.  It's not impossible that it will get
larger in the future.  Similarly, bitwise arithmetic is currently done on
64-bit values; it is not impossible that they will get wider in the future.
- Fractions are truncated toward zero.

If you have any questions, just ask.


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I need identifiers that begin with digits for my libraries of parts some of which begin with digits. On Sun, 16 Mar 2025, 18:43 Jordan Brown via Discuss, < discuss@lists.openscad.org> wrote: > My PR#4833 just merged, adding hexadecimal constants and bitwise > arithmetic to the language. I think it appears first in 2025.03.14. > > If you're not interested in bitwise arithmetic, here's what you might need > to know: > > - Historically, OpenSCAD allowed identifiers (variable names, module > names, et cetera) that start with digits. (I can't think of any other > language that allows this.) These are now deprecated and will yield a > warning - except for ones starting with 0x and a hex digit; they will be > interpreted as hexadecimal constants. > - Very large numbers, larger than approximately 1016, have always been > imprecise. The 64-bit floating point representation that OpenSCAD uses can > only represent about 16 decimal digits. (Check it out: echo(9007199254740992 > == 9007199254740993); yields true.) Integers that cannot be > represented precisely (like 9007199254740993) will now yield warning > messages. In the unlikely event that you actually want to work with > numbers that large, add a period on the end so that it's no longer an > integer. > > If you *are* interested in bitwise arithmetic: > > - As noted above, OpenSCAD numbers have only 53 significant bits. You > can do bitwise operations on larger values than that, up to 64 bits, but > the results will be imprecise. > - As in C, the prefix "0x" introduces a hexadecimal constant. Thus, > e.g., 0xC0 is 192 decimal. > - The "x" must be lower case; the digits are allowed to be either > upper or lower case. > - You can specify up to 64 bits (16 hexadecimal digits), but as > noted above only 53 bits are significant. > - As mentioned above, values that cannot be represented precisely > yield warnings. > - Bitwise arithmetic is done internally on 64-bit signed values. > Negative values are allowed and behave in obvious two's-complement ways. > - Five operators are supported. The semantics should be unsurprising, > as long as you stay within the 53-bit limit. > - A & B > - Bitwise AND > - For each bit, the result bit is on if both input bits are on. > - A | B > - Bitwise OR > - For each bit, the result bit is on if either input bit is on. > - A << B > - Shift A left by B bits > - This can shift bits off into the sign bit > - It can shift bits off the left side of the 64-bit value. > - A >> B > - Shift A right by B bits > - This is an "arithmetic" shift; the sign bit is replicated and > so the sign of A is preserved. > - It can shift bits off the right side of a value. > - ~A > - Bitwise NOT > - For each bit, the result bit is on if the input bit is off, > and vice versa. > - Note that because the values are signed this makes positive > numbers negative, and negative numbers positive. > - Unlike C, the bitwise operators are higher priority than > comparison operators. Like C, they are lower priority than other > arithmetic operators. Like C, shift is higher priority than AND, and AND > is higher priority than OR. > - There is no XOR operator (^ in C). This is because ^ is already > used for exponentiation in OpenSCAD. You can readily define an XOR > function: > - > > function XOR(a,b) = (a | b) & ~(a & b); > > - Other operators (NAND, NOR, implication, et cetera) are left as > an exercise for the reader. > - There is no way to convert a value to a string in hexadecimal. It's > a little tedious, but you can write your own conversion. > - 53 bits is the limit today. It's not impossible that it will get > larger in the future. Similarly, bitwise arithmetic is currently done on > 64-bit values; it is not impossible that they will get wider in the future. > - Fractions are truncated toward zero. > > If you have any questions, just ask. > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
MK
Marius Kintel
Sun, Mar 16, 2025 9:19 PM

On Mar 16, 2025, at 15:05, nop head via Discuss discuss@lists.openscad.org wrote:

I need identifiers that begin with digits for my libraries of parts some of which begin with digits.

While they are deprecated, they will still work also in the next stable release of OpenSCAD, to give people time to transition off such variables (with the exception of variable names starting with “0x”, which we had to disallow immediately).
We don’t have a concrete timeline for removing that support. Historically we tend to support deprecated features for a few full releases.

-Marius

On Mar 16, 2025, at 15:05, nop head via Discuss <discuss@lists.openscad.org> wrote: > I need identifiers that begin with digits for my libraries of parts some of which begin with digits. > While they are deprecated, they will still work also in the next stable release of OpenSCAD, to give people time to transition off such variables (with the exception of variable names starting with “0x”, which we had to disallow immediately). We don’t have a concrete timeline for removing that support. Historically we tend to support deprecated features for a few full releases. -Marius