-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Add lint to improve floating-point expressions #4897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
bors
merged 14 commits into
rust-lang:master
from
krishna-veerareddy:issue-2040-accurate-float-functions
Feb 24, 2020
+1,092
−263
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
c636c6a
Add lints to detect inaccurate and inefficient FP operations
krishna-veerareddy 1f4f357
Consolidate the accuracy and efficiency lints
krishna-veerareddy 9520d3d
Suggest usage of `powi` method when applicable
krishna-veerareddy de79733
Lint expressions of the form `x.log(b) / y.log(b)`
krishna-veerareddy a60ae5d
Split test cases into separate files
krishna-veerareddy de07c84
Detect usage of `(x + 1).ln()` and suggest `x.ln_1p()` instead
krishna-veerareddy fd2506b
Add type suffixes to unsuffixed method receiver suggestions
krishna-veerareddy bc03f46
Remove lint for logarithm division identity
krishna-veerareddy 6dacb1a
Change lint name to `suboptimal_flops`
krishna-veerareddy bc706e3
Fix `powi` suggestion and add general improvements
krishna-veerareddy 454e505
Run rust-fix on tests
krishna-veerareddy 4065ca9
Move `manual_mul_add` into `suboptimal_flops` lint
krishna-veerareddy e94a167
Rename `mul_add` test file and add general improvements
krishna-veerareddy ff0d44e
Add `imprecise_flops` lint
krishna-veerareddy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,380 @@ | ||
use crate::consts::{ | ||
constant, Constant, | ||
Constant::{F32, F64}, | ||
}; | ||
use crate::utils::{span_lint_and_sugg, sugg}; | ||
use if_chain::if_chain; | ||
use rustc::ty; | ||
use rustc_errors::Applicability; | ||
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp}; | ||
use rustc_lint::{LateContext, LateLintPass}; | ||
use rustc_session::{declare_lint_pass, declare_tool_lint}; | ||
use rustc_span::source_map::Spanned; | ||
|
||
use std::f32::consts as f32_consts; | ||
use std::f64::consts as f64_consts; | ||
use sugg::{format_numeric_literal, Sugg}; | ||
use syntax::ast; | ||
|
||
declare_clippy_lint! { | ||
/// **What it does:** Looks for floating-point expressions that | ||
/// can be expressed using built-in methods to improve accuracy | ||
/// at the cost of performance. | ||
/// | ||
/// **Why is this bad?** Negatively impacts accuracy. | ||
/// | ||
/// **Known problems:** None | ||
/// | ||
/// **Example:** | ||
/// | ||
/// ```rust | ||
/// | ||
/// let a = 3f32; | ||
/// let _ = a.powf(1.0 / 3.0); | ||
/// let _ = (1.0 + a).ln(); | ||
/// let _ = a.exp() - 1.0; | ||
/// ``` | ||
/// | ||
/// is better expressed as | ||
/// | ||
/// ```rust | ||
/// | ||
/// let a = 3f32; | ||
/// let _ = a.cbrt(); | ||
/// let _ = a.ln_1p(); | ||
/// let _ = a.exp_m1(); | ||
/// ``` | ||
pub IMPRECISE_FLOPS, | ||
nursery, | ||
"usage of imprecise floating point operations" | ||
} | ||
|
||
declare_clippy_lint! { | ||
/// **What it does:** Looks for floating-point expressions that | ||
/// can be expressed using built-in methods to improve both | ||
/// accuracy and performance. | ||
/// | ||
/// **Why is this bad?** Negatively impacts accuracy and performance. | ||
/// | ||
/// **Known problems:** None | ||
/// | ||
/// **Example:** | ||
/// | ||
/// ```rust | ||
/// use std::f32::consts::E; | ||
/// | ||
/// let a = 3f32; | ||
/// let _ = (2f32).powf(a); | ||
/// let _ = E.powf(a); | ||
/// let _ = a.powf(1.0 / 2.0); | ||
/// let _ = a.log(2.0); | ||
/// let _ = a.log(10.0); | ||
/// let _ = a.log(E); | ||
/// let _ = a.powf(2.0); | ||
/// let _ = a * 2.0 + 4.0; | ||
/// ``` | ||
/// | ||
/// is better expressed as | ||
/// | ||
/// ```rust | ||
/// use std::f32::consts::E; | ||
/// | ||
/// let a = 3f32; | ||
/// let _ = a.exp2(); | ||
/// let _ = a.exp(); | ||
/// let _ = a.sqrt(); | ||
/// let _ = a.log2(); | ||
/// let _ = a.log10(); | ||
/// let _ = a.ln(); | ||
/// let _ = a.powi(2); | ||
/// let _ = a.mul_add(2.0, 4.0); | ||
/// ``` | ||
pub SUBOPTIMAL_FLOPS, | ||
nursery, | ||
"usage of sub-optimal floating point operations" | ||
} | ||
|
||
declare_lint_pass!(FloatingPointArithmetic => [ | ||
IMPRECISE_FLOPS, | ||
SUBOPTIMAL_FLOPS | ||
]); | ||
|
||
// Returns the specialized log method for a given base if base is constant | ||
// and is one of 2, 10 and e | ||
fn get_specialized_log_method(cx: &LateContext<'_, '_>, base: &Expr<'_>) -> Option<&'static str> { | ||
if let Some((value, _)) = constant(cx, cx.tables, base) { | ||
if F32(2.0) == value || F64(2.0) == value { | ||
return Some("log2"); | ||
} else if F32(10.0) == value || F64(10.0) == value { | ||
return Some("log10"); | ||
} else if F32(f32_consts::E) == value || F64(f64_consts::E) == value { | ||
return Some("ln"); | ||
} | ||
} | ||
|
||
None | ||
} | ||
|
||
// Adds type suffixes and parenthesis to method receivers if necessary | ||
fn prepare_receiver_sugg<'a>(cx: &LateContext<'_, '_>, mut expr: &'a Expr<'a>) -> Sugg<'a> { | ||
let mut suggestion = Sugg::hir(cx, expr, ".."); | ||
|
||
if let ExprKind::Unary(UnOp::UnNeg, inner_expr) = &expr.kind { | ||
expr = &inner_expr; | ||
} | ||
|
||
if_chain! { | ||
// if the expression is a float literal and it is unsuffixed then | ||
// add a suffix so the suggestion is valid and unambiguous | ||
if let ty::Float(float_ty) = cx.tables.expr_ty(expr).kind; | ||
if let ExprKind::Lit(lit) = &expr.kind; | ||
if let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node; | ||
then { | ||
let op = format!( | ||
"{}{}{}", | ||
suggestion, | ||
// Check for float literals without numbers following the decimal | ||
// separator such as `2.` and adds a trailing zero | ||
if sym.as_str().ends_with('.') { | ||
"0" | ||
} else { | ||
"" | ||
}, | ||
float_ty.name_str() | ||
).into(); | ||
|
||
suggestion = match suggestion { | ||
Sugg::MaybeParen(_) => Sugg::MaybeParen(op), | ||
_ => Sugg::NonParen(op) | ||
}; | ||
} | ||
} | ||
|
||
suggestion.maybe_par() | ||
} | ||
|
||
fn check_log_base(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { | ||
if let Some(method) = get_specialized_log_method(cx, &args[1]) { | ||
span_lint_and_sugg( | ||
cx, | ||
SUBOPTIMAL_FLOPS, | ||
expr.span, | ||
"logarithm for bases 2, 10 and e can be computed more accurately", | ||
"consider using", | ||
format!("{}.{}()", Sugg::hir(cx, &args[0], ".."), method), | ||
Applicability::MachineApplicable, | ||
); | ||
} | ||
} | ||
|
||
// TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and | ||
// suggest usage of `(x + (y - 1)).ln_1p()` instead | ||
fn check_ln1p(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { | ||
if let ExprKind::Binary( | ||
Spanned { | ||
node: BinOpKind::Add, .. | ||
}, | ||
lhs, | ||
rhs, | ||
) = &args[0].kind | ||
{ | ||
let recv = match (constant(cx, cx.tables, lhs), constant(cx, cx.tables, rhs)) { | ||
(Some((value, _)), _) if F32(1.0) == value || F64(1.0) == value => rhs, | ||
(_, Some((value, _))) if F32(1.0) == value || F64(1.0) == value => lhs, | ||
_ => return, | ||
}; | ||
|
||
span_lint_and_sugg( | ||
cx, | ||
IMPRECISE_FLOPS, | ||
expr.span, | ||
"ln(1 + x) can be computed more accurately", | ||
"consider using", | ||
format!("{}.ln_1p()", prepare_receiver_sugg(cx, recv)), | ||
Applicability::MachineApplicable, | ||
); | ||
} | ||
} | ||
|
||
// Returns an integer if the float constant is a whole number and it can be | ||
// converted to an integer without loss of precision. For now we only check | ||
// ranges [-16777215, 16777216) for type f32 as whole number floats outside | ||
// this range are lossy and ambiguous. | ||
#[allow(clippy::cast_possible_truncation)] | ||
fn get_integer_from_float_constant(value: &Constant) -> Option<i32> { | ||
match value { | ||
F32(num) if num.fract() == 0.0 => { | ||
if (-16_777_215.0..16_777_216.0).contains(num) { | ||
Some(num.round() as i32) | ||
} else { | ||
None | ||
} | ||
}, | ||
F64(num) if num.fract() == 0.0 => { | ||
if (-2_147_483_648.0..2_147_483_648.0).contains(num) { | ||
Some(num.round() as i32) | ||
} else { | ||
None | ||
} | ||
}, | ||
_ => None, | ||
} | ||
} | ||
|
||
fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) { | ||
// Check receiver | ||
if let Some((value, _)) = constant(cx, cx.tables, &args[0]) { | ||
let method = if F32(f32_consts::E) == value || F64(f64_consts::E) == value { | ||
"exp" | ||
} else if F32(2.0) == value || F64(2.0) == value { | ||
"exp2" | ||
} else { | ||
return; | ||
}; | ||
|
||
span_lint_and_sugg( | ||
cx, | ||
SUBOPTIMAL_FLOPS, | ||
expr.span, | ||
"exponent for bases 2 and e can be computed more accurately", | ||
"consider using", | ||
format!("{}.{}()", prepare_receiver_sugg(cx, &args[1]), method), | ||
Applicability::MachineApplicable, | ||
); | ||
} | ||
|
||
// Check argument | ||
if let Some((value, _)) = constant(cx, cx.tables, &args[1]) { | ||
let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value { | ||
( | ||
SUBOPTIMAL_FLOPS, | ||
"square-root of a number can be computed more efficiently and accurately", | ||
format!("{}.sqrt()", Sugg::hir(cx, &args[0], "..")), | ||
) | ||
} else if F32(1.0 / 3.0) == value || F64(1.0 / 3.0) == value { | ||
( | ||
IMPRECISE_FLOPS, | ||
"cube-root of a number can be computed more accurately", | ||
format!("{}.cbrt()", Sugg::hir(cx, &args[0], "..")), | ||
) | ||
} else if let Some(exponent) = get_integer_from_float_constant(&value) { | ||
( | ||
SUBOPTIMAL_FLOPS, | ||
"exponentiation with integer powers can be computed more efficiently", | ||
format!( | ||
"{}.powi({})", | ||
Sugg::hir(cx, &args[0], ".."), | ||
format_numeric_literal(&exponent.to_string(), None, false) | ||
), | ||
) | ||
} else { | ||
return; | ||
}; | ||
|
||
span_lint_and_sugg( | ||
cx, | ||
lint, | ||
expr.span, | ||
help, | ||
"consider using", | ||
suggestion, | ||
Applicability::MachineApplicable, | ||
); | ||
} | ||
} | ||
|
||
// TODO: Lint expressions of the form `x.exp() - y` where y > 1 | ||
// and suggest usage of `x.exp_m1() - (y - 1)` instead | ||
fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { | ||
if_chain! { | ||
if let ExprKind::Binary(Spanned { node: BinOpKind::Sub, .. }, ref lhs, ref rhs) = expr.kind; | ||
if cx.tables.expr_ty(lhs).is_floating_point(); | ||
if let Some((value, _)) = constant(cx, cx.tables, rhs); | ||
if F32(1.0) == value || F64(1.0) == value; | ||
if let ExprKind::MethodCall(ref path, _, ref method_args) = lhs.kind; | ||
if cx.tables.expr_ty(&method_args[0]).is_floating_point(); | ||
if path.ident.name.as_str() == "exp"; | ||
then { | ||
span_lint_and_sugg( | ||
cx, | ||
IMPRECISE_FLOPS, | ||
expr.span, | ||
"(e.pow(x) - 1) can be computed more accurately", | ||
"consider using", | ||
format!( | ||
"{}.exp_m1()", | ||
Sugg::hir(cx, &method_args[0], "..") | ||
), | ||
Applicability::MachineApplicable, | ||
); | ||
} | ||
} | ||
} | ||
|
||
fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> { | ||
if_chain! { | ||
if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref lhs, ref rhs) = &expr.kind; | ||
if cx.tables.expr_ty(lhs).is_floating_point(); | ||
if cx.tables.expr_ty(rhs).is_floating_point(); | ||
then { | ||
return Some((lhs, rhs)); | ||
} | ||
} | ||
|
||
None | ||
} | ||
|
||
// TODO: Fix rust-lang/rust-clippy#4735 | ||
fn check_mul_add(cx: &LateContext<'_, '_>, expr: &Expr<'_>) { | ||
if let ExprKind::Binary( | ||
Spanned { | ||
node: BinOpKind::Add, .. | ||
}, | ||
lhs, | ||
rhs, | ||
) = &expr.kind | ||
{ | ||
let (recv, arg1, arg2) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs) { | ||
(inner_lhs, inner_rhs, rhs) | ||
} else if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs) { | ||
(inner_lhs, inner_rhs, lhs) | ||
} else { | ||
return; | ||
}; | ||
|
||
span_lint_and_sugg( | ||
cx, | ||
SUBOPTIMAL_FLOPS, | ||
expr.span, | ||
"multiply and add expressions can be calculated more efficiently and accurately", | ||
"consider using", | ||
format!( | ||
"{}.mul_add({}, {})", | ||
prepare_receiver_sugg(cx, recv), | ||
Sugg::hir(cx, arg1, ".."), | ||
Sugg::hir(cx, arg2, ".."), | ||
), | ||
Applicability::MachineApplicable, | ||
); | ||
} | ||
} | ||
|
||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic { | ||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) { | ||
if let ExprKind::MethodCall(ref path, _, args) = &expr.kind { | ||
let recv_ty = cx.tables.expr_ty(&args[0]); | ||
|
||
if recv_ty.is_floating_point() { | ||
match &*path.ident.name.as_str() { | ||
"ln" => check_ln1p(cx, expr, args), | ||
"log" => check_log_base(cx, expr, args), | ||
"powf" => check_powf(cx, expr, args), | ||
_ => {}, | ||
} | ||
} | ||
} else { | ||
check_expm1(cx, expr); | ||
check_mul_add(cx, expr); | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// run-rustfix | ||
#![warn(clippy::imprecise_flops)] | ||
|
||
fn main() { | ||
let x = 2f32; | ||
let _ = x.exp_m1(); | ||
let _ = x.exp_m1() + 2.0; | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.exp() - 2.0; | ||
let _ = x.exp() - 1.0 * 2.0; | ||
|
||
let x = 2f64; | ||
let _ = x.exp_m1(); | ||
let _ = x.exp_m1() + 2.0; | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.exp() - 2.0; | ||
let _ = x.exp() - 1.0 * 2.0; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// run-rustfix | ||
#![warn(clippy::imprecise_flops)] | ||
|
||
fn main() { | ||
let x = 2f32; | ||
let _ = x.exp() - 1.0; | ||
let _ = x.exp() - 1.0 + 2.0; | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.exp() - 2.0; | ||
let _ = x.exp() - 1.0 * 2.0; | ||
|
||
let x = 2f64; | ||
let _ = x.exp() - 1.0; | ||
let _ = x.exp() - 1.0 + 2.0; | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.exp() - 2.0; | ||
let _ = x.exp() - 1.0 * 2.0; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
error: (e.pow(x) - 1) can be computed more accurately | ||
--> $DIR/floating_point_exp.rs:6:13 | ||
| | ||
LL | let _ = x.exp() - 1.0; | ||
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` | ||
| | ||
= note: `-D clippy::imprecise-flops` implied by `-D warnings` | ||
|
||
error: (e.pow(x) - 1) can be computed more accurately | ||
--> $DIR/floating_point_exp.rs:7:13 | ||
| | ||
LL | let _ = x.exp() - 1.0 + 2.0; | ||
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` | ||
|
||
error: (e.pow(x) - 1) can be computed more accurately | ||
--> $DIR/floating_point_exp.rs:13:13 | ||
| | ||
LL | let _ = x.exp() - 1.0; | ||
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` | ||
|
||
error: (e.pow(x) - 1) can be computed more accurately | ||
--> $DIR/floating_point_exp.rs:14:13 | ||
| | ||
LL | let _ = x.exp() - 1.0 + 2.0; | ||
| ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()` | ||
|
||
error: aborting due to 4 previous errors | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// run-rustfix | ||
#![allow(dead_code, clippy::double_parens)] | ||
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] | ||
|
||
const TWO: f32 = 2.0; | ||
const E: f32 = std::f32::consts::E; | ||
|
||
fn check_log_base() { | ||
let x = 1f32; | ||
let _ = x.log2(); | ||
let _ = x.log10(); | ||
let _ = x.ln(); | ||
let _ = x.log2(); | ||
let _ = x.ln(); | ||
|
||
let x = 1f64; | ||
let _ = x.log2(); | ||
let _ = x.log10(); | ||
let _ = x.ln(); | ||
} | ||
|
||
fn check_ln1p() { | ||
let x = 1f32; | ||
let _ = 2.0f32.ln_1p(); | ||
let _ = 2.0f32.ln_1p(); | ||
let _ = x.ln_1p(); | ||
let _ = (x / 2.0).ln_1p(); | ||
let _ = x.powi(2).ln_1p(); | ||
let _ = (x.powi(2) / 2.0).ln_1p(); | ||
let _ = ((std::f32::consts::E - 1.0)).ln_1p(); | ||
let _ = x.ln_1p(); | ||
let _ = x.powi(2).ln_1p(); | ||
let _ = (x + 2.0).ln_1p(); | ||
let _ = (x / 2.0).ln_1p(); | ||
// Cases where the lint shouldn't be applied | ||
let _ = (1.0 + x + 2.0).ln(); | ||
let _ = (x + 1.0 + 2.0).ln(); | ||
let _ = (x + 1.0 / 2.0).ln(); | ||
let _ = (1.0 + x - 2.0).ln(); | ||
|
||
let x = 1f64; | ||
let _ = 2.0f64.ln_1p(); | ||
let _ = 2.0f64.ln_1p(); | ||
let _ = x.ln_1p(); | ||
let _ = (x / 2.0).ln_1p(); | ||
let _ = x.powi(2).ln_1p(); | ||
let _ = x.ln_1p(); | ||
let _ = x.powi(2).ln_1p(); | ||
let _ = (x + 2.0).ln_1p(); | ||
let _ = (x / 2.0).ln_1p(); | ||
// Cases where the lint shouldn't be applied | ||
let _ = (1.0 + x + 2.0).ln(); | ||
let _ = (x + 1.0 + 2.0).ln(); | ||
let _ = (x + 1.0 / 2.0).ln(); | ||
let _ = (1.0 + x - 2.0).ln(); | ||
} | ||
|
||
fn main() {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// run-rustfix | ||
#![allow(dead_code, clippy::double_parens)] | ||
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] | ||
|
||
const TWO: f32 = 2.0; | ||
const E: f32 = std::f32::consts::E; | ||
|
||
fn check_log_base() { | ||
let x = 1f32; | ||
let _ = x.log(2f32); | ||
let _ = x.log(10f32); | ||
let _ = x.log(std::f32::consts::E); | ||
let _ = x.log(TWO); | ||
let _ = x.log(E); | ||
|
||
let x = 1f64; | ||
let _ = x.log(2f64); | ||
let _ = x.log(10f64); | ||
let _ = x.log(std::f64::consts::E); | ||
} | ||
|
||
fn check_ln1p() { | ||
let x = 1f32; | ||
let _ = (1f32 + 2.).ln(); | ||
let _ = (1f32 + 2.0).ln(); | ||
let _ = (1.0 + x).ln(); | ||
let _ = (1.0 + x / 2.0).ln(); | ||
let _ = (1.0 + x.powi(2)).ln(); | ||
let _ = (1.0 + x.powi(2) / 2.0).ln(); | ||
let _ = (1.0 + (std::f32::consts::E - 1.0)).ln(); | ||
let _ = (x + 1.0).ln(); | ||
let _ = (x.powi(2) + 1.0).ln(); | ||
let _ = (x + 2.0 + 1.0).ln(); | ||
let _ = (x / 2.0 + 1.0).ln(); | ||
// Cases where the lint shouldn't be applied | ||
let _ = (1.0 + x + 2.0).ln(); | ||
let _ = (x + 1.0 + 2.0).ln(); | ||
let _ = (x + 1.0 / 2.0).ln(); | ||
let _ = (1.0 + x - 2.0).ln(); | ||
|
||
let x = 1f64; | ||
let _ = (1f64 + 2.).ln(); | ||
let _ = (1f64 + 2.0).ln(); | ||
let _ = (1.0 + x).ln(); | ||
let _ = (1.0 + x / 2.0).ln(); | ||
let _ = (1.0 + x.powi(2)).ln(); | ||
let _ = (x + 1.0).ln(); | ||
let _ = (x.powi(2) + 1.0).ln(); | ||
let _ = (x + 2.0 + 1.0).ln(); | ||
let _ = (x / 2.0 + 1.0).ln(); | ||
// Cases where the lint shouldn't be applied | ||
let _ = (1.0 + x + 2.0).ln(); | ||
let _ = (x + 1.0 + 2.0).ln(); | ||
let _ = (x + 1.0 / 2.0).ln(); | ||
let _ = (1.0 + x - 2.0).ln(); | ||
} | ||
|
||
fn main() {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:10:13 | ||
| | ||
LL | let _ = x.log(2f32); | ||
| ^^^^^^^^^^^ help: consider using: `x.log2()` | ||
| | ||
= note: `-D clippy::suboptimal-flops` implied by `-D warnings` | ||
|
||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:11:13 | ||
| | ||
LL | let _ = x.log(10f32); | ||
| ^^^^^^^^^^^^ help: consider using: `x.log10()` | ||
|
||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:12:13 | ||
| | ||
LL | let _ = x.log(std::f32::consts::E); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()` | ||
|
||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:13:13 | ||
| | ||
LL | let _ = x.log(TWO); | ||
| ^^^^^^^^^^ help: consider using: `x.log2()` | ||
|
||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:14:13 | ||
| | ||
LL | let _ = x.log(E); | ||
| ^^^^^^^^ help: consider using: `x.ln()` | ||
|
||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:17:13 | ||
| | ||
LL | let _ = x.log(2f64); | ||
| ^^^^^^^^^^^ help: consider using: `x.log2()` | ||
|
||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:18:13 | ||
| | ||
LL | let _ = x.log(10f64); | ||
| ^^^^^^^^^^^^ help: consider using: `x.log10()` | ||
|
||
error: logarithm for bases 2, 10 and e can be computed more accurately | ||
--> $DIR/floating_point_log.rs:19:13 | ||
| | ||
LL | let _ = x.log(std::f64::consts::E); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:24:13 | ||
| | ||
LL | let _ = (1f32 + 2.).ln(); | ||
| ^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` | ||
| | ||
= note: `-D clippy::imprecise-flops` implied by `-D warnings` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:25:13 | ||
| | ||
LL | let _ = (1f32 + 2.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:26:13 | ||
| | ||
LL | let _ = (1.0 + x).ln(); | ||
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:27:13 | ||
| | ||
LL | let _ = (1.0 + x / 2.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:28:13 | ||
| | ||
LL | let _ = (1.0 + x.powi(2)).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:29:13 | ||
| | ||
LL | let _ = (1.0 + x.powi(2) / 2.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(2) / 2.0).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:30:13 | ||
| | ||
LL | let _ = (1.0 + (std::f32::consts::E - 1.0)).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `((std::f32::consts::E - 1.0)).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:31:13 | ||
| | ||
LL | let _ = (x + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:32:13 | ||
| | ||
LL | let _ = (x.powi(2) + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:33:13 | ||
| | ||
LL | let _ = (x + 2.0 + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:34:13 | ||
| | ||
LL | let _ = (x / 2.0 + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:42:13 | ||
| | ||
LL | let _ = (1f64 + 2.).ln(); | ||
| ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:43:13 | ||
| | ||
LL | let _ = (1f64 + 2.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:44:13 | ||
| | ||
LL | let _ = (1.0 + x).ln(); | ||
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:45:13 | ||
| | ||
LL | let _ = (1.0 + x / 2.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:46:13 | ||
| | ||
LL | let _ = (1.0 + x.powi(2)).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:47:13 | ||
| | ||
LL | let _ = (x + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:48:13 | ||
| | ||
LL | let _ = (x.powi(2) + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:49:13 | ||
| | ||
LL | let _ = (x + 2.0 + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()` | ||
|
||
error: ln(1 + x) can be computed more accurately | ||
--> $DIR/floating_point_log.rs:50:13 | ||
| | ||
LL | let _ = (x / 2.0 + 1.0).ln(); | ||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()` | ||
|
||
error: aborting due to 28 previous errors | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// run-rustfix | ||
#![warn(clippy::suboptimal_flops)] | ||
|
||
fn main() { | ||
let a: f64 = 1234.567; | ||
let b: f64 = 45.67834; | ||
let c: f64 = 0.0004; | ||
let d: f64 = 0.0001; | ||
|
||
let _ = a.mul_add(b, c); | ||
let _ = a.mul_add(b, c); | ||
let _ = 2.0f64.mul_add(4.0, a); | ||
let _ = 2.0f64.mul_add(4., a); | ||
|
||
let _ = a.mul_add(b, c); | ||
let _ = a.mul_add(b, c); | ||
let _ = (a * b).mul_add(c, d); | ||
|
||
let _ = a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c)) + c; | ||
let _ = 1234.567_f64.mul_add(45.67834_f64, 0.0004_f64); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// run-rustfix | ||
#![warn(clippy::suboptimal_flops)] | ||
|
||
fn main() { | ||
let a: f64 = 1234.567; | ||
let b: f64 = 45.67834; | ||
let c: f64 = 0.0004; | ||
let d: f64 = 0.0001; | ||
|
||
let _ = a * b + c; | ||
let _ = c + a * b; | ||
let _ = a + 2.0 * 4.0; | ||
let _ = a + 2. * 4.; | ||
|
||
let _ = (a * b) + c; | ||
let _ = c + (a * b); | ||
let _ = a * b * c + d; | ||
|
||
let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c; | ||
let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:10:13 | ||
| | ||
LL | let _ = a * b + c; | ||
| ^^^^^^^^^ help: consider using: `a.mul_add(b, c)` | ||
| | ||
= note: `-D clippy::suboptimal-flops` implied by `-D warnings` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:11:13 | ||
| | ||
LL | let _ = c + a * b; | ||
| ^^^^^^^^^ help: consider using: `a.mul_add(b, c)` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:12:13 | ||
| | ||
LL | let _ = a + 2.0 * 4.0; | ||
| ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:13:13 | ||
| | ||
LL | let _ = a + 2. * 4.; | ||
| ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:15:13 | ||
| | ||
LL | let _ = (a * b) + c; | ||
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:16:13 | ||
| | ||
LL | let _ = c + (a * b); | ||
| ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:17:13 | ||
| | ||
LL | let _ = a * b * c + d; | ||
| ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:19:13 | ||
| | ||
LL | let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c; | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))` | ||
|
||
error: multiply and add expressions can be calculated more efficiently and accurately | ||
--> $DIR/floating_point_mul_add.rs:20:13 | ||
| | ||
LL | let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64; | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)` | ||
|
||
error: aborting due to 9 previous errors | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// run-rustfix | ||
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] | ||
|
||
fn main() { | ||
let x = 3f32; | ||
let _ = x.exp2(); | ||
let _ = 3.1f32.exp2(); | ||
let _ = (-3.1f32).exp2(); | ||
let _ = x.exp(); | ||
let _ = 3.1f32.exp(); | ||
let _ = (-3.1f32).exp(); | ||
let _ = x.sqrt(); | ||
let _ = x.cbrt(); | ||
let _ = x.powi(2); | ||
let _ = x.powi(-2); | ||
let _ = x.powi(16_777_215); | ||
let _ = x.powi(-16_777_215); | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.powf(2.1); | ||
let _ = x.powf(-2.1); | ||
let _ = x.powf(16_777_216.0); | ||
let _ = x.powf(-16_777_216.0); | ||
|
||
let x = 3f64; | ||
let _ = x.exp2(); | ||
let _ = 3.1f64.exp2(); | ||
let _ = (-3.1f64).exp2(); | ||
let _ = x.exp(); | ||
let _ = 3.1f64.exp(); | ||
let _ = (-3.1f64).exp(); | ||
let _ = x.sqrt(); | ||
let _ = x.cbrt(); | ||
let _ = x.powi(2); | ||
let _ = x.powi(-2); | ||
let _ = x.powi(-2_147_483_648); | ||
let _ = x.powi(2_147_483_647); | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.powf(2.1); | ||
let _ = x.powf(-2.1); | ||
let _ = x.powf(-2_147_483_649.0); | ||
let _ = x.powf(2_147_483_648.0); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// run-rustfix | ||
#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] | ||
|
||
fn main() { | ||
let x = 3f32; | ||
let _ = 2f32.powf(x); | ||
let _ = 2f32.powf(3.1); | ||
let _ = 2f32.powf(-3.1); | ||
let _ = std::f32::consts::E.powf(x); | ||
let _ = std::f32::consts::E.powf(3.1); | ||
let _ = std::f32::consts::E.powf(-3.1); | ||
let _ = x.powf(1.0 / 2.0); | ||
let _ = x.powf(1.0 / 3.0); | ||
let _ = x.powf(2.0); | ||
let _ = x.powf(-2.0); | ||
let _ = x.powf(16_777_215.0); | ||
let _ = x.powf(-16_777_215.0); | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.powf(2.1); | ||
krishna-veerareddy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let _ = x.powf(-2.1); | ||
let _ = x.powf(16_777_216.0); | ||
let _ = x.powf(-16_777_216.0); | ||
|
||
let x = 3f64; | ||
let _ = 2f64.powf(x); | ||
let _ = 2f64.powf(3.1); | ||
let _ = 2f64.powf(-3.1); | ||
let _ = std::f64::consts::E.powf(x); | ||
let _ = std::f64::consts::E.powf(3.1); | ||
let _ = std::f64::consts::E.powf(-3.1); | ||
let _ = x.powf(1.0 / 2.0); | ||
let _ = x.powf(1.0 / 3.0); | ||
let _ = x.powf(2.0); | ||
let _ = x.powf(-2.0); | ||
let _ = x.powf(-2_147_483_648.0); | ||
let _ = x.powf(2_147_483_647.0); | ||
// Cases where the lint shouldn't be applied | ||
let _ = x.powf(2.1); | ||
krishna-veerareddy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let _ = x.powf(-2.1); | ||
let _ = x.powf(-2_147_483_649.0); | ||
let _ = x.powf(2_147_483_648.0); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:6:13 | ||
| | ||
LL | let _ = 2f32.powf(x); | ||
| ^^^^^^^^^^^^ help: consider using: `x.exp2()` | ||
| | ||
= note: `-D clippy::suboptimal-flops` implied by `-D warnings` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:7:13 | ||
| | ||
LL | let _ = 2f32.powf(3.1); | ||
| ^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp2()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:8:13 | ||
| | ||
LL | let _ = 2f32.powf(-3.1); | ||
| ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp2()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:9:13 | ||
| | ||
LL | let _ = std::f32::consts::E.powf(x); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:10:13 | ||
| | ||
LL | let _ = std::f32::consts::E.powf(3.1); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:11:13 | ||
| | ||
LL | let _ = std::f32::consts::E.powf(-3.1); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp()` | ||
|
||
error: square-root of a number can be computed more efficiently and accurately | ||
--> $DIR/floating_point_powf.rs:12:13 | ||
| | ||
LL | let _ = x.powf(1.0 / 2.0); | ||
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()` | ||
|
||
error: cube-root of a number can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:13:13 | ||
| | ||
LL | let _ = x.powf(1.0 / 3.0); | ||
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()` | ||
| | ||
= note: `-D clippy::imprecise-flops` implied by `-D warnings` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:14:13 | ||
| | ||
LL | let _ = x.powf(2.0); | ||
| ^^^^^^^^^^^ help: consider using: `x.powi(2)` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:15:13 | ||
| | ||
LL | let _ = x.powf(-2.0); | ||
| ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:16:13 | ||
| | ||
LL | let _ = x.powf(16_777_215.0); | ||
| ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:17:13 | ||
| | ||
LL | let _ = x.powf(-16_777_215.0); | ||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:25:13 | ||
| | ||
LL | let _ = 2f64.powf(x); | ||
| ^^^^^^^^^^^^ help: consider using: `x.exp2()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:26:13 | ||
| | ||
LL | let _ = 2f64.powf(3.1); | ||
| ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:27:13 | ||
| | ||
LL | let _ = 2f64.powf(-3.1); | ||
| ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:28:13 | ||
| | ||
LL | let _ = std::f64::consts::E.powf(x); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:29:13 | ||
| | ||
LL | let _ = std::f64::consts::E.powf(3.1); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()` | ||
|
||
error: exponent for bases 2 and e can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:30:13 | ||
| | ||
LL | let _ = std::f64::consts::E.powf(-3.1); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()` | ||
|
||
error: square-root of a number can be computed more efficiently and accurately | ||
--> $DIR/floating_point_powf.rs:31:13 | ||
| | ||
LL | let _ = x.powf(1.0 / 2.0); | ||
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()` | ||
|
||
error: cube-root of a number can be computed more accurately | ||
--> $DIR/floating_point_powf.rs:32:13 | ||
| | ||
LL | let _ = x.powf(1.0 / 3.0); | ||
| ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:33:13 | ||
| | ||
LL | let _ = x.powf(2.0); | ||
| ^^^^^^^^^^^ help: consider using: `x.powi(2)` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:34:13 | ||
| | ||
LL | let _ = x.powf(-2.0); | ||
| ^^^^^^^^^^^^ help: consider using: `x.powi(-2)` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:35:13 | ||
| | ||
LL | let _ = x.powf(-2_147_483_648.0); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)` | ||
|
||
error: exponentiation with integer powers can be computed more efficiently | ||
--> $DIR/floating_point_powf.rs:36:13 | ||
| | ||
LL | let _ = x.powf(2_147_483_647.0); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)` | ||
|
||
error: aborting due to 24 previous errors | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.