go mismatched types uint64 and int32 - go

I don't see what I'm doing wrong here with this error, both are of type syscall.Timeval Usec
Thanks
package common
import (
"syscall"
)
func getUsecSince(oldTime syscall.Timeval) (result uint64) {
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
for now.Sec > oldTime.Sec {
result += 1000000
now.Sec--
}
return result + (now.Usec - oldTime.Usec)
}
./common.go:15: invalid operation: result + (now.Usec - oldTime.Usec) (mismatched types uint64 and int32)

Use a signed return value (int64), like Timeval.Sec and Timeval.Usec. Use TimevalToNsec for portability across operating systems. For example, Timeval fields may be int32 or int64. For a correct result, use,
package main
import (
"fmt"
"syscall"
"time"
)
func getUsecSince(old syscall.Timeval) int64 {
var now syscall.Timeval
syscall.Gettimeofday(&now)
nsecs := syscall.TimevalToNsec(now) - syscall.TimevalToNsec(old)
return nsecs / int64(time.Microsecond)
}
func main() {
old := syscall.Timeval{}
syscall.Gettimeofday(&old)
time.Sleep(2*time.Second + 42*time.Microsecond)
fmt.Println(getUsecSince(old))
}
Output:
2000377

The simplest solution to this is:
func getUsecSince(oldTime syscall.Timeval) (result uint64) {
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
// Automatically ignore cases like 12.5 - 11.8
result = uint64((now.Sec - oldTime.Sec) * 1000000 + int64(now.Usec - oldTime.Usec))
return result
}
By converting to the smallest unit you can ignore the boundary conditions easily as long as there is no overflow during conversion.
Note that if you purposely test the above by using an oldTime in the future, the function will fail. You will need to do a check (with both times converted to Usec) if you want to cover such cases.

Timeval.Usec is defined as int32. Maybe result should be also int32? Alternatively if you want to use uint64 you can cast it by uint64(now.Usec - oldTime.Usec).

result is uint64.
The other operands are int32
Running this
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
typeUsec := reflect.TypeOf(now.Usec)
fmt.Printf("type %s, value %d \n", typeUsec, now.Usec)
will print
type int32, value 238376
Strangely, the go documents have the following
type Timeval struct {
Sec int64
Usec int64
}

Related

Is there a way to get the size of a type within a generic function without reflection? [duplicate]

This question already has answers here:
generic function to get size of any structure in Go
(2 answers)
Closed 6 months ago.
In the case of a generic function that does byte serialization for a generic types, is there a way to proceed--other than reflection--if the different supported types have different sizes? For example:
package main
import (
"fmt"
)
type KeyType interface {
uint16 | uint32 | uint64
}
type Item[KT KeyType] struct {
Key KT
Data []byte
}
// set of generic types that hold collections of Item[T]
// sets of methods that operate on those generic types
func MarshalBinary[KT KeyType](i *Item[KT]) ([]byte, error) {
// How do I compute the size of the item and marshal it?
// It's 2 bytes for uint16, 4 for uint32, 8 for uint64,
// how do I distinguish here?
}
func main() {
i := new(Item[uint32])
i.Key = 42
fmt.Println(i)
}
Is there a way to access the size of the type within the serialization function without reflection?
I know I can proceed with reflection like this:
package main
import (
"fmt"
"reflect"
"strings"
)
type KeyType interface {
uint16 | uint32 | uint64
}
type Item[KT KeyType] struct {
Key KT
Data []byte
}
// set of generic types that hold collections of Item[T]
// sets of methods that operate on those generic types
func MarshalBinary[KT KeyType](i *Item[KT]) ([]byte, error) {
t := reflect.TypeOf(i)
var size int
if strings.Contains(t.String(), `uint32`) {
size = 4
}
fmt.Println(size)
// rest of function here
return nil, nil
}
func main() {
i := new(Item[uint32])
i.Key = 42
MarshalBinary(i)
fmt.Println(i)
}
Is there a better way? My main concern with using reflection here is the potential performance cost.
First off, I think your sample code may be incorrect, because you're using reflect.TypeOf(i), but i is of type Item[KT], and since Item includes both a KT and a []byte, it will be the size of KY plus the size of a pointer (the pointer to the byte slice). So, it will be 4 + pointer size if KT is a uint32, but you're setting it to 4.
So the question is, are you trying to get the size of i (Item[KT]), or the size of an instance of KT?
I assume it's the size of KT that you're actually looking for, since you're assigning a size of 4 if it's a uint32. You can do this without reflect by casting the value you want the size of as an interface{}, then using a standard type switch, as follows:
func MarshalBinary[KT KeyType](i *Item[KT]) ([]byte, error) {
var size int
switch (interface{})(i.Key).(type) {
case uint16:
size = 2
case uint32:
size = 4
case uint64:
size = 8
default:
panic("Unexpected type")
}
...
}
This is a bit problematic if you ever want to expand the different possible types that KeyType could be, though.

