diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs
index ea29f5d12c6..031cedb9072 100644
--- a/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/clippy_lints/src/casts/unnecessary_cast.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::get_parent_expr;
 use clippy_utils::numeric_literal::NumericLiteral;
 use clippy_utils::source::snippet_opt;
 use if_chain::if_chain;
@@ -85,22 +86,38 @@ pub(super) fn check<'tcx>(
     false
 }
 
-fn lint_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) {
+fn lint_unnecessary_cast(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    raw_literal_str: &str,
+    cast_from: Ty<'_>,
+    cast_to: Ty<'_>,
+) {
     let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" };
-    let replaced_literal;
-    let matchless = if literal_str.contains(['(', ')']) {
-        replaced_literal = literal_str.replace(['(', ')'], "");
-        &replaced_literal
-    } else {
-        literal_str
+    // first we remove all matches so `-(1)` become `-1`, and remove trailing dots, so `1.` become `1`
+    let literal_str = raw_literal_str
+        .replace(['(', ')'], "")
+        .trim_end_matches('.')
+        .to_string();
+    // we know need to check if the parent is a method call, to add parenthesis accordingly (eg:
+    // (-1).foo() instead of -1.foo())
+    let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr)
+        && let ExprKind::MethodCall(..) = parent_expr.kind
+        && literal_str.starts_with('-')
+        {
+            format!("({literal_str}_{cast_to})")
+
+        } else {
+            format!("{literal_str}_{cast_to}")
     };
+
     span_lint_and_sugg(
         cx,
         UNNECESSARY_CAST,
         expr.span,
         &format!("casting {literal_kind_name} literal to `{cast_to}` is unnecessary"),
         "try",
-        format!("{}_{cast_to}", matchless.trim_end_matches('.')),
+        sugg,
         Applicability::MachineApplicable,
     );
 }
diff --git a/tests/ui/unnecessary_cast.fixed b/tests/ui/unnecessary_cast.fixed
index ee9f157342d..70ec3e94380 100644
--- a/tests/ui/unnecessary_cast.fixed
+++ b/tests/ui/unnecessary_cast.fixed
@@ -97,4 +97,10 @@ mod fixable {
 
         let _ = -(1 + 1) as i64;
     }
+
+    fn issue_9563() {
+        let _: f64 = (-8.0_f64).exp();
+        #[allow(clippy::precedence)]
+        let _: f64 = -8.0_f64.exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
+    }
 }
diff --git a/tests/ui/unnecessary_cast.rs b/tests/ui/unnecessary_cast.rs
index 5b70412424c..36c1a87fab6 100644
--- a/tests/ui/unnecessary_cast.rs
+++ b/tests/ui/unnecessary_cast.rs
@@ -97,4 +97,10 @@ mod fixable {
 
         let _ = -(1 + 1) as i64;
     }
+
+    fn issue_9563() {
+        let _: f64 = (-8.0 as f64).exp();
+        #[allow(clippy::precedence)]
+        let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
+    }
 }
diff --git a/tests/ui/unnecessary_cast.stderr b/tests/ui/unnecessary_cast.stderr
index f7829ff3b0e..a52b92c339c 100644
--- a/tests/ui/unnecessary_cast.stderr
+++ b/tests/ui/unnecessary_cast.stderr
@@ -162,5 +162,17 @@ error: casting integer literal to `i64` is unnecessary
 LL |         let _: i64 = -(1) as i64;
    |                      ^^^^^^^^^^^ help: try: `-1_i64`
 
-error: aborting due to 27 previous errors
+error: casting float literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:102:22
+   |
+LL |         let _: f64 = (-8.0 as f64).exp();
+   |                      ^^^^^^^^^^^^^ help: try: `(-8.0_f64)`
+
+error: casting float literal to `f64` is unnecessary
+  --> $DIR/unnecessary_cast.rs:104:23
+   |
+LL |         let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior
+   |                       ^^^^^^^^^^^^ help: try: `8.0_f64`
+
+error: aborting due to 29 previous errors