Skip to content

Instantly share code, notes, and snippets.

@sgeos
Last active August 11, 2023 12:32
Show Gist options
  • Save sgeos/c3a27aaf1988dc1799da1a614233a3e4 to your computer and use it in GitHub Desktop.
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.
// 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