Golang default return 2 decimal places

I need to export the json with default 2 decimal places for amount.
In Query i have used "SELECT FORMAT(amount, 2) from product"
type product struct {
Amount float32 `db:"Amount"`
}
So i need if the Amount value is 99 it should export 99.00
every time it is returning 99.
I just simply retrieving data from DB and exporting like json marshal the dynamic product struct.
From DB i am getting with decimal formatted value but the decimal getting lost when we are assigning the value in struct.
NOTE :: fmt.Sprintf("%.2f", value) will not work.
To export 99.00 instead of 99 ,you can convert the amount value from int to float with specified number of decimal points.Here is a simple code with the same logic :
package main
import (
"fmt"
)
func main() {
amount := 99
var desiredVal float64 = float64(amount)
fmt.Printf("amount = %d \n", amount)
fmt.Printf("\nnew amount= %.2f", desiredVal)
}
Output:
amount = 99
new amount= 99.00
As stated above, the formatting needs to be done on the client side - it make sense that way.
Nevertheless here is a workaround - just create a another type with the formatted values, and marshal it:
package main
import (
"encoding/json"
"fmt"
)
type product struct {
Amount float32
}
func main() {
p := product{Amount: 99.00}
fmt.Println(string(marshal(p)))
}
type N struct {
Amount string
}
func NewN(p product) N {
return N{
Amount: fmt.Sprintf("%.2f", p.Amount),
}
}
func marshal(p product) []byte {
n := NewN(p)
r, _ := json.Marshal(&n)
return r
}
{"Amount":"99.00"}
One solution is to assign some improbable value like 7777.777 and then marshal the structure. Then do a string replace of the marshalled string i.e., replace 7777.77 with 99.00.

Looping over slice of aliased(user defined) types gives type before aliasing

I'm trying to loop over slice of user defined types (in example below these are aliased int), but range produces values of type int, instead of MyInt as I would expect. Casting inside 'if' helps for sure, but I would like to understand why range does not produces values of type MyInt.
package main
import (
"fmt"
)
type MyInt int
const (
MYINT00 MyInt = iota
MYINT01
)
func main() {
var myInt02 MyInt = 2
myInts := []MyInt{MYINT00, MYINT01}
for i := range myInts {
if i == myInt02 {
fmt.Println("same")
}
}
}
Playground: https://play.golang.org/p/nb77pvTMdkW
Error:
prog.go:18:8: invalid operation: i == myInt02 (mismatched types int and MyInt)
Then I thought that problem can be related to consts and iota, so I used variables declared in function - didn't change anything.
https://play.golang.org/p/0fVRhBtvlOL
https://play.golang.org/p/pioDSU4oJdP
I haven't found any info in Effective Go/other questions. If anybody has some input on that, please share!
The Go Programming Language Specification
For statements with range clause
Range expression 1st value 2nd value
array or slice a [n]E, *[n]E, or []E index i int a[i] E
i is the range index, an int, not the range value.
For example, fixing your code to use the range value,
package main
import (
"fmt"
)
type MyInt int
const (
MYINT00 MyInt = iota
MYINT01
)
func main() {
var myInt02 MyInt = 2
myInts := []MyInt{MYINT00, MYINT01}
for _, v := range myInts {
if v == myInt02 {
fmt.Println("same")
}
}
}

string to big Int in Go?

