MCPcopy Create free account
hub / github.com/apache/fory / Float16FromFloat32

Function Float16FromFloat32

go/fory/float16/float16.go:68–167  ·  view source on GitHub ↗

Float16FromFloat32 converts a float32 to a Float16. Rounds to nearest, ties to even.

(f32 float32)

Source from the content-addressed store, hash-verified

66// Float16FromFloat32 converts a float32 to a Float16.
67// Rounds to nearest, ties to even.
68func Float16FromFloat32(f32 float32) Float16 {
69 bits := math.Float32bits(f32)
70 sign := (bits >> 31) & 0x1
71 exp := (bits >> 23) & 0xff
72 mant := bits & 0x7fffff
73
74 var outSign uint16 = uint16(sign) << 15
75 var outExp uint16
76 var outMant uint16
77
78 if exp == 0xff {
79 // NaN or Inf
80 outExp = 0x1f
81 if mant != 0 {
82 // NaN - preserve top bit of mantissa for quiet/signaling if possible, but simplest is canonical QNaN
83 outMant = 0x200 | (uint16(mant>>13) & 0x1ff)
84 if outMant == 0 {
85 outMant = 0x200 // Ensure at least one bit
86 }
87 } else {
88 // Inf
89 outMant = 0
90 }
91 } else if exp == 0 {
92 // Signed zero or subnormal float32 (which becomes zero in float16 usually)
93 outExp = 0
94 outMant = 0
95 } else {
96 // Normalized
97 newExp := int(exp) - 127 + 15
98 if newExp >= 31 {
99 // Overflow to Inf
100 outExp = 0x1f
101 outMant = 0
102 } else if newExp <= 0 {
103 // Underflow to subnormal or zero
104 // Shift mantissa to align with float16 subnormal range
105 // float32 mantissa has implicit 1.
106 fullMant := mant | 0x800000
107 shift := 1 - newExp // 1 for implicit bit alignment
108 // We need to round.
109 // Mantissa bits: 23. Subnormal 16 mant bits: 10.
110 // We want to shift right by (13 + shift).
111
112 // Let's do a more precise soft-float rounding
113 // Re-assemble float value to handle subnormal rounding correctly is hard with just bit shifts
114 // But since we have hardware float32...
115 // Actually pure bit manipulation is robust if careful.
116
117 // Shift right amount
118 netShift := 13 + shift // 23 - 10 + shift
119
120 if netShift >= 24 {
121 // Too small, becomes zero
122 outExp = 0
123 outMant = 0
124 } else {
125 outExp = 0

Callers 4

AddMethod · 0.85
SubMethod · 0.85
MulMethod · 0.85
DivMethod · 0.85

Calls 2

Float16TypeAlias · 0.70
uint16Function · 0.50

Tested by

no test coverage detected