Fix intrinsics and expand tests
This commit is contained in:
parent
85ec09187c
commit
dc14a108ae
3 changed files with 85 additions and 55 deletions
|
@ -24,10 +24,15 @@
|
||||||
|
|
||||||
#![allow(non_camel_case_types, unused_variables)]
|
#![allow(non_camel_case_types, unused_variables)]
|
||||||
|
|
||||||
|
|
||||||
#[cfg(any(target_pointer_width="32", target_pointer_width="16"))]
|
#[cfg(any(target_pointer_width="32", target_pointer_width="16"))]
|
||||||
pub mod reimpls {
|
pub mod reimpls {
|
||||||
|
|
||||||
#![allow(unused_comparisons)]
|
#![allow(unused_comparisons)]
|
||||||
|
|
||||||
|
use core::intrinsics::unchecked_div;
|
||||||
|
use core::intrinsics::unchecked_rem;
|
||||||
|
use core::ptr;
|
||||||
|
|
||||||
// C API is expected to tolerate some amount of size mismatch in ABI. Hopefully the amount of
|
// C API is expected to tolerate some amount of size mismatch in ABI. Hopefully the amount of
|
||||||
// handling is sufficient for bootstrapping.
|
// handling is sufficient for bootstrapping.
|
||||||
#[cfg(stage0)]
|
#[cfg(stage0)]
|
||||||
|
@ -112,26 +117,27 @@ pub mod reimpls {
|
||||||
pub extern fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
|
pub extern fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !rem.is_null() {
|
if !rem.is_null() {
|
||||||
*rem = n % d;
|
*rem = unchecked_rem(n, d);
|
||||||
}
|
}
|
||||||
n / d
|
unchecked_div(n, d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(stage0))]
|
#[cfg(not(stage0))]
|
||||||
#[export_name="__udivmodti4"]
|
#[export_name="__udivmodti4"]
|
||||||
pub extern fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
|
pub extern fn u128_div_mod(n: u128_, d: u128_, rem: *mut u128_) -> u128_ {
|
||||||
|
// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
|
||||||
unsafe {
|
unsafe {
|
||||||
// NOTE X is unknown, K != 0
|
// special cases, X is unknown, K != 0
|
||||||
if n.high() == 0 {
|
if n.high() == 0 {
|
||||||
if d.high() == 0 {
|
if d.high() == 0 {
|
||||||
// 0 X
|
// 0 X
|
||||||
// ---
|
// ---
|
||||||
// 0 X
|
// 0 X
|
||||||
if !rem.is_null() {
|
if !rem.is_null() {
|
||||||
*rem = u128::from(n.low() % d.low());
|
*rem = u128::from(unchecked_rem(n.low(), d.low()));
|
||||||
}
|
}
|
||||||
return u128::from(n.low() / d.low());
|
return u128::from(unchecked_div(n.low(), d.low()));
|
||||||
} else {
|
} else {
|
||||||
// 0 X
|
// 0 X
|
||||||
// ---
|
// ---
|
||||||
|
@ -152,7 +158,10 @@ pub mod reimpls {
|
||||||
// K X
|
// K X
|
||||||
// ---
|
// ---
|
||||||
// 0 0
|
// 0 0
|
||||||
unimplemented()
|
if !rem.is_null() {
|
||||||
|
*rem = u128::from(unchecked_rem(n.high(), d.low()));
|
||||||
|
}
|
||||||
|
return u128::from(unchecked_div(n.high(), d.low()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.low() == 0 {
|
if n.low() == 0 {
|
||||||
|
@ -160,9 +169,9 @@ pub mod reimpls {
|
||||||
// ---
|
// ---
|
||||||
// K 0
|
// K 0
|
||||||
if !rem.is_null() {
|
if !rem.is_null() {
|
||||||
*rem = u128::from_parts(0, n.high() % d.high());
|
*rem = u128::from_parts(0, unchecked_rem(n.high(), d.high()));
|
||||||
}
|
}
|
||||||
return u128::from(n.high() / d.high());
|
return u128::from(unchecked_div(n.high(), d.high()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// K K
|
// K K
|
||||||
|
@ -176,6 +185,9 @@ pub mod reimpls {
|
||||||
return u128::from(n.high() >> d.high().trailing_zeros());
|
return u128::from(n.high() >> d.high().trailing_zeros());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// K K
|
||||||
|
// ---
|
||||||
|
// K 0
|
||||||
sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros());
|
sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros());
|
||||||
|
|
||||||
// D > N
|
// D > N
|
||||||
|
@ -188,8 +200,8 @@ pub mod reimpls {
|
||||||
|
|
||||||
sr += 1;
|
sr += 1;
|
||||||
|
|
||||||
// 1 <= sr <= u32::bits() - 1
|
// 1 <= sr <= u64::bits() - 1
|
||||||
q = n << (128 - sr);
|
q = n << (64 - sr);
|
||||||
r = n >> sr;
|
r = n >> sr;
|
||||||
} else {
|
} else {
|
||||||
if d.high() == 0 {
|
if d.high() == 0 {
|
||||||
|
@ -214,6 +226,10 @@ pub mod reimpls {
|
||||||
// 2 <= sr <= u64::bits() - 1
|
// 2 <= sr <= u64::bits() - 1
|
||||||
q = n << (128 - sr);
|
q = n << (128 - sr);
|
||||||
r = n >> sr;
|
r = n >> sr;
|
||||||
|
// FIXME the C compiler-rt implementation has something here
|
||||||
|
// that looks like a speed optimisation.
|
||||||
|
// It would be worth a try to port it to Rust too and
|
||||||
|
// compare the speed.
|
||||||
} else {
|
} else {
|
||||||
// K X
|
// K X
|
||||||
// ---
|
// ---
|
||||||
|
@ -292,23 +308,17 @@ pub mod reimpls {
|
||||||
let sb = b.signum();
|
let sb = b.signum();
|
||||||
let a = a.abs();
|
let a = a.abs();
|
||||||
let b = b.abs();
|
let b = b.abs();
|
||||||
let sr = sa ^ sb;
|
let sr = sa * sb; // sign of quotient
|
||||||
unsafe {
|
if sr == -1 {
|
||||||
let mut r = ::core::mem::zeroed();
|
-(u128_div_mod(a as u128_, b as u128_, ptr::null_mut()) as i128_)
|
||||||
if sa == -1 {
|
|
||||||
-(u128_div_mod(a as u128_, b as u128_, &mut r) as i128_)
|
|
||||||
} else {
|
} else {
|
||||||
u128_div_mod(a as u128_, b as u128_, &mut r) as i128_
|
u128_div_mod(a as u128_, b as u128_, ptr::null_mut()) as i128_
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[export_name="__udivti3"]
|
#[export_name="__udivti3"]
|
||||||
pub extern fn u128_div(a: u128_, b: u128_) -> u128_ {
|
pub extern fn u128_div(a: u128_, b: u128_) -> u128_ {
|
||||||
unsafe {
|
u128_div_mod(a, b, ptr::null_mut())
|
||||||
let mut r = ::core::mem::zeroed();
|
|
||||||
u128_div_mod(a, b, &mut r)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! mulo {
|
macro_rules! mulo {
|
||||||
|
@ -329,23 +339,24 @@ pub mod reimpls {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bits = ::core::mem::size_of::<$ty>() * 8;
|
let sa = a.signum();
|
||||||
let sa = a >> (bits - 1);
|
let abs_a = a.abs();
|
||||||
let abs_a = (a ^ sa) - sa;
|
let sb = b.signum();
|
||||||
let sb = b >> (bits - 1);
|
let abs_b = b.abs();
|
||||||
let abs_b = (b ^ sb) - sb;
|
|
||||||
if abs_a < 2 || abs_b < 2 {
|
if abs_a < 2 || abs_b < 2 {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
unsafe {
|
||||||
if sa == sb {
|
if sa == sb {
|
||||||
if abs_a > <$ty>::max_value() / abs_b {
|
if abs_a > unchecked_div(<$ty>::max_value(), abs_b) {
|
||||||
*overflow = 1;
|
*overflow = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if abs_a > <$ty>::min_value() / -abs_b {
|
if abs_a > unchecked_div(<$ty>::min_value(), -abs_b) {
|
||||||
*overflow = 1;
|
*overflow = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
result
|
result
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -353,13 +364,7 @@ pub mod reimpls {
|
||||||
// FIXME: i32 here should be c_int.
|
// FIXME: i32 here should be c_int.
|
||||||
#[export_name="__muloti4"]
|
#[export_name="__muloti4"]
|
||||||
pub extern fn i128_mul_oflow(a: i128_, b: i128_, o: &mut i32) -> i128_ {
|
pub extern fn i128_mul_oflow(a: i128_, b: i128_, o: &mut i32) -> i128_ {
|
||||||
if let Some(v) = (a as i64).checked_mul(b as i64) {
|
mulo!(a, b, o, i128_)
|
||||||
*o = 0;
|
|
||||||
v as i128_
|
|
||||||
} else {
|
|
||||||
*o = 1;
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LargeInt {
|
pub trait LargeInt {
|
||||||
|
@ -407,7 +412,7 @@ pub mod reimpls {
|
||||||
self as u64
|
self as u64
|
||||||
}
|
}
|
||||||
fn high(self) -> u64 {
|
fn high(self) -> u64 {
|
||||||
unsafe { *(&self as *const u128 as *const u64) }
|
unsafe { *(&self as *const u128 as *const u64).offset(1) }
|
||||||
}
|
}
|
||||||
fn from_parts(low: u64, high: u64) -> u128 {
|
fn from_parts(low: u64, high: u64) -> u128 {
|
||||||
#[repr(C, packed)] struct Parts(u64, u64);
|
#[repr(C, packed)] struct Parts(u64, u64);
|
||||||
|
@ -423,7 +428,7 @@ pub mod reimpls {
|
||||||
self as u64
|
self as u64
|
||||||
}
|
}
|
||||||
fn high(self) -> i64 {
|
fn high(self) -> i64 {
|
||||||
unsafe { *(&self as *const i128 as *const i64) }
|
unsafe { *(&self as *const i128 as *const i64).offset(1) }
|
||||||
}
|
}
|
||||||
fn from_parts(low: u64, high: i64) -> i128 {
|
fn from_parts(low: u64, high: i64) -> i128 {
|
||||||
u128::from_parts(low, high as u64) as i128
|
u128::from_parts(low, high as u64) as i128
|
||||||
|
@ -431,37 +436,41 @@ pub mod reimpls {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! mul {
|
macro_rules! mul {
|
||||||
($a:expr, $b:expr, $ty: ty) => {{
|
($a:expr, $b:expr, $ty: ty, $tyh: ty) => {{
|
||||||
let (a, b) = ($a, $b);
|
let (a, b) = ($a, $b);
|
||||||
let bits = ::core::mem::size_of::<$ty>() * 8;
|
let half_bits = (::core::mem::size_of::<$tyh>() * 8) / 2;
|
||||||
let half_bits = bits / 4;
|
|
||||||
let lower_mask = !0 >> half_bits;
|
let lower_mask = !0 >> half_bits;
|
||||||
let mut low = (a.low() & lower_mask) * (b.low() & lower_mask);
|
let mut low = (a.low() & lower_mask) * (b.low() & lower_mask);
|
||||||
let mut t = low >> half_bits;
|
let mut t = low >> half_bits;
|
||||||
low &= lower_mask;
|
low &= lower_mask;
|
||||||
t += (a.low() >> half_bits) * (b.low() & lower_mask);
|
t += (a.low() >> half_bits) * (b.low() & lower_mask);
|
||||||
low += (t & lower_mask) << half_bits;
|
low += (t & lower_mask) << half_bits;
|
||||||
let mut high = t >> half_bits;
|
let mut high = (t >> half_bits) as $tyh;
|
||||||
t = low >> half_bits;
|
t = low >> half_bits;
|
||||||
low &= lower_mask;
|
low &= lower_mask;
|
||||||
t += (b.low() >> half_bits) * (a.low() & lower_mask);
|
t += (b.low() >> half_bits) * (a.low() & lower_mask);
|
||||||
low += (t & lower_mask) << half_bits;
|
low += (t & lower_mask) << half_bits;
|
||||||
high += t >> half_bits;
|
high += (t >> half_bits) as $tyh;
|
||||||
high += (a.low() >> half_bits) * (b.low() >> half_bits);
|
high += ((a.low() >> half_bits) * (b.low() >> half_bits)) as $tyh;
|
||||||
high = high
|
high = high
|
||||||
.wrapping_add(a.high()
|
.wrapping_add(a.high()
|
||||||
.wrapping_mul(b.low())
|
.wrapping_mul(b.low() as $tyh))
|
||||||
.wrapping_add(a.low()
|
.wrapping_add((a.low() as $tyh)
|
||||||
.wrapping_mul(b.high())));
|
.wrapping_mul(b.high()));
|
||||||
<$ty>::from_parts(low, high)
|
<$ty>::from_parts(low, high)
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
#[export_name="__multi3"]
|
#[export_name="__multi3"]
|
||||||
pub extern fn u128_mul(a: u128_, b: u128_) -> u128_ {
|
pub extern fn u128_mul(a: i128_, b: i128_) -> i128_ {
|
||||||
(a as u64 * b as u64) as u128_
|
(a as i64 * b as i64) as i128_
|
||||||
// mul!(a, b, u128_)
|
}
|
||||||
|
|
||||||
|
#[cfg(not(stage0))]
|
||||||
|
#[export_name="__multi3"]
|
||||||
|
pub extern fn u128_mul(a: i128_, b: i128_) -> i128_ {
|
||||||
|
mul!(a, b, i128_, i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait FloatStuff: Sized {
|
trait FloatStuff: Sized {
|
||||||
|
@ -471,6 +480,7 @@ pub mod reimpls {
|
||||||
const MAX_EXP: i32;
|
const MAX_EXP: i32;
|
||||||
const EXP_MASK: Self::ToBytes;
|
const EXP_MASK: Self::ToBytes;
|
||||||
const MANTISSA_MASK: Self::ToBytes;
|
const MANTISSA_MASK: Self::ToBytes;
|
||||||
|
const MANTISSA_LEAD_BIT: Self::ToBytes;
|
||||||
|
|
||||||
fn to_bytes(self) -> Self::ToBytes;
|
fn to_bytes(self) -> Self::ToBytes;
|
||||||
fn get_exponent(self) -> i32;
|
fn get_exponent(self) -> i32;
|
||||||
|
@ -480,8 +490,9 @@ pub mod reimpls {
|
||||||
type ToBytes = u32;
|
type ToBytes = u32;
|
||||||
const MANTISSA_BITS: u32 = 23;
|
const MANTISSA_BITS: u32 = 23;
|
||||||
const MAX_EXP: i32 = 127;
|
const MAX_EXP: i32 = 127;
|
||||||
const MANTISSA_MASK: u32 = 0x007F_FFFF;
|
|
||||||
const EXP_MASK: u32 = 0x7F80_0000;
|
const EXP_MASK: u32 = 0x7F80_0000;
|
||||||
|
const MANTISSA_MASK: u32 = 0x007F_FFFF;
|
||||||
|
const MANTISSA_LEAD_BIT: u32 = 0x0080_0000;
|
||||||
|
|
||||||
fn to_bytes(self) -> u32 { unsafe { ::core::mem::transmute(self) } }
|
fn to_bytes(self) -> u32 { unsafe { ::core::mem::transmute(self) } }
|
||||||
fn get_exponent(self) -> i32 {
|
fn get_exponent(self) -> i32 {
|
||||||
|
@ -495,6 +506,7 @@ pub mod reimpls {
|
||||||
const MAX_EXP: i32 = 1023;
|
const MAX_EXP: i32 = 1023;
|
||||||
const EXP_MASK: u64 = 0x7FF0_0000_0000_0000;
|
const EXP_MASK: u64 = 0x7FF0_0000_0000_0000;
|
||||||
const MANTISSA_MASK: u64 = 0x000F_FFFF_FFFF_FFFF;
|
const MANTISSA_MASK: u64 = 0x000F_FFFF_FFFF_FFFF;
|
||||||
|
const MANTISSA_LEAD_BIT: u64 = 0x0010_0000_0000_0000;
|
||||||
|
|
||||||
fn to_bytes(self) -> u64 { unsafe { ::core::mem::transmute(self) } }
|
fn to_bytes(self) -> u64 { unsafe { ::core::mem::transmute(self) } }
|
||||||
fn get_exponent(self) -> i32 {
|
fn get_exponent(self) -> i32 {
|
||||||
|
@ -508,7 +520,8 @@ pub mod reimpls {
|
||||||
let repr = $from.to_bytes();
|
let repr = $from.to_bytes();
|
||||||
let sign = $from.signum();
|
let sign = $from.signum();
|
||||||
let exponent = $from.get_exponent();
|
let exponent = $from.get_exponent();
|
||||||
let mantissa = repr & <$fromty as FloatStuff>::MANTISSA_MASK;
|
let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK;
|
||||||
|
let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT;
|
||||||
if sign == -1.0 || exponent < 0 { return 0; }
|
if sign == -1.0 || exponent < 0 { return 0; }
|
||||||
if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 {
|
if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 {
|
||||||
return !0;
|
return !0;
|
||||||
|
@ -537,7 +550,8 @@ pub mod reimpls {
|
||||||
let repr = $from.to_bytes();
|
let repr = $from.to_bytes();
|
||||||
let sign = $from.signum();
|
let sign = $from.signum();
|
||||||
let exponent = $from.get_exponent();
|
let exponent = $from.get_exponent();
|
||||||
let mantissa = repr & <$fromty as FloatStuff>::MANTISSA_MASK;
|
let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK;
|
||||||
|
let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT;
|
||||||
|
|
||||||
if exponent < 0 { return 0; }
|
if exponent < 0 { return 0; }
|
||||||
if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 {
|
if exponent > ::core::mem::size_of::<$outty>() as i32 * 8 {
|
||||||
|
|
|
@ -18,6 +18,9 @@ fn main() {
|
||||||
let y: i128 = -2;
|
let y: i128 = -2;
|
||||||
assert_eq!(!1, y);
|
assert_eq!(!1, y);
|
||||||
let z: i128 = 0xABCD_EF;
|
let z: i128 = 0xABCD_EF;
|
||||||
|
assert_eq!(z * z, 0x734C_C2F2_A521);
|
||||||
|
assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41);
|
||||||
|
assert_eq!(-z * -z, 0x734C_C2F2_A521);
|
||||||
assert_eq!(-z * -z * -z * -z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41);
|
assert_eq!(-z * -z * -z * -z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41);
|
||||||
assert_eq!(-z + -z + -z + -z, -0x2AF3_7BC);
|
assert_eq!(-z + -z + -z + -z, -0x2AF3_7BC);
|
||||||
let k: i128 = -0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
|
let k: i128 = -0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
|
||||||
|
@ -38,6 +41,10 @@ fn main() {
|
||||||
assert_eq!(k as i64, -0xFEDC_BA98_7654_3210);
|
assert_eq!(k as i64, -0xFEDC_BA98_7654_3210);
|
||||||
assert_eq!(k as u128, 0xFEDC_BA98_7654_3210_0123_4567_89AB_CDF0);
|
assert_eq!(k as u128, 0xFEDC_BA98_7654_3210_0123_4567_89AB_CDF0);
|
||||||
assert_eq!(-k as u128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210);
|
assert_eq!(-k as u128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210);
|
||||||
|
assert_eq!((-z as f64) as i128, -z);
|
||||||
|
assert_eq!((-z as f32) as i128, -z);
|
||||||
|
assert_eq!((-z as f64 * 16.0) as i128, -z * 16);
|
||||||
|
assert_eq!((-z as f32 * 16.0) as i128, -z * 16);
|
||||||
// formatting
|
// formatting
|
||||||
let j: i128 = -(1 << 67);
|
let j: i128 = -(1 << 67);
|
||||||
assert_eq!("-147573952589676412928", format!("{}", j));
|
assert_eq!("-147573952589676412928", format!("{}", j));
|
||||||
|
|
|
@ -23,6 +23,7 @@ fn main() {
|
||||||
y &
|
y &
|
||||||
0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFF);
|
0xFAFF_0000_FF8F_0000__FFFF_0000_FFFF_FFFF);
|
||||||
let z: u128 = 0xABCD_EF;
|
let z: u128 = 0xABCD_EF;
|
||||||
|
assert_eq!(z * z, 0x734C_C2F2_A521);
|
||||||
assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41);
|
assert_eq!(z * z * z * z, 0x33EE_0E2A_54E2_59DA_A0E7_8E41);
|
||||||
assert_eq!(z + z + z + z, 0x2AF3_7BC);
|
assert_eq!(z + z + z + z, 0x2AF3_7BC);
|
||||||
let k: u128 = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
|
let k: u128 = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
|
||||||
|
@ -34,6 +35,7 @@ fn main() {
|
||||||
assert_eq!(0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42);
|
assert_eq!(0x6EF5_DE4C_D3BC_2AAA_3BB4_CC5D_D6EE_8, k / 42);
|
||||||
assert_eq!(0, k % 42);
|
assert_eq!(0, k % 42);
|
||||||
assert_eq!(15, z % 42);
|
assert_eq!(15, z % 42);
|
||||||
|
assert_eq!(0x169D_A8020_CEC18, k % 0x3ACB_FE49_FF24_AC);
|
||||||
assert_eq!(0x91A2_B3C4_D5E6_F7, k >> 65);
|
assert_eq!(0x91A2_B3C4_D5E6_F7, k >> 65);
|
||||||
assert_eq!(0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65);
|
assert_eq!(0xFDB9_7530_ECA8_6420_0000_0000_0000_0000, k << 65);
|
||||||
assert!(k > z);
|
assert!(k > z);
|
||||||
|
@ -43,6 +45,13 @@ fn main() {
|
||||||
assert_eq!(z as u64, 0xABCD_EF);
|
assert_eq!(z as u64, 0xABCD_EF);
|
||||||
assert_eq!(k as u64, 0xFEDC_BA98_7654_3210);
|
assert_eq!(k as u64, 0xFEDC_BA98_7654_3210);
|
||||||
assert_eq!(k as i128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210);
|
assert_eq!(k as i128, 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210);
|
||||||
|
assert_eq!((z as f64) as u128, z);
|
||||||
|
assert_eq!((z as f32) as u128, z);
|
||||||
|
assert_eq!((z as f64 * 16.0) as u128, z * 16);
|
||||||
|
assert_eq!((z as f32 * 16.0) as u128, z * 16);
|
||||||
|
let l :u128 = 432 << 100;
|
||||||
|
assert_eq!((l as f32) as u128, l);
|
||||||
|
assert_eq!((l as f64) as u128, l);
|
||||||
// formatting
|
// formatting
|
||||||
let j: u128 = 1 << 67;
|
let j: u128 = 1 << 67;
|
||||||
assert_eq!("147573952589676412928", format!("{}", j));
|
assert_eq!("147573952589676412928", format!("{}", j));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue