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