Skip to content

Why the usage of int to hold values that overflow it (when it can only 32 bits wide) #24

Closed
@bbuck

Description

@bbuck

In the scalars.go file the coerceInt function and intOrNil deal with checking against large integer values but they use the int type:

var (
    MaxInt = 9007199254740991
    MinInt = -9007199254740991
)

func coerceInt(value interface{}) interface{} {
    switch value := value.(type) {
    case bool:
        if value == true {
            return int(1)
        }
        return int(0)
    case int:
        return value
    case float32:
        return intOrNil(int(value))
    case float64:
        return intOrNil(int(value))
    case string:
        val, err := strconv.ParseFloat(value, 0)
        if err != nil {
            return nil
        }
        return coerceInt(val)
    }
    return int(0)
}

// Integers are only safe when between -(2^53 - 1) and 2^53 - 1 due to being
// encoded in JavaScript and represented in JSON as double-precision floating
// point numbers, as specified by IEEE 754.
func intOrNil(value int) interface{} {
    if value <= MaxInt && value >= MinInt {
        return value
    }
    return nil
}

The constants you have for MaxInt and MinInt will only work fine when this is running on a 64-bit machine. I think it would be much safer to use int64 explicitly here since that appears to be what you really want and you can eliminate the 32 vs. 64 issues completely. This isn't something I've directly run across, but it just feels wrong to depend on the variable size int type when you're using values that fit only inside of an int64.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions