CrackedRuby logo

CrackedRuby

Numeric Literals (Integer, Float, Binary, Octal, Hex)

Overview

Ruby provides extensive support for numeric literals in multiple formats and bases. The language handles two primary numeric types through dedicated classes: Integer for whole numbers and Float for decimal numbers. Ruby's numeric system supports literals in decimal (base 10), binary (base 2), octal (base 8), and hexadecimal (base 16) formats.

Integer literals can be written as simple digits, with underscores for readability, or with prefixes to indicate different number bases. Float literals use decimal point notation and can include scientific notation for very large or small numbers.

# Basic integer and float literals
integer = 42
float = 3.14
large_number = 1_000_000
scientific = 1.5e10

# Different number bases
binary = 0b1010        # Binary: 10 in decimal
octal = 0o755          # Octal: 493 in decimal
hex = 0xFF             # Hexadecimal: 255 in decimal

Ruby automatically chooses the appropriate internal representation and provides methods for converting between different bases and formats. The language handles arbitrarily large integers without overflow, automatically promoting to Bignum when needed.

Basic Usage

Integer Literals

Integer literals in Ruby can be written in several ways. The most common form uses standard decimal notation:

positive = 123
negative = -456
zero = 0

# Underscores improve readability for large numbers
million = 1_000_000
billion = 1_000_000_000

Float Literals

Floating-point literals require a decimal point or scientific notation:

simple_float = 3.14
small_decimal = 0.001
large_float = 123.456

# Scientific notation
speed_of_light = 2.998e8    # 299,800,000
planck_constant = 6.626e-34 # 0.0000000000000000000000000000000006626

Binary Literals (Base 2)

Binary literals use the 0b prefix followed by digits 0 and 1:

binary_eight = 0b1000      # 8 in decimal
binary_flags = 0b11110000  # 240 in decimal
binary_mask = 0b1111       # 15 in decimal

# Binary representation of file permissions
read_write = 0b110         # 6 in decimal (rw-)
executable = 0b001         # 1 in decimal (--x)
full_permissions = 0b111   # 7 in decimal (rwx)

Octal Literals (Base 8)

Octal literals use the 0o prefix (or just 0 in older Ruby versions):

octal_permission = 0o755   # 493 in decimal (rwxr-xr-x)
octal_value = 0o123        # 83 in decimal
octal_zero = 0o0           # 0 in decimal

# Traditional Unix file permissions
owner_rw = 0o600          # 384 in decimal
world_readable = 0o644    # 420 in decimal
executable_script = 0o755 # 493 in decimal

Hexadecimal Literals (Base 16)

Hexadecimal literals use the 0x prefix with digits 0-9 and letters A-F:

hex_color = 0xFF0000      # Red: 16711680 in decimal
hex_byte = 0xFF           # 255 in decimal
hex_memory = 0x1000       # 4096 in decimal

# Common hexadecimal values
max_byte = 0xFF           # 255
hex_kilobyte = 0x400      # 1024
hex_address = 0xDEADBEEF  # 3735928559

Advanced Usage

Numeric Conversion Methods

Ruby provides methods to convert numbers between different representations:

number = 42

# Convert to different base strings
binary_string = number.to_s(2)      # "101010"
octal_string = number.to_s(8)       # "52"
hex_string = number.to_s(16)        # "2a"
hex_upper = number.to_s(16).upcase  # "2A"

# Parse strings in different bases
parsed_binary = "101010".to_i(2)    # 42
parsed_octal = "52".to_i(8)         # 42
parsed_hex = "2a".to_i(16)          # 42

Working with Bit Operations

Numeric literals work naturally with bitwise operations:

# Bitwise operations with different literal formats
flags = 0b11110000
mask = 0x0F

result = flags & mask              # Bitwise AND
combined = 0b1010 | 0b0101        # Bitwise OR: 15
flipped = ~0b1010                 # Bitwise NOT
shifted = 0b1010 << 2             # Left shift: 40 (0b101000)

Range Operations with Numeric Literals

Ruby ranges work seamlessly with numeric literals in different bases:

# Ranges using different literal formats
binary_range = (0b1000..0b1111)           # 8 to 15
hex_range = (0x10..0x1F)                  # 16 to 31
octal_range = (0o10..0o17)                # 8 to 15

# Iterating over ranges
hex_range.each { |n| puts "0x#{n.to_s(16).upcase}" }
# Output: 0x10, 0x11, 0x12, ... 0x1F

Complex Numeric Expressions

Combining different literal formats in mathematical operations:

