runtime: use dedicated printfloat32
It can be unexpected that printing a float32 involves 64-bit floating point routines, see for example: https://github.com/tinygo-org/tinygo/issues/1415 This commit adds a dedicated printfloat32 instead just for printing float32 values. It comes with a possible code size increase, but only if both float32 and float64 values are printed. Therefore, this should be an improvement in almost all cases. I also tried using printfloat32 for everything (and casting a float64 to float32 to print) but the printed values are slightly different, breaking the testdata/math.go test for example.
Этот коммит содержится в:
родитель
67de8b490d
коммит
431e51b8a0
3 изменённых файлов: 87 добавлений и 3 удалений
|
@ -98,10 +98,90 @@ func printint64(n int64) {
|
||||||
printuint64(uint64(n))
|
printuint64(uint64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printfloat32() was copied from the relevant source in the original Go
|
||||||
|
// implementation and modified to work with float32 instead of float64. It is
|
||||||
|
// copyright by the Go authors, licensed under the same BSD 3-clause license.
|
||||||
|
// See https://golang.org/LICENSE for details.
|
||||||
|
//
|
||||||
|
// It is a near-duplicate of printfloat64. This is done so that printing a
|
||||||
|
// float32 value doesn't involve float64 routines, which can be unexpected and a
|
||||||
|
// problem sometimes. It comes with a possible code size reduction if both
|
||||||
|
// printfloat32 and printfloat64 are used, which seems uncommon.
|
||||||
|
//
|
||||||
|
// Source:
|
||||||
|
// https://github.com/golang/go/blob/master/src/runtime/print.go
|
||||||
func printfloat32(v float32) {
|
func printfloat32(v float32) {
|
||||||
// TODO: write an implementation like printfloat64, as some systems have
|
switch {
|
||||||
// 32-bit floats but only software emulation for 64-bit floats.
|
case v != v:
|
||||||
printfloat64(float64(v))
|
printstring("NaN")
|
||||||
|
return
|
||||||
|
case v+v == v && v > 0:
|
||||||
|
printstring("+Inf")
|
||||||
|
return
|
||||||
|
case v+v == v && v < 0:
|
||||||
|
printstring("-Inf")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const n = 7 // digits printed
|
||||||
|
var buf [n + 7]byte
|
||||||
|
buf[0] = '+'
|
||||||
|
e := 0 // exp
|
||||||
|
if v == 0 {
|
||||||
|
if 1/v < 0 {
|
||||||
|
buf[0] = '-'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if v < 0 {
|
||||||
|
v = -v
|
||||||
|
buf[0] = '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize
|
||||||
|
for v >= 10 {
|
||||||
|
e++
|
||||||
|
v /= 10
|
||||||
|
}
|
||||||
|
for v < 1 {
|
||||||
|
e--
|
||||||
|
v *= 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// round
|
||||||
|
h := float32(5.0)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
h /= 10
|
||||||
|
}
|
||||||
|
v += h
|
||||||
|
if v >= 10 {
|
||||||
|
e++
|
||||||
|
v /= 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// format +d.dddd+edd
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
s := int(v)
|
||||||
|
buf[i+2] = byte(s + '0')
|
||||||
|
v -= float32(s)
|
||||||
|
v *= 10
|
||||||
|
}
|
||||||
|
buf[1] = buf[2]
|
||||||
|
buf[2] = '.'
|
||||||
|
|
||||||
|
buf[n+2] = 'e'
|
||||||
|
buf[n+3] = '+'
|
||||||
|
if e < 0 {
|
||||||
|
e = -e
|
||||||
|
buf[n+3] = '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[n+4] = byte(e/100) + '0'
|
||||||
|
buf[n+5] = byte(e/10)%10 + '0'
|
||||||
|
buf[n+6] = byte(e%10) + '0'
|
||||||
|
for _, c := range buf {
|
||||||
|
putchar(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// printfloat64() was copied from the relevant source in the original Go
|
// printfloat64() was copied from the relevant source in the original Go
|
||||||
|
|
3
testdata/print.go
предоставленный
3
testdata/print.go
предоставленный
|
@ -29,6 +29,9 @@ func main() {
|
||||||
// print float64
|
// print float64
|
||||||
println(3.14)
|
println(3.14)
|
||||||
|
|
||||||
|
// print float32
|
||||||
|
println(float32(3.14))
|
||||||
|
|
||||||
// print complex128
|
// print complex128
|
||||||
println(5 + 1.2345i)
|
println(5 + 1.2345i)
|
||||||
|
|
||||||
|
|
1
testdata/print.txt
предоставленный
1
testdata/print.txt
предоставленный
|
@ -16,6 +16,7 @@ a b c
|
||||||
123456789012
|
123456789012
|
||||||
-123456789012
|
-123456789012
|
||||||
+3.140000e+000
|
+3.140000e+000
|
||||||
|
+3.140000e+000
|
||||||
(+5.000000e+000+1.234500e+000i)
|
(+5.000000e+000+1.234500e+000i)
|
||||||
(0:nil)
|
(0:nil)
|
||||||
map[2]
|
map[2]
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче