html/template is not showing a float value with e+07 notation in exact decimal places - go

I'm trying an example where I'm passing a value 1.8e+07 to the TestVal field of struct Student. Now I want this 1.8e+07 value to be in exact decimal places but it is not doing so. It is able to show the value in exact decimal places(180000) if the value is 1.8e+05. But if it is greater than e+05 then it is unable to show it.
Example
package main
import (
"fmt"
"os"
"text/template"
)
// declaring a struct
type Student struct {
Name string
TestVal float32
}
// main function
func main() {
std1 := Student{"AJ", 1.8e+07}
// "Parse" parses a string into a template
tmp1 := template.Must(template.New("Template_1").Parse("Hello {{.Name}}, value is {{.TestVal}}"))
// standard output to print merged data
err := tmp1.Execute(os.Stdout, std1)
// if there is no error,
// prints the output
if err != nil {
fmt.Println(err)
}
}
Please help.

That's just the default formatting for floating point numbers. The package doc of fmt explains it: The %v verb is the default format, which for floating numbers means / reverts to %g which is
%e for large exponents, %f otherwise. Precision is discussed below.
If you don't want the default formatting, use the printf template function and specify the format you want, for example:
{{printf "%f" .TestVal}}
This will output (try it on the Go Playground):
Hello AJ, value is 18000000.000000
Or use:
{{printf "%.0f" .TestVal}}
Which will output (try it on the Go Playground):
Hello AJ, value is 18000000
See related:
Format float in golang html/template

Related

Printing value of a *big.Int field in a Go struct

I have a big.Int I need to store inside of a struct, but when I try to do so it overflows. Code example below
type NumberStore struct {
mainnumber *big.Int
}
var ledger NumberStore
// In decimal this is 33753000000000000000
var largehex string = "1D46ABEAB3FC28000"
myNumber := new(big.Int)
myNumber.SetString(largehex, 16)
ledger.mainnumber = myNumber
fmt.Println(ledger)// Prints 0xc0000a64c0, but I need it to be 33753000000000000000
Since mainnumber is a pointer field in your NumberStore struct, printing out the struct by default will just print out the value of the pointer, not the value it points to.
As the comment says, if you make your field exported then fmt.Println will show the underlying value; but if you don't need it exported, then fmt.Println(ledger.mainnumber) should print the number you expect. Here's your full code with one line added at the end:
package main
import (
"fmt"
"math/big"
)
type NumberStore struct {
mainnumber *big.Int
}
func main() {
var ledger NumberStore
// In decimal this is 33753000000000000000
var largehex string = "1D46ABEAB3FC28000"
myNumber := new(big.Int)
myNumber.SetString(largehex, 16)
ledger.mainnumber = myNumber
fmt.Println(ledger)
fmt.Println(ledger.mainnumber)
}
Run on the Playground, it prints:
{0xc000092000}
33753000000000000000
By printing like this fmt.Println(ledger), you're relying on the default formatting of the value ledger. For each field in the struct, it will only print the default representation of that value, unless it can access the appropriate custom formatting code for that type. For mainnumber of type *big.Int, that is "pointer to big.Int", it's simply printing the pointer address.
In order to give fmt access to the custom string formatting code for a *big.Int value, you either need to pass it directly: fmt.Println(ledger.mainnumber), or change mainnumber to an exported field, like this:
type NumberStore struct {
Mainnumber *big.Int
}
The fmt package cannot automatically find the value's formatting code (the .String() string method) if it is an unexported struct field.

Parsefloat give output in scientific format in golang

