ast.NewAny numeric accessors lose stored values
Describe the bug
Numeric values stored by ast.NewAny are not preserved by the loose Number and String accessors:
Numberconverts every non-zero integer or float to"1"and every zero to"0".Stringconverts wide integers through the platformint, and formatsfloat32with 64-bit precision.
This conflicts with the numeric loose-casting behavior introduced in #294 and can silently change values.
Affected commit: 2a36d6da63e25b9080cc4e11398bd5b3512dfc2a (current main).
To Reproduce
package main
import (
"fmt"
"github.com/bytedance/sonic/ast"
)
func main() {
numberNode := ast.NewAny(42)
uintNode := ast.NewAny(^uint64(0))
floatNode := ast.NewAny(float32(1.1))
number, _ := numberNode.Number()
uintText, _ := uintNode.String()
floatText, _ := floatNode.String()
fmt.Printf("number=%q uint64=%q float32=%q\n", number, uintText, floatText)
}Output on amd64:
number="1" uint64="-1" float32="1.100000023841858"Expected behavior
The accessors should preserve the stored numeric value and use the source type's width:
number="42" uint64="18446744073709551615" float32="1.1"Sonic version:
Current main at 2a36d6da63e25b9080cc4e11398bd5b3512dfc2a.
Environment:
go version go1.26.3 windows/amd64
GOOS=windows
GOARCH=amd64
CGO_ENABLED=0Additional context
The _V_ANY branch of Number passes numeric values to the boolean-only castNumber(v != 0) helper. The corresponding String branch uses strconv.Itoa(int(v)) for signed and unsigned wide types and uses bit size 64 for float32. Existing tests use only the value 1, which masks all three problems.
Source: bytedance/sonic