I've got a usize
that does hit very large values. I also apply a delta to it that I receive in the form of an isize
. What's the best way to apply the delta without losing any precision?
fn main() {
let mut big_indexer: usize = 4295032832; // 2^32 + 2^16
let delta: isize = -65792; // 2^16 + 2^8
let big_indexer = (big_indexer as isize) + delta // Can't do this b/c overflow
let big_indexer = big_indexer + (delta as usize) // Can't do this b/c lose negative number
// This is ugly
if delta < 0 {
let big_indexer -= delta.abs() as usize;
} else {
let big_indexer += delta.abs() as usize;
}
}
Conservatively assume that usize may be as narrow as 8 bits. Liberally assume that usize is at least 32 bits wide (as it is on all current officially supported platforms). Let me know if I missed any other corners of the standard library which make assumptions (identical to one of these or not).
Introduction to Rust usize. It is a primitive type of rust, which is based on pointer like C programming language. If we have a type that does not have a definite size, we call those primitive types as 'usize' in rust or dynamically sized types in rust. It is representing as the pointer sized unsigned type in rust.
Use usize and isize when it's related to memory size -- the size of an object, or indexing a vector, for instance. It will be a 32-bit number on 32-bit platforms, as that's the limit of memory they can address, and likewise for 64-bit. Use u32 and i32 when you just want numbers.
There are two ways:
isize
(the choice of rust std
for example)usize
and handle sign yourself (clearly my preferred choice).But the implementation is up to you; for example, you could have a bool
that tells you if the offset is a difference or an addition, or use an enum:
fn foo(n: usize, offset: usize, sub: bool) -> Option<usize> {
(if sub {
usize::checked_sub
} else {
usize::checked_add
})(n, offset)
}
enum OffSet {
Neg(usize),
Pos(usize),
}
fn bar(n: usize, offset: OffSet) -> Option<usize> {
match offset {
OffSet::Pos(offset) => n.checked_add(offset),
OffSet::Neg(offset) => n.checked_sub(offset),
}
}
fn main() {
let n = 4295032832; // 2^32 + 2^16
let offset = 65792; // 2^16 + 2^8
let sub = true;
assert_eq!(Some(n - offset), foo(n, offset, sub));
assert_eq!(Some(n - offset), bar(n, OffSet::Neg(offset)));
}
This is not ugly at all; you just have to use some trait to hide the logic and then you just have to use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With