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.
Related
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
I want to format float64 value to 2 decimal places in golang html/template say in index.html file. In .go file I can format like:
strconv.FormatFloat(value, 'f', 2, 32)
But I don't know how to format it in template. I am using gin-gonic/gin framework for backend. Any help will be appreciated. Thanks.
You have many options:
You may decide to format the number e.g. using fmt.Sprintf() before passing it to the template execution (n1)
Or you may create your own type where you define the String() string method, formatting to your liking. This is checked and used by the template engine (n2).
You may also call printf directly and explicitly from the template and use custom format string (n3).
Even though you can call printf directly, this requires to pass the format string. If you don't want to do this every time, you can register a custom function doing just that (n4)
See this example:
type MyFloat float64
func (mf MyFloat) String() string {
return fmt.Sprintf("%.2f", float64(mf))
}
func main() {
t := template.Must(template.New("").Funcs(template.FuncMap{
"MyFormat": func(f float64) string { return fmt.Sprintf("%.2f", f) },
}).Parse(templ))
m := map[string]interface{}{
"n0": 3.1415,
"n1": fmt.Sprintf("%.2f", 3.1415),
"n2": MyFloat(3.1415),
"n3": 3.1415,
"n4": 3.1415,
}
if err := t.Execute(os.Stdout, m); err != nil {
fmt.Println(err)
}
}
const templ = `
Number: n0 = {{.n0}}
Formatted: n1 = {{.n1}}
Custom type: n2 = {{.n2}}
Calling printf: n3 = {{printf "%.2f" .n3}}
MyFormat: n4 = {{MyFormat .n4}}`
Output (try it on the Go Playground):
Number: n0 = 3.1415
Formatted: n1 = 3.14
Custom type: n2 = 3.14
Calling printf: n3 = 3.14
MyFormat: n4 = 3.14
Use the printf template built-in function with the "%.2f" format:
tmpl := template.Must(template.New("test").Parse(`The formatted value is = {{printf "%.2f" .}}`))
tmpl.Execute(os.Stdout, 123.456789)
Go Playgroung
You can register a FuncMap.
package main
import (
"fmt"
"os"
"text/template"
)
type Tpl struct {
Value float64
}
func main() {
funcMap := template.FuncMap{
"FormatNumber": func(value float64) string {
return fmt.Sprintf("%.2f", value)
},
}
tmpl, _ := template.New("test").Funcs(funcMap).Parse(string("The formatted value is = {{ .Value | FormatNumber }}"))
tmpl.Execute(os.Stdout, Tpl{Value: 123.45678})
}
Playground
Edit: I was wrong about rounding/truncating.
The problem with %.2f formatting is that it does not round but truncates.
I've developed a decimal class based on int64 for handling money that is handling floats, string parsing, JSON, etc.
It stores amount as 64 bit integer number of cents. Can be easily created from float or converted back to float.
Handy for storing in DB as well.
https://github.com/strongo/decimal
package example
import "github.com/strongo/decimal"
func Example() {
var amount decimal.Decimal64p2; print(amount) // 0
amount = decimal.NewDecimal64p2(0, 43); print(amount) // 0.43
amount = decimal.NewDecimal64p2(1, 43); print(amount) // 1.43
amount = decimal.NewDecimal64p2FromFloat64(23.100001); print(amount) // 23.10
amount, _ = decimal.ParseDecimal64p2("2.34"); print(amount) // 2.34
amount, _ = decimal.ParseDecimal64p2("-3.42"); print(amount) // -3.42
}
Works well for my debts tracker app https://debtstracker.io/
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
}
They seem to be the same:
package main
import "fmt"
type S struct {
i int
}
func main() {
var s1 *S = new(S)
fmt.Println(s1)
var s2 *S = &S{}
fmt.Println(s2) // Prints the same thing.
}
Update:
Hm. I just realized that there's no obvious way to initialize S.i using new. Is there a way to do that? new(S{i:1}) does not seem to work :/
From Effective Go:
As a limiting case, if a composite literal contains no fields at all, it creates a zero value for the type. The expressions new(File) and &File{} are equivalent.
Not only do they give the same resulting value, but if we allocate something both ways and look at their values...
// Adapted from http://tour.golang.org/#30
package main
import "fmt"
type Vertex struct {
X, Y int
}
func main() {
v := &Vertex{}
v2 := new(Vertex)
fmt.Printf("%p %p", v, v2)
}
...we'll see that they are in fact allocated in consecutive memory slots. Typical output: 0x10328100 0x10328108. I'm not sure if this is an implementation detail or part of the specification, but it does demonstrate that they're both being allocated from the same pool.
Play around with the code here.
As for initializing with new, according to the language spec: The built-in function new takes a type T and returns a value of type *T. The memory [pointed to] is initialized as described in the section on initial values. Because functions in go can't be overloaded, and this isn't a variadic function, there's no way to pass in any initialization data. Instead, go will initialize it with whatever version of 0 makes sense for the type and any member fields, as appropriate.
Case 1: package main
import (
"fmt"
)
type Drink struct {
Name string
Flavour string
}
func main() {
a := new(Drink)
a.Name = "Maaza"
a.Flavour = "Mango"
b := a
fmt.Println(&a)
fmt.Println(&b)
b.Name = "Frooti"
fmt.Println(a.Name)
}//This will output Frooti for a.Name, even though the addresses for a and b are different.
Case 2:
package main
import (
"fmt"
)
type Drink struct {
Name string
Flavour string
}
func main() {
a := Drink{
Name: "Maaza",
Flavour: "Mango",
}
b := a
fmt.Println(&a)
fmt.Println(&b)
b.Name = "Froti"
fmt.Println(a.Name)
}//This will output Maaza for a.Name. To get Frooti in this case assign b:=&a.
having a rough time working with struct fields using reflect package. in particular, have not figured out how to set the field value.
type t struct { fi int; fs string }
var r t = t{ 123, "jblow" }
var i64 int64 = 456
getting Name of field i - this seems to work
var field = reflect.TypeOf(r).Field(i).Name
getting value of field i as a) interface{}, b) int - this seems to work
var iface interface{} = reflect.ValueOf(r).Field(i).Interface()
var i int = int(reflect.ValueOf(r).Field(i).Int())
setting value of field i - try one - panic
reflect.ValueOf(r).Field(i).SetInt( i64 )
panic: reflect.Value·SetInt using value obtained using unexported field
assuming it did not like field names "id" and "name", so renamed to "Id" and "Name"
a) is this assumption correct?
b) if correct, thought not necessary since in same file / package
setting value of field i - try two (with field names capitalized ) - panic
reflect.ValueOf(r).Field(i).SetInt( 465 )
reflect.ValueOf(r).Field(i).SetInt( i64 )
panic: reflect.Value·SetInt using unaddressable value
Instructions below by #peterSO are thorough and high quality
Four. this works:
reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )
he documents as well that the field names must be exportable (begin with capital letter)
The Go json package marshals and unmarshals JSON from and to Go structures.
Here's a step-by-step example which sets the value of a struct field while carefully avoiding errors.
The Go reflect package has a CanAddr function.
func (v Value) CanAddr() bool
CanAddr returns true if the value's
address can be obtained with Addr.
Such values are called addressable. A
value is addressable if it is an
element of a slice, an element of an
addressable array, a field of an
addressable struct, or the result of
dereferencing a pointer. If CanAddr
returns false, calling Addr will
panic.
The Go reflect package has a CanSet function, which, if true, implies that CanAddr is also true.
func (v Value) CanSet() bool
CanSet returns true if the value of v
can be changed. A Value can be changed
only if it is addressable and was not
obtained by the use of unexported
struct fields. If CanSet returns
false, calling Set or any
type-specific setter (e.g., SetBool,
SetInt64) will panic.
We need to make sure we can Set the struct field. For example,
package main
import (
"fmt"
"reflect"
)
func main() {
type t struct {
N int
}
var n = t{42}
// N at start
fmt.Println(n.N)
// pointer to struct - addressable
ps := reflect.ValueOf(&n)
// struct
s := ps.Elem()
if s.Kind() == reflect.Struct {
// exported field
f := s.FieldByName("N")
if f.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if f.CanSet() {
// change value of N
if f.Kind() == reflect.Int {
x := int64(7)
if !f.OverflowInt(x) {
f.SetInt(x)
}
}
}
}
}
// N at end
fmt.Println(n.N)
}
Output:
42
7
If we can be certain that all the error checks are unnecessary, the example simplifies to,
package main
import (
"fmt"
"reflect"
)
func main() {
type t struct {
N int
}
var n = t{42}
fmt.Println(n.N)
reflect.ValueOf(&n).Elem().FieldByName("N").SetInt(7)
fmt.Println(n.N)
}
BTW, Go is available as open source code. A good way to learn about reflection is to see how the core Go developers use it. For example, the Go fmt and json packages. The package documentation has links to the source code files under the heading Package files.
This seems to work:
package main
import (
"fmt"
"reflect"
)
type Foo struct {
Number int
Text string
}
func main() {
foo := Foo{123, "Hello"}
fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))
reflect.ValueOf(&foo).Elem().Field(0).SetInt(321)
fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))
}
Prints:
123
321