"Sputnik" help  
Sputnik Help
Language Reference - Variables - Direct Casting

Direct Casting

The Direct Cast Operator (^) in Sputnik can also be used to convert the endian representation of a value. By appending either the greater-than symbol (>) or the less-than symbol (<) to the type within the parentheses, you can specify the desired endian format.

For example, if you want to interpret a value as big-endian, you would use the syntax (^type>). This instructs Sputnik to reinterpret the bits of the value as big-endian, regardless of the underlying system's endian format.

Similarly, if you want to interpret a value as little-endian, you would use the syntax (^type<). This tells Sputnik to reinterpret the bits of the value as little-endian.

By leveraging the Direct Cast Operator with endian notation, you can easily convert the endian representation of a value without resorting to manual bit manipulation or complex conversion functions. This can be particularly useful when working with binary data or when dealing with systems that use a different endian format than the one expected by your code.

It's important to note that endian conversion using the Direct Cast Operator should be done with caution and awareness of the data's original format and the desired endian format. Incorrect interpretation of the endian representation can lead to incorrect results or data corruption.

To specify the endianness of the interpretation, you can add a > (greater than) or < (less than) symbol after the type. The > symbol indicates big endian interpretation, while the < symbol indicates little endian interpretation.

In summary, the Direct Cast Operator (^) in Sputnik not only allows you to reinterpret the bits of a value as a different type but also provides a convenient way to convert the endian representation of a value. By appending the appropriate endian symbol, you can effortlessly handle endian conversions in your code, enhancing compatibility and flexibility when working with binary data.

Syntax (Normal):
(^type) expression

Syntax (BigEndian):
(^type>) expression

Syntax (LittleEndian):
(^type<) expression

Usage:
The Direct Cast Operator (^) is placed before the desired type, and the expression to be cast follows within parentheses. The operator is used to interpret the bits of the expression as the specified type.

Imperative Casting:
The imperative cast operation with the Direct Cast Operator (^) does not change the underlying bit representation of the value. It treats the bits as the specified type without any modification. It allows you to view the bits as a different type, providing flexibility in how you interpret and work with the data.

Example:
Consider the following code snippet:

my $value = 1151803392; // Integer value
my $castedValue = (^float)$value; // Imperative cast to float
say $castedValue;
// PRINTS
// 1337

In this example, the variable 'value' holds an integer value of 1151803392. The line '(^float)value' performs an imperative cast of the integer value to a float. It interprets the underlying bits of 'value' as a floating-point value without altering the bit representation. The resulting 'castedValue' variable will hold the floating-point representation of 1337.0.

Imperative casting is useful when you need to access or manipulate the bits of a value directly, treating them as a different type. It provides low-level control over the bit representation of data, but requires caution and proper understanding of the underlying data format and its implications.

Note:
- Imperative casting should be used with care, as it bypasses the usual type system and can lead to unexpected results or undefined behavior if not used correctly.
- Ensure that the bit representation of the source value is compatible with the target type to avoid data corruption or misinterpretation.

An example using 32 bits:

my $vec = null;
Vec($vec, 0, 32) = (^UInt32)(133.42);
Vec($vec, 1, 32) = (^UInt32)(777.42);
Vec($vec, 2, 32) = (^UInt32)(@PI);
Vec($vec, 3, 32) = (^UInt32)(@FloatMax);
 
say (^Float)(Vec($vec, 0, 32));
say (^Float)(Vec($vec, 1, 32));
say (^Float)(Vec($vec, 2, 32));
say (^Float)(Vec($vec, 3, 32));

// PRINTS
// 133.42
// 777.42
// 3.141593
// 3.402823E+38

An example using 64 bits:

my $vec = null;
Vec($vec, 0, 64) = (^UInt64)(133.42);
Vec($vec, 1, 64) = (^UInt64)(777.42);
Vec($vec, 2, 64) = (^UInt64)(@PI);
Vec($vec, 3, 64) = (^UInt64)(@FloatMax);
 
say (^Double)(Vec($vec, 0, 64));
say (^Double)(Vec($vec, 1, 64));
say (^Double)(Vec($vec, 2, 64));
say (^Double)(Vec($vec, 3, 64));

