Discussion:
Masking bits in Oberon
(too old to reply)
j***@usm.edu
2019-05-11 17:55:04 UTC
Permalink
Hello

I apologize if this is a boneheaded question, but what is the best way to mask an integer's bits in Oberon-07?

As I understand it, one way is to convert the integer to a SET and multiply . This conversion, however, requires use of the SYSTEM module. I'm trying to avoid that.

Another way is to use LSL and ASR to isolate bits, but that seems wasteful.

Is there some other way I'm missing?

thanks in advance
john perry
c***@gmail.com
2019-05-11 23:42:54 UTC
Permalink
John:
Do you have SYSTEM.VAL function in the version of Oberon you use?
[Oberon-07 for RISC has SYSTEM.VAL]

You should be able to convert bi-directionally between SET and INTEGER as I assume they are the same word size, below I assume 32-bit:

VAR s, t ; SET;
i, j : INTEGER;

BEGIN
i := 12345678;
s := SYSTEM.VAL(SET, i);
t := s * {0..17};
j := SYSTEM.VAL(INTEGER, t);
...

If you are using OberonMicrosystem's BlackBox Component-Pascal (BB), you can use the standard functions BITS and ORD to convert from INTEGER to SET and SET to INTEGER, respectively.

In Oberon, you should be able to use standard function ORD to convert SET to INTEGER, but I know of no Oberon standard function to convert INTEGER to SET, but I might be wrong. If I am correct, you will need to use SYSTEM.VAL

Maybe someone has a better answer, since I am more familiar with Modula-2 in the area of converting between BITSET and CARDINAL.

Carl
---
Post by j***@usm.edu
Hello
I apologize if this is a boneheaded question, but what is the best way to mask an integer's bits in Oberon-07?
As I understand it, one way is to convert the integer to a SET and multiply . This conversion, however, requires use of the SYSTEM module. I'm trying to avoid that.
Another way is to use LSL and ASR to isolate bits, but that seems wasteful.
Is there some other way I'm missing?
thanks in advance
john perry
c***@gmail.com
2019-05-12 01:26:12 UTC
Permalink
John,
I found a more complete series of answers with Oberon source at:

https COLON SLASH SLASH lists DOT inf DOT ethz DOT ch SLASH pipermail SLASH oberon SLASH 2018 SLASH 012333 DOT html

You can also do a search on "[Oberon] Bit manipulation in Oberon-07" to find the thread.

There are more than 2 messages in the thread, and the answers are better than mine.

The above link though has Oberon source that is designed to emulate the BITS standard function, in a portable way. I haven't tested it but it looks good to me.

Carl
----
Post by j***@usm.edu
Hello
I apologize if this is a boneheaded question, but what is the best way to mask an integer's bits in Oberon-07?
As I understand it, one way is to convert the integer to a SET and multiply . This conversion, however, requires use of the SYSTEM module. I'm trying to avoid that.
Another way is to use LSL and ASR to isolate bits, but that seems wasteful.
Is there some other way I'm missing?
thanks in advance
john perry
j***@usm.edu
2019-05-12 02:58:49 UTC
Permalink
Carl

Thank you for pointing out that interesting thread to me.
Post by c***@gmail.com
Do you have SYSTEM.VAL function in the version of Oberon you use?
I do, but I was trying to avoid it because I’m under the impression that should be used only for low-level programming.

Essentially, I’m performing some modular addition and multiplication, and trying to avoid using MOD until I know the integer has grown to a certain size. I’m doing a *lot* of operations, so I know the integer will eventually overflow, but I want to catch it right before it does, and use MOD then. In addition, I’m packing 2 or more numbers into a machine word, so as to do this arithmetic in parallel, so using the greater-than operator is out of the question.

I had already implemented this with a mask in a couple of other languages (C, Nim). I was curious how Oberon would handle it, and as I set about doing this, it quickly became apparent that you can’t mask an integer using a SET without falling back on SYSTEM.VAL.

I settled on using LSL and ASR, because it turns out to be pretty simple in this case and doesn’t affect efficiency. But the general question remained.

regards
john perry


John Perry + Associate Professor + Department of Mathematics
University of Southern Mississippi

Absent-mindedness is not absence of mind; it’s presence of mind elsewhere. — G.K. Chesterton
c***@gmail.com
2019-05-12 03:28:38 UTC
Permalink
Hi John:

Curious if your using either Astrobe's implementation of Oberon-07 or perhaps Saanlima's Oberon Workstation?

The following may be a perhaps slightly more efficient version of BITS ---at least it avoids the IF test once i becomes zero:

PROCEDURE BITS(i : INTEGER) : SET;
VAR s : SET; n : INTEGER;

BEGIN
s := {};
n := 0;
WHILE (n < 32) & (i > 0) DO
IF ODD(i) THEN INCL(s, n) END (* if *);
i := i DIV 2;
INC(n)
END (* while *);
RETURN s
END BITS;

Carl
-----
Post by j***@usm.edu
Carl
Thank you for pointing out that interesting thread to me.
Post by c***@gmail.com
Do you have SYSTEM.VAL function in the version of Oberon you use?
I do, but I was trying to avoid it because I’m under the impression that should be used only for low-level programming.
Essentially, I’m performing some modular addition and multiplication, and trying to avoid using MOD until I know the integer has grown to a certain size. I’m doing a *lot* of operations, so I know the integer will eventually overflow, but I want to catch it right before it does, and use MOD then. In addition, I’m packing 2 or more numbers into a machine word, so as to do this arithmetic in parallel, so using the greater-than operator is out of the question.
I had already implemented this with a mask in a couple of other languages (C, Nim). I was curious how Oberon would handle it, and as I set about doing this, it quickly became apparent that you can’t mask an integer using a SET without falling back on SYSTEM.VAL.
I settled on using LSL and ASR, because it turns out to be pretty simple in this case and doesn’t affect efficiency. But the general question remained.
regards
john perry

John Perry + Associate Professor + Department of Mathematics
University of Southern Mississippi
Absent-mindedness is not absence of mind; it’s presence of mind elsewhere. — G.K. Chesterton
j***@usm.edu
2019-05-12 14:35:13 UTC
Permalink
Hi Carl
Post by c***@gmail.com
Curious if your using either Astrobe's implementation of Oberon-07 or perhaps Saanlima's Oberon Workstation?
No; I usually use OBNC or oberonc on a Mac or Linux. I don't use Windows at all, and I wasn't aware of Saanlima.

Thanks for the suggestions.

regards
john perry
c***@gmail.com
2019-05-12 06:37:28 UTC
Permalink
Post by j***@usm.edu
Carl
Thank you for pointing out that interesting thread to me.
Post by c***@gmail.com
Do you have SYSTEM.VAL function in the version of Oberon you use?
I do, but I was trying to avoid it because I’m under the impression that should be used only for low-level programming.
If you are performing bit mask operations on integer values then the Oberon view is that you ARE doing 'low-level programming'. The presence of the SYSTEM qualifier is to highlight that whatever you are doing might not be portable.

However, now that the shift operations in Oberon-07 are no longer SYSTEM operations the distinction between these and other built-in functions has become inconsistent / blurred. For more discussion on this see:

http://lists.inf.ethz.ch/pipermail/oberon/2018/012506.html

The end result of these discussions is that in the Astrobe Oberon-07 implementations for the ARM Cortex-M microcontrollers we have kept the requirement for SYSTEM to be used for the functions specified that way in the language report. However, we do not require SYSTEM to be used as a qualifier for the extended built-in bit-manipulation operations that we have implemented:

BITS - cast an INTEGER to SET
BFI - bitfield insert
BFX - bitfield extract

Consequently, a very efficient mask operation with integers (e.g. A AND B) just becomes:

ORD(BITS(A) * BITS(B))

If B = {0..3} i.e. BITS(0FH) this is equivalent to:

BFX(A, 3, 0)

For more details see the Logic Operations discussion on the Astrobe forum:

http://www.astrobe.com/forum/viewtopic.php?f=9&t=569

Regards,
Chris Burrows
CFB Software
http://www.astrobe.com
j***@usm.edu
2019-05-12 14:38:04 UTC
Permalink
Post by c***@gmail.com
Post by j***@usm.edu
Post by c***@gmail.com
Do you have SYSTEM.VAL function in the version of Oberon you use?
I do, but I was trying to avoid it because I’m under the impression that should be used only for low-level programming.
If you are performing bit mask operations on integer values then the Oberon view is that you ARE doing 'low-level programming'. The presence of the SYSTEM qualifier is to highlight that whatever you are doing might not be portable.
http://lists.inf.ethz.ch/pipermail/oberon/2018/012506.html
Thank you, that was an interesting read. I wonder if LSL and ASR are considered non-SYSTEM because they can be used for multiplication and division by 2 (which is really what I'm doing).

regards
john perry
August Karlstrom
2019-05-12 17:36:25 UTC
Permalink
Post by j***@usm.edu
Thank you, that was an interesting read. I wonder if LSL and ASR are considered non-SYSTEM because they can be used for multiplication and division by 2 (which is really what I'm doing).
Sounds reasonable. ROT is probably non-SYSTEM because it's a bit
shifting function like LSL and ASR, even though it has no similar
"mathematical" interpretation.


-- August

Loading...