What's the exact meaning of iota? - go

In the code below:
const (
signature uint32 = 0xae3179fb
dhkxGroup = 2
ReplySuccessful byte = iota
ReplyBufferCorrupted
ReplyDecryptFailed
ReplySessionExpired
ReplyPending
)
ReplySuccessful is compiled to 2, while I think it should definitly be ZERO. If I move signature and dhkxGroup below ReplyPending, then ReplySuccessful becomes 0.
Why is this?
PS. To me, the only "benefit" of using iota is that you can ommit the value assigned to later constants, so that you can easily modify/insert new values. However, if iota is not FIXED to zero, it could cause big problem especially in doing things like communication protocols.

The spec defines iota's usage in Go (emphasis added):
Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants. Its value is the index of the respective ConstSpec in that constant declaration, starting at zero.
Note that the index is relative to the ConstSpec, basically meanining the current const block.
Of particular interest is probably the example provided:
const (
a = 1 << iota // a == 1 (iota == 0)
b = 1 << iota // b == 2 (iota == 1)
c = 3 // c == 3 (iota == 2, unused)
d = 1 << iota // d == 8 (iota == 3)
)
Notice line 3 (iota value 2) is unused. You have essentially the same, with two unused values coming first.
What you probably meant in your code is:
const (
signature uint32 = 0xae3179fb
dhkxGroup = 2
)
const (
ReplySuccessful byte = iota
ReplyBufferCorrupted
ReplyDecryptFailed
ReplySessionExpired
ReplyPending
)
See it on the playground

Related

Odd behavior of Golang type conversion [duplicate]

Why does below code fail to compile?
package main
import (
"fmt"
"unsafe"
)
var x int = 1
const (
ONE int = 1
MIN_INT int = ONE << (unsafe.Sizeof(x)*8 - 1)
)
func main() {
fmt.Println(MIN_INT)
}
I get an error
main.go:12: constant 2147483648 overflows int
Above statement is correct. Yes, 2147483648 overflows int (In 32 bit architecture). But the shift operation should result in a negative value ie -2147483648.
But the same code works, If I change the constants into variables and I get the expected output.
package main
import (
"fmt"
"unsafe"
)
var x int = 1
var (
ONE int = 1
MIN_INT int = ONE << (unsafe.Sizeof(x)*8 - 1)
)
func main() {
fmt.Println(MIN_INT)
}
There is a difference in evaluation between constant and non-constant expression that arises from constants being precise:
Numeric constants represent exact values of arbitrary precision and do not overflow.
Typed constant expressions cannot overflow; if the result cannot be represented by its type, it's a compile-time error (this can be detected at compile-time).
The same thing does not apply to non-constant expressions, as this can't be detected at compile-time (it could only be detected at runtime). Operations on variables can overflow.
In your first example ONE is a typed constant with type int. This constant expression:
ONE << (unsafe.Sizeof(x)*8 - 1)
Is a constant shift expression, the following applies: Spec: Constant expressions:
If the left operand of a constant shift expression is an untyped constant, the result is an integer constant; otherwise it is a constant of the same type as the left operand, which must be of integer type.
So the result of the shift expression must fit into an int because this is a constant expression; but since it doesn't, it's a compile-time error.
In your second example ONE is not a constant, it's a variable of type int. So the shift expression here may –and will– overflow, resulting in the expected negative value.
Notes:
Should you change ONE in the 2nd example to a constant instead of a variable, you'd get the same error (as the expression in the initializer would be a constant expression). Should you change ONE to a variable in the first example, it wouldn't work as variables cannot be used in constant expressions (it must be a constant expression because it initializes a constant).
Constant expressions to find min-max values
You may use the following solution which yields the max and min values of uint and int types:
const (
MaxUint = ^uint(0)
MinUint = 0
MaxInt = int(MaxUint >> 1)
MinInt = -MaxInt - 1
)
func main() {
fmt.Printf("uint: %d..%d\n", MinUint, MaxUint)
fmt.Printf("int: %d..%d\n", MinInt, MaxInt)
}
Output (try it on the Go Playground):
uint: 0..4294967295
int: -2147483648..2147483647
The logic behind it lies in the Spec: Constant expressions:
The mask used by the unary bitwise complement operator ^ matches the rule for non-constants: the mask is all 1s for unsigned constants and -1 for signed and untyped constants.
So the typed constant expression ^uint(0) is of type uint and is the max value of uint: it has all its bits set to 1. Given that integers are represented using 2's complement: shifting this to the left by 1 you'll get the value of max int, from which the min int value is -MaxInt - 1 (-1 due to the 0 value).
Reasoning for the different behavior
Why is there no overflow for constant expressions and overflow for non-constant expressions?
The latter is easy: in most other (programming) languages there is overflow. So this behavior is consistent with other languages and it has its benefits.
The real question is the first: why isn't overflow allowed for constant expressions?
Constants in Go are more than values of typed variables: they represent exact values of arbitrary precision. Staying at the word exact, if you have a value that you want to assign to a typed constant, allowing overflow and assigning a completely different value doesn't really live up to exact.
Going forward, this type checking and disallowing overflow can catch mistakes like this one:
type Char byte
var c1 Char = 'a' // OK
var c2 Char = '世' // Compile-time error: constant 19990 overflows Char
What happens here? c1 Char = 'a' works because 'a' is a rune constant, and rune is alias for int32, and 'a' has numeric value 97 which fits into byte's valid range (which is 0..255).
But c2 Char = '世' results in a compile-time error because the rune '世' has numeric value 19990 which doesn't fit into a byte. If overflow would be allowed, your code would compile and assign 22 numeric value ('\x16') to c2 but obviously this wasn't your intent. By disallowing overflow this mistake is easily caught, and at compile-time.
To verify the results:
var c1 Char = 'a'
fmt.Printf("%d %q %c\n", c1, c1, c1)
// var c2 Char = '世' // Compile-time error: constant 19990 overflows Char
r := '世'
var c2 Char = Char(r)
fmt.Printf("%d %q %c\n", c2, c2, c2)
Output (try it on the Go Playground):
97 'a' a
22 '\x16'
To read more about constants and their philosophy, read the blog post: The Go Blog: Constants
And a couple more questions (+answers) that relate and / or are interesting:
Golang: on-purpose int overflow
How does Go perform arithmetic on constants?
Find address of constant in go
Why do these two float64s have different values?
How to change a float64 number to uint64 in a right way?
Writing powers of 10 as constants compactly

Different behavior of len() with const or non-const value

The code below
const s = "golang.go"
var a byte = 1 << len(s) / 128
The result of a is 4. However, after changing const s to var s as following
var s = "golang.go"
var a byte = 1 << len(s) / 128
The result of a is 0 now.
Also other test codes as below
const s = "golang.go"
var a byte = 1 << len(s) / 128 // the result of a is 4
var b byte = 1 << len(s[:]) / 128 // the result of b is 0
var ss = "golang.go"
var aa byte = 1 << len(ss) / 128 // the result of aa is 0
var bb byte = 1 << len(ss[:]) / 128 // the result of bb is 0
It is weird that b is 0 with evaluating the length of s[:]
I try to understand it per golang spec
The expression len(s) is constant if s is a string constant. The expressions len(s) and cap(s) are constants if the type of s is an array or pointer to an array and the expression s does not contain channel receives or (non-constant) function calls
But I failed. Could someone explain it more clearly to me?
The difference is that when s is constant, the expression is interpreted and executed as a constant expression, using untyped integer type and resulting in int type. When s is a variable, the expression is interpreted and executed as a non-constant expression, using byte type.
Spec: Operators:
The right operand in a shift expression must have integer type or be an untyped constant representable by a value of type uint. If the left operand of a non-constant shift expression is an untyped constant, it is first implicitly converted to the type it would assume if the shift expression were replaced by its left operand alone.
The quoted part applies when s is a variable. The expression is a non-constant shift expression (1 << len(s)) because s is a variable (so len(s) is non-constant), and the left operand is an untyped constant (1). So 1 is converted to a type it would assume if the shift expression were replaced by its left operand alone:
var a byte = 1 << len(s) / 128
replaced to
var a byte = 1 / 128
In this variable declaration byte type will be used because that type is used for the variable a. So back to the original: byte(1) shifted left by 9 will be 0, dividing it by 128 will also be 0.
And when s is constant, int will be used because Spec: Constant expressions:
If the left operand of a constant shift expression is an untyped constant, the result is an integer constant; otherwise it is a constant of the same type as the left operand, which must be of integer type.
Here 1 will not be converted to byte but 1 << len(s) => 1 << 9 will be 512, divided by 128 will be 4.
Constant in Go behave differently than you might expect. They are "arbitrary precision and _un_typed".
With const consts = "golang.go" the expression 1 << len(consts) / 128 is a constant expression and evaluated as a constant expression with arbitrary precision resulting in an untyped integer 4 which can be assigned to a byte resulting in a == 4.
With var vars = "golang.go" the expression 1 << len(vars) / 128 no longer is a constant expression but has to be evaluated as some typed int. How is defined in https://go.dev/ref/spec#Operators
The right operand in a shift expression must have integer type or be an untyped constant representable by a value of type uint. If the left operand of a non-constant shift expression is an untyped constant, it is first implicitly converted to the type it would assume if the shift expression were replaced by its left operand alone.
The second sentence applies to your problem. The 1 is converted to "the type it would [read will] assume". Spelled out this is byte(1) << len(vars) which is 0.
https://go.dev/blog/constants

