Error-free calculation with big.Float of golang

Introduction

When performing the four arithmetic operations of ETH with golang, a floating point calculation with 18 digits after the decimal point is required. If you are not aware of overflow, there will be an error in the calculation, so use the double precision floating point type in the correct usage.

let's try it

Things necessary

only golang

What kind of error will occur?

ETH is subtracted from the budget of 1000 ETH and then re-added. If there is no error, it should return to 1000 ETH.

error.go


package main

import (
	"fmt"
	"math/big"
	"strings"
)

func main() {
	budget, _ := new(big.Float).SetString("1000")
	amount, _ := new(big.Float).SetString("0.123456789012345678")
	balance := new(big.Float).Sub(budget, amount)
	summary := new(big.Float).SetPrec(128).Add(balance, amount)

	fmt.Printf("budget  = %v\n", formatFloatPrice(budget, 18))
	fmt.Printf("amount  = %v\n\n", formatFloatPrice(amount, 18))

	fmt.Printf("balance = budget - amount = %v\n", formatFloatPrice(balance, 18))
	fmt.Printf("budget = balance + amount = %v\n", formatFloatPrice(summary, 18))
}

func formatFloatPrice(amount *big.Float, decimals int) string {
	str := amount.Text('f', decimals)
	if strings.Contains(str, ".") {
		str = strings.TrimRight(str, "0")
		if strings.HasSuffix(str, ".") {
			str = str + "0"
		}
	}
	return str
}

When I run it, it should be 1000 ETH, but it doesn't work due to the error.

Execution result


budget  = 1000.0
amount  = 0.123456789012345678

balance = budget - amount = 999.876543210987654309
budget = balance + amount = 999.999999999999999987

How to eliminate the error?

Use the magic method SetPrec () to improve the accuracy of floating point numbers.

ok.go


package main

import (
	"fmt"
	"math/big"
	"strings"
)

func main() {
	budget, _ := new(big.Float).SetPrec(128).SetString("1000")
	amount, _ := new(big.Float).SetPrec(128).SetString("0.123456789012345678")
	balance := new(big.Float).SetPrec(128).Sub(budget, amount)

	summary := new(big.Float).SetPrec(128).Add(balance, amount)

	fmt.Printf("budget  = %v\n", formatFloatPrice(budget, 18))
	fmt.Printf("amount  = %v\n\n", formatFloatPrice(amount, 18))

	fmt.Printf("balance = budget - amount = %v\n", formatFloatPrice(balance, 18))
	fmt.Printf("budget = balance + amount = %v\n", formatFloatPrice(summary, 18))
}

func formatFloatPrice(amount *big.Float, decimals int) string {
	str := amount.Text('f', decimals)
	if strings.Contains(str, ".") {
		str = strings.TrimRight(str, "0")
		if strings.HasSuffix(str, ".") {
			str = str + "0"
		}
	}
	return str
}

I have returned to 1000 ETH safely!

Execution result


budget  = 1000.0
amount  = 0.123456789012345678

balance = budget - amount = 999.876543210987654322
budget = balance + amount = 1000.0

Recommended Posts

Error-free calculation with big.Float of golang
Play with numerical calculation of magnetohydrodynamics
Numerical calculation of differential equations with TensorFlow 2.0
1. Statistics learned with Python 1-3. Calculation of various statistics (statistics)
Real-time calculation of mean values with coroutines
1. Statistics learned with Python 1-2. Calculation of various statistics (Numpy)
Sequential calculation of mean value with online algorithm
Calculation of mutual information (continuous value) with numpy
Performs high-speed calculation of only specific descriptors with mordred
Getting Started with Golang 2
Getting Started with Golang 1
Try to get the contents of Word with Golang
Getting Started with Golang 3
Call bash with golang
Getting Started with Golang 4
Numerical calculation with Python
How to enable Read / Write of net.Conn with context with golang
Getting Started with PKI with Golang ―― 4
[Python] Calculation method with numpy
Equation of motion with sympy
Parallel processing with Parallel of scikit-learn
Calculation of similarity by MinHash
Prediction of Nikkei 225 with Pytorch 2
Memories of fighting with Selenium
About cost calculation of MeCab
Prediction of Nikkei 225 with Pytorch