// PRINTS
// 133.42
// 777.42
// 3.14159265358979
// 3.40282346638529E+38

In the above examples example, we are creating a null vector $vec and then assigning values to its elements using the direct cast system. We use (^UInt64) to reinterpret the floating-point values as unsigned 64-bit integers and store them in the vector.

Later, we retrieve the values from the vector using Vec($vec, index, bits) and apply the (^Double) direct cast to reinterpret the bits as double-precision floating-point values. This allows us to restore the original floating-point values from the vector.

To convert the endian representation of a value using the Direct Cast Operator (^), you can use the following symbols:

> symbol: Indicates big-endian conversion. When applied, it reinterprets the bits of the value as big-endian.
< symbol: Indicates little-endian conversion. When applied, it reinterprets the bits of the value as little-endian.

Example of using the Endian changes < and > :

say "Raw Bytes";
printr (binary)(int32)100;

say "As BigEndian";
say (^int32>)100;
say "As LittleEndian";
say (^int32<)100;

say "BigEndian Bytes";
printr (binary)(^int32>)100;
say "LittleEndian Bytes";
printr (binary)(^int32<)100;

// PRINTS
// Raw Bytes
// Binary
// (
//     [0] => 0x64 [100] (d)
//     [1] => 0x00 [0] (.)
//     [2] => 0x00 [0] (.)
//     [3] => 0x00 [0] (.)
// )
// As BigEndian
// 1677721600
// As LittleEndian
// 100
// BigEndian Bytes
// Binary
// (
//     [0] => 0x00 [0] (.)
//     [1] => 0x00 [0] (.)
//     [2] => 0x00 [0] (.)
//     [3] => 0x64 [100] (d)
// )
// LittleEndian Bytes
// Binary
// (
//     [0] => 0x64 [100] (d)
//     [1] => 0x00 [0] (.)
//     [2] => 0x00 [0] (.)
//     [3] => 0x00 [0] (.)
// )

In the provided example, we demonstrate how to convert an integer value to big-endian and little-endian representations using the Direct Cast Operator (^) with the appropriate endian symbols. The resulting output showcases the converted values and their corresponding byte representations in the desired endian format.

By leveraging the endian conversion capabilities of the Direct Cast Operator (^), Sputnik empowers you to work seamlessly with binary data and handle endian-related considerations effortlessly.

Note: It's recommended to understand the endian format of the target system or the specific requirements of the data format you're working with to ensure proper interpretation and compatibility.

Feel free to explore and leverage the endian conversion capabilities of the Direct Cast Operator (^) to handle endian-related scenarios in your Sputnik code efficiently.

Built in casts are:

(^Bool) // 1 bit
(^Boolean) // Alias for (bool)
(^Char) // 16 bits
(^Byte) // 8 bits
(^SByte) // 8 bits
(^Int16) // 16 bits
(^Short) // Alias for Int16
(^Int32 // 32 bits
(^Int) // Alias for Int32
(^Int64) // 64 bits
(^Integer) // Alias for Intt64
(^Long) // Alias for Int64
(^UInt16) // 16 bits
(^UShort) // Alias for UInt16
(^UInt32) // 32 bits
(^UInt) // Alias for UInt32
(^UInt64) // 64 bits
(^UInteger) // Alias for Int64
(^ULong) // Alias for Int64
(^IntPtr) // Size depends on the platform, typically 32 or 64 bits
(^Ptr) // Alias for IntPtr
(^UIntPtr) // Size depends on the platform, typically 32 or 64 bits
(^UPtr) // Alias for IntPtr
(^Float) // 32 bits
(^Single) // Alias for Float
(^Double) // 64 bits

It's important to note that the direct cast system in Sputnik operates purely at the bit level and doesn't perform any conversion or interpretation of the values. It is your responsibility to ensure that the types you are casting to are appropriate for the underlying bit representation.

Using the direct cast system can be powerful but also carries certain risks, as it bypasses the usual type system and may result in unexpected behavior if used incorrectly. Therefore, it's recommended to use it with caution and make sure you understand the implications of working directly with the underlying bits of a value.


Contact
Cheryl (uberfox@hotmail.com)
Homepage
http://ubersoft.org