Your Question

go code: tx.Model(order).Debug().Updates(map[string]interface{}{"orderhy_fundrate": gorm.Expr("orderhy_fundrate + ?", lastFundRate), "orderhy_frtime": lastFundRateTime})

sql debug: UPDATEorderSETorderhy_frtime=1640332800000,orderhy_fundrate=orderhy_fundrate + 0.000100 WHEREorder_id= 13

column: orderhy_fundrate decimal(60,20) NOT NULL

mysql data: orderhy_fundrate: 0.00030000000000000000 => 0.00039999999999999996

Execute in MySQL is ok,but exec in go code is not ok?

The document you expected this should be explained

Expected answer

mysql data: orderhy_fundrate: 0.00030000000000000000 => 0.00040000000000000000

Comment From: ghost

@LFXiaoFei hello, can you provide a demo in https://github.com/go-gorm/playground ?

Comment From: LFXiaoFei

@LFXiaoFei hello, can you provide a demo in https://github.com/go-gorm/playground ?

DB is MySQL,Tables is created by gotm.AutoMigrate.

go codes:

// model 
type Order struct {
    OrderID         int64   `gorm:"column:order_id;not null;PRIMARY_KEY;AUTO_INCREMENT;index:order_id_idx;"`  
    OrderHYFundRate float64 `gorm:"column:orderhy_fundrate;type:decimal(60,20);not null"`       
    OrderHYFRTime   int64   `gorm:"column:orderhy_frtime;type:bigint(20);not null"`    
}

// update model row
tx.Model(order).Debug().Updates(map[string]interface{}{"orderhy_fundrate": gorm.Expr("orderhy_fundrate + ?", lastFundRate), "orderhy_frtime": lastFundRateTime})

// debug sql:
UPDATE orderSETorderhy_frtime=1640332800000,orderhy_fundrate=orderhy_fundrate + 0.000100 WHERE order_id = 13

orderhy_fundrate old value is 0.00030000000000000000, lastFundRate is 0.000100 Exec in Navicat value is 0.00040000000000000000,but with gorm in the code,the value is 0.00039999999999999996

Comment From: halfcrazy

package main

import (
    "fmt"
    "math/big"
)

func main() {
    var (
        a float64
        b float64
        c float64
    )
    a = 0.00030000000000000000
    b = 0.000100
    c = a + b
    a1 := big.NewFloat(a)
    fmt.Println(a, a1) // 0.0003 0.0003
    b1 := big.NewFloat(b)
    fmt.Println(b, b1) // 0.0001 0.0001
    a1.Add(a1, b1)
    fmt.Println(c, a1.String()) // 0.00039999999999999996 0.0004
}

Looks like result overflow.

Comment From: LFXiaoFei

```go package main

import ( "fmt" "math/big" )

func main() { var ( a float64 b float64 c float64 ) a = 0.00030000000000000000 b = 0.000100 c = a + b a1 := big.NewFloat(a) fmt.Println(a, a1) // 0.0003 0.0003 b1 := big.NewFloat(b) fmt.Println(b, b1) // 0.0001 0.0001 a1.Add(a1, b1) fmt.Println(c, a1.String()) // 0.00039999999999999996 0.0004 } ```

Looks like result overflow.

I still have this problem.

Comment From: jinzhu

float should not be used for in this case, and GORM can't help on that.