---
# System prepended metadata

title: go 编程常用的辅助函数
tags: [Golang]

---

# go 编程常用的辅助函数
---

## 1. int to string
```go=
package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(IntToString(10))
}

func IntToString(i int) string {
	return strconv.Itoa(i)
}
```
- **结果输出**
```go=
10
```

## 2. string to int
```go=
package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(StringToInt("10")) // 如果解析的字符串为空，会抛出异常的
}

func StringToInt(str string) (int, error) {
	return strconv.Atoi(str)
}
```
- **结果输出**
```go=
10 <nil>
```
## 3. int64 to string
```go=
package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(int64ToString(10))
}
/*
函数原型

FormatInt(i int64, base int) string

FormatInt返回i在给定基数下的字符串表示形式

base代表输出时的数据用的什么进制表示
*/

func int64ToString(i int64) string {
	return strconv.FormatInt(i, 10)
}
```
- **结果输出**
```go=
10
```
## 4. string to int64
```go=

/*
函数原型

ParseInt(s string, base int, bitSize int) (i int64, err error)

ParseInt解析给定基(0,2到36)和中的字符串s,位大小(0到64)，并返回对应的值i。

如果基值base==0，则基值隐含在字符串的前缀中:
	以16为基数表示“0x”，以8为基数表示“0”，以10为基数表示“0”。
	对于基数为1的情况，低于0或高于36的情况会返回一个错误。

bitSize参数指定整数类型，结果必须符合。位大小0,8,16,32和64，对应int, int8, int16, int32, int64。对于小于0或大于64的位元，将返回错误。

ParseInt返回的错误有具体类型*NumError，包括err。如果s是空的或包含无效的数字,就一定会犯错误。Err = ErrSyntax，返回值为0;

如果s对应的值不能用a表示给定大小的带符号整数。Err = ErrRange同时会返回适当的位大小和符号的最大星等整数。

比如代码中返回的是有符号位最大值的int64 // stringToInt64("10000000000000000000000000000000")
*/

package main

import (
	"fmt"
	"strconv"
)

func main() {
    fmt.Println(stringToInt64("10000000000000000000000000000000")) //int64的最大值为9223372036854775807
    fmt.Println(stringToInt64("10000"))
}

func stringToInt64(str string) (int64, error) {
	return strconv.ParseInt(str, 10, 64)
}
```
- **结果输出**
```go=
9223372036854775807 strconv.ParseInt: parsing "10000000000000000000000000000000": value out of range
10000 <nil>
```

## 5. string to float64
```go=
package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(stringToFloat64("10.666666666666666666666666666"))
	fmt.Println(float32(10.666666666666666666666666666))
}

func stringToFloat64(str string) (float64, error) {
	return strconv.ParseFloat(str, 10)
}

/*
float32的指数范围为-127~128，而float64的指数范围为-1023~1024，并且指数位是按补码的形式来划分的。
其中负指数决定了浮点数所能表达的绝对值最小的数；
而正指数决定了浮点数所能表达的绝对值最大的数，也即决定了浮点数的取值范围。

float32的范围为-2^128 ~ +2^128，也即-3.40E+38 ~ +3.40E+38；
float64的范围为-2^1024 ~ +2^1024，也即-1.79E+308 ~ +1.79E+308。

float32和float64的精度是由尾数的位数来决定的。
浮点数在内存中是按科学计数法来存储的，其整数部分始终是一个隐含着的“1”，由于它是不变的，故不能对精度造成影响。

float32：2^23 = 8388608，一共七位，这意味着最多能有7位有效数字，但绝对能保证的为6位，也即float的精度为6~7位有效数字；

float64：2^52 = 4503599627370496，一共16位，同理，double的精度为15~16位。
*/

```
- **结果输出**
```go=
10.666666666666666 <nil> // 15位有效位
10.666667 // 6位有效位
```
## 6. float64 to string
```go=
package main

import (
	"fmt"
	"strconv"
)

func main() {
    fmt.Println(float32ToString(10.666666666666666666666666666))
	fmt.Println(float64ToString(10.666666666666666666666666666))
}

// 函数原型 FormatFloat(f float64, fmt byte, prec, bitSize int) string

/* fmt的取值及含义
'b' (-ddddp±ddd，二进制指数)
'e' (-d.dddde±dd，十进制指数)
'E' (-d.ddddE±dd，十进制指数)
'f' (-ddd.dddd，没有指数)
'g' ('e':大指数，'f':其它情况)
'G' ('E':大指数，'f':其它情况)
*/

// prec 特殊的精度-1使用的是最小的位数

// bitSize 32->float32, 64-> float64

func float64ToString(f float64) string {
	return strconv.FormatFloat(f,'f',-1,64)
}

func float32ToString(f float64) string {
	return strconv.FormatFloat(f,'f',-1,32)
}

```

