I'm working on a smart contract using the ink! framework for Polkadot, and I need to perform some trigonometric calculations, specifically using the sin() and cos() functions. Since ink! is based on Rust, I understand I can use Rust's standard math library, but I have some questions about the best way to do this.
pub fn calculate_distance(lat1: f64, lon1: f64, lat2: f64, lon2: f64) -> f64 {
let r = 6371000.0; // Radius of the Earth in meters
let d_lat = to_radian((lat2 - lat1) as f64);
let d_lon = to_radian((lon2 - lon1) as f64);
let a = (d_lat / 2.0).sin() * (d_lat / 2.0).sin()
+ to_radian(lat1 as f64).cos()
* to_radian(lat2 as f64).cos()
* (d_lon / 2.0).sin()
* (d_lon / 2.0).sin();
let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
r * c
}
i get the following error message while compiling the ink! contract
error[E0599]: no method named `cos` found for type `f64` in the current scope
--> /Users/dave/Work/match-contract-polkadot/lib.rs:50:38
|
50 | + to_radian(lat1 as f64).cos()
| ^^^ method not found in `f64`
error[E0599]: no method named `cos` found for type `f64` in the current scope
--> /Users/dave/Work/match-contract-polkadot/lib.rs:51:42
|
51 | * to_radian(lat2 as f64).cos()
| ^^^ method not found in `f64`
error[E0599]: no method named `sin` found for type `f64` in the current scope
--> /Users/dave/Work/match-contract-polkadot/lib.rs:52:33
|
52 | * (d_lon / 2.0).sin()
| ^^^
|
help: there is a method `min` with a similar name, but with different arguments
--> /Users/dave/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/num/f64.rs:963:5
|
963 | pub fn min(self, other: f64) -> f64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0599]: no method named `sin` found for type `f64` in the current scope
--> /Users/dave/Work/match-contract-polkadot/lib.rs:53:33
|
53 | * (d_lon / 2.0).sin();
| ^^^
|
help: there is a method `min` with a similar name, but with different arguments
--> /Users/dave/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/num/f64.rs:963:5
|
963 | pub fn min(self, other: f64) -> f64 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0599]: no method named `sqrt` found for type `{float}` in the current scope
--> /Users/dave/Work/match-contract-polkadot/lib.rs:55:48
|
55 | let c = 2.0 * a.sqrt().atan2((1.0 - a).sqrt());
Questions:
- Is there any concern with using floating-point numbers in ink! contracts, specifically for trigonometric functions like sin() and cos()?
- Would it be better to implement fixed-point math instead of using f64 for more precision and gas efficiency?
- Are there any best practices for handling math operations like these in smart contracts on Polkadot? Thanks for the help!