Back
C
/******************************************************************************
* LICENSE *
******************************************************************************
* This file is part of mitx_mathematics_programming_examples. *
* *
* mitx_mathematics_programming_examples is free software: you can *
* redistribute it and/or modify it under the terms of the GNU General *
* Public License as published by the Free Software Foundation, either *
* version 3 of the License, or (at your option) any later version. *
* *
* mitx_mathematics_programming_examples is distributed in the hope that *
* it will be useful but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with mitx_mathematics_programming_examples. If not, see *
* <https://www.gnu.org/licenses/>. *
******************************************************************************
* Purpose: *
* Shows that integers addition can overflow, setting back to zero. *
******************************************************************************
* Author: Ryan Maguire *
* Date: 2024/12/03 *
******************************************************************************/
/* stdio.h provides the "printf" function, used for printing text. */
#include <stdio.h>
/* Computes the number of bits used for unsigned int's. */
static int get_number_of_bits(void)
{
/* Variables for keeping track of the largest power of two possible for *
* unsigned integers. Most computers use 32-bit int's. */
int exponent = 0;
unsigned int power_of_two = 1;
/* We start with power_of_two = 1 and iteratively multiply by two. After *
* enough iterations, this will overflow and we will get zero. */
while (power_of_two != 0U)
{
/* Increment the exponent since we haven't overflowed yet. */
exponent = exponent + 1;
/* C syntax: "x << n" takes x and shifts it up n bits. This is the *
* mathematical equivalent of multiplying x by 2^n. Setting *
* power_of_two equal to power_of_two << 1 will compute the next *
* power of two up. */
power_of_two = power_of_two << 1;
}
/* "exponent" now stores the first value N such that 2^N overflows to *
* zero. This is the number of bits used for the number. Return this. */
return exponent;
}
/* End of get_number_of_bits. */
/* Computes the largest number possible for unsigned int. */
static unsigned int get_max_number(void)
{
/* We will compute the maximum number for unsigned int as follows: *
* *
* N - 1 *
* ----- *
* \ n *
* max = / 2 *
* ----- *
* n = 0 *
* *
* where N is the number of bits in unsigned int. That is, we create the *
* number that is all ones in binary and is number-of-bits long. */
const int number_of_bits = get_number_of_bits();
/* We start the sum at zero and compute it iteratively. */
unsigned int max_integer = 0U;
/* Variable for looping over the bits of the number. */
int index;
/* Variable for computing 2^n as n varies from 0 to number_of_bits - 1. */
unsigned int two_to_the_n;
/* Loop through the bits and perform the sum. */
for (index = 0; index < number_of_bits; ++index)
{
/* We compute 2^n by bit-shifting 1 by n bits. Consider the same *
* idea but in decimal. If you have 10.00 and want one hundred, you *
* would simply shift the decimal over by one, obtaining 100.0. This *
* is the binary equivalent of that idea. */
two_to_the_n = 1 << index;
/* Add this power of two to the output. */
max_integer = max_integer + two_to_the_n;
}
/* max_integer is now 111....111_2, in binary, with number_of_bits 1's. */
return max_integer;
}
/* End of get_max_number. */
/* A short program for testing our functions. */
int main(void)
{
/* Compute the number of bits and the max number using our functions. */
const int number_of_bits = get_number_of_bits();
const unsigned int max_number = get_max_number();
/* If we add 1 to the max number, it will overflow to zero. Let's see. */
const unsigned int max_number_plus_one = max_number + 1U;
/* Print all of the results to the screen. printf is found in stdio.h. */
printf("Total Number of Bits: %d\n", number_of_bits);
printf("Largest Integer Value: %u\n", max_number);
printf("Largest Value Plus One: %u\n", max_number_plus_one);
return 0;
}
/* We can execute this on GNU, Linux, FreeBSD, macOS, etc., via: *
* cc integer_overflow.c -o main *
* ./main *
* This will output the following: *
* Total Number of Bits: 32 *
* Largest Integer Value: 4294967295 *
* Largest Value Plus One: 0 *
* This final line indicates the overflow, we've wrapped around to zero. *
* *
* On Windows you will need to install a C compiler. Common options are *
* Microsoft's MSVC, LLVM's clang, MinGW (which uses the GNU toolchain), *
* or installing Cygwin and running the commands above. */
C3
/******************************************************************************
* LICENSE *
******************************************************************************
* This file is part of mitx_mathematics_programming_examples. *
* *
* mitx_mathematics_programming_examples is free software: you can *
* redistribute it and/or modify it under the terms of the GNU General *
* Public License as published by the Free Software Foundation, either *
* version 3 of the License, or (at your option) any later version. *
* *
* mitx_mathematics_programming_examples is distributed in the hope that *
* it will be useful but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with mitx_mathematics_programming_examples. If not, see *
* <https://www.gnu.org/licenses/>. *
******************************************************************************
* Purpose: *
* Shows that integers addition can overflow, setting back to zero. *
******************************************************************************
* Author: Ryan Maguire *
* Date: 2025/05/29 *
******************************************************************************/
/* std::io provides the "printfn" function, used for printing text. */
import std::io;
/* Computes the number of bits used for unsigned int's. */
fn int get_number_of_bits()
{
/* Variables for keeping track of the largest power of two possible for *
* unsigned integers. C3 uses 32-bit int's and unsigned int's. */
int exponent = 0;
uint power_of_two = 1;
/* We start with power_of_two = 1 and iteratively multiply by two. After *
* enough iterations, this will overflow and we will get zero. */
while (power_of_two != 0U)
{
/* Increment the exponent since we haven't overflowed yet. */
exponent = exponent + 1;
/* C syntax: "x << n" takes x and shifts it up n bits. This is the *
* mathematical equivalent of multiplying x by 2^n. Setting *
* power_of_two equal to power_of_two << 1 will compute the next *
* power of two up. */
power_of_two = power_of_two << 1;
}
/* "exponent" now stores the first value N such that 2^N overflows to *
* zero. This is the number of bits used for the number. Return this. */
return exponent;
}
/* End of get_number_of_bits. */
/* Computes the largest number possible for unsigned int. */
fn uint get_max_number()
{
/* We will compute the maximum number for unsigned int as follows: *
* *
* N - 1 *
* ----- *
* \ n *
* max = / 2 *
* ----- *
* n = 0 *
* *
* where N is the number of bits in unsigned int. That is, we create the *
* number that is all ones in binary and is number-of-bits long. */
int number_of_bits = get_number_of_bits();
/* We start the sum at zero and compute it iteratively. */
uint max_integer = 0U;
/* Variable for looping over the bits of the number. */
int index;
/* Variable for computing 2^n as n varies from 0 to number_of_bits - 1. */
uint two_to_the_n;
/* Loop through the bits and perform the sum. */
for (index = 0; index < number_of_bits; ++index)
{
/* We compute 2^n by bit-shifting 1 by n bits. Consider the same *
* idea but in decimal. If you have 10.00 and want one hundred, you *
* would simply shift the decimal over by one, obtaining 100.0. This *
* is the binary equivalent of that idea. */
two_to_the_n = 1 << index;
/* Add this power of two to the output. */
max_integer = max_integer + two_to_the_n;
}
/* max_integer is now 111....111_2, in binary, with number_of_bits 1's. */
return max_integer;
}
/* End of get_max_number. */
/* A short program for testing our functions. */
fn int main()
{
/* Compute the number of bits and the max number using our functions. */
int number_of_bits = get_number_of_bits();
uint max_number = get_max_number();
/* If we add 1 to the max number, it will overflow to zero. Let's see. */
uint max_number_plus_one = max_number + 1U;
/* Print all of the results to the screen. printfn adds a new line, too. */
io::printfn("Total Number of Bits: %d", number_of_bits);
io::printfn("Largest Integer Value: %d", max_number);
io::printfn("Largest Value Plus One: %d", max_number_plus_one);
return 0;
}
Rust
/******************************************************************************
* LICENSE *
******************************************************************************
* This file is part of mitx_mathematics_programming_examples. *
* *
* mitx_mathematics_programming_examples is free software: you can *
* redistribute it and/or modify it under the terms of the GNU General *
* Public License as published by the Free Software Foundation, either *
* version 3 of the License, or (at your option) any later version. *
* *
* mitx_mathematics_programming_examples is distributed in the hope that *
* it will be useful but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with mitx_mathematics_programming_examples. If not, see *
* <https://www.gnu.org/licenses/>. *
******************************************************************************
* Purpose: *
* Shows that integers addition can overflow, setting back to zero. *
******************************************************************************
* Author: Ryan Maguire *
* Date: 2025/05/29 *
******************************************************************************/
/* Computes the number of bits used for unsigned integers. */
fn get_number_of_bits() -> u32 {
/* Variables for keeping track of the largest power of two possible for *
* unsigned integers. Rust has fixed-width 32-bit integers. */
let mut exponent: u32 = 0;
let mut power_of_two: u32 = 1;
/* We start with power_of_two = 1 and iteratively multiply by two. After *
* enough iterations, this will overflow and we will get zero. */
while power_of_two != 0 {
/* Increment the exponent since we haven't overflowed yet. */
exponent = exponent + 1;
/* C syntax: "x << n" takes x and shifts it up n bits. This is the *
* mathematical equivalent of multiplying x by 2^n. Setting *
* power_of_two equal to power_of_two << 1 will compute the next *
* power of two up. */
power_of_two = power_of_two << 1;
}
/* "exponent" now stores the first value N such that 2^N overflows to *
* zero. This is the number of bits used for the number. Return this. */
return exponent;
}
/* End of get_number_of_bits. */
/* Computes the largest number possible for unsigned integers. */
fn get_max_number() -> u32 {
/* We will compute the maximum number for unsigned int as follows: *
* *
* N - 1 *
* ----- *
* \ n *
* max = / 2 *
* ----- *
* n = 0 *
* *
* where N is the number of bits in the unsigned integer type. That is, *
* we create the number that is all 1 in binary and number-of-bits long. */
let number_of_bits: u32 = get_number_of_bits();
/* We start the sum at zero and compute it iteratively. */
let mut max_integer: u32 = 0;
/* Variable for computing 2^n as n varies from 0 to number_of_bits - 1. */
let mut two_to_the_n: u32;
/* Loop through the bits and perform the sum. */
for index in 0 .. number_of_bits {
/* We compute 2^n by bit-shifting 1 by n bits. Consider the same *
* idea but in decimal. If you have 10.00 and want one hundred, you *
* would simply shift the decimal over by one, obtaining 100.0. This *
* is the binary equivalent of that idea. wrapping_shl, which is the *
* "wrapping-shift-left" method, allows for shifting to overflow, or *
* "wrap", in Rust. */
two_to_the_n = 1u32.wrapping_shl(index);
/* Add this power of two to the output. wrapping_add also allows one *
* to add with wrapping enabled. */
max_integer = max_integer.wrapping_add(two_to_the_n);
}
/* max_integer is now 111....111_2, in binary, with number_of_bits 1's. */
return max_integer;
}
/* End of get_max_number. */
/* A short program for testing our functions. */
fn main() {
/* Compute the number of bits and the max number using our functions. */
let number_of_bits: u32 = get_number_of_bits();
let max_number: u32 = get_max_number();
/* If we add 1 to the max number, it will overflow to zero. Let's see. *
* Rust will catch overflows and stop the program by default unless we *
* use wrapping_add. Use this instead of the "+" symbol. */
let max_number_plus_one: u32 = max_number.wrapping_add(1);
/* Print all of the results to the screen. */
println!("Total Number of Bits: {}", number_of_bits);
println!("Largest Integer Value: {}", max_number);
println!("Largest Value Plus One: {}", max_number_plus_one);
}