- **结果输出**
```go=
10.666666666666666 // 15位有效位
10.666667 // 6位有效位
```

## 7. float64，int64的转换
```go=
package main

import (
	"fmt"
	"math"
)

func main() {
	fmt.Println(float64ToInt64(10.6666666666, 10))
	fmt.Println(int64ToNormalFloat64(106666666666, 10))
	fmt.Println(accurateFloat64(10.666, 3))
	fmt.Println(accurateInt641(10666, 3))
	fmt.Println(accurateInt642(10.666, 3))
}

//将float64转成精确的int64
func float64ToInt64(f float64, i int) int64 {
	return int64(f * math.Pow10(i))
}

//将int64恢复成正常的float64
func int64ToNormalFloat64(num int64, i int) float64 {
	return float64(num) / math.Pow10(i)
}

//精准float64
func accurateFloat64(f float64, i int) float64 {
	return f * math.Pow10(i)
}

//精准int64
func accurateInt641(num int64, i int) int64 {
	return float64ToInt64(int64ToNormalFloat64(num, i), i)
}

//精准int64
func accurateInt642(f float64, i int) int64 {
	return int64(accurateFloat64(f, i))
}

```

- **结果输出**
```go=
106666666666
10.6666666666
10666
10666
10666
```

## 8. string，bool的转换
```go=
package main

import (
	"fmt"
	"strconv"
)

func main() {
	fmt.Println(stringToBool("1"))
    fmt.Println(stringToBool("TRUE"))
	fmt.Println(stringToBool("TrUE"))
	fmt.Println(boolToString(true))
	fmt.Println(boolToString(false))
}

/*
函数入参只接受 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.
任何其它的值都是会返回一个error.
函数原型及内部实现代码
func ParseBool(str string) (bool, error) {
	switch str {
	case "1", "t", "T", "true", "TRUE", "True":
		return true, nil
	case "0", "f", "F", "false", "FALSE", "False":
		return false, nil
	}
	return false, syntaxError("ParseBool", str)
}
 */

func stringToBool(str string) (bool, error) {
	return strconv.ParseBool(str)
}

func boolToString(b bool) string {
	return strconv.FormatBool(b)
}

```

- **结果输出**
```go=
true <nil>
true <nil>
false strconv.ParseBool: parsing "TrUE": invalid syntax
true
false
```

## 9. string, decimal的转换
```go=
package main

import (
	"fmt"
	"github.com/shopspring/decimal"
)

func main() {
	d1, err := decimal.NewFromString("459.8249613756665465") //string to decimal
	fmt.Println("d1", d1, err)
	d2, err := decimal.NewFromString("3.824961375456446132") //string to decimal
	fmt.Println("d2", d2, err)
	q1, q2 := decimal.NewFromFloat(459.8249613756665465), decimal.NewFromFloat(3.824961375456446132) // float64 to decimal, 有效位增多还是会出现精度的丢失，建议存储的时候使用big int或者string
	fmt.Println("q1", q1, "q2", q2)

	fmt.Println("add", add(d1, d2))
	fmt.Println("sub", sub(d1, d2))
	fmt.Println("mul", mul(d1, d2))
	fmt.Println("div", div(d1, d2))
	fmt.Println("int d1", int(d1))
	fmt.Println("int d2", int(d2))
	fmt.Println("float64 d1",float(d1))
	fmt.Println("float64 d2",float(d2))

	d3, err := decimal.NewFromString(".035")
	fmt.Println(d3, err)
	d4, err := decimal.NewFromString(".08875")
	fmt.Println(d4, err)

	fmt.Println("add", add(d3, d4))
	fmt.Println("sub", sub(d3, d4))
	fmt.Println("mul", mul(d3, d4))
	fmt.Println("div", div(d3, d4))
	fmt.Println("int d3", int(d3))
	fmt.Println("int d4", int(d4))
	fmt.Println("float64 d3",float(d3))
	fmt.Println("float64 d4",float(d4))
}

// 加法
func add(d1, d2 decimal.Decimal) decimal.Decimal {
	return d1.Add(d2)
}

// 减法
func sub(d1, d2 decimal.Decimal) decimal.Decimal {
	return d1.Sub(d2)
}

// 乘法
func mul(d1, d2 decimal.Decimal) decimal.Decimal {
	return d1.Mul(d2)
}

// 除法
func div(d1, d2 decimal.Decimal) decimal.Decimal {
	return d1.Div(d2)
}

// int64
func int(d decimal.Decimal) int64 {
	return d.IntPart()
}

// float64
func float(d decimal.Decimal) float64 { //存在转换时的精度丢失，详见打印输出
	f, ok := d.Float64()
	if !ok {
		return f
	}
	return 0
}
```