i am trying to parse this string "7046260" using Parsefloat function in golang , but i am getting output in scientific format 7.04626e+06. i want the output in the format 7046260. how to get this?
package main
import (
"fmt"
"strconv"
)
func main() {
Value := "7046260"
Fval, err := strconv.ParseFloat(Value, 64)
if err == nil {
fmt.Println(Fval)
}
}
ouput :- 7.04626e+06
Parsefloat give output in scientific format in golang
i am trying to parse this string "7046260" using Parsefloat function in golang , but i am getting output in scientific format 7.04626e+06. i want the output in the format 7046260
You're confusing the floating-point value's (default) formatted output with its internal representation.
ParseFloat is working fine.
You just need to specify an output format:
See the fmt package documentation.
Use Printf to specify a format-string.
Use the format %.0f to instruct Go to print the value as-follows:
% marks the start of a placeholder.
. denotes default width (i.e. don't add leading or trailing zeroes).
0 denotes zero radix precision (i.e. don't print any decimal places, even if the value has them)
f denotes the end of the placeholder, and that the placeholder is for a floating-point value.
I have a few other recommendations:
Local variables in Go should use camelCase, not PascalCase. Go does not encourage the use of snake_case.
You should check err != nil after each nil-returning function returns and either fail-fast (if appropriate), pass the error up (and optionally log it), or handle it gracefully.
When working with floating-point numbers, you should be aware of NaN's special status. The IsNaN function is the only way to correctly check for NaN values (because ( aNaNValue1 == math.NaN ) == false).
The same applies in all languages that implement IEEE-754, including Java, JavaScript, C, C#.NET and Go.
Like so:
package main
import (
"fmt"
"strconv"
"math"
"log"
)
func main() {
numberText := "7046260"
numberFloat, err := strconv.ParseFloat(numberText, 64)
if err != nil {
log.Fatal(err)
}
if math.IsNaN(numberFloat) {
log.Fatal("NaN value encountered")
}
fmt.Printf("%.0f",numberFloat)
fmt.Println()
}

prevent json.Marshal time.Time removing trailing zeros

I have code similar to the following
package main
import (
"fmt"
"time"
"encoding/json"
)
type Message struct {
Time time.Time `json:"timestamp,omitempty"`
}
func main() {
t, _ := time.Parse("2006-01-02T15:04:05.999Z07:00", "2017-05-01T15:04:05.630Z")
msg := Message{
Time: t,
}
bs, _ := json.Marshal(msg)
fmt.Println(string(bs[:]))
}
This prints
{"timestamp":"2017-05-01T15:04:05.63Z"}
How can I make json marshalling keep the trailing 0? I.e., to print this?
{"timestamp":"2017-05-01T15:04:05.630Z"}
Edit:
Here's the playground https://play.golang.org/p/9p3kWeiwu2
time.Time always marshals to RFC 3339, only including sub-second precision if present: https://golang.org/pkg/time/#Time.MarshalJSON
You can write your own custom version using a named time.Time type, or you can define a custom marshal function for your structure, or you can make your structure hold a string in that place instead. In any case, if you want to use the same format, but including trailing zeros, you need to use a modified version of the RFC3339Nano constant.
Its value is: "2006-01-02T15:04:05.999999999Z07:00".
The 9's at the end mean "include until the rightmost non-zero value, omit after that". If you change those 9's to 0's, it will always include them. For example, if you always want millisecond precision (and nothing after that, regardless of whether it's non-zero or not), you would use:
"2006-01-02T15:04:05.000Z07:00"
If you feed that to Format() on your time.Time value, you'll get out the string you want, and can thus include it in the JSON.
Functioning example: https://play.golang.org/p/oqwnma6odw

What is the correct string format specifier for integer in fmt.Printf?

var count int = 5
fmt.Printf("count:%i\n", count)
Its output is
count:%!i(int=5)
What is the correct format specifier so that the output is
count:5
I look up the package fmt's method Printf in Go's package website, but it doesn't say about the syntax for a format specifier. Where can I find the syntax?
Thanks.
%d is the format specifier for base 10 integers (what you typically want) a full listing of fmt's format specifiers can be found here; https://golang.org/pkg/fmt/
var count int = 5
fmt.Printf("count:%d\n", count)
// prints count:5
%d is the format specifier for integer. However, You can use %v to print the value of the variable in default format, no matter what the data type is.
For example:
package main
import (
"fmt"
)
func main() {
//prints Hello 1 0.5 {Hello}
fmt.Printf("%v %v %v %v", "Hello", 1, 0.5, struct{ v string }{"Hello"})
}
You could also simply opt for the Println function:
fmt.Println("count:", count)

What is "%!s" in the output of a float?

I'm getting coordinates (location) as an output of 2 float64 numbers, and it looks like this:
&{%!s(float64=42.539679) %!s(float64=42.601339)}
This is the first time I'm seeing anything like that, so what is "%!s"?
"TypeOf" says "%!s(float64=42.539679)" is float64. So how do I work with this kind of floats? Is there any way to parse it, or somehow to make the %!s(float64=42.539679) look like 42.539679?
UPD: the highlighted line is a *tgbotapi.Location object from Syfaro's telegram bot api.
The api has this structure:
type Location struct {
Longitude float64 `json:"longitude"`
Latitude float64 `json:"latitude"`
}
and the Location.Latitude gives me this: "%!s(float64=42.539679)" (float64)(?)
https://golang.org/pkg/fmt/
%!s is basically used in errors to help you identify a problem.
I think this is a matter of using an incorrect format "verb." You need to use %f instead of %s
package main
import (
"fmt"
)
func main() {
var f float64 = 3.14
fmt.Printf("attempting to print as string: %s \n", f)
fmt.Printf("attempting to print as float: %f", f)
}
Runnable: https://play.golang.org/p/Pec_QrxBIl

Resources