1use crate::message::Message;
2use crate::translation::fixed_point::{big_uint_to_sfixed, big_uint_to_ufixed};
3use crate::variable_type::INTEGER_TYPES;
4use crate::wave_container::{ScopeId, VarId};
5use color_eyre::Result;
6use half::{bf16, f16};
7use num::BigUint;
8use softposit::{P16E1, P32E2, P8E0, Q16E1, Q8E0};
9use surfer_translation_types::{
10 translates_all_bit_types, BasicTranslator, TranslationResult, Translator, ValueKind, ValueRepr,
11 VariableInfo, VariableMeta, VariableValue,
12};
13
14use super::{check_single_wordlength, match_variable_type_name, TranslationPreference};
15
16#[inline]
17fn shortest_float_representation<T: std::fmt::LowerExp + std::fmt::Display>(v: T) -> String {
18 let dec = format!("{v}");
19 let exp = format!("{v:e}");
20 if dec.len() > exp.len() {
21 exp
22 } else {
23 dec
24 }
25}
26
27fn translate_numeric(
31 biguint_translator: impl Fn(BigUint) -> String,
32 value: &VariableValue,
33) -> (String, ValueKind) {
34 match value.clone().parse_biguint() {
35 Ok(v) => (biguint_translator(v), ValueKind::Normal),
36 Err((v, k)) => (v, k),
37 }
38}
39
40pub struct UnsignedTranslator {}
41
42impl BasicTranslator<VarId, ScopeId> for UnsignedTranslator {
43 fn name(&self) -> String {
44 String::from("Unsigned")
45 }
46
47 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
48 translate_numeric(|v| format!("{v}"), v)
49 }
50
51 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
52 let candidates = ["unresolved_unsigned".to_string(), "unsigned".to_string()];
53 if match_variable_type_name(&variable.variable_type_name, &candidates) {
54 Ok(TranslationPreference::Prefer)
55 } else {
56 translates_all_bit_types(variable)
57 }
58 }
59}
60
61pub struct SignedTranslator {}
62
63impl BasicTranslator<VarId, ScopeId> for SignedTranslator {
64 fn name(&self) -> String {
65 String::from("Signed")
66 }
67
68 fn basic_translate(&self, num_bits: u64, v: &VariableValue) -> (String, ValueKind) {
69 translate_numeric(
70 |v| {
71 let signweight = BigUint::from(1u8) << (num_bits - 1);
72 if v < signweight {
73 format!("{v}")
74 } else {
75 let v2 = (signweight << 1) - v;
76 format!("-{v2}")
77 }
78 },
79 v,
80 )
81 }
82
83 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
84 let candidates = ["unresolved_signed".to_string(), "signed".to_string()];
85 if INTEGER_TYPES.contains(&variable.variable_type)
86 | match_variable_type_name(&variable.variable_type_name, &candidates)
87 {
88 Ok(TranslationPreference::Prefer)
89 } else {
90 translates_all_bit_types(variable)
91 }
92 }
93}
94
95pub struct SinglePrecisionTranslator {}
96
97impl BasicTranslator<VarId, ScopeId> for SinglePrecisionTranslator {
98 fn name(&self) -> String {
99 String::from("FP: 32-bit IEEE 754")
100 }
101
102 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
103 translate_numeric(
104 |v| {
105 shortest_float_representation(f32::from_bits(
106 v.iter_u32_digits().next().unwrap_or(0),
107 ))
108 },
109 v,
110 )
111 }
112
113 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
114 check_single_wordlength(variable.num_bits, 32)
115 }
116}
117
118pub struct DoublePrecisionTranslator {}
119
120impl BasicTranslator<VarId, ScopeId> for DoublePrecisionTranslator {
121 fn name(&self) -> String {
122 String::from("FP: 64-bit IEEE 754")
123 }
124 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
125 translate_numeric(
126 |v| {
127 shortest_float_representation(f64::from_bits(
128 v.iter_u64_digits().next().unwrap_or(0),
129 ))
130 },
131 v,
132 )
133 }
134 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
135 check_single_wordlength(variable.num_bits, 64)
136 }
137}
138
139#[cfg(feature = "f128")]
140pub struct QuadPrecisionTranslator {}
141
142#[cfg(feature = "f128")]
143impl BasicTranslator<VarId, ScopeId> for QuadPrecisionTranslator {
144 fn name(&self) -> String {
145 String::from("FP: 128-bit IEEE 754")
146 }
147 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
148 translate_numeric(
149 |v| {
150 let mut digits = v.iter_u64_digits();
151 let lsb = digits.next().unwrap_or(0);
152 let msb = if digits.len() > 0 {
153 digits.next().unwrap_or(0)
154 } else {
155 0
156 };
157 let val = lsb as u128 | (msb as u128) << 64;
158 f128::f128::from_bits(val).to_string()
159 },
160 v,
161 )
162 }
163 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
164 check_single_wordlength(variable.num_bits, 128)
165 }
166}
167
168pub struct HalfPrecisionTranslator {}
169
170impl BasicTranslator<VarId, ScopeId> for HalfPrecisionTranslator {
171 fn name(&self) -> String {
172 String::from("FP: 16-bit IEEE 754")
173 }
174 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
175 translate_numeric(
176 |v| {
177 shortest_float_representation(f16::from_bits(
178 v.iter_u32_digits().next().unwrap_or(0) as u16,
179 ))
180 },
181 v,
182 )
183 }
184 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
185 check_single_wordlength(variable.num_bits, 16)
186 }
187}
188
189pub struct BFloat16Translator {}
190
191impl BasicTranslator<VarId, ScopeId> for BFloat16Translator {
192 fn name(&self) -> String {
193 String::from("FP: bfloat16")
194 }
195 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
196 translate_numeric(
197 |v| {
198 shortest_float_representation(bf16::from_bits(
199 v.iter_u32_digits().next().unwrap_or(0) as u16,
200 ))
201 },
202 v,
203 )
204 }
205 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
206 check_single_wordlength(variable.num_bits, 16)
207 }
208}
209
210pub struct Posit32Translator {}
211
212impl BasicTranslator<VarId, ScopeId> for Posit32Translator {
213 fn name(&self) -> String {
214 String::from("Posit: 32-bit (two exponent bits)")
215 }
216
217 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
218 translate_numeric(
219 |v| {
220 format!(
221 "{p}",
222 p = P32E2::from_bits(v.iter_u32_digits().next().unwrap_or(0))
223 )
224 },
225 v,
226 )
227 }
228
229 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
230 check_single_wordlength(variable.num_bits, 32)
231 }
232}
233
234pub struct Posit16Translator {}
235
236impl BasicTranslator<VarId, ScopeId> for Posit16Translator {
237 fn name(&self) -> String {
238 String::from("Posit: 16-bit (one exponent bit)")
239 }
240
241 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
242 translate_numeric(
243 |v| {
244 format!(
245 "{p}",
246 p = P16E1::from_bits(v.iter_u32_digits().next().unwrap_or(0) as u16)
247 )
248 },
249 v,
250 )
251 }
252
253 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
254 check_single_wordlength(variable.num_bits, 16)
255 }
256}
257
258pub struct Posit8Translator {}
259
260impl BasicTranslator<VarId, ScopeId> for Posit8Translator {
261 fn name(&self) -> String {
262 String::from("Posit: 8-bit (no exponent bit)")
263 }
264
265 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
266 translate_numeric(
267 |v| {
268 format!(
269 "{p}",
270 p = P8E0::from_bits(v.iter_u32_digits().next().unwrap_or(0) as u8)
271 )
272 },
273 v,
274 )
275 }
276
277 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
278 check_single_wordlength(variable.num_bits, 8)
279 }
280}
281
282pub struct PositQuire8Translator {}
283
284impl BasicTranslator<VarId, ScopeId> for PositQuire8Translator {
285 fn name(&self) -> String {
286 String::from("Posit: quire for 8-bit (no exponent bit)")
287 }
288
289 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
290 translate_numeric(
291 |v| {
292 format!(
293 "{p}",
294 p = Q8E0::from_bits(v.iter_u32_digits().next().unwrap_or(0))
295 )
296 },
297 v,
298 )
299 }
300
301 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
302 check_single_wordlength(variable.num_bits, 32)
303 }
304}
305
306pub struct PositQuire16Translator {}
307
308impl BasicTranslator<VarId, ScopeId> for PositQuire16Translator {
309 fn name(&self) -> String {
310 String::from("Posit: quire for 16-bit (one exponent bit)")
311 }
312
313 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
314 translate_numeric(
315 |v| {
316 let mut digits = v.iter_u64_digits();
317 let lsb = digits.next().unwrap_or(0);
318 let msb = if digits.len() > 0 {
319 digits.next().unwrap_or(0)
320 } else {
321 0
322 };
323 let val = lsb as u128 | ((msb as u128) << 64);
324 format!("{p}", p = Q16E1::from_bits(val))
325 },
326 v,
327 )
328 }
329
330 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
331 check_single_wordlength(variable.num_bits, 128)
332 }
333}
334
335#[allow(clippy::excessive_precision)]
336fn decode_e5m2(v: u8) -> String {
338 let mant = v & 3;
339 let exp = (v >> 2) & 31;
340 let sign: i8 = 1 - ((v >> 6) & 2) as i8; match (exp, mant) {
342 (31, 0) => "∞".to_string(),
343 (31, ..) => "NaN".to_string(),
344 (0, 0) => {
345 if sign == -1 {
346 "-0".to_string()
347 } else {
348 "0".to_string()
349 }
350 }
351 (0, ..) => shortest_float_representation(
352 ((sign * mant as i8) as f32) * 0.0000152587890625f32, ),
354 _ => shortest_float_representation(
355 ((sign * (4 + mant as i8)) as f32) * 2.0f32.powi(exp as i32 - 17), ),
357 }
358}
359
360pub struct E5M2Translator {}
361
362impl BasicTranslator<VarId, ScopeId> for E5M2Translator {
363 fn name(&self) -> String {
364 String::from("FP: 8-bit (E5M2)")
365 }
366
367 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
368 translate_numeric(
369 |v| decode_e5m2(v.iter_u32_digits().next().unwrap_or(0) as u8),
370 v,
371 )
372 }
373
374 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
375 check_single_wordlength(variable.num_bits, 8)
376 }
377}
378
379fn decode_e4m3(v: u8) -> String {
381 let mant = v & 7;
382 let exp = (v >> 3) & 15;
383 let sign: i8 = 1 - ((v >> 6) & 2) as i8; match (exp, mant) {
385 (15, 7) => "NaN".to_string(),
386 (0, 0) => {
387 if sign == -1 {
388 "-0".to_string()
389 } else {
390 "0".to_string()
391 }
392 }
393 (0, ..) => shortest_float_representation(((sign * mant as i8) as f32) * 0.001953125f32), _ => shortest_float_representation(
395 ((sign * (8 + mant) as i8) as f32) * 2.0f32.powi(exp as i32 - 10), ),
397 }
398}
399
400pub struct E4M3Translator {}
401
402impl BasicTranslator<VarId, ScopeId> for E4M3Translator {
403 fn name(&self) -> String {
404 String::from("FP: 8-bit (E4M3)")
405 }
406
407 fn basic_translate(&self, _: u64, v: &VariableValue) -> (String, ValueKind) {
408 translate_numeric(
409 |v| decode_e4m3(v.iter_u32_digits().next().unwrap_or(0) as u8),
410 v,
411 )
412 }
413
414 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
415 check_single_wordlength(variable.num_bits, 8)
416 }
417}
418
419pub struct UnsignedFixedPointTranslator;
420
421impl Translator<VarId, ScopeId, Message> for UnsignedFixedPointTranslator {
422 fn name(&self) -> String {
423 "Unsigned fixed point".into()
424 }
425
426 fn translate(
427 &self,
428 variable: &VariableMeta<VarId, ScopeId>,
429 value: &VariableValue,
430 ) -> Result<TranslationResult> {
431 let (string, value_kind) = if let Some(idx) = &variable.index {
432 translate_numeric(|v| big_uint_to_ufixed(&v, -idx.lsb), value)
433 } else {
434 translate_numeric(|v| format!("{}", v), value)
435 };
436 Ok(TranslationResult {
437 kind: value_kind,
438 val: ValueRepr::String(string),
439 subfields: vec![],
440 })
441 }
442
443 fn variable_info(&self, _: &VariableMeta<VarId, ScopeId>) -> Result<VariableInfo> {
444 Ok(VariableInfo::Bits)
445 }
446
447 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
448 let candidates = ["unresolved_ufixed".to_string(), "ufixed".to_string()];
449 if match_variable_type_name(&variable.variable_type_name, &candidates) {
450 Ok(TranslationPreference::Prefer)
451 } else {
452 translates_all_bit_types(variable)
453 }
454 }
455}
456
457pub struct SignedFixedPointTranslator;
458
459impl Translator<VarId, ScopeId, Message> for SignedFixedPointTranslator {
460 fn name(&self) -> String {
461 "Signed fixed point".into()
462 }
463
464 fn translate(
465 &self,
466 variable: &VariableMeta<VarId, ScopeId>,
467 value: &VariableValue,
468 ) -> Result<TranslationResult> {
469 let (string, value_kind) = if let Some(idx) = &variable.index {
470 translate_numeric(
471 |v| big_uint_to_sfixed(&v, variable.num_bits.unwrap_or(0) as u64, -idx.lsb),
472 value,
473 )
474 } else {
475 translate_numeric(|v| format!("{}", v), value)
476 };
477 Ok(TranslationResult {
478 kind: value_kind,
479 val: ValueRepr::String(string),
480 subfields: vec![],
481 })
482 }
483
484 fn variable_info(&self, _: &VariableMeta<VarId, ScopeId>) -> Result<VariableInfo> {
485 Ok(VariableInfo::Bits)
486 }
487
488 fn translates(&self, variable: &VariableMeta<VarId, ScopeId>) -> Result<TranslationPreference> {
489 let candidates = ["unresolved_sfixed".to_string(), "sfixed".to_string()];
490 if match_variable_type_name(&variable.variable_type_name, &candidates) {
491 Ok(TranslationPreference::Prefer)
492 } else {
493 translates_all_bit_types(variable)
494 }
495 }
496}
497
498#[cfg(test)]
499mod test {
500 use super::*;
501 use surfer_translation_types::VariableValue;
502
503 #[test]
504 fn signed_translation_from_string() {
505 assert_eq!(
506 SignedTranslator {}
507 .basic_translate(5, &VariableValue::String("10000".to_string()))
508 .0,
509 "-16"
510 );
511
512 assert_eq!(
513 SignedTranslator {}
514 .basic_translate(5, &VariableValue::String("01000".to_string()))
515 .0,
516 "8"
517 );
518 }
519
520 #[test]
521 fn signed_translation_from_biguint() {
522 assert_eq!(
523 SignedTranslator {}
524 .basic_translate(5, &VariableValue::BigUint(BigUint::from(0b10011u32)))
525 .0,
526 "-13"
527 );
528
529 assert_eq!(
530 SignedTranslator {}
531 .basic_translate(5, &VariableValue::BigUint(BigUint::from(0b01000u32)))
532 .0,
533 "8"
534 );
535 assert_eq!(
536 SignedTranslator {}
537 .basic_translate(2, &VariableValue::BigUint(BigUint::from(0u32)))
538 .0,
539 "0"
540 );
541 }
542
543 #[test]
544 fn unsigned_translation_from_string() {
545 assert_eq!(
546 UnsignedTranslator {}
547 .basic_translate(5, &VariableValue::String("10000".to_string()))
548 .0,
549 "16"
550 );
551
552 assert_eq!(
553 UnsignedTranslator {}
554 .basic_translate(5, &VariableValue::String("01000".to_string()))
555 .0,
556 "8"
557 );
558 }
559
560 #[test]
561 fn unsigned_translation_from_biguint() {
562 assert_eq!(
563 UnsignedTranslator {}
564 .basic_translate(5, &VariableValue::BigUint(BigUint::from(0b10011u32)))
565 .0,
566 "19"
567 );
568
569 assert_eq!(
570 UnsignedTranslator {}
571 .basic_translate(5, &VariableValue::BigUint(BigUint::from(0b01000u32)))
572 .0,
573 "8"
574 );
575 assert_eq!(
576 UnsignedTranslator {}
577 .basic_translate(2, &VariableValue::BigUint(BigUint::from(0u32)))
578 .0,
579 "0"
580 );
581 }
582
583 #[test]
584 fn e4m3_translation_from_biguint() {
585 assert_eq!(
586 E4M3Translator {}
587 .basic_translate(8, &VariableValue::BigUint(BigUint::from(0b10001000u8)))
588 .0,
589 "-0.015625"
590 );
591 }
592
593 #[test]
594 fn e4m3_translation_from_string() {
595 assert_eq!(
596 E4M3Translator {}
597 .basic_translate(8, &VariableValue::String("11111111".to_string()))
598 .0,
599 "NaN"
600 );
601 assert_eq!(
602 E4M3Translator {}
603 .basic_translate(8, &VariableValue::String("00000011".to_string()))
604 .0,
605 "0.005859375"
606 );
607 assert_eq!(
608 E4M3Translator {}
609 .basic_translate(8, &VariableValue::String("10000000".to_string()))
610 .0,
611 "-0"
612 );
613 assert_eq!(
614 E4M3Translator {}
615 .basic_translate(8, &VariableValue::String("00000000".to_string()))
616 .0,
617 "0"
618 );
619 assert_eq!(
620 E4M3Translator {}
621 .basic_translate(8, &VariableValue::String("11110111".to_string()))
622 .0,
623 "-240"
624 );
625 assert_eq!(
626 E4M3Translator {}
627 .basic_translate(8, &VariableValue::String("01000000".to_string()))
628 .0,
629 "2"
630 );
631 }
632
633 #[test]
634 fn e5m2_translation_from_biguint() {
635 assert_eq!(
636 E5M2Translator {}
637 .basic_translate(8, &VariableValue::BigUint(BigUint::from(0b10000100u8)))
638 .0,
639 "-6.1035156e-5"
640 );
641 assert_eq!(
642 E5M2Translator {}
643 .basic_translate(8, &VariableValue::BigUint(BigUint::from(0b11111100u8)))
644 .0,
645 "∞"
646 );
647 }
648
649 #[test]
650 fn e5m2_translation_from_string() {
651 assert_eq!(
652 E5M2Translator {}
653 .basic_translate(8, &VariableValue::String("11111111".to_string()))
654 .0,
655 "NaN"
656 );
657 assert_eq!(
658 E5M2Translator {}
659 .basic_translate(8, &VariableValue::String("00000011".to_string()))
660 .0,
661 "4.5776367e-5"
662 );
663 assert_eq!(
664 E5M2Translator {}
665 .basic_translate(8, &VariableValue::String("10000000".to_string()))
666 .0,
667 "-0"
668 );
669 assert_eq!(
670 E5M2Translator {}
671 .basic_translate(8, &VariableValue::String("00000000".to_string()))
672 .0,
673 "0"
674 );
675 assert_eq!(
676 E5M2Translator {}
677 .basic_translate(8, &VariableValue::String("11111011".to_string()))
678 .0,
679 "-57344"
680 );
681 assert_eq!(
682 E5M2Translator {}
683 .basic_translate(8, &VariableValue::String("01000000".to_string()))
684 .0,
685 "2"
686 );
687 }
688
689 #[test]
690 fn posit8_translation_from_biguint() {
691 assert_eq!(
692 Posit8Translator {}
693 .basic_translate(8, &VariableValue::BigUint(BigUint::from(0b10001000u8)))
694 .0,
695 "-8"
696 );
697 assert_eq!(
698 Posit8Translator {}
699 .basic_translate(8, &VariableValue::BigUint(BigUint::from(0u8)))
700 .0,
701 "0"
702 );
703 }
704
705 #[test]
706 fn posit8_translation_from_string() {
707 assert_eq!(
708 Posit8Translator {}
709 .basic_translate(8, &VariableValue::String("11111111".to_string()))
710 .0,
711 "-0.015625"
712 );
713 assert_eq!(
714 Posit8Translator {}
715 .basic_translate(8, &VariableValue::String("00000011".to_string()))
716 .0,
717 "0.046875"
718 );
719 assert_eq!(
720 Posit8Translator {}
721 .basic_translate(8, &VariableValue::String("10000000".to_string()))
722 .0,
723 "NaN"
724 );
725 }
726
727 #[test]
728 fn posit16_translation_from_biguint() {
729 assert_eq!(
730 Posit16Translator {}
731 .basic_translate(
732 16,
733 &VariableValue::BigUint(BigUint::from(0b1010101010001000u16))
734 )
735 .0,
736 "-2.68359375"
737 );
738 assert_eq!(
739 Posit16Translator {}
740 .basic_translate(16, &VariableValue::BigUint(BigUint::from(0u16)))
741 .0,
742 "0"
743 );
744 }
745
746 #[test]
747 fn posit16_translation_from_string() {
748 assert_eq!(
749 Posit16Translator {}
750 .basic_translate(16, &VariableValue::String("1111111111111111".to_string()))
751 .0,
752 "-0.000000003725290298461914"
753 );
754 assert_eq!(
755 Posit16Translator {}
756 .basic_translate(16, &VariableValue::String("0111000000000011".to_string()))
757 .0,
758 "16.046875"
759 );
760 assert_eq!(
761 Posit16Translator {}
762 .basic_translate(16, &VariableValue::String("1000000000000000".to_string()))
763 .0,
764 "NaN"
765 );
766 }
767
768 #[test]
769 fn posit32_translation_from_biguint() {
770 assert_eq!(
771 Posit32Translator {}
772 .basic_translate(
773 32,
774 &VariableValue::BigUint(BigUint::from(0b1010101010001000u16))
775 )
776 .0,
777 "0.0000000000000000023056236824262055"
778 );
779 assert_eq!(
780 Posit32Translator {}
781 .basic_translate(32, &VariableValue::BigUint(BigUint::from(0u32)))
782 .0,
783 "0"
784 );
785 }
786
787 #[test]
788 fn posit32_translation_from_string() {
789 assert_eq!(
790 Posit32Translator {}
791 .basic_translate(
792 32,
793 &VariableValue::String("10000111000000001111111111111111".to_string())
794 )
795 .0,
796 "-8176.000244140625"
797 );
798 assert_eq!(
799 Posit32Translator {}
800 .basic_translate(
801 32,
802 &VariableValue::String("01110000000000111000000000000000".to_string())
803 )
804 .0,
805 "257.75"
806 );
807 }
808
809 #[test]
810 fn quire8_translation_from_biguint() {
811 assert_eq!(
812 PositQuire8Translator {}
813 .basic_translate(
814 32,
815 &VariableValue::BigUint(BigUint::from(0b1010101010001000u16))
816 )
817 .0,
818 "10"
819 );
820 assert_eq!(
821 PositQuire8Translator {}
822 .basic_translate(32, &VariableValue::BigUint(BigUint::from(0u16)))
823 .0,
824 "0"
825 );
826 }
827
828 #[test]
829 fn quire8_translation_from_string() {
830 assert_eq!(
831 PositQuire8Translator {}
832 .basic_translate(
833 32,
834 &VariableValue::String("10000111000000001111111111111111".to_string())
835 )
836 .0,
837 "-64"
838 );
839 assert_eq!(
840 PositQuire8Translator {}
841 .basic_translate(
842 32,
843 &VariableValue::String("01110000000000111000000000000000".to_string())
844 )
845 .0,
846 "64"
847 );
848 }
849
850 #[test]
851 fn quire16_translation_from_biguint() {
852 assert_eq!(
853 PositQuire16Translator {}
854 .basic_translate(128, &VariableValue::BigUint(BigUint::from(0b10101010100010001010101010001000101010101000100010101010100010001010101010001000101010101000100010101010100010001010101010001000u128)))
855 .0,
856 "-268435456"
857 );
858 assert_eq!(
859 PositQuire16Translator {}
860 .basic_translate(128, &VariableValue::BigUint(BigUint::from(7u8)))
861 .0,
862 "0.000000003725290298461914"
863 );
864 assert_eq!(
865 PositQuire16Translator {}
866 .basic_translate(128, &VariableValue::BigUint(BigUint::from(0u8)))
867 .0,
868 "0"
869 );
870 }
871
872 #[test]
873 fn quire16_translation_from_string() {
874 assert_eq!(
875 PositQuire16Translator {}
876 .basic_translate(
877 128,
878 &VariableValue::String(
879 "1000011100000000111111111111111101110000000000111000000000000000"
880 .to_string()
881 )
882 )
883 .0,
884 "135"
885 );
886 assert_eq!(
887 PositQuire16Translator {}
888 .basic_translate(
889 128,
890 &VariableValue::String("01110000000000111000000000000000".to_string())
891 )
892 .0,
893 "0.000000029802322387695313"
894 );
895 }
896
897 #[test]
898 fn bloat16_translation_from_string() {
899 assert_eq!(
900 BFloat16Translator {}
901 .basic_translate(16, &VariableValue::String("0100100011100011".to_string()))
902 .0,
903 "464896"
904 );
905 assert_eq!(
906 BFloat16Translator {}
907 .basic_translate(16, &VariableValue::String("1000000000000000".to_string()))
908 .0,
909 "-0"
910 );
911 assert_eq!(
912 BFloat16Translator {}
913 .basic_translate(16, &VariableValue::String("1111111111111111".to_string()))
914 .0,
915 "NaN"
916 );
917 assert_eq!(
918 BFloat16Translator {}
919 .basic_translate(16, &VariableValue::String("01001z0011100011".to_string()))
920 .0,
921 "HIGHIMP"
922 );
923 assert_eq!(
924 BFloat16Translator {}
925 .basic_translate(16, &VariableValue::String("01001q0011100011".to_string()))
926 .0,
927 "UNKNOWN VALUES"
928 );
929 assert_eq!(
930 BFloat16Translator {}
931 .basic_translate(16, &VariableValue::String("01001-0011100011".to_string()))
932 .0,
933 "DON'T CARE"
934 );
935 assert_eq!(
936 BFloat16Translator {}
937 .basic_translate(16, &VariableValue::String("01001w0011100011".to_string()))
938 .0,
939 "UNDEF WEAK"
940 );
941 assert_eq!(
942 BFloat16Translator {}
943 .basic_translate(16, &VariableValue::String("01001h0011100011".to_string()))
944 .0,
945 "WEAK"
946 );
947 assert_eq!(
948 BFloat16Translator {}
949 .basic_translate(16, &VariableValue::String("01001u0011100011".to_string()))
950 .0,
951 "UNDEF"
952 );
953 }
954
955 #[test]
956 fn bloat16_translation_from_bigunit() {
957 assert_eq!(
958 BFloat16Translator {}
959 .basic_translate(
960 16,
961 &VariableValue::BigUint(BigUint::from(0b1010101010001000u16))
962 )
963 .0,
964 "-2.4158453e-13"
965 );
966 assert_eq!(
967 BFloat16Translator {}
968 .basic_translate(
969 16,
970 &VariableValue::BigUint(BigUint::from(0b1000000000000000u16))
971 )
972 .0,
973 "-0"
974 );
975 assert_eq!(
976 BFloat16Translator {}
977 .basic_translate(
978 16,
979 &VariableValue::BigUint(BigUint::from(0b0000000000000000u16))
980 )
981 .0,
982 "0"
983 );
984 assert_eq!(
985 BFloat16Translator {}
986 .basic_translate(
987 16,
988 &VariableValue::BigUint(BigUint::from(0b1111111111111111u16))
989 )
990 .0,
991 "NaN"
992 );
993 }
994
995 #[test]
996 fn half_translation_from_biguint() {
997 assert_eq!(
998 HalfPrecisionTranslator {}
999 .basic_translate(
1000 16,
1001 &VariableValue::BigUint(BigUint::from(0b1000000000000000u16))
1002 )
1003 .0,
1004 "-0"
1005 );
1006 assert_eq!(
1007 HalfPrecisionTranslator {}
1008 .basic_translate(
1009 16,
1010 &VariableValue::BigUint(BigUint::from(0b0000000000000000u16))
1011 )
1012 .0,
1013 "0"
1014 );
1015 assert_eq!(
1016 HalfPrecisionTranslator {}
1017 .basic_translate(
1018 16,
1019 &VariableValue::BigUint(BigUint::from(0b1111111111111111u16))
1020 )
1021 .0,
1022 "NaN"
1023 );
1024 }
1025
1026 #[test]
1027 fn half_translation_from_string() {
1028 assert_eq!(
1029 HalfPrecisionTranslator {}
1030 .basic_translate(16, &VariableValue::String("0100100011100011".to_string()))
1031 .0,
1032 "9.7734375"
1033 );
1034 assert_eq!(
1035 HalfPrecisionTranslator {}
1036 .basic_translate(16, &VariableValue::String("1000000000000000".to_string()))
1037 .0,
1038 "-0"
1039 );
1040 assert_eq!(
1041 HalfPrecisionTranslator {}
1042 .basic_translate(16, &VariableValue::String("1111111111111111".to_string()))
1043 .0,
1044 "NaN"
1045 );
1046 }
1047
1048 #[test]
1049 fn single_translation_from_bigunit() {
1050 assert_eq!(
1051 SinglePrecisionTranslator {}
1052 .basic_translate(
1053 32,
1054 &VariableValue::BigUint(BigUint::from(0b01010101010001001010101010001000u32))
1055 )
1056 .0,
1057 "1.3514794e13"
1058 );
1059 assert_eq!(
1060 SinglePrecisionTranslator {}
1061 .basic_translate(
1062 32,
1063 &VariableValue::BigUint(BigUint::from(0b10000000000000000000000000000000u32))
1064 )
1065 .0,
1066 "-0"
1067 );
1068 assert_eq!(
1069 SinglePrecisionTranslator {}
1070 .basic_translate(
1071 32,
1072 &VariableValue::BigUint(BigUint::from(0b00000000000000000000000000000000u32))
1073 )
1074 .0,
1075 "0"
1076 );
1077 assert_eq!(
1078 SinglePrecisionTranslator {}
1079 .basic_translate(
1080 32,
1081 &VariableValue::BigUint(BigUint::from(0b11111111111111111111111111111111u32))
1082 )
1083 .0,
1084 "NaN"
1085 );
1086 }
1087
1088 #[test]
1089 fn double_translation_from_bigunit() {
1090 assert_eq!(
1091 DoublePrecisionTranslator {}
1092 .basic_translate(
1093 64,
1094 &VariableValue::BigUint(BigUint::from(
1095 0b0101010101000100101010101000100001010101010001001010101010001000u64
1096 ))
1097 )
1098 .0,
1099 "5.785860578429741e102"
1100 );
1101 assert_eq!(
1102 DoublePrecisionTranslator {}
1103 .basic_translate(
1104 64,
1105 &VariableValue::BigUint(BigUint::from(
1106 0b1000000000000000000000000000000000000000000000000000000000000000u64
1107 ))
1108 )
1109 .0,
1110 "-0"
1111 );
1112 assert_eq!(
1113 DoublePrecisionTranslator {}
1114 .basic_translate(
1115 64,
1116 &VariableValue::BigUint(BigUint::from(
1117 0b0000000000000000000000000000000000000000000000000000000000000000u64
1118 ))
1119 )
1120 .0,
1121 "0"
1122 );
1123 assert_eq!(
1124 DoublePrecisionTranslator {}
1125 .basic_translate(
1126 64,
1127 &VariableValue::BigUint(BigUint::from(
1128 0b1111111111111111111111111111111111111111111111111111111111111111u64
1129 ))
1130 )
1131 .0,
1132 "NaN"
1133 );
1134 }
1135}