- **结果输出**
```go=
d1 459.8249613756665465 <nil>
d2 3.824961375456446132 <nil>
q1 459.82496137566653 q2 3.824961375456446
add 463.649922751122992632
sub 456.000000000210100368
mul 1758.812716732676730259113831571723138
div 120.2168901171698791
int d1 459
int d2 3
float64 d1 459.82496137566653
float64 d2 3.824961375456446
0.035 <nil>
0.08875 <nil>
add 0.12375
sub -0.05375
mul 0.00310625
div 0.3943661971830986
int d3 0
int d4 0
float64 d3 0.035
float64 d4 0.08875
```

## 10. big.Int，string的转换
```go=
package main

import (
	"fmt"
	"math/big"
)

func main()  {
	fmt.Println(stringToBigInt("123456789"))
	fmt.Println(stringToBigInt("abc"))
	fmt.Println(bigIntToString(big.NewInt(923456789000000)))
}

func stringToBigInt(s string) (*big.Int, error) {
	n := new(big.Int)
	n, ok := n.SetString(s, 10)
	if !ok {
		return n, fmt.Errorf("set a string to covert big int failed")
	}

	return n, nil
}

func bigIntToString(bigInt *big.Int) string {
	return bigInt.String()
}
```

- **结果输出**
```go=
123456789 <nil>
<nil> set a string to covert big int failed
923456789000000
```

## 11. big.Float，string的转换
```go=
import (
	"fmt"
	"math/big"
)

func main()  {
	fmt.Println(stringToBigFloat("1.45611312346498"))  // TODO ： 有效位数
	fmt.Println(stringToBigFloat("abc"))
	f, b := new(big.Float).SetString("8.2148797302021")
	fmt.Println(f, b)
	if b {
		fmt.Println(bigFloatToString(f))
	}
}

func stringToBigFloat(s string) (*big.Float, bool) {
	n := new(big.Float)
	return n.SetString(s)
}

func bigFloatToString(bigFloat *big.Float) string { // TODO ： 完整输出全部的数据
	return bigFloat.String()
}
```

- **结果输出**
```go=
1.45611312346498 true
<nil> false
8.2148797302021 true
8.21487973
```
## 12. string的比较
```go=
package main

import (
	"fmt"
	"strings"
)

/*
1，自建方法“==”，区分大小写，最简单的方法

2，Compare函数，区分大小写，比自建方法“==”的速度要快

3，比较UTF-8编码在小写的条件下是否相等，不区分大小写
*/

func main()  {
	fmt.Println("go"=="go")
	fmt.Println("GO"=="go")

	fmt.Println(strings.Compare("GO","go"))
	fmt.Println(strings.Compare("go","go"))

	fmt.Println(strings.EqualFold("GO","go"))
}
```

- **结果输出**
```go=
true
false
-1
0
true
```

## 13. float的比较
```go=
package main

import (
	"fmt"
	"math"
)

const MIN = 0.000001 // MIN 为用户自定义的比较精度

func main()  {
	fmt.Println(floatEquals(0, 0))
	fmt.Println(floatEquals(0, 0.1))
}

func floatEquals(a, b float64) bool {
	return math.Abs(a - b) < MIN
}
```

- **结果输出**
```go=
true
false
```

###### tags: `Golang`