Skip to content

Instantly share code, notes, and snippets.

@preetpalS
Created May 23, 2016 00:10
Show Gist options
  • Save preetpalS/8f4705fc0ca80f902f3862befd9d7550 to your computer and use it in GitHub Desktop.
Save preetpalS/8f4705fc0ca80f902f3862befd9d7550 to your computer and use it in GitHub Desktop.
Calculations of how many primes can be encoded into a product for fixed-width integer types.
# Contains utilities for working with Prime numbers.
class Prime
class << self
def prime?(n)
return false if n < 2
return true if n < 4
return false if n.even?
(3..(Math.sqrt n).ceil).each do |i|
return false if n % i == 0
end
true
end
def primes
Enumerator.new do |yielder|
yielder.yield 2
to_test = 3
loop do
yielder.yield to_test if prime?(to_test)
to_test += 2
end
end
end
end
end
module NativeTypes
UNSIGNED_INT8 = { bytes: 1, name: 'uint8_t',
range: { min: 0,
max: 255 } }.freeze
INT8 = { bytes: 1, name: 'int8_t',
range: { min: -128,
max: 127 } }.freeze
UNSIGNED_INT16 = { bytes: 2, name: 'uint16_t',
range: { min: 0,
max: 65_535 } }.freeze
INT16 = { bytes: 2, name: 'int16_t',
range: { min: -32_768,
max: 32_767 } }.freeze
UNSIGNED_INT32 = { bytes: 4, name: 'uint32_t',
range: { min: 0,
max: 4_294_967_295 } }.freeze
INT32 = { bytes: 4, name: 'int32_t',
range: { min: -2_147_483_648,
max: 2_147_483_647 } }.freeze
UNSIGNED_INT64 = { bytes: 8, name: 'uint64_t',
range: { min: 0,
max: 18_446_744_073_709_551_615 } }.freeze
INT64 = { bytes: 8, name: 'int64_t',
range: { min: -9_223_372_036_854_775_808,
max: 9_223_372_036_854_775_807 } }.freeze
end
table = []
[NativeTypes::INT8,
NativeTypes::UNSIGNED_INT8,
NativeTypes::INT16,
NativeTypes::UNSIGNED_INT16,
NativeTypes::INT32,
NativeTypes::UNSIGNED_INT32,
NativeTypes::INT64,
NativeTypes::UNSIGNED_INT64].each do |native_integral_type|
=begin
puts <<INTRO
Type: #{native_integral_type[:name]}
Number of bytes: #{native_integral_type[:bytes]}
Range:
Min: #{native_integral_type[:range][:min]}
Max: #{native_integral_type[:range][:max]}
Calculations:
INTRO
=end
product = 1
primes = Prime.primes
current_prime_index = 0
current_prime = nil
largest_encodable_prime = nil
while product <= native_integral_type[:range][:max]
largest_encodable_prime = current_prime if current_prime_index > 0
current_prime = primes.next
current_prime_index += 1
product = current_prime * product
# puts " Current prime: #{current_prime}"
# puts " Product: #{product}"
end
table.push({
largest_encodable_prime: largest_encodable_prime,
number_of_encodable_primes: (current_prime_index - 1),
bits: (native_integral_type[:bytes] * 8)
}.merge(native_integral_type))
=begin
puts <<SUMMARY
#{native_integral_type[:name]} can encode #{current_prime_index - 1} primes.
The largest encodable prime is #{largest_encodable_prime}.
SUMMARY
=end
end
table_format = [
{ header: 'Name',
func: ->(row) { row[:name] } },
{ header: 'Min',
func: ->(row) { row[:range][:min] } },
{ header: 'Max',
func: ->(row) { row[:range][:max] } },
{ header: 'Bytes',
func: ->(row) { row[:bytes] } },
{ header: 'Bits',
func: ->(row) { row[:bits] } },
{ header: 'Number of Encodable Primes',
func: ->(row) { row[:number_of_encodable_primes] } },
{ header: 'Largest Encodable Prime',
func: ->(row) { row[:largest_encodable_prime] } }
]
table_format.each_with_index do |tf, index|
max_column_length = table.map(&tf[:func]).map(&:to_s).map(&:length).max
tf[:length] = [max_column_length, tf[:header].length].max
print ' | ' if index > 0
print tf[:header].ljust(tf[:length])
end
print "\n"
table_format.each_with_index do |tf, index|
print '-+-' if index > 0
print ''.ljust(tf[:length], '-')
end
table.each do |row|
print "\n"
table_format.each_with_index do |tf, index|
print ' | ' if index > 0
print tf[:func].call(row).to_s.ljust(tf[:length])
end
end
# Results of execution below (Ruby 2.3.0)
=begin
Name | Min | Max | Bytes | Bits | Number of Encodable Primes | Largest Encodable Prime
---------+----------------------+----------------------+-------+------+----------------------------+------------------------
int8_t | -128 | 127 | 1 | 8 | 3 | 5
uint8_t | 0 | 255 | 1 | 8 | 4 | 7
int16_t | -32768 | 32767 | 2 | 16 | 6 | 13
uint16_t | 0 | 65535 | 2 | 16 | 6 | 13
int32_t | -2147483648 | 2147483647 | 4 | 32 | 9 | 23
uint32_t | 0 | 4294967295 | 4 | 32 | 9 | 23
int64_t | -9223372036854775808 | 9223372036854775807 | 8 | 64 | 15 | 47
uint64_t | 0 | 18446744073709551615 | 8 | 64 | 15 | 47
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment