CrackedRuby logo

CrackedRuby

Integer Class and Methods

Overview

Ruby represents integers through the Integer class, which handles both small and arbitrarily large whole numbers without requiring explicit size declarations. The class provides mathematical operations, bitwise manipulation, type conversion, and iteration methods.

Ruby automatically manages integer precision, promoting Fixnum values to Bignum when calculations exceed machine word size. This automatic scaling occurs transparently during arithmetic operations, allowing mathematical calculations without overflow concerns in most scenarios.

small_int = 42
large_int = 999999999999999999999999999999
calculation = small_int * large_int
# => 41999999999999999999999999999958

The Integer class supports standard arithmetic operators, comparison operations, and specialized methods for mathematical functions. All integer objects are immutable, meaning operations return new integer instances rather than modifying existing values.

original = 100
doubled = original * 2
original  # => 100 (unchanged)
doubled   # => 200

Ruby integers integrate with numeric coercion protocols, automatically converting between integer and floating-point types during mixed-type arithmetic operations.

integer_result = 10 / 3     # => 3 (integer division)
float_result = 10 / 3.0     # => 3.3333333333333335
mixed_operation = 42 + 3.14 # => 45.14

Basic Usage

Integer literals support multiple numeric bases including decimal, binary, octal, and hexadecimal representations. Ruby provides underscore separators for improved readability in large numeric literals.

decimal = 1_000_000
binary = 0b1010_1100
octal = 0o755
hexadecimal = 0xFF_AA_BB
scientific = 1e6.to_i  # => 1000000

Basic arithmetic operations include addition, subtraction, multiplication, division, modulo, and exponentiation. Integer division truncates toward negative infinity, differing from some programming languages that truncate toward zero.

standard_ops = [
  7 + 3,    # => 10
  7 - 3,    # => 4  
  7 * 3,    # => 21
  7 / 3,    # => 2
  7 % 3,    # => 1
  7 ** 3    # => 343
]

Ruby provides comparison operators that return boolean values for equality, inequality, and magnitude relationships. The spaceship operator returns -1, 0, or 1 for less-than, equal, or greater-than comparisons.

comparisons = [
  5 == 5,   # => true
  5 != 3,   # => true
  5 > 3,    # => true
  5 < 3,    # => false
  5 >= 5,   # => true
  5 <=> 3   # => 1
]

Type conversion methods transform integers to other numeric types and string representations. The to_s method accepts an optional radix parameter for different numeric bases.

number = 255
conversions = {
  to_float: number.to_f,        # => 255.0
  to_string: number.to_s,       # => "255"
  to_binary: number.to_s(2),    # => "11111111"
  to_hex: number.to_s(16),      # => "ff"
  to_octal: number.to_s(8)      # => "377"
}

Advanced Usage

Bitwise operations manipulate integer values at the binary level, providing AND, OR, XOR, NOT, and bit shifting capabilities. These operations work on the two's complement representation of integers.

a, b = 0b1100, 0b1010

bitwise_results = {
  and_operation: a & b,     # => 8  (0b1000)
  or_operation: a | b,      # => 14 (0b1110)
  xor_operation: a ^ b,     # => 6  (0b0110)
  not_operation: ~a,        # => -13
  left_shift: a << 2,       # => 48 (0b110000)
  right_shift: a >> 1       # => 6  (0b110)
}

Ruby integers support advanced mathematical functions including greatest common divisor, least common multiple, and mathematical properties testing. These methods handle edge cases and negative numbers appropriately.

mathematical_operations = [
  12.gcd(8),          # => 4
  12.lcm(8),          # => 24
  17.prime?,          # => true (requires 'prime' library)
  (-5).abs,           # => 5
  7.zero?,            # => false
  0.nonzero?,         # => nil
  (-3).positive?,     # => false
  (-3).negative?      # => true
]

Integer iteration methods provide functional programming capabilities, executing blocks for numeric ranges and repetition patterns. The times, upto, downto, and step methods control iteration direction and increment.

# Accumulating squares using times
squares = []
5.times { |i| squares << i ** 2 }
# => [0, 1, 4, 9, 16]