Is there a way to convert a string (which is essentially a huge number) from string to Big int in Go?
I tried to first convert it into bytes array
array := []byte(string)
Then converting the array into BigInt.
I thought that worked, however, the output was different than the original input. So I'm guessing the conversion didn't do the right thing for some reason.
The numbers I'm dealing with are more than 300 digits long, so I don't think I can use regular int.
Any suggestions of what is the best approach for this?
Package big
import "math/big"
func (*Int) SetString
func (z *Int) SetString(s string, base int) (*Int, bool)
SetString sets z to the value of s, interpreted in the given base, and
returns z and a boolean indicating success. The entire string (not
just a prefix) must be valid for success. If SetString fails, the
value of z is undefined but the returned value is nil.
The base argument must be 0 or a value between 2 and MaxBase. If the
base is 0, the string prefix determines the actual conversion base. A
prefix of “0x” or “0X” selects base 16; the “0” prefix selects base 8,
and a “0b” or “0B” prefix selects base 2. Otherwise the selected base
is 10.
For example,
package main
import (
"fmt"
"math/big"
)
func main() {
n := new(big.Int)
n, ok := n.SetString("314159265358979323846264338327950288419716939937510582097494459", 10)
if !ok {
fmt.Println("SetString: error")
return
}
fmt.Println(n)
}
Playground: https://play.golang.org/p/ZaSOQoqZB_
Output:
314159265358979323846264338327950288419716939937510582097494459
See Example for string to big int conversion.
package main
import (
"fmt"
"log"
"math/big"
)
func main() {
i := new(big.Int)
_, err := fmt.Sscan("18446744073709551617", i)
if err != nil {
log.Println("error scanning value:", err)
} else {
fmt.Println(i)
}
}
Output:
18446744073709551617

generic function to get size of any structure in Go

I am writing a generic function to get the size of any type of structure, similar to sizeof function in C.
I am trying to do this using interfaces and reflection but I'm not able to get the correct result. Code is below:
package main
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
type myType struct {
a int
b int64
c float32
d float64
e float64
}
info := myType{1, 2, 3.0, 4.0, 5.0}
getSize(info)
}
func getSize(T interface{}) {
v := reflect.ValueOf(T)
const size = unsafe.Sizeof(v)
fmt.Println(size)
}
This code returns wrong result as 12. I am very new to Go, kindly help me on this.
You're getting the size of the reflect.Value struct, not of the object contained in the interface T. Fortunately, reflect.Type has a Size() method:
size := reflect.TypeOf(T).Size()
This gives me 40, which makes sense because of padding.
Go 1.18
With Go 1.18 you can use a generic function with unsafe.Sizeof:
func getSize[T any]() uintptr {
var v T
return unsafe.Sizeof(v)
}
Note that this will be more performant than using reflect, but it will introduce unsafe in your code base — some static analysis tools may give warnings about that.
However if your goal is to improve code reuse or get sizes at run time (read on for the solution to that), this won't help much because you still need to call the function with proper instantiation:
type myType struct {
a int
b int64
c float32
d float64
e float64
}
func main() {
fmt.Println(getSize[myType]())
}
You might get the most out of this when used as part of some other generic code, e.g. a generic type or function where you pass a type param into getSize. Although if you have the argument v this is equivalent to calling unsafe.Sizeof(v) directly. Using a function could be still useful to hide usage of unsafe. A trivial example:
func printSize[T any](v T) {
// (doing something with v)
// instantiate with T and call
s := getSize[T]()
// s := unsafe.Sizeof(v)
fmt.Println(s)
}
Otherwise you can pass an actual argument to getSize. Then type inference will make it unnecessary to specify the type param. This code perhaps is more flexible and allows you to pass arbitrary arguments at runtime, while keeping the benefits of avoiding reflection:
func getSize[T any](v T) uintptr {
return unsafe.Sizeof(v)
}
func main() {
type myType struct {
a int
b int64
c float32
d float64
e float64
}
info := myType{1, 2, 3.0, 4.0, 5.0}
// inferred type params
fmt.Println(getSize(info)) // 40
fmt.Println(getSize(5.0)) // 8
fmt.Println(getSize([]string{})) // 24
fmt.Println(getSize(struct {
id uint64
s *string
}{})) // 16
}
Playground: https://go.dev/play/p/kfhqYHUwB2S

Resources