# Mixed base arithmetic
result = 0xFF + 0b11111111 + 0o377        # All equal 255, sum is 765
percentage = 0x64                          # 100 in hex
fraction = percentage / 100.0              # Convert to float for division

# File permission calculations
owner_perms = 0o700     # rwx------
group_perms = 0o050     # ---r-x---
other_perms = 0o005     # -----r-x
combined_perms = owner_perms | group_perms | other_perms  # 0o755

Common Pitfalls

Leading Zero Confusion

One of the most common mistakes involves leading zeros in numeric literals:

# DANGER: Leading zeros create octal numbers in older Ruby
wrong_month = 08        # SyntaxError: Invalid octal digit
wrong_day = 09          # SyntaxError: Invalid octal digit

# Correct approaches
correct_month = 8       # Decimal 8
explicit_octal = 0o10   # Octal 10 (decimal 8)
string_month = "08"     # Keep as string if zero-padding needed

Float Precision Issues

Floating-point representation can lead to unexpected results:

# Precision problems with float literals
sum = 0.1 + 0.2                    # 0.30000000000000004, not 0.3
comparison = (0.1 + 0.2) == 0.3    # false

# Solutions for precision-critical calculations
require 'bigdecimal'
precise_sum = BigDecimal('0.1') + BigDecimal('0.2')  # Exact decimal
tolerance = (0.1 + 0.2 - 0.3).abs < 1e-10          # true

Base Conversion Edge Cases

Converting between bases can produce unexpected results:

# Large numbers and string conversion
large_hex = 0xFFFFFFFFFFFFFFFF
hex_string = large_hex.to_s(16)    # "ffffffffffffffff"

# Negative numbers in different bases
negative = -10
binary_negative = negative.to_s(2)  # "-1010", not two's complement
hex_negative = negative.to_s(16)    # "-a"

# Handling invalid characters in parsing
begin
  invalid = "1G".to_i(16)          # 1, stops at invalid character
  strict_parse = Integer("1G", 16)  # ArgumentError
rescue ArgumentError => e
  puts "Invalid hexadecimal format"
end

Type Coercion Gotchas

Mixed operations between integers and floats:

# Integer division vs float division
int_division = 5 / 2               # 2 (integer result)
float_division = 5 / 2.0           # 2.5 (float result)
mixed_division = 5.0 / 2           # 2.5 (float result)

# Unexpected type promotion
hex_int = 0xFF                     # Integer
result = hex_int + 0.1             # Float (255.1)
back_to_int = result.to_i          # 255, loses decimal portion

Memory and Performance Considerations

Very large numeric literals can impact memory usage:

# Ruby automatically handles big integers
huge_number = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
puts huge_number.class             # Integer (automatically uses Bignum)

# Binary string representations for large numbers
binary_rep = huge_number.to_s(2)   # Very long string
memory_usage = binary_rep.bytesize # Significant memory usage

Reference

Integer Literal Formats

Format Prefix Valid Digits Example Decimal Value
Decimal None 0-9 123 123
Binary 0b 0-1 0b1111 15
Octal 0o 0-7 0o755 493
Hexadecimal 0x 0-9, A-F 0xFF 255

Float Literal Formats

Format Example Description
Decimal 3.14 Standard decimal notation
Scientific 1.5e10 Exponential notation
Negative Exponent 6.626e-34 Small number notation

Conversion Methods

Method Parameters Returns Description
#to_s(base) base (2-36) String Convert number to string in specified base
String#to_i(base) base (2-36) Integer Parse string as integer in specified base
Integer(string, base) string, base Integer Strict parsing with error checking
#to_f None Float Convert to floating-point

Common Constants

Constant Value Description
Float::INFINITY Infinity Positive infinity
Float::NAN NaN Not a number
Float::EPSILON 2.220446049250313e-16 Smallest representable difference

Bitwise Operators

Operator Name Example Result
& AND 0b1100 & 0b1010 0b1000 (8)
| OR 0b1100 | 0b1010 0b1110 (14)
^ XOR 0b1100 ^ 0b1010 0b0110 (6)
~ NOT ~0b1010 -11 (two's complement)
<< Left shift 0b1010 << 2 0b101000 (40)
>> Right shift 0b1010 >> 1 0b101 (5)

Error Types

Error When Raised Example
SyntaxError Invalid literal format 08, 0b2, 0xG
ArgumentError Invalid base in conversion Integer("FF", 8)
FloatDomainError Invalid float operation Math.sqrt(-1)