2018-12-12 14:14:34 +01:00
|
|
|
extern crate num_bigint_dig as num_bigint;
|
2018-07-11 12:14:46 +02:00
|
|
|
extern crate num_integer;
|
|
|
|
extern crate num_traits;
|
|
|
|
|
|
|
|
mod biguint {
|
|
|
|
use num_bigint::BigUint;
|
2018-07-19 17:07:57 +02:00
|
|
|
use num_traits::Pow;
|
2018-07-11 12:14:46 +02:00
|
|
|
use std::str::FromStr;
|
|
|
|
|
2018-07-13 12:52:40 +02:00
|
|
|
fn check(x: u64, n: u32) {
|
|
|
|
let big_x = BigUint::from(x);
|
|
|
|
let res = big_x.nth_root(n);
|
2018-07-11 12:14:46 +02:00
|
|
|
|
2018-07-13 12:52:40 +02:00
|
|
|
if n == 2 {
|
|
|
|
assert_eq!(&res, &big_x.sqrt())
|
|
|
|
} else if n == 3 {
|
|
|
|
assert_eq!(&res, &big_x.cbrt())
|
|
|
|
}
|
|
|
|
|
2018-07-19 17:07:57 +02:00
|
|
|
assert!(res.pow(n) <= big_x);
|
|
|
|
assert!((res + 1u32).pow(n) > big_x);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_sqrt() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(99, 2);
|
|
|
|
check(100, 2);
|
|
|
|
check(120, 2);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_cbrt() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(8, 3);
|
|
|
|
check(26, 3);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_nth_root() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(0, 1);
|
|
|
|
check(10, 1);
|
|
|
|
check(100, 4);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_nth_root_n_is_zero() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(4, 0);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_nth_root_big() {
|
2018-07-13 12:52:40 +02:00
|
|
|
let x = BigUint::from_str("123_456_789").unwrap();
|
|
|
|
let expected = BigUint::from(6u32);
|
2018-07-11 12:14:46 +02:00
|
|
|
|
|
|
|
assert_eq!(x.nth_root(10), expected);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mod bigint {
|
|
|
|
use num_bigint::BigInt;
|
2018-07-21 18:42:30 +02:00
|
|
|
use num_traits::{Pow, Signed};
|
2018-07-13 12:52:40 +02:00
|
|
|
|
|
|
|
fn check(x: i64, n: u32) {
|
|
|
|
let big_x = BigInt::from(x);
|
|
|
|
let res = big_x.nth_root(n);
|
|
|
|
|
|
|
|
if n == 2 {
|
|
|
|
assert_eq!(&res, &big_x.sqrt())
|
|
|
|
} else if n == 3 {
|
|
|
|
assert_eq!(&res, &big_x.cbrt())
|
|
|
|
}
|
|
|
|
|
|
|
|
if big_x.is_negative() {
|
2018-07-19 17:07:57 +02:00
|
|
|
assert!(res.pow(n) >= big_x);
|
|
|
|
assert!((res - 1u32).pow(n) < big_x);
|
2018-07-13 12:52:40 +02:00
|
|
|
} else {
|
2018-07-19 17:07:57 +02:00
|
|
|
assert!(res.pow(n) <= big_x);
|
|
|
|
assert!((res + 1u32).pow(n) > big_x);
|
2018-07-13 12:52:40 +02:00
|
|
|
}
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_nth_root() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(-100, 3);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_nth_root_x_neg_n_even() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(-100, 4);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_sqrt_x_neg() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(-4, 2);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_cbrt() {
|
2018-07-13 12:52:40 +02:00
|
|
|
check(8, 3);
|
|
|
|
check(-8, 3);
|
2018-07-11 12:14:46 +02:00
|
|
|
}
|
|
|
|
}
|