# Range iteration with upto
result = []
1.upto(5) { |n| result << n * 2 }
# => [2, 4, 6, 8, 10]

# Custom step iteration
fibonacci_like = []
current, previous = 1, 0
10.times do
  fibonacci_like << current
  current, previous = current + previous, current
end
# => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Advanced numeric methods include rounding operations, digit manipulation, and mathematical functions. The round method supports precision arguments for decimal place control, while digits extracts individual numeric digits.

number = 12345

digit_operations = {
  digit_array: number.digits,           # => [5, 4, 3, 2, 1]
  digit_count: number.digits.length,    # => 5
  sum_of_digits: number.digits.sum,     # => 15
  reverse_digits: number.digits.reverse # => [1, 2, 3, 4, 5]
}

# Complex digit manipulation
def is_palindrome?(num)
  digits = num.digits
  digits == digits.reverse
end

palindrome_test = is_palindrome?(12321)  # => true

Performance & Memory

Integer arithmetic performance varies significantly based on number size and operation complexity. Small integers fitting within machine word size execute faster than arbitrary precision calculations requiring heap allocation.

require 'benchmark'

small_int = 1000
large_int = 10 ** 100

Benchmark.bm(15) do |bm|
  bm.report("small arithmetic:") do
    100_000.times { small_int * small_int + small_int }
  end
  
  bm.report("large arithmetic:") do  
    100_000.times { large_int * large_int + large_int }
  end
end
# Small arithmetic executes significantly faster

Memory allocation patterns differ between small and large integers. Ruby's integer implementation uses immediate values for small integers, avoiding heap allocation overhead. Large integers require dynamic memory allocation proportional to digit count.

# Memory-efficient integer operations
def factorial_iterative(n)
  result = 1
  2.upto(n) { |i| result *= i }
  result
end

def factorial_recursive(n)
  return 1 if n <= 1
  n * factorial_recursive(n - 1)
end

# Iterative approach uses less memory for large factorials
large_factorial = factorial_iterative(1000)

Bitwise operations generally execute faster than arithmetic operations, particularly for multiplication and division by powers of two. Bit shifting replaces multiplication and division operations when working with binary powers.

# Efficient operations using bit manipulation
def multiply_by_8(n)
  n << 3  # Faster than n * 8
end

def divide_by_4(n)
  n >> 2  # Faster than n / 4
end

def is_power_of_two?(n)
  n > 0 && (n & (n - 1)) == 0
end

performance_optimized = [
  multiply_by_8(100),    # => 800
  divide_by_4(100),      # => 25
  is_power_of_two?(64)   # => true
]

Common Pitfalls

Integer division behavior surprises developers expecting floating-point results. Ruby performs integer division when both operands are integers, truncating fractional portions rather than rounding.

# Common division misconceptions
misleading_division = 10 / 3      # => 3, not 3.333...
expected_float = 10.0 / 3         # => 3.3333333333333335
alternative = 10.fdiv(3)          # => 3.3333333333333335

# Negative number division truncates toward negative infinity
negative_division = [
  -10 / 3,    # => -4 (not -3)
  -10 % 3,    # => 2  (not -1)
  10 / -3,    # => -4
  10 % -3     # => -2
]

Comparison operations with floating-point numbers can produce unexpected results due to precision limitations. Direct equality comparisons between integers and floats may fail when mathematical equality exists.

# Precision-related comparison issues
integer_value = 1
float_value = 0.9 + 0.1

direct_comparison = integer_value == float_value  # => false
precision_aware = (integer_value - float_value).abs < 0.001  # => true

# Large integer to float conversion loses precision
large_int = 9007199254740993
converted_float = large_int.to_f
back_to_int = converted_float.to_i
precision_lost = large_int == back_to_int  # => false

Bitwise operations on negative integers follow two's complement representation, producing results that may seem counterintuitive. The bitwise NOT operator creates large negative values due to sign extension.

# Bitwise operation surprises with negative numbers
positive_not = ~5        # => -6 (not 250 in 8-bit)
negative_shift = -8 >> 1 # => -4 (arithmetic shift, preserves sign)
unexpected_and = -1 & 0xFF  # => 255 (masks to positive)

# Two's complement behavior
def explain_twos_complement(n)
  {
    original: n,
    binary_representation: "%032b" % (n & 0xFFFFFFFF),
    bitwise_not: ~n,
    not_binary: "%032b" % (~n & 0xFFFFFFFF)
  }
end

complement_demo = explain_twos_complement(5)
# Shows how bitwise NOT produces -6 from 5

Range and iteration methods can create memory issues when used with large integer ranges. Creating arrays from large ranges consumes significant memory, while iterator methods provide memory-efficient alternatives.

# Memory-intensive range operations
# BAD: Creates large array in memory
# large_array = (1..1_000_000).to_a

# GOOD: Memory-efficient iteration
sum = 0
1.upto(1_000_000) { |n| sum += n }

# GOOD: Using Enumerator for lazy evaluation
large_range_enum = (1..Float::INFINITY).lazy
first_ten_squares = large_range_enum.map { |n| n ** 2 }.first(10)
# => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Reference

Core Arithmetic Methods

Method Parameters Returns Description
#+ other (Numeric) Integer/Float Addition with type coercion
#- other (Numeric) Integer/Float Subtraction with type coercion
#* other (Numeric) Integer/Float Multiplication with type coercion
#/ other (Numeric) Integer/Float Division (integer division for integers)
#% other (Numeric) Integer/Float Modulo operation
#** other (Numeric) Integer/Float Exponentiation
#divmod other (Numeric) Array[Integer, Integer] Returns quotient and remainder
#fdiv other (Numeric) Float Floating-point division
#abs None Integer Absolute value
#magnitude None Integer Alias for abs

Comparison Methods

Method Parameters Returns Description
#== other (Object) Boolean Equality comparison
#!= other (Object) Boolean Inequality comparison
#< other (Numeric) Boolean Less than comparison
#<= other (Numeric) Boolean Less than or equal comparison
#> other (Numeric) Boolean Greater than comparison
#>= other (Numeric) Boolean Greater than or equal comparison
#<=> other (Numeric) Integer Spaceship operator (-1, 0, 1)
#eql? other (Object) Boolean Type-strict equality

Bitwise Operations

Method Parameters Returns Description
#& other (Integer) Integer Bitwise AND
#| other (Integer) Integer Bitwise OR
#^ other (Integer) Integer Bitwise XOR
#~ None Integer Bitwise NOT
#<< positions (Integer) Integer Left bit shift
#>> positions (Integer) Integer Right bit shift

Type Conversion Methods

Method Parameters Returns Description
#to_i None Integer Returns self
#to_f None Float Convert to floating-point
#to_r None Rational Convert to rational number
#to_c None Complex Convert to complex number
#to_s base=10 (Integer) String String representation in given base
#inspect None String String representation for debugging

Mathematical Methods

Method Parameters Returns Description
#gcd other (Integer) Integer Greatest common divisor
#lcm other (Integer) Integer Least common multiple
#gcdlcm other (Integer) Array[Integer, Integer] Returns GCD and LCM
#next None Integer Next integer (self + 1)
#succ None Integer Alias for next
#pred None Integer Previous integer (self - 1)
#digits base=10 (Integer) Array[Integer] Array of digits in given base

Iteration Methods

Method Parameters Returns Description
#times Block Integer/Enumerator Execute block n times
#upto limit (Numeric), Block Integer/Enumerator Iterate from self to limit
#downto limit (Numeric), Block Integer/Enumerator Iterate from self down to limit
#step limit (Numeric), step=1, Block Integer/Enumerator Iterate with custom step size

Predicate Methods

Method Parameters Returns Description
#zero? None Boolean True if value equals zero
#nonzero? None Integer/nil Self if non-zero, nil if zero
#positive? None Boolean True if value is positive
#negative? None Boolean True if value is negative
#even? None Boolean True if value is even
#odd? None Boolean True if value is odd
#integer? None Boolean Always returns true

Constants

Constant Value Description
Integer::MAX Platform-dependent Maximum machine integer value
Integer::MIN Platform-dependent Minimum machine integer value