Skip to content

Commit e79de2a

Browse files
grotivalcopybara-github
authored andcommitted
Add float32 from_uint32
PiperOrigin-RevId: 764176724
1 parent 52f25f4 commit e79de2a

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

xls/dslx/stdlib/float32.x

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,7 @@ pub fn fixed_fraction(input_float: F32) -> u23 {
216216
fixed_fraction as u23
217217
}
218218

219-
// Converts the given signed integer, into a floating-point number, rounding
220-
// the resulting fraction with the usual guard, round, sticky bits according to
221-
// the usual "round to nearest, half to even" rounding mode.
222-
pub fn from_int32(x: s32) -> F32 {
223-
let sign = (x >> 31) as u1;
224-
let fraction = if sign { -x as u31 } else { x as u31 };
225-
let lz = clz(fraction) as u8;
226-
219+
fn from_int32_internal(sign: u1, fraction: u32, lz: u8) -> F32 {
227220
// Shift the fraction to be max width, normalize it, and drop the
228221
// leading/implicit one.
229222
let fraction = (fraction as u34 << (lz + u8:3)) as u33;
@@ -250,12 +243,34 @@ pub fn from_int32(x: s32) -> F32 {
250243

251244
let zero = F32 { sign: u1:0, bexp: u8:0, fraction: u23:0 };
252245
let result = if bexp <= u8:126 && fraction == u23:0 { zero } else { result };
246+
result
247+
}
253248

249+
// Converts the given signed integer, into a floating-point number, rounding
250+
// the resulting fraction with the usual guard, round, sticky bits according to
251+
// the usual "round to nearest, half to even" rounding mode.
252+
pub fn from_int32(x: s32) -> F32 {
254253
// -INT_MAX is a special case; making it positive can drop its value.
255254
let is_neg_int_max = x == s32:-2147483648;
256255
let neg_int_max = F32 { sign: u1:1, bexp: u8:158, fraction: u23:0 };
257-
let result = if is_neg_int_max { neg_int_max } else { result };
258-
result
256+
if is_neg_int_max {
257+
neg_int_max
258+
} else {
259+
let sign = (x >> 31) as u1;
260+
let fraction = if sign { -x as u31 } else { x as u31 };
261+
let lz = clz(fraction) as u8;
262+
from_int32_internal(sign, fraction as u32, lz)
263+
}
264+
}
265+
266+
// Converts the given unsigned integer, into a floating-point number, rounding
267+
// the resulting fraction with the usual guard, round, sticky bits according to
268+
// the usual "round to nearest, half to even" rounding mode.
269+
pub fn from_uint32(x: u32) -> F32 {
270+
let sign = u1:0;
271+
let fraction = x as u32;
272+
let lz = (clz(x) as u8) - u8:1;
273+
from_int32_internal(sign, fraction, lz)
259274
}
260275

261276
#[test]
@@ -312,6 +327,40 @@ fn from_int32_test() {
312327
assert_eq(expected, actual);
313328
}
314329

330+
#[test]
331+
fn from_uint32_test() {
332+
type ExpBits = uN[F32_EXP_SZ];
333+
type FractionBits = uN[F32_FRACTION_SZ];
334+
335+
let expected = F32 { sign: u1:0, bexp: ExpBits:0, fraction: FractionBits:0 };
336+
let actual = from_uint32(u32:0);
337+
assert_eq(expected, actual);
338+
339+
let expected = F32 { sign: u1:0, bexp: ExpBits:127, fraction: FractionBits:0 };
340+
let actual = from_uint32(u32:1);
341+
assert_eq(expected, actual);
342+
343+
let expected = F32 { sign: u1:0, bexp: ExpBits:128, fraction: FractionBits:0 };
344+
let actual = from_uint32(u32:2);
345+
assert_eq(expected, actual);
346+
347+
let expected = F32 { sign: u1:0, bexp: ExpBits:156, fraction: FractionBits:0x7fffff };
348+
let actual = from_uint32(u32:1073741760);
349+
assert_eq(expected, actual);
350+
351+
let expected = F32 { sign: u1:0, bexp: ExpBits:156, fraction: FractionBits:0x3fffff };
352+
let actual = from_uint32(u32:805306304);
353+
assert_eq(expected, actual);
354+
355+
let expected = F32 { sign: u1:0, bexp: ExpBits:157, fraction: FractionBits:0x7fffff };
356+
let actual = from_uint32(u32:2147483583);
357+
assert_eq(expected, actual);
358+
359+
let expected = F32 { sign: u1:0, bexp: ExpBits:158, fraction: FractionBits:0x0 };
360+
let actual = from_uint32(u32:2147483647);
361+
assert_eq(expected, actual);
362+
}
363+
315364
pub fn add(x: F32, y: F32) -> F32 { apfloat::add(x, y) }
316365

317366
pub fn sub(x: F32, y: F32) -> F32 { apfloat::sub(x, y) }

0 commit comments

Comments
 (0)