User Tools

Site Tools


simulating_20a_20union_20_28lbb_29

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
simulating_20a_20union_20_28lbb_29 [2018/03/31 13:19] – external edit 127.0.0.1simulating_20a_20union_20_28lbb_29 [2024/01/05 00:21] (current) – external edit 127.0.0.1
Line 2: Line 2:
  
 //by Richard Russell, September 2016//\\ \\  A [[https://en.wikipedia.org/wiki/Union_type|union]] is a value or data structure that may have two or more different representations or formats. Liberty BASIC doesn't have unions, but it is simple to simulate them in LBB using structures. The trick is to create two (or more) structures, which should be the same size, and then to arrange for them to share the same memory address.\\ \\  Here is a simple example of creating a **union** between two 32-bit **integers** and a 64-bit floating-point **double**:\\ \\  //by Richard Russell, September 2016//\\ \\  A [[https://en.wikipedia.org/wiki/Union_type|union]] is a value or data structure that may have two or more different representations or formats. Liberty BASIC doesn't have unions, but it is simple to simulate them in LBB using structures. The trick is to create two (or more) structures, which should be the same size, and then to arrange for them to share the same memory address.\\ \\  Here is a simple example of creating a **union** between two 32-bit **integers** and a 64-bit floating-point **double**:\\ \\ 
 +<code lb>
       struct union1, low as ulong, high as ulong       struct union1, low as ulong, high as ulong
       struct union2, float as double       struct union2, float as double
Line 10: Line 11:
  
       print union2.float.struct       print union2.float.struct
 +</code>
 Here the structure **union1** contains the two 32-bit integers and the structure **union2** contains the floating-point double. The third line sets **union2** to point to the same memory block as **union1**. Hence you can write and read the data using either of the two formats. In the example above the data is written as two integers and read as a double, but the converse is just as straightforward.\\ \\  Note that, unlike languages which have true unions, this technique will not save memory. The memory originally allocated to the structure **union1** is leaked, but that is very unlikely to matter.\\ \\  You can use the same technique to convert between a numeric value and a string containing the same data in binary format. For example here is an example of creating a union between an 8-character-long **string** and a 64-bit **double**:\\ \\  Here the structure **union1** contains the two 32-bit integers and the structure **union2** contains the floating-point double. The third line sets **union2** to point to the same memory block as **union1**. Hence you can write and read the data using either of the two formats. In the example above the data is written as two integers and read as a double, but the converse is just as straightforward.\\ \\  Note that, unlike languages which have true unions, this technique will not save memory. The memory originally allocated to the structure **union1** is leaked, but that is very unlikely to matter.\\ \\  You can use the same technique to convert between a numeric value and a string containing the same data in binary format. For example here is an example of creating a union between an 8-character-long **string** and a 64-bit **double**:\\ \\ 
 +<code lb>
       struct union1, string as char[9]       struct union1, string as char[9]
       struct union2, number as double, pad as char[1]       struct union2, number as double, pad as char[1]
Line 19: Line 22:
  
       print union2.number.struct       print union2.number.struct
 +</code>
 Note that in this case there is a slight complication in that the string is declared as **char[9]** rather than as **char[8]** as you might expect; that's because you have to make room for the additional NUL character **chr$(0)** which terminates the string. It also results in the structures being a different length, so to avoid memory corruption and a probable crash **union2** is padded to the same length as **union1** (this isn't strictly essential if the **shorter** structure is equated to the **longer** structure rather than the other way around). Note that in this case there is a slight complication in that the string is declared as **char[9]** rather than as **char[8]** as you might expect; that's because you have to make room for the additional NUL character **chr$(0)** which terminates the string. It also results in the structures being a different length, so to avoid memory corruption and a probable crash **union2** is padded to the same length as **union1** (this isn't strictly essential if the **shorter** structure is equated to the **longer** structure rather than the other way around).
simulating_20a_20union_20_28lbb_29.1522502383.txt.gz · Last modified: 2024/01/05 00:16 (external edit)