diff --git a/libraries/math/src/instruction.rs b/libraries/math/src/instruction.rs index adb768a4498..dd45073cb99 100644 --- a/libraries/math/src/instruction.rs +++ b/libraries/math/src/instruction.rs @@ -97,6 +97,16 @@ pub enum MathInstruction { argument: f32, }, + /// Pow two float values + /// + /// No accounts required for this instruction + F64Pow { + /// The base + base: f64, + /// The exponent + exponent: f64, + }, + /// Don't do anything for comparison /// /// No accounts required for this instruction @@ -219,6 +229,17 @@ pub fn f32_normal_cdf(argument: f32) -> Instruction { } } +/// Create F64Pow instruction +pub fn f64_pow(base: f64, exponent: f64) -> Instruction { + Instruction { + program_id: id(), + accounts: vec![], + data: MathInstruction::F64Pow { base, exponent } + .try_to_vec() + .unwrap(), + } +} + /// Create Noop instruction pub fn noop() -> Instruction { Instruction { diff --git a/libraries/math/src/processor.rs b/libraries/math/src/processor.rs index 3b307889be8..db23f44b92e 100644 --- a/libraries/math/src/processor.rs +++ b/libraries/math/src/processor.rs @@ -145,6 +145,18 @@ pub fn process_instruction( msg!("{}", result as u64); Ok(()) } + MathInstruction::F64Pow { base, exponent } => { + msg!("Calculating f64 Pow"); + sol_log_compute_units(); + let result = base.powi(exponent as i32); + sol_log_compute_units(); + msg!("{}", result as u64); + sol_log_compute_units(); + let result = base.powf(exponent); + sol_log_compute_units(); + msg!("{}", result as u64); + Ok(()) + } MathInstruction::Noop => { msg!("Do nothing"); msg!("{}", 0_u64); diff --git a/libraries/math/tests/instruction_count.rs b/libraries/math/tests/instruction_count.rs index e2353e6da3b..bf97d1e806f 100644 --- a/libraries/math/tests/instruction_count.rs +++ b/libraries/math/tests/instruction_count.rs @@ -194,6 +194,22 @@ async fn test_f32_normal_cdf() { banks_client.process_transaction(transaction).await.unwrap(); } +#[tokio::test] +async fn test_f64_pow() { + let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction)); + + pc.set_compute_max_units(30_000); + + let (mut banks_client, payer, recent_blockhash) = pc.start().await; + + let mut transaction = Transaction::new_with_payer( + &[instruction::f64_pow(50_f64, 10.5_f64)], + Some(&payer.pubkey()), + ); + transaction.sign(&[&payer], recent_blockhash); + banks_client.process_transaction(transaction).await.unwrap(); +} + #[tokio::test] async fn test_noop() { let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));