I am coming from looking at Rust and How do I detect unsigned integer multiply overflow? where in Rust they have checked_add
, which is implemented like this:
pub const fn checked_add(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_add(rhs);
if unlikely!(b) {None} else {Some(a)}
}
pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
(a as Self, b)
}
// can't find where this is implemented...
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
If you try adding two u8
large integers, compiler doesn't let you:
fn main() {
let a: u8 = 255;
let b: u8 = 255;
let c = a + b;
// ^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
}
How is this done in C? How can I simulate this sort of thing in JavaScript?
For example, in JavaScript. I guess in JavaScript you would check if it hits Infinity
, as in Number.MAX_VALUE * 2 == Infinity
. But in the case of Rust, how can I simulate this (or in C), using a specific low-level uint data type? (Without resorting to the checked_add
helper methods which already solve it). Basically I am wondering how you can tell if it will overflow if the datatypes don't allow you to overflow.
I am working on building a programming language so would like to know how this is implemented.
Specifically right now what I am trying to do is, if you have a function called get_next_power_of_2(u8)
, it should return a u8 if it fits, otherwise a u16. But not a u16 in all cases. So I am wondering how to first check that it is going to overflow, and if it does, cast to a higher int.