Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Numeric to float64 conversion doesn't work #27

Closed
crodwell opened this issue May 4, 2020 · 4 comments
Closed

Numeric to float64 conversion doesn't work #27

crodwell opened this issue May 4, 2020 · 4 comments

Comments

@crodwell
Copy link

crodwell commented May 4, 2020

The built in method AssignTo() for converting a postgresql numeric such as Numeric(5,2) to float64 does not work.

@crodwell
Copy link
Author

crodwell commented May 4, 2020

could be fixed with following code

func (src *Numeric) Float64() float64 {
    f, err := strconv.ParseFloat(src.Int.String(), 64)
    if err != nil {
        return 0
    }
    var roundTo float64 = 1
    if src.Exp > 0 {
        for i := 0; i < int(src.Exp); i++ {
            f *= 10
            roundTo *= 10
        }
    } else if src.Exp < 0 {
        for i := 0; i > int(src.Exp); i-- {
            f /= 10
            roundTo /= 10
        }
    }
    return math.Round(f/roundTo) * roundTo
}

@jackc
Copy link
Owner

jackc commented May 4, 2020

As far as it not working, do you have an example?

There is a passing test for assigning to float:

{src: &pgtype.Numeric{Int: big.NewInt(42), Exp: -1, Status: pgtype.Present}, dst: &f64, expected: float64(4.2)},

@crodwell
Copy link
Author

crodwell commented May 4, 2020

Hi Jack,

Sorry for being vague, it's an accuracy issue, so if I have 10.06 in my database:

		var test float64
		err = myFiveTwoNumeric.AssignTo(&test)
		fmt.Println(test)
		fmt.Println(myFiveTwoNumeric.Float64())

output:
10.059999999999999
10.06

Also the AssignTo method returning an error isn't as easy to use as when the dev just wants a float representation of the Big.Int, the same way I can get a .String or .Int from varchar/int4 types.

@jackc jackc closed this as completed in 238967e May 13, 2020
@jackc
Copy link
Owner

jackc commented May 13, 2020

Should be fixed now.

As far as convenience goes AssignTo is mostly used internally. If you need a float64 you can scan directly into that and skip the numeric step. A public Float64() method would need an error return as well to handle null and undefined states.

Beyond that, pgtype.Numeric provides just enough functionality to transcode numeric values. https://github.com/shopspring/decimal provides a real decimal type in Go. pgtype.Numeric doesn't use it to avoid forcing an external dependency on everyone. But if you are using numerics you can use https://github.com/jackc/pgtype/tree/master/ext/shopspring-numeric to integrate with a real decimal type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants