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
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
F32Multiply {
@ -52,7 +61,7 @@ pub enum MathInstruction {
/// The multipier
multiplier: f32,
},
/// Divide two float valies
/// Divide two float values
///
/// No accounts required for this instruction
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
pub fn f32_multiply(multiplicand: f32, multiplier: f32) -> Instruction {
Instruction {

View File

@ -3,9 +3,36 @@
use {
crate::{approximations::sqrt, instruction::MathInstruction, precise_number::PreciseNumber},
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
pub fn process_instruction(
_program_id: &Pubkey,
@ -17,19 +44,25 @@ pub fn process_instruction(
MathInstruction::PreciseSquareRoot { radicand } => {
msg!("Calculating square root using PreciseNumber");
let radicand = PreciseNumber::new(radicand as u128).unwrap();
sol_log_compute_units();
let result = radicand.sqrt().unwrap().to_imprecise().unwrap() as u64;
sol_log_compute_units();
msg!("{}", result);
Ok(())
}
MathInstruction::SquareRootU64 { radicand } => {
msg!("Calculating u64 square root");
sol_log_compute_units();
let result = sqrt(radicand).unwrap();
sol_log_compute_units();
msg!("{}", result);
Ok(())
}
MathInstruction::SquareRootU128 { radicand } => {
msg!("Calculating u128 square root");
sol_log_compute_units();
let result = sqrt(radicand).unwrap();
sol_log_compute_units();
msg!("{}", result);
Ok(())
}
@ -38,7 +71,17 @@ pub fn process_instruction(
multiplier,
} => {
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);
Ok(())
}
@ -47,13 +90,17 @@ pub fn process_instruction(
multiplier,
} => {
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);
Ok(())
}
MathInstruction::F32Divide { dividend, divisor } => {
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);
Ok(())
}

View File

@ -102,6 +102,20 @@ async fn test_u64_multiply() {
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]
async fn test_f32_multiply() {
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));