golang高精度十进制数扩展包decimal用法
在Go语言中,没有内置的十进制数(decimal)类型或相关的标准库。然而,有一些第三方包可用于处理十进制数,其中比较常用的是decimal包。
decimal包提供了一个big.Float的子类型decimal.Decimal,可以用于表示和操作十进制数。它具有更高的精度和更大的范围,可以处理任意精度的十进制数。
golang中的任意精度定点十进制数扩展包decimal。
demimal包特点:
- 零值为0,无需初始化即可安全使用
- 不损失精度的加法、减法、乘法
- 以指定精度除法
- 数据库/sql序列化/反序列化
- JSON 和 XML 序列化/反序列化
要使用decimal包,首先需要确保已经安装了该包。你可以通过以下命令安装该包:
一、安装方法:
go get github.com/shopspring/decimal
二、安装要求
decimal包需要 Go 版本 >=1.7
三、使用方法
package mainimport ("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.06fmt.Println("Pre-tax:", preTax) // Pre-tax: 422.3421fmt.Println("Taxes:", total.Sub(preTax)) // Taxes: 37.482861375fmt.Println("Total:", total) // Total: 459.824961375fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875
}
安装完成后,你可以在你的Go代码中导入该包并使用decimal.Decimal类型。以下是一个简单的示例代码:
package main import ( "fmt" "gopkg.in/decimal.v1"
) func main() { // 创建一个十进制数 d := decimal.New(12345, 2) // 12345精确到小数点后2位 // 输出十进制数的字符串表示 fmt.Println(d.String()) // 输出:"12.34" // 进行十进制数的四则运算 a := decimal.New(10, 0) // 整数10 b := decimal.New(20, 2) // 十进制数20.00 c := decimal.New(30, 2) // 十进制数30.00 d = a.Add(b, c) // 加法运算 e := a.Sub(b, c) // 减法运算 f := a.Mul(b, c) // 乘法运算 g := a.Quo(b, c) // 除法运算 // 输出结果 fmt.Println(d.String()) // 输出:"31.00" fmt.Println(e.String()) // 输出:"-10.00" fmt.Println(f.String()) // 输出:"2200.00" fmt.Println(g.String()) // 输出:"0.50"
}
这个示例展示了如何创建十进制数、进行四则运算以及输出字符串表示。decimal包还提供了其他一些方法和函数,你可以根据需要进一步探索和使用。
四、FAQ
为什么不直接使用 float64 呢?
因为 float64(实际上是任何二进制浮点类型)无法精确表示 0.1 等数字。
你为什么不直接使用big.Rat呢?
big.Rat 适合表示有理数,但 Decimal 更适合表示金钱。 为什么? 这是一个(人为的)示例:
假设您使用 big.Rat,并且有两个数字 x 和 y,都代表 1/3,并且 z = 1 - x - y = 1/3。 如果打印出每个数字,则字符串输出必须在某个地方停止(为简单起见,假设它停止在 3 个小数位处),因此您将得到 0.333、0.333 和 0.333。 但另外的0.001去哪儿了呢?
对于 Decimal,打印出来的字符串准确地表示数字。 因此,如果 x = y = 1/3(精度为 3),它们实际上等于 0.333,而当 z = 1 - x - y 时,z 将等于 0.334。 没有钱下落不明!
你还是要小心。 如果你想将一个数字分成 N 3 种方式,你不能只将 N/3 发送给三个不同的人。 您必须选择一个发送 N - (2/3*N) 给。 该人将收到剩余的一分钱的一小部分。
但是,使用 Decimal 比使用 big.Rat 容易得多。
为什么 API 与 big.Int 的不相似?
big.Int 的 API 旨在减少内存分配数量以实现最佳性能。 这对于它的用例来说是有意义的,但代价是 API 很笨拙并且容易被误用。
例如,要添加两个 big.Int,您可以执行以下操作:z := new(big.Int).Add(x, y)。 不熟悉此 API 的开发人员可能会尝试执行 z := a.Add(a, b)。 这会修改 a 并将 z 设置为 a 的别名,这是他们意想不到的。 它还将任何其他别名修改为 a。
相比之下,使用小数就很难犯这样的错误。 Decimal 的行为与其他 Go 数字类型类似:即使 a = b 不会将 b 深度复制到 a 中,但也不可能修改 Decimal,因为所有 Decimal 方法都会返回新的 Decimal,并且不会修改原始的 Decimal。 缺点是这会导致额外的分配,因此 Decimal 的性能较差。 我的假设是,如果您使用小数,您可能更关心正确性而不是性能。
相关文章:
golang高精度十进制数扩展包decimal用法
在Go语言中,没有内置的十进制数(decimal)类型或相关的标准库。然而,有一些第三方包可用于处理十进制数,其中比较常用的是decimal包。 decimal包提供了一个big.Float的子类型decimal.Decimal,可以用于表示和…...

STM32F4X RNG随机数发生器
STM32F4X RNG随机数发生器 随机数的作用STM32F4X 随机数发生器RNG控制寄存器RNG状态寄存器RNG数据寄存器RNG数据步骤RNG例程 随机数的作用 随机数顾名思义就是随机产生的数字,这种数字最大的特点就是其不确定性,你不知道它下一次产生的数字是什么。随机…...
5、QT中SQLite数据库的操作
一、QT中的SQLite数据库 1、添加头文件和模块 Header: #include <QSqlDatabase> qmake: QT sql//pro文件添加sql模块执行数据库操作的类: Header: #include <QSqlQuery> qmake: QT sql2、C语言中的SQLite增删减查 SQLite3的基础教程 3、SQLite的…...
git回退到某个提交
git是一个分布式版本控制软件,分布式版本库的做法使源代码的发布和交流都极为方便,因此有不少用户都在使用git。最近小编也正在学习git这款软件,发现要想熟练运用git,学会git中的一些命令是很重要的,如果我们要回滚到某…...

对可再生能源和微电网集成研究的新控制技术和保护算法进行基线和测试及静态、时域和频率分析研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Full authentication is required to access this resource解决办法
我们在使用postman调接口时候,有的时候需要权限才可以访问,否则可能会报下面这个错误 {"success": false,"message": "Full authentication is required to access this resource","code": 401,"result&q…...
Jetty:使用上下文文件部署离线瓦片.md
说明 介绍利用jetty在任意位置如桌面的资源进行发布。比如下载的离线瓦片数据,如果放到jetty的webapps目录下,则启动时间会比较久,可以通过本文的步骤进行配置,也免去了拷贝过程的耗时。 关键字:自定义路径、Jetty、…...

Docker实战:docker compose 搭建Rocketmq
1、配置文件准备 1.1、 新建目录:/home/docker/data/rocketmq/conf mkdir /home/docker/data/rocketmq/conf1.2、 在上面目录下新建文件broker.conf文件,内容如下 brokerClusterName DefaultCluster brokerName broker-a brokerId 0 deleteWhen 0…...

STL常用容器 (C++核心基础教程之STL容器详解)String的API
在C的标准模板库(STL)中,有多种容器可供使用。以下是一些常见的容器类型: 序列容器(Sequential Containers): std::vector:动态数组,支持快速随机访问。 std::list&…...

《人生苦短,我学Python》——条件判断->(if-elif-else)多向选择 条件嵌套
今天,我们来学习多向选择!if--elif--else if 后的语句是当 if 判断条件成立时,执行的操作。elif 后的语句是当 if 判断不成立时,再判断一次,如果成立,执行的操作。else 后的语句是当以上所有判断条件都不成…...
MongoDB 数据库性能优化技巧
原文:MongoDB 数据库性能优化技巧 (techdatafuture.com) MongoDB 是一款灵活且可扩展的NoSQL数据库,为了提高其性能,我们可以采取一些优化技巧。本文将介绍一些MongoDB性能优化的关键点,包括索引的使用、查询优化、数据模型设计和…...

网络安全人才缺口超百万,如今的就业情况怎样?
网络安全人才缺口超百万,如今的就业情况怎样? 2022年9月7日,国家网络安全宣传周准时开始。本次网络安全宣传周和以前一样,主要目的都是为了普及网络安全知识,提高网络安全的防护技能,提升对电信网络诈骗的…...
「MySQL」MySQL面试题全解析:常见问题与高级技巧详解
MySQL面试题全解析:常见问题与高级技巧详解 1. 什么是数据库?2. 什么是MySQL?3. 什么是SQL?4. 什么是主键?5. 什么是外键?6. 请解释索引是什么以及为什么使用索引?7. 什么是事务?8. …...

【USRP】产品型号、参数、架构全解析系列 6:N320 / N321
一、USRP 简介 通用软件无线电外设( USRP ) 是由 Ettus Research 及其母公司National Instruments设计和销售的一系列软件定义无线电。USRP 产品系列由Matt Ettus领导的团队开发,被研究实验室、大学和业余爱好者广泛使用。 大多数 USRP 通过以太网线连接到主机&am…...
Apifox 常用 JS 脚本
前置脚本常用 1、时间戳生成(秒级): // 1、生成秒级时间戳到全局变量中 //let timestamp parseInt(new Date().getTime() / 1000) //pm.globals.set(timestamp, timestamp) // 2、生成秒级时间戳到全局变量中 pm.globals.set(timestamp, p…...
防止SQL注入的四种方案
一、什么是SQL注入? SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服…...

java单元测试
版本区别 特性Junit 4Junit 5在当前类的所有测试方法之前执行。注解在静态方法上。此方法可以包含一些初始化代码。BeforeClassBeforeAll在当前类中的所有测试方法之后执行。注解在静态方法上。此方法可以包含一些清理代码。AfterClassAfterAll在每个测试方法之前执行。注解在…...

【LeetCode】双指针求解和为s的两个数字
Problem: 剑指 Offer 57. 和为s的两个数字 文章目录 题目解析算法思路分析复杂度Code 题目解析 首先来讲解一下本题的思路 我们看到本题的意思很简单,就是去这个nums这个数组中进行寻找,如果找到了两个数相加之和为target的话,那构成一个结果…...

opencv识别一张图片的多个红框,并截取红框的内容
需求 需要获取图片的红框的内容,实体的图片我就不放了 获取红框 先截取获得图片的多个轮廓 import cv2 import numpy as np # 加载图像并转换为灰度图像 image cv2.imread(image6.jpg) gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 应用高斯模糊以减…...
数据库-事务
介绍: 事务是一组操作的集合,它是一个不可分割的工作单位,事物会把所有的操作作为一个整体一起向系统 提交或撤销操作请求,即这些操作要么同时成功,要么同时失败 操作:事务控制 开启事务:start…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...