Fix float measurements (#1613)

* Fix float measurements

* add u64 divide
This commit is contained in:
Jack May 2021-04-20 17:33:49 -07:00 committed by GitHub
parent 6fee08be2f
commit df994bf426
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 6 deletions

View File

@ -43,7 +43,16 @@ pub enum MathInstruction {
/// The multipier /// The multipier
multiplier: u64, multiplier: u64,
}, },
/// Multiply two float valies /// Divide two u64 values
///
/// No accounts required for this instruction
U64Divide {
/// The dividend
dividend: u64,
/// The divisor
divisor: u64,
},
/// Multiply two float values
/// ///
/// No accounts required for this instruction /// No accounts required for this instruction
F32Multiply { F32Multiply {
@ -52,7 +61,7 @@ pub enum MathInstruction {
/// The multipier /// The multipier
multiplier: f32, multiplier: f32,
}, },
/// Divide two float valies /// Divide two float values
/// ///
/// No accounts required for this instruction /// No accounts required for this instruction
F32Divide { F32Divide {
@ -114,6 +123,17 @@ pub fn u64_multiply(multiplicand: u64, multiplier: u64) -> Instruction {
} }
} }
/// Create PreciseSquareRoot instruction
pub fn u64_divide(dividend: u64, divisor: u64) -> Instruction {
Instruction {
program_id: id(),
accounts: vec![],
data: MathInstruction::U64Divide { dividend, divisor }
.try_to_vec()
.unwrap(),
}
}
/// Create PreciseSquareRoot instruction /// Create PreciseSquareRoot instruction
pub fn f32_multiply(multiplicand: f32, multiplier: f32) -> Instruction { pub fn f32_multiply(multiplicand: f32, multiplier: f32) -> Instruction {
Instruction { Instruction {

View File

@ -3,9 +3,36 @@
use { use {
crate::{approximations::sqrt, instruction::MathInstruction, precise_number::PreciseNumber}, crate::{approximations::sqrt, instruction::MathInstruction, precise_number::PreciseNumber},
borsh::BorshDeserialize, borsh::BorshDeserialize,
solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg, pubkey::Pubkey}, solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, log::sol_log_compute_units, msg,
pubkey::Pubkey,
},
}; };
/// u64_multiply
#[inline(never)]
fn u64_multiply(multiplicand: u64, multiplier: u64) -> u64 {
multiplicand * multiplier
}
/// u64_divide
#[inline(never)]
fn u64_divide(dividend: u64, divisor: u64) -> u64 {
dividend / divisor
}
/// f32_multiply
#[inline(never)]
fn f32_multiply(multiplicand: f32, multiplier: f32) -> f32 {
multiplicand * multiplier
}
/// f32_divide
#[inline(never)]
fn f32_divide(dividend: f32, divisor: f32) -> f32 {
dividend / divisor
}
/// Instruction processor /// Instruction processor
pub fn process_instruction( pub fn process_instruction(
_program_id: &Pubkey, _program_id: &Pubkey,
@ -17,19 +44,25 @@ pub fn process_instruction(
MathInstruction::PreciseSquareRoot { radicand } => { MathInstruction::PreciseSquareRoot { radicand } => {
msg!("Calculating square root using PreciseNumber"); msg!("Calculating square root using PreciseNumber");
let radicand = PreciseNumber::new(radicand as u128).unwrap(); let radicand = PreciseNumber::new(radicand as u128).unwrap();
sol_log_compute_units();
let result = radicand.sqrt().unwrap().to_imprecise().unwrap() as u64; let result = radicand.sqrt().unwrap().to_imprecise().unwrap() as u64;
sol_log_compute_units();
msg!("{}", result); msg!("{}", result);
Ok(()) Ok(())
} }
MathInstruction::SquareRootU64 { radicand } => { MathInstruction::SquareRootU64 { radicand } => {
msg!("Calculating u64 square root"); msg!("Calculating u64 square root");
sol_log_compute_units();
let result = sqrt(radicand).unwrap(); let result = sqrt(radicand).unwrap();
sol_log_compute_units();
msg!("{}", result); msg!("{}", result);
Ok(()) Ok(())
} }
MathInstruction::SquareRootU128 { radicand } => { MathInstruction::SquareRootU128 { radicand } => {
msg!("Calculating u128 square root"); msg!("Calculating u128 square root");
sol_log_compute_units();
let result = sqrt(radicand).unwrap(); let result = sqrt(radicand).unwrap();
sol_log_compute_units();
msg!("{}", result); msg!("{}", result);
Ok(()) Ok(())
} }
@ -38,7 +71,17 @@ pub fn process_instruction(
multiplier, multiplier,
} => { } => {
msg!("Calculating U64 Multiply"); msg!("Calculating U64 Multiply");
let result = multiplicand * multiplier; sol_log_compute_units();
let result = u64_multiply(multiplicand, multiplier);
sol_log_compute_units();
msg!("{}", result);
Ok(())
}
MathInstruction::U64Divide { dividend, divisor } => {
msg!("Calculating U64 Divide");
sol_log_compute_units();
let result = u64_divide(dividend, divisor);
sol_log_compute_units();
msg!("{}", result); msg!("{}", result);
Ok(()) Ok(())
} }
@ -47,13 +90,17 @@ pub fn process_instruction(
multiplier, multiplier,
} => { } => {
msg!("Calculating f32 Multiply"); msg!("Calculating f32 Multiply");
let result = multiplicand * multiplier; sol_log_compute_units();
let result = f32_multiply(multiplicand, multiplier);
sol_log_compute_units();
msg!("{}", result as u64); msg!("{}", result as u64);
Ok(()) Ok(())
} }
MathInstruction::F32Divide { dividend, divisor } => { MathInstruction::F32Divide { dividend, divisor } => {
msg!("Calculating f32 Divide"); msg!("Calculating f32 Divide");
let result = dividend / divisor; sol_log_compute_units();
let result = f32_divide(dividend, divisor);
sol_log_compute_units();
msg!("{}", result as u64); msg!("{}", result as u64);
Ok(()) Ok(())
} }

View File

@ -102,6 +102,20 @@ async fn test_u64_multiply() {
banks_client.process_transaction(transaction).await.unwrap(); banks_client.process_transaction(transaction).await.unwrap();
} }
#[tokio::test]
async fn test_u64_divide() {
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));
pc.set_bpf_compute_max_units(1650);
let (mut banks_client, payer, recent_blockhash) = pc.start().await;
let mut transaction =
Transaction::new_with_payer(&[instruction::u64_divide(3, 1)], Some(&payer.pubkey()));
transaction.sign(&[&payer], recent_blockhash);
banks_client.process_transaction(transaction).await.unwrap();
}
#[tokio::test] #[tokio::test]
async fn test_f32_multiply() { async fn test_f32_multiply() {
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction)); let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));