penumbra_sdk_num/fixpoint/
from.rs1use crate::fixpoint;
2use crate::fixpoint::U128x128;
3use ethnum::U256;
4
5impl From<u8> for U128x128 {
6 fn from(value: u8) -> Self {
7 Self(U256::from_words(value.into(), 0))
8 }
9}
10
11impl From<u16> for U128x128 {
12 fn from(value: u16) -> Self {
13 Self(U256::from_words(value.into(), 0))
14 }
15}
16
17impl From<u32> for U128x128 {
18 fn from(value: u32) -> Self {
19 Self(U256::from_words(value.into(), 0))
20 }
21}
22
23impl From<u64> for U128x128 {
24 fn from(value: u64) -> Self {
25 Self(U256::from_words(value.into(), 0))
26 }
27}
28
29impl From<u128> for U128x128 {
30 fn from(value: u128) -> Self {
31 Self(U256::from_words(value, 0))
32 }
33}
34
35impl TryFrom<U128x128> for u128 {
36 type Error = super::Error;
37 fn try_from(value: U128x128) -> Result<Self, Self::Error> {
38 match value.is_integral() {
39 true => Ok(value.0.into_words().0),
40 false => Err(super::Error::NonIntegral { value }),
41 }
42 }
43}
44
45impl TryFrom<U128x128> for u64 {
46 type Error = super::Error;
47 fn try_from(value: U128x128) -> Result<Self, Self::Error> {
48 u128::try_from(value).and_then(|x| u64::try_from(x).map_err(|_| super::Error::Overflow))
49 }
50}
51
52impl From<[u8; 32]> for U128x128 {
53 fn from(value: [u8; 32]) -> Self {
54 Self::from_bytes(value)
55 }
56}
57
58impl From<U128x128> for [u8; 32] {
59 fn from(value: U128x128) -> Self {
60 value.to_bytes()
61 }
62}
63
64impl From<U128x128> for f64 {
65 fn from(value: U128x128) -> Self {
66 let (hi, lo) = value.0.into_words();
69 const BASE: u64 = 0x47f0000000000000;
71 (hi as f64) + (lo as f64) / f64::from_bits(BASE)
72 }
73}
74
75impl TryFrom<f64> for U128x128 {
76 type Error = fixpoint::Error;
77
78 #[allow(clippy::if_same_then_else)]
79 fn try_from(value: f64) -> Result<U128x128, Self::Error> {
80 if value < 0.0 {
81 Err(fixpoint::Error::InvalidFloat64 { value })
82 } else if value.is_infinite() {
83 Err(fixpoint::Error::InvalidFloat64 { value })
84 } else if value.is_nan() {
85 Err(fixpoint::Error::InvalidFloat64 { value })
86 } else {
87 let integral = value as u128;
88 let fractional = value.fract();
89
90 let fractional_as_u128 =
95 (fractional * f64::from_bits(0x47f0000000000000)).trunc() as u128;
96 let combined = U256::from_words(integral, fractional_as_u128);
97 Ok(U128x128(combined))
98 }
99 }
100}
101
102impl From<U128x128> for Vec<u8> {
103 fn from(value: U128x128) -> Self {
104 value.to_bytes().to_vec()
105 }
106}
107
108impl TryFrom<&[u8]> for U128x128 {
109 type Error = super::Error;
110 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
111 Ok(<[u8; 32]>::try_from(value)
112 .map_err(|_| super::Error::SliceLength(value.len()))?
113 .into())
114 }
115}