converting Golang float32 to half-precision float (GLSL float16) as uint16

I need to pass some data over from Go to an '300 es' shader. The data consists of two uint16s packed into a uint32. Each uint16 represents a half-precision float (float16). I found some PD Java code that looks like it will do the job, but I am struggling with porting the last statement, which uses a couple of zero-extend right shifts (I think the other shifts are fine i.e. non-negative). Since Go is a bit clever with extending, the solution to the port is eluding me. I did think maybe the first one could be changed into a left shift, since it just seems to be positioning a single bit for addition? but the final shift blows my mind out the water :)
btw I hope I got the bracketing right, since the operator precedence seems to be different between Go and Java regarding '-' and '>>'...
I need to go the other way around next, but that is hopefully easier without right shifts... famous last words!
Java code:
https://stackoverflow.com/a/6162687/345165
// returns all higher 16 bits as 0 for all results
public static int fromFloat( float fval )
{
int fbits = Float.floatToIntBits( fval );
int sign = fbits >>> 16 & 0x8000; // sign only
int val = ( fbits & 0x7fffffff ) + 0x1000; // rounded value
if( val >= 0x47800000 ) // might be or become NaN/Inf
{ // avoid Inf due to rounding
if( ( fbits & 0x7fffffff ) >= 0x47800000 )
{ // is or must become NaN/Inf
if( val < 0x7f800000 ) // was value but too large
return sign | 0x7c00; // make it +/-Inf
return sign | 0x7c00 | // remains +/-Inf or NaN
( fbits & 0x007fffff ) >>> 13; // keep NaN (and Inf) bits
}
return sign | 0x7bff; // unrounded not quite Inf
}
if( val >= 0x38800000 ) // remains normalized value
return sign | val - 0x38000000 >>> 13; // exp - 127 + 15
if( val < 0x33000000 ) // too small for subnormal
return sign; // becomes +/-0
val = ( fbits & 0x7fffffff ) >>> 23; // tmp exp for subnormal calc
return sign | ( ( fbits & 0x7fffff | 0x800000 ) // add subnormal bit
+ ( 0x800000 >>> val - 102 ) // round depending on cut off
>>> 126 - val ); // div by 2^(1-(exp-127+15)) and >> 13 | exp=0
}
My partial port:
func float32toUint16(f float32) uint16 {
fbits := math.Float32bits(f)
sign := uint16((fbits >> 16) & 0x00008000)
rv := (fbits & 0x7fffffff) + 0x1000
if rv >= 0x47800000 {
if (fbits & 0x7fffffff) >= 0x47800000 {
if rv < 0x7f800000 {
return sign | 0x7c00
}
return sign | 0x7c00 | uint16((fbits&0x007fffff)>>13)
}
return sign | 0x7bff
}
if rv >= 0x38800000 {
return sign | uint16((rv-0x38000000)>>13)
}
if rv < 0x33000000 {
return sign
}
rv = (fbits & 0x7fffffff) >> 23
return sign | uint16(((fbits&0x7fffff)|0x800000)+(0x800000>>(rv-102))>>(126-rv)) //these two shifts are my problem
}
func pack16(f1 float32, f2 float32) uint32 {
ui161 := float32toUint16(f1)
ui162 := float32toUint16(f2)
return ((uint32(ui161) << 16) | uint32(ui162))
}
I found what looked like even more efficient code, with no branching, but understanding the mechanics of how that works to be able to port it is a bit ;) beyond my rusty (not the language) skills.
https://stackoverflow.com/a/5587983
Cheers
[Edit] The code appears to work with the values I am currently using (it's hard to be precise since I have no experience debuging a shader). So I guess my question is about the correctness of my port, especially the final two shifts.
[Edit2] In the light of day I can see I already got the precedence wrong in one place and fixed the above example.
changed:
return sign | uint16(rv-(0x38000000>>13))
to:
return sign | uint16((rv-0x38000000)>>13)

How do I pass an array of C.double's to a Cgo function?

I'm just getting started with CGo and I'm trying to send data to a C library that performs statistical computations on arrays of floats/doubles. What I'm trying to figure out right now is how to send an array of floats, or C.double's, to a CGo function that has a signature like this:
double pop_mean(int numPoints, double a[])
I've figured out how to get in the C.int in there, but I'm having trouble figuring out how to send in an array of doubles.
I haven't yet seen any blog posts or SO Questions about this exact thing, so I thought I'd ask.
The following is my best effort so far.
// Get a basic function to work, while passing in an ARRAY arr := make([]C.double, 0)
arr = append(arr, C.double(10.0))
arr = append(arr, C.double(20.0))
arr = append(arr, C.double(30.0))
var fixedArray [3]C.double = arr[:]
// ptr := C.CBytes(arr)
// defer C.free(unsafe.Pointer(ptr))
coolMean := C.pop_mean(3, &fixedArray)
fmt.Println("pop_mean (10, 20, 30): ", coolMean)
And this is the error I'm getting:
./main.go:64:6: cannot use arr[:] (type []_Ctype_double) as type [3]_Ctype_double in assignment
./main.go:69:35: cannot use &fixedArray (type *[3]_Ctype_double) as type *_Ctype_double in argument to _Cfunc_pop_mean
How should I be passing an array of C.double to the code?
When an array name is passed to a function, what is passed is the
location of the initial element. Within the called function, this
argument is a local variable, and so an array name parameter is a
pointer, that is, a variable containing an address.
C Programming Language, 2nd Edition
Slice types
A slice is a descriptor for a contiguous segment of an underlying
array and provides access to a numbered sequence of elements from that
array.
Like arrays, slices are indexable and have a length. The length of a
slice s can be discovered by the built-in function len; unlike with
arrays it may change during execution. The elements can be addressed
by integer indices 0 through len(s)-1. The slice index of a given
element may be less than the index of the same element in the
underlying array.
A slice, once initialized, is always associated with an underlying
array that holds its elements.
The Go Programming Language Specification
Reference: Go Command cgo
For a slice a, the arguments to the pop_mean(int numPoints, double a[]) C function are len(a), the length of the slice underlying array, and &a[0], the address of the first element of the slice underlying array.
In Go, we often hide details in a function. For example, a popMean function,
package main
import (
"fmt"
)
/*
double pop_mean(int numPoints, double a[]) {
if (a == NULL || numPoints == 0) {
return 0;
}
double mean = 0;
for (int i = 0; i < numPoints; i++) {
mean+=a[i];
}
return mean / numPoints;
}
*/
import "C"
func popMean(a []float64) float64 {
// This is the general case, which includes the special cases
// of zero-value (a == nil and len(a) == 0)
// and zero-length (len(a) == 0) slices.
if len(a) == 0 {
return 0
}
return float64(C.pop_mean(C.int(len(a)), (*C.double)(&a[0])))
}
func main() {
a := make([]float64, 10)
for i := range a {
a[i] = float64(i + 1)
}
// slice
fmt.Println(len(a), a)
pm := popMean(a)
fmt.Println(pm)
// subslice
b := a[1:4]
fmt.Println(len(b), b)
pm = popMean(b)
fmt.Println(pm)
// zero length
c := a[:0]
fmt.Println(len(c), c)
pm = popMean(c)
fmt.Println(pm)
// zero value (nil)
var z []float64
fmt.Println(len(z), z, z == nil)
pm = popMean(z)
fmt.Println(pm)
}
Output:
10 [1 2 3 4 5 6 7 8 9 10]
5.5
3 [2 3 4]
3
0 []
0
0 [] true
0
I figured out that you have to send a pointer to the first value in the array, rather than sending a pointer to the first element of the slice, or to the slice itself.
AND I also ran into the problem where I had created a new variable that was assigned the value of the first item in the slice and later created a pointer to that variable (which was no longer a part of the original array), instead of creating a pointer to the first item in the array (like I wanted).
Below is the working code, with comments to help avoid the problem in the paragraph above.
// Get a basic function to work, while passing in an ARRAY
// Create a dummy array of (10,20,30), the mean of which is 20.
arr := make([]C.double, 0)
arr = append(arr, C.double(10.0))
arr = append(arr, C.double(20.0))
arr = append(arr, C.double(30.0))
firstValue := &(arr[0]) // this notation seems to be pretty important... Re-use this!
// if you don't make it a pointer right away, then you make a whole new object in a different location, so the contiguous-ness of the array is jeopardized.
// Because we have IMMEDIATELY made a pointer to the original value,the first value in the array, we have preserved the contiguous-ness of the array.
fmt.Println("array length: ", len(arr))
var arrayLength C.int
arrayLength = C.int(len(arr))
// arrayLength = C.int(2)
fmt.Println("array length we are using: ", arrayLength)
arrayMean := C.pop_mean(arrayLength, firstValue)
fmt.Println("pop_mean (10, 20, 30): ", arrayMean)
This produces the following result:
array length: 3
array length we are using: 3
pop_mean (10, 20, 30): 20
Or if we uncomment the line that changes the arrayLength to be 2, we get this result:
array length: 3
array length we are using: 2
pop_mean (10, 20, 30): 15

How to add or subtract two enum values in swift

So I have this enum that defines different view positions on a View controller when a side bar menu is presented. I need to add, subtract, multiply, or divide the different values based on different situations. How exactly do I form a method to allow me to use -, +, *, or / operators on the values in the enum. I can find plenty examples that use the compare operator ==. Although I haven't been able to find any that use >=. Which I also need to be able to do.
Here is the enum
enum FrontViewPosition: Int {
case None
case LeftSideMostRemoved
case LeftSideMost
case LeftSide
case Left
case Right
case RightMost
case RightMostRemoved
}
Now I'm trying to use these operators in functions like so.
func getAdjustedFrontViewPosition(_ frontViewPosition: FrontViewPosition, forSymetry symetry: Int) {
var frontViewPosition = frontViewPosition
if symetry < 0 {
frontViewPosition = .Left + symetry * (frontViewPosition - .Left)
}
}
Also in another function like so.
func rightRevealToggle(animated: Bool) {
var toggledFrontViewPosition: FrontViewPosition = .Left
if self.frontViewPosition >= .Left {
toggledFrontViewPosition = .LeftSide
}
self.setFrontViewPosition(toggledFrontViewPosition, animated: animated)
}
I know that i need to directly create the functions to allow me to use these operators. I just don't understand how to go about doing it. A little help would be greatly appreciated.
The type you are trying to define has a similar algebra to pointers in that you can add an offset to a pointer to get a pointer and subtract two pointers to get a difference. Define these two operators on your enum and your other functions will work.
Any operators over your type should produce results in your type. There are different ways to achieve this, depending on your requirements. Here we shall treat your type as a wrap-around ("modulo") one - add 1 to the last literal and you get the first. To do this we use raw values from 0 to n for your types literals and use modulo arithmetic.
First we need a modulo operator which always returns a +ve result, the Swift % can return a -ve one which is not what is required for modulo arithmetic.
infix operator %% : MultiplicationPrecedence
func %%(_ a: Int, _ n: Int) -> Int
{
precondition(n > 0, "modulus must be positive")
let r = a % n
return r >= 0 ? r : r + n
}
Now your enum assigning suitable raw values:
enum FrontViewPosition: Int
{
case None = 0
case LeftSideMostRemoved = 1
case LeftSideMost = 2
case LeftSide = 3
case Left = 4
case Right = 5
case RightMost = 6
case RightMostRemoved = 7
Now we define the appropriate operators.
For addition we can add an integer to a FrontViewPosition and get a FrontViewPosition back. To do this we convert to raw values, add, and then reduce modulo 8 to wrap-around. Note the need for a ! to return a non-optional FrontViewPosition - this will always succeed due to the modulo math:
static func +(_ x : FrontViewPosition, _ y : Int) -> FrontViewPosition
{
return FrontViewPosition(rawValue: (x.rawValue + y) %% 8)!
}
For subtraction we return the integer difference between two FrontViewPosition values:
static func -(_ x : FrontViewPosition, _ y : FrontViewPosition) -> Int
{
return x.rawValue - y.rawValue
}
}
You can define further operators as needed, say a subtraction operator which takes a FrontViewPosition and an Int and returns a FrontViewPosition.
HTH
Enum could have function~
enum Tst:Int {
case A = 10
case B = 20
case C = 30
static func + (t1:Tst,t2:Tst) -> Tst {
return Tst.init(rawValue: t1.rawValue+t2.rawValue)! //here could be wrong!
}
}
var a = Tst.A
var b = Tst.B
var c = a+b

Resources