Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit df994bf

Browse files
authored
Fix float measurements (#1613)
* Fix float measurements * add u64 divide
1 parent 6fee08b commit df994bf

File tree

3 files changed

+87
-6
lines changed

3 files changed

+87
-6
lines changed

libraries/math/src/instruction.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,16 @@ pub enum MathInstruction {
4343
/// The multipier
4444
multiplier: u64,
4545
},
46-
/// Multiply two float valies
46+
/// Divide two u64 values
47+
///
48+
/// No accounts required for this instruction
49+
U64Divide {
50+
/// The dividend
51+
dividend: u64,
52+
/// The divisor
53+
divisor: u64,
54+
},
55+
/// Multiply two float values
4756
///
4857
/// No accounts required for this instruction
4958
F32Multiply {
@@ -52,7 +61,7 @@ pub enum MathInstruction {
5261
/// The multipier
5362
multiplier: f32,
5463
},
55-
/// Divide two float valies
64+
/// Divide two float values
5665
///
5766
/// No accounts required for this instruction
5867
F32Divide {
@@ -114,6 +123,17 @@ pub fn u64_multiply(multiplicand: u64, multiplier: u64) -> Instruction {
114123
}
115124
}
116125

126+
/// Create PreciseSquareRoot instruction
127+
pub fn u64_divide(dividend: u64, divisor: u64) -> Instruction {
128+
Instruction {
129+
program_id: id(),
130+
accounts: vec![],
131+
data: MathInstruction::U64Divide { dividend, divisor }
132+
.try_to_vec()
133+
.unwrap(),
134+
}
135+
}
136+
117137
/// Create PreciseSquareRoot instruction
118138
pub fn f32_multiply(multiplicand: f32, multiplier: f32) -> Instruction {
119139
Instruction {

libraries/math/src/processor.rs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,36 @@
33
use {
44
crate::{approximations::sqrt, instruction::MathInstruction, precise_number::PreciseNumber},
55
borsh::BorshDeserialize,
6-
solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, msg, pubkey::Pubkey},
6+
solana_program::{
7+
account_info::AccountInfo, entrypoint::ProgramResult, log::sol_log_compute_units, msg,
8+
pubkey::Pubkey,
9+
},
710
};
811

12+
/// u64_multiply
13+
#[inline(never)]
14+
fn u64_multiply(multiplicand: u64, multiplier: u64) -> u64 {
15+
multiplicand * multiplier
16+
}
17+
18+
/// u64_divide
19+
#[inline(never)]
20+
fn u64_divide(dividend: u64, divisor: u64) -> u64 {
21+
dividend / divisor
22+
}
23+
24+
/// f32_multiply
25+
#[inline(never)]
26+
fn f32_multiply(multiplicand: f32, multiplier: f32) -> f32 {
27+
multiplicand * multiplier
28+
}
29+
30+
/// f32_divide
31+
#[inline(never)]
32+
fn f32_divide(dividend: f32, divisor: f32) -> f32 {
33+
dividend / divisor
34+
}
35+
936
/// Instruction processor
1037
pub fn process_instruction(
1138
_program_id: &Pubkey,
@@ -17,19 +44,25 @@ pub fn process_instruction(
1744
MathInstruction::PreciseSquareRoot { radicand } => {
1845
msg!("Calculating square root using PreciseNumber");
1946
let radicand = PreciseNumber::new(radicand as u128).unwrap();
47+
sol_log_compute_units();
2048
let result = radicand.sqrt().unwrap().to_imprecise().unwrap() as u64;
49+
sol_log_compute_units();
2150
msg!("{}", result);
2251
Ok(())
2352
}
2453
MathInstruction::SquareRootU64 { radicand } => {
2554
msg!("Calculating u64 square root");
55+
sol_log_compute_units();
2656
let result = sqrt(radicand).unwrap();
57+
sol_log_compute_units();
2758
msg!("{}", result);
2859
Ok(())
2960
}
3061
MathInstruction::SquareRootU128 { radicand } => {
3162
msg!("Calculating u128 square root");
63+
sol_log_compute_units();
3264
let result = sqrt(radicand).unwrap();
65+
sol_log_compute_units();
3366
msg!("{}", result);
3467
Ok(())
3568
}
@@ -38,7 +71,17 @@ pub fn process_instruction(
3871
multiplier,
3972
} => {
4073
msg!("Calculating U64 Multiply");
41-
let result = multiplicand * multiplier;
74+
sol_log_compute_units();
75+
let result = u64_multiply(multiplicand, multiplier);
76+
sol_log_compute_units();
77+
msg!("{}", result);
78+
Ok(())
79+
}
80+
MathInstruction::U64Divide { dividend, divisor } => {
81+
msg!("Calculating U64 Divide");
82+
sol_log_compute_units();
83+
let result = u64_divide(dividend, divisor);
84+
sol_log_compute_units();
4285
msg!("{}", result);
4386
Ok(())
4487
}
@@ -47,13 +90,17 @@ pub fn process_instruction(
4790
multiplier,
4891
} => {
4992
msg!("Calculating f32 Multiply");
50-
let result = multiplicand * multiplier;
93+
sol_log_compute_units();
94+
let result = f32_multiply(multiplicand, multiplier);
95+
sol_log_compute_units();
5196
msg!("{}", result as u64);
5297
Ok(())
5398
}
5499
MathInstruction::F32Divide { dividend, divisor } => {
55100
msg!("Calculating f32 Divide");
56-
let result = dividend / divisor;
101+
sol_log_compute_units();
102+
let result = f32_divide(dividend, divisor);
103+
sol_log_compute_units();
57104
msg!("{}", result as u64);
58105
Ok(())
59106
}

libraries/math/tests/instruction_count.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,20 @@ async fn test_u64_multiply() {
102102
banks_client.process_transaction(transaction).await.unwrap();
103103
}
104104

105+
#[tokio::test]
106+
async fn test_u64_divide() {
107+
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));
108+
109+
pc.set_bpf_compute_max_units(1650);
110+
111+
let (mut banks_client, payer, recent_blockhash) = pc.start().await;
112+
113+
let mut transaction =
114+
Transaction::new_with_payer(&[instruction::u64_divide(3, 1)], Some(&payer.pubkey()));
115+
transaction.sign(&[&payer], recent_blockhash);
116+
banks_client.process_transaction(transaction).await.unwrap();
117+
}
118+
105119
#[tokio::test]
106120
async fn test_f32_multiply() {
107121
let mut pc = ProgramTest::new("spl_math", id(), processor!(process_instruction));

0 commit comments

Comments
 (0)