convert.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. use ibig::{error::OutOfBoundsError, ibig, ubig, IBig, UBig};
  2. use std::convert::TryFrom;
  3. #[test]
  4. fn test_from_to_le_bytes() {
  5. let empty: [u8; 0] = [];
  6. assert_eq!(UBig::from_le_bytes(&[]).to_le_bytes(), empty);
  7. assert_eq!(UBig::from_le_bytes(&[0; 100]).to_le_bytes(), empty);
  8. assert_eq!(UBig::from_le_bytes(&[1, 2, 3, 0]).to_le_bytes(), [1, 2, 3]);
  9. let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
  10. assert_eq!(UBig::from_le_bytes(&bytes).to_le_bytes(), bytes);
  11. }
  12. #[test]
  13. fn test_from_to_be_bytes() {
  14. let empty: [u8; 0] = [];
  15. assert_eq!(UBig::from_be_bytes(&[]).to_be_bytes(), empty);
  16. assert_eq!(UBig::from_be_bytes(&[0; 100]).to_be_bytes(), empty);
  17. assert_eq!(UBig::from_be_bytes(&[0, 1, 2, 3]).to_be_bytes(), [1, 2, 3]);
  18. let bytes = [100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17];
  19. assert_eq!(UBig::from_be_bytes(&bytes).to_be_bytes(), bytes);
  20. }
  21. #[test]
  22. fn test_ubig_from_unsigned() {
  23. assert_eq!(UBig::from(0xf1u8), UBig::from_be_bytes(&[0xf1]));
  24. assert_eq!(UBig::from(0xf123u16), UBig::from_be_bytes(&[0xf1, 0x23]));
  25. assert_eq!(
  26. UBig::from(0xf1234567u32),
  27. UBig::from_be_bytes(&[0xf1, 0x23, 0x45, 0x67])
  28. );
  29. assert_eq!(
  30. UBig::from(0xf123456701234567u64),
  31. UBig::from_be_bytes(&[0xf1, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67])
  32. );
  33. assert_eq!(
  34. UBig::from(0xf1234567012345670123456701234567u128),
  35. UBig::from_be_bytes(&[
  36. 0xf1, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67, 0x01, 0x23,
  37. 0x45, 0x67
  38. ])
  39. );
  40. assert_eq!(UBig::from(5u128), UBig::from_be_bytes(&[5]));
  41. assert_eq!(UBig::from(5usize), UBig::from_be_bytes(&[5]));
  42. }
  43. #[test]
  44. fn test_ubig_from_bool() {
  45. assert_eq!(UBig::from(false), UBig::from(0u8));
  46. assert_eq!(UBig::from(true), UBig::from(1u8));
  47. }
  48. #[test]
  49. fn test_ubig_from_signed() {
  50. assert!(UBig::try_from(-5i32).is_err());
  51. assert_eq!(UBig::try_from(5i32), Ok(UBig::from(5u32)));
  52. assert_eq!(UBig::try_from(5i128 << 120), Ok(UBig::from(5u128 << 120)));
  53. }
  54. #[test]
  55. fn test_ubig_to_unsigned() {
  56. assert_eq!(u8::try_from(UBig::from(0xeeu8)), Ok(0xeeu8));
  57. assert!(u8::try_from(UBig::from(0x123u16)).is_err());
  58. assert_eq!(u16::try_from(UBig::from(0x1234u16)), Ok(0x1234u16));
  59. assert!(u16::try_from(UBig::from(0x12345u32)).is_err());
  60. assert_eq!(u32::try_from(UBig::from(0xf1234567u32)), Ok(0xf1234567u32));
  61. assert!(u32::try_from(UBig::from(0x101234567u64)).is_err());
  62. assert_eq!(
  63. u64::try_from(UBig::from(0xf123456789abcdefu64)),
  64. Ok(0xf123456789abcdefu64)
  65. );
  66. assert!(u64::try_from(UBig::from(0x10123456789abcdefu128)).is_err());
  67. assert_eq!(
  68. u128::try_from(UBig::from(0xf123456789abcdef0123456789abcdefu128)),
  69. Ok(0xf123456789abcdef0123456789abcdefu128)
  70. );
  71. let big = UBig::from_be_bytes(&[1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
  72. assert!(u8::try_from(&big).is_err());
  73. assert!(u128::try_from(&big).is_err());
  74. assert_eq!(usize::try_from(UBig::from(5u8)), Ok(5usize));
  75. }
  76. #[test]
  77. fn test_ubig_to_signed() {
  78. assert_eq!(i8::try_from(UBig::from(0x7eu8)), Ok(0x7ei8));
  79. assert!(i8::try_from(UBig::from(0xeeu8)).is_err());
  80. assert!(i8::try_from(UBig::from(0x100u16)).is_err());
  81. assert_eq!(i16::try_from(&UBig::from(0x1234u16)), Ok(0x1234i16));
  82. assert!(i16::try_from(UBig::from(0x8234u32)).is_err());
  83. assert_eq!(i32::try_from(UBig::from(0x61234567u32)), Ok(0x61234567i32));
  84. assert!(i32::try_from(UBig::from(0x91234567u32)).is_err());
  85. assert_eq!(
  86. i64::try_from(UBig::from(0x3123456789abcdefu64)),
  87. Ok(0x3123456789abcdefi64)
  88. );
  89. assert!(i64::try_from(UBig::from(0xf123456789abcdefu64)).is_err());
  90. assert_eq!(
  91. i128::try_from(UBig::from(0x6123456789abcdef0123456789abcdefu128)),
  92. Ok(0x6123456789abcdef0123456789abcdefi128)
  93. );
  94. assert!(i128::try_from(UBig::from(0xf123456789abcdef0123456789abcdefu128)).is_err());
  95. let big = UBig::from_be_bytes(&[1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
  96. assert!(i8::try_from(&big).is_err());
  97. assert!(i128::try_from(&big).is_err());
  98. assert_eq!(isize::try_from(UBig::from(5u8)), Ok(5isize));
  99. }
  100. #[test]
  101. fn test_ibig_from_unsigned() {
  102. assert_eq!(IBig::from(0u32), IBig::from(UBig::from(0u32)));
  103. assert_eq!(IBig::from(100u32), IBig::from(UBig::from(100u32)));
  104. }
  105. #[test]
  106. fn test_ibig_from_bool() {
  107. assert_eq!(IBig::from(false), IBig::from(0u8));
  108. assert_eq!(IBig::from(true), IBig::from(1u8));
  109. }
  110. #[test]
  111. fn test_ibig_from_signed() {
  112. assert_eq!(IBig::from(0i32), IBig::from(UBig::from(0u32)));
  113. assert_eq!(IBig::from(100i32), IBig::from(UBig::from(100u32)));
  114. assert_eq!(IBig::from(-0xeei32).in_radix(16).to_string(), "-ee");
  115. }
  116. #[test]
  117. fn test_ibig_to_unsigned() {
  118. assert_eq!(u8::try_from(IBig::from(0i32)), Ok(0u8));
  119. assert_eq!(u8::try_from(IBig::from(0x7fi32)), Ok(0x7fu8));
  120. assert_eq!(u8::try_from(&IBig::from(0xffi32)), Ok(0xffu8));
  121. assert!(u8::try_from(IBig::from(0x100i32)).is_err());
  122. assert!(u8::try_from(IBig::from(-1i32)).is_err());
  123. assert!(u8::try_from(IBig::from(-0x7fi32)).is_err());
  124. assert!(u8::try_from(IBig::from(-0x80i32)).is_err());
  125. }
  126. #[test]
  127. fn test_ibig_to_signed() {
  128. assert_eq!(i8::try_from(IBig::from(0i32)), Ok(0i8));
  129. assert_eq!(i8::try_from(&IBig::from(0x7fi32)), Ok(0x7fi8));
  130. assert!(i8::try_from(IBig::from(0x80i32)).is_err());
  131. assert!(i8::try_from(IBig::from(0xffi32)).is_err());
  132. assert!(i8::try_from(IBig::from(0x100i32)).is_err());
  133. assert_eq!(i8::try_from(IBig::from(-1i32)), Ok(-1i8));
  134. assert_eq!(i8::try_from(IBig::from(-0x7fi32)), Ok(-0x7fi8));
  135. assert_eq!(i8::try_from(IBig::from(-0x80i32)), Ok(-0x80i8));
  136. assert!(i8::try_from(IBig::from(-0x81i32)).is_err());
  137. assert!(i8::try_from(IBig::from(-0x100i32)).is_err());
  138. }
  139. #[test]
  140. fn test_ubig_to_ibig() {
  141. assert_eq!(IBig::from(UBig::from(0u32)), IBig::from(0i32));
  142. assert_eq!(IBig::from(UBig::from(100u32)), IBig::from(100i32));
  143. assert_eq!(IBig::from(&UBig::from(100u32)), IBig::from(100i32));
  144. }
  145. #[test]
  146. fn test_ibig_to_ubig() {
  147. assert_eq!(UBig::try_from(IBig::from(0i32)), Ok(UBig::from(0u32)));
  148. assert_eq!(UBig::try_from(IBig::from(1000i32)), Ok(UBig::from(1000u32)));
  149. assert_eq!(
  150. UBig::try_from(&IBig::from(1000i32)),
  151. Ok(UBig::from(1000u32))
  152. );
  153. assert!(UBig::try_from(IBig::from(-1000i32)).is_err());
  154. assert!(UBig::try_from(&IBig::from(-1000i32)).is_err());
  155. }
  156. #[test]
  157. fn test_default() {
  158. assert_eq!(UBig::default(), ubig!(0));
  159. assert_eq!(IBig::default(), ibig!(0));
  160. }
  161. #[test]
  162. fn test_display_out_of_bounds_error() {
  163. assert_eq!(OutOfBoundsError.to_string(), "number out of bounds");
  164. }
  165. #[test]
  166. #[allow(clippy::float_cmp)]
  167. fn test_to_f32() {
  168. assert_eq!(ubig!(0).to_f32(), 0.0f32);
  169. assert_eq!(ubig!(7).to_f32(), 7.0f32);
  170. // 2^24 - 1 is still exactly representable
  171. assert_eq!(ubig!(0xffffff).to_f32(), 16777215.0f32);
  172. assert_eq!(ubig!(0x1000000).to_f32(), 16777216.0f32);
  173. // Now round to even should begin.
  174. assert_eq!(ubig!(0x1000001).to_f32(), 16777216.0f32);
  175. assert_eq!(ubig!(0x1000002).to_f32(), 16777218.0f32);
  176. assert_eq!(ubig!(0x1000003).to_f32(), 16777220.0f32);
  177. assert_eq!(ubig!(0x1000004).to_f32(), 16777220.0f32);
  178. assert_eq!(ubig!(0x1000005).to_f32(), 16777220.0f32);
  179. for i in 10..80 {
  180. assert_eq!(
  181. (ubig!(0xfff3330) << i).to_f32(),
  182. (0xfff3330 as f32) * (i as f32).exp2()
  183. );
  184. assert_eq!(
  185. (ubig!(0xfff3331) << i).to_f32(),
  186. (0xfff3330 as f32) * (i as f32).exp2()
  187. );
  188. assert_eq!(
  189. (ubig!(0xfff3337) << i).to_f32(),
  190. (0xfff3330 as f32) * (i as f32).exp2()
  191. );
  192. assert_eq!(
  193. (ubig!(0xfff3338) << i).to_f32(),
  194. (0xfff3340 as f32) * (i as f32).exp2()
  195. );
  196. assert_eq!(
  197. ((ubig!(0xfff3338) << i) + ubig!(1)).to_f32(),
  198. (0xfff3340 as f32) * (i as f32).exp2()
  199. );
  200. assert_eq!(
  201. (ubig!(0xfff3339) << i).to_f32(),
  202. (0xfff3340 as f32) * (i as f32).exp2()
  203. );
  204. assert_eq!(
  205. (ubig!(0xfff3347) << i).to_f32(),
  206. (0xfff3340 as f32) * (i as f32).exp2()
  207. );
  208. assert_eq!(
  209. (ubig!(0xfff3348) << i).to_f32(),
  210. (0xfff3340 as f32) * (i as f32).exp2()
  211. );
  212. assert_eq!(
  213. ((ubig!(0xfff3348) << i) + ubig!(1)).to_f32(),
  214. (0xfff3350 as f32) * (i as f32).exp2()
  215. );
  216. assert_eq!(
  217. (ubig!(0xfff3349) << i).to_f32(),
  218. (0xfff3350 as f32) * (i as f32).exp2()
  219. );
  220. }
  221. assert!((ubig!(0xffffff7) << 100).to_f32() < f32::INFINITY);
  222. assert!((ubig!(0xffffff8) << 100).to_f32() == f32::INFINITY);
  223. assert!((ubig!(1) << 1000).to_f32() == f32::INFINITY);
  224. assert_eq!(ibig!(0).to_f32(), 0.0f32);
  225. assert_eq!(ibig!(7).to_f32(), 7.0f32);
  226. assert_eq!(ibig!(-7).to_f32(), -7.0f32);
  227. assert!((ibig!(-0xffffff7) << 100).to_f32() > -f32::INFINITY);
  228. assert!((ibig!(-0xffffff8) << 100).to_f32() == -f32::INFINITY);
  229. }
  230. #[test]
  231. #[allow(clippy::float_cmp)]
  232. fn test_to_f64() {
  233. assert_eq!(ubig!(0).to_f64(), 0.0f64);
  234. assert_eq!(ubig!(7).to_f64(), 7.0f64);
  235. // 2^53 - 1 is still exactly representable
  236. assert_eq!(ubig!(0x1fffffffffffff).to_f64(), 9007199254740991.0f64);
  237. assert_eq!(ubig!(0x20000000000000).to_f64(), 9007199254740992.0f64);
  238. // Now round to even should begin.
  239. assert_eq!(ubig!(0x20000000000001).to_f64(), 9007199254740992.0f64);
  240. assert_eq!(ubig!(0x20000000000002).to_f64(), 9007199254740994.0f64);
  241. assert_eq!(ubig!(0x20000000000003).to_f64(), 9007199254740996.0f64);
  242. assert_eq!(ubig!(0x20000000000004).to_f64(), 9007199254740996.0f64);
  243. assert_eq!(ubig!(0x20000000000005).to_f64(), 9007199254740996.0f64);
  244. for i in 10..500 {
  245. assert_eq!(
  246. (ubig!(0x1ffffffffff3330) << i).to_f64(),
  247. (0x1ffffffffff3330u64 as f64) * (i as f64).exp2()
  248. );
  249. assert_eq!(
  250. (ubig!(0x1ffffffffff3331) << i).to_f64(),
  251. (0x1ffffffffff3330u64 as f64) * (i as f64).exp2()
  252. );
  253. assert_eq!(
  254. (ubig!(0x1ffffffffff3337) << i).to_f64(),
  255. (0x1ffffffffff3330u64 as f64) * (i as f64).exp2()
  256. );
  257. assert_eq!(
  258. (ubig!(0x1ffffffffff3338) << i).to_f64(),
  259. (0x1ffffffffff3340u64 as f64) * (i as f64).exp2()
  260. );
  261. assert_eq!(
  262. ((ubig!(0x1ffffffffff3338) << i) + ubig!(1)).to_f64(),
  263. (0x1ffffffffff3340u64 as f64) * (i as f64).exp2()
  264. );
  265. assert_eq!(
  266. (ubig!(0x1ffffffffff3339) << i).to_f64(),
  267. (0x1ffffffffff3340u64 as f64) * (i as f64).exp2()
  268. );
  269. assert_eq!(
  270. (ubig!(0x1ffffffffff3347) << i).to_f64(),
  271. (0x1ffffffffff3340u64 as f64) * (i as f64).exp2()
  272. );
  273. assert_eq!(
  274. (ubig!(0x1ffffffffff3348) << i).to_f64(),
  275. (0x1ffffffffff3340u64 as f64) * (i as f64).exp2()
  276. );
  277. assert_eq!(
  278. ((ubig!(0x1ffffffffff3348) << i) + ubig!(1)).to_f64(),
  279. (0x1ffffffffff3350u64 as f64) * (i as f64).exp2()
  280. );
  281. assert_eq!(
  282. (ubig!(0x1ffffffffff3349) << i).to_f64(),
  283. (0x1ffffffffff3350u64 as f64) * (i as f64).exp2()
  284. );
  285. }
  286. assert!((ubig!(0x1fffffffffffff7) << 967).to_f64() < f64::INFINITY);
  287. assert!((ubig!(0x1fffffffffffff8) << 967).to_f64() == f64::INFINITY);
  288. assert!((ubig!(1) << 10000).to_f64() == f64::INFINITY);
  289. assert_eq!(ibig!(0).to_f64(), 0.0f64);
  290. assert_eq!(ibig!(7).to_f64(), 7.0f64);
  291. assert_eq!(ibig!(-7).to_f64(), -7.0f64);
  292. assert!((ibig!(-0x1fffffffffffff7) << 967).to_f64() > -f64::INFINITY);
  293. assert!((ibig!(-0x1fffffffffffff8) << 967).to_f64() == -f64::INFINITY);
  294. }