Last active
August 11, 2023 12:32
-
-
Save sgeos/c3a27aaf1988dc1799da1a614233a3e4 to your computer and use it in GitHub Desktop.
Gold atom and price calculations in Rust. Fact checking, prompts, combining code, and refactoring done by a human engineer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// u128 seem like the right type for debiting and crediting atoms of gold | |
// u256 should be enough account for all the gold atoms in the universe | |
// micrograms of gold seem like a good unit for small transactions | |
fn gold_atoms_in_microgram(quantity: f64) -> u128 { | |
const AVOGADROS_NUMBER: f64 = 6.02214076e23; // atoms | |
const ATOMIC_WEIGHT_OF_GOLD: u128 = 196_966_570; // microgram/mol | |
(quantity * AVOGADROS_NUMBER) as u128 / ATOMIC_WEIGHT_OF_GOLD | |
} | |
fn gold_atoms_in_troy_ounce(quantity: f64) -> u128 { | |
const TROY_OUNCE_IN_MICROGRAMS: f64 = 31_103_476.8; // microgram | |
gold_atoms_in_microgram(quantity * TROY_OUNCE_IN_MICROGRAMS) | |
} | |
fn gold_atoms_in_kilogram(quantity: f64) -> u128 { | |
const KILOGRAM_IN_MICROGRAMS: f64 = 1_000_000_000.0; // microgram | |
gold_atoms_in_microgram(quantity * KILOGRAM_IN_MICROGRAMS) | |
} | |
fn format_hex_with_separator(num: u128) -> String { | |
let hex_str = format!("{:032X}", num); | |
let mut result = String::new(); | |
for (idx, ch) in hex_str.chars().rev().enumerate() { | |
if idx != 0 && idx % 4 == 0 { | |
result.push('_'); | |
} | |
result.push(ch); | |
} | |
result.push('x'); | |
result.push('0'); | |
result.chars().rev().collect() | |
} | |
fn print_atoms_in_microgram_of_gold(quantity: f64) { | |
let atoms = gold_atoms_in_microgram(quantity); | |
let formatted_atoms = format_hex_with_separator(atoms); | |
println!( | |
"Number of gold atoms in {quantity} micrograms: {formatted_atoms} == {atoms:.3e}", | |
); | |
price(atoms); | |
} | |
fn print_atoms_in_troy_ounce_of_gold(quantity: f64) { | |
let atoms = gold_atoms_in_troy_ounce(quantity); | |
let formatted_atoms = format_hex_with_separator(atoms); | |
println!( | |
"Number of gold atoms in {quantity} troy ounces: {formatted_atoms} == {atoms:.3e}", | |
); | |
price(atoms); | |
} | |
fn print_atoms_in_kilogram_of_gold(quantity: f64) { | |
let atoms = gold_atoms_in_kilogram(quantity); | |
let formatted_atoms = format_hex_with_separator(atoms); | |
println!( | |
"Number of gold atoms in {quantity} kilograms: {formatted_atoms} == {atoms:.3e}", | |
); | |
price(atoms); | |
} | |
fn price(atoms: u128) { | |
const PRICE_PER_TROY_OUNCE: f64 = 1911.80; // in USD | |
const TROY_OUNCE_IN_MICROGRAMS: f64 = 31_103_476.8; // microgram | |
let price_per_microgram = PRICE_PER_TROY_OUNCE / TROY_OUNCE_IN_MICROGRAMS; | |
let atoms_in_microgram = gold_atoms_in_microgram(1.0); | |
let micrograms = atoms as f64 / atoms_in_microgram as f64; | |
let price = price_per_microgram * micrograms; | |
if 0.01 < price { | |
println!("Price of {micrograms:.2} micrograms of gold: ${price:.2} USD"); | |
} else { | |
let fraction = (0.01 / price) as u32; | |
println!("Price of {micrograms:.2} micrograms of gold: ${price:.6} USD (about 1/{fraction} cents)"); | |
} | |
} | |
fn price_to_micrograms(target_price: f64) { | |
const PRICE_PER_TROY_OUNCE: f64 = 1911.80; // in USD | |
const TROY_OUNCE_IN_MICROGRAMS: f64 = 31_103_476.8; // microgram | |
let price_per_microgram = PRICE_PER_TROY_OUNCE / TROY_OUNCE_IN_MICROGRAMS; | |
let micrograms = target_price / price_per_microgram; | |
let atoms = gold_atoms_in_microgram(micrograms); | |
price(atoms); | |
} | |
fn section_break(message: String) { | |
println!(""); | |
if message.len() < 1 { | |
println!("---"); | |
} else { | |
println!("--- {message} ---"); | |
} | |
} | |
#[no_mangle] | |
pub extern "C" fn run() { | |
let iteration_max = 6; | |
section_break(format!("Atoms (Micrograms)")); | |
for i in 0..=iteration_max { | |
print_atoms_in_microgram_of_gold(10_u32.pow(i) as f64); | |
} | |
section_break(format!("Atoms (Troy Ounce)")); | |
for i in 0..=iteration_max { | |
print_atoms_in_troy_ounce_of_gold(2_u32.pow(i) as f64 / 2.0); | |
} | |
section_break(format!("Atoms (Kilograms)")); | |
for i in 0..=iteration_max { | |
print_atoms_in_kilogram_of_gold(2_u32.pow(i) as f64 / 2.0); | |
} | |
section_break(format!("Target Price")); | |
for i in 0..=iteration_max { | |
price_to_micrograms(10_u32.pow(i) as f64 / 100.0); | |
} | |
} | |
fn main() { | |
run(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment