猿问

在 Go 中将货币从浮点数转换为整数的最佳方法是什么?

在 Go 中将货币从浮点数转换为整数的最佳方法是什么?


------------- 新增问题说明 ----------


为了稍微扩展我的问题,以下是我认为通过添加 0.004(对于 2 位十进制货币)的舍入值解决的“问题”的示例。


据我所知,外部值存储为例如。RDBMS 中的十进制、双精度、货币需要作为浮点数“导入”到 Go。为了执行计算,然后需要将它们转换为整数,或者至少这是一种方法。


在下面的示例中,fVal1 模拟从数据库导入的金额。要对其进行计算,我想将其转换为整数。在我看来,最简单的方法是添加一个四舍五入的数字,如图所示。


示例代码:


var fVal1 float64 = 19.08

var f100 float64 = 100.0

var fRound float64 = 0.004

var fResult float64 = fVal1 * f100

fmt.Printf("%f * %f as float = %f\n", fVal1, f100, fResult)

var iResult1 int64 = int64(fResult)

fmt.Printf("as Integer unrounded = %d\n", iResult1)

var iResult2 int64 = int64(fResult + fRound)

fmt.Printf("as Integer rounded = %d\n", iResult2)

控制台输出:


19.080000 * 100.000000 as float = 1908.000000

as Integer unrounded = 1907

as Integer rounded = 1908

----------- 问题补充结束-----------


我已经实现了一个小包来处理 Go 中的多种货币,基本上它围绕以下代码(如下)。


当我发现在浮点数和整数之间转换时存在舍入错误时,我尝试的第一个舍入因子是 0.004(2 位小数),它似乎工作正常。


基本上,以下用于从 float 到 int 的货币转换的代码围绕这两行替代代码:


  var iCcyAmt1 int64 = int64(fCcyBase * fScale)

  var iCcyAmt2 int64 = int64((fCcyBase + fRound) * fScale)

第二个选项中“fRound”中使用的舍入是“0.004”。


运行此测试程序(1000 万次迭代)会导致一致的舍入误差约为 588,000 美分,其中未添加“0.004”,并且使用舍入数字的差异为零。


这是处理这种情况的安全方法(我不想使用字符串),还是有更好的方法?


泛舟湖上清波郎朗
浏览 627回答 3
3回答

慕森王

这里的问题是,不可能存储您在浮点数中给出的值的精确表示。在Printf()你正在做的是误导,它被四舍五入为你的价值。试试这个:package mainimport "fmt"func main() {    a := 19.08    b := 100.0    c := a * b    fmt.Printf("%.20f * %.20f as float = %.20f\n", a, b, c)}这使:19.07999999999999829470 * 100.00000000000000000000 as float = 1907.99999999999977262632现在int64()可能只是切断数字的非整数部分。
随时随地看视频慕课网APP

相关分类

Go
我要回答