decimal
Kho lưu trữ: shopspring/decimal: Arbitrary-precision fixed-point decimal numbers in go (github.com)
Tài liệu: decimal package - github.com/shopspring/decimal - Go Packages
Giới thiệu
Một thư viện số thập phân dấu phẩy động được viết bằng Go, có các đặc điểm sau:
- Giá trị 0 mặc định, có thể sử dụng an toàn mà không cần khởi tạo
- Phép cộng, trừ, nhân không mất độ chính xác
- Phép chia với độ chính xác chỉ định
- Serialization/deserialization database/sql
- Serialization/deserialization JSON và XML
Cài đặt
go get github.com/shopspring/decimalBắt đầu nhanh
go
package main
import (
"fmt"
"github.com/shopspring/decimal"
)
func main() {
price, err := decimal.NewFromString("136.02")
if err != nil {
panic(err)
}
quantity := decimal.NewFromInt(3)
fee, _ := decimal.NewFromString(".035")
taxRate, _ := decimal.NewFromString(".08875")
subtotal := price.Mul(quantity)
preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1)))
total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1)))
fmt.Println("Subtotal:", subtotal) // Subtotal: 408.06
fmt.Println("Pre-tax:", preTax) // Pre-tax: 422.3421
fmt.Println("Taxes:", total.Sub(preTax)) // Taxes: 37.482861375
fmt.Println("Total:", total) // Total: 459.824961375
fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
}Các phương thức hữu ích
go
// Tạo từ chuỗi
func NewFromString(value string) (Decimal, error)
// Tạo từ float64
func NewFromFloat(value float64) Decimal
// Tạo từ int64
func NewFromInt(value int64) Decimal
// Tạo từ int32
func NewFromInt32(value int32) Decimal
// Cộng
func (d Decimal) Add(d2 Decimal) Decimal
// Trừ
func (d Decimal) Sub(d2 Decimal) Decimal
// Nhân
func (d Decimal) Mul(d2 Decimal) Decimal
// Chia
func (d Decimal) Div(d2 Decimal) Decimal
// Chia với độ chính xác
func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal
// Làm tròn
func (d Decimal) Round(places int32) Decimal
// So sánh
func (d Decimal) Equal(d2 Decimal) bool
func (d Decimal) GreaterThan(d2 Decimal) bool
func (d Decimal) LessThan(d2 Decimal) bool
// Giá trị tuyệt đối
func (d Decimal) Abs() Decimal
// Đảo dấu
func (d Decimal) Negate() Decimal
// Chuyển đổi thành float64
func (d Decimal) Float64() (float64, error)
// Chuyển đổi thành int64
func (d Decimal) Int64() (int64, error)
// Chuyển đổi thành chuỗi
func (d Decimal) String() string
// MarshalJSON
func (d Decimal) MarshalJSON() ([]byte, error)
// UnmarshalJSON
func (d *Decimal) UnmarshalJSON(data []byte) errorVí dụ bổ sung
go
package main
import (
"fmt"
"github.com/shopspring/decimal"
)
func main() {
// Tạo decimal từ các kiểu khác nhau
d1 := decimal.NewFromFloat(10.5)
d2 := decimal.NewFromInt(3)
d3, _ := decimal.NewFromString("5.25")
// Các phép toán cơ bản
fmt.Println("Cộng:", d1.Add(d2)) // 13.5
fmt.Println("Trừ:", d1.Sub(d3)) // 5.25
fmt.Println("Nhân:", d2.Mul(d3)) // 15.75
fmt.Println("Chia:", d1.Div(d3)) // 2
// Làm tròn
d4 := decimal.NewFromFloat(10.123456)
fmt.Println("Làm tròn 2:", d4.Round(2)) // 10.12
fmt.Println("Làm tròn 4:", d4.Round(4)) // 10.1235
// So sánh
fmt.Println("So sánh bằng:", d1.Equal(d2)) // false
fmt.Println("Lớn hơn:", d1.GreaterThan(d2)) // true
// Giá trị tuyệt đối
d5 := decimal.NewFromInt(-100)
fmt.Println("Giá trị tuyệt đối:", d5.Abs()) // 100
}Sử dụng với Database
go
package main
import (
"database/sql"
"github.com/shopspring/decimal"
)
type Product struct {
ID int
Name string
Price decimal.Decimal
}
// Scan implements sql.Scanner interface
func (d *Decimal) Scan(value interface{}) error {
// Implementation
}
// Value implements driver.Valuer interface
func (d Decimal) Value() (driver.Value, error) {
// Implementation
}Best Practices
- Sử dụng NewFromString: Ưu tiên sử dụng NewFromString để tránh mất độ chính xác với float
- Kiểm tra lỗi: Luôn kiểm tra lỗi khi tạo từ chuỗi
- Độ chính xác: Chỉ định độ chính xác phù hợp cho từng trường hợp sử dụng
- Performance: Decimal chậm hơn float64 nhưng đảm bảo độ chính xác
- Serialization: Hỗ trợ tốt cho JSON và database serialization
Kết luận
decimal là một thư viện hữu ích cho việc xử lý số thập phân trong Go, đặc biệt phù hợp cho các ứng dụng tài chính, kế toán nơi độ chính xác là yêu cầu bắt buộc. Với API đơn giản và nhiều tính năng hữu ích, decimal là lựa chọn tuyệt vời khi làm việc với số thập phân trong Go.
