Flutter二次方程计算器出现invalid double红屏错误,求排查解决
问题排查与解决
核心错误原因
- 页面初始化时输入框为空,直接调用
double.parse()转换空字符串,触发"invalid double"错误 - 二次求根公式写错:正确公式是
x = [-b ± √(b²-4ac)]/(2a),代码中误将-B写成了-A - 计算逻辑放在
build方法中,每次UI重建都会执行,包括用户未输入内容的场景 - 未处理判别式
b²-4ac为负数的情况,会导致sqrt()返回NaN引发异常 - 缺少输入校验,用户输入非数字内容时也会触发转换错误
修复方案
- 添加输入校验:给
TextFormField添加validator,确保输入为有效数字 - 延迟计算逻辑:将求根计算放在按钮点击事件中,仅在用户提交表单后执行
- 修正求根公式:把
(-1 * A)改为-B - 处理边界情况:判断判别式是否非负、a是否为0,给出对应提示
- 初始化默认值:给输入框设置初始值,避免空字符串转换错误
修复后的完整代码
import 'dart:math'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '二次方程求解器', theme: ThemeData( brightness: Brightness.dark, primarySwatch: Colors.blue, primaryColor: const Color(0xFF212121), accentColor: const Color(0xFF64ffda), canvasColor: const Color(0xFF303030), ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final GlobalKey<FormState> formstate = GlobalKey(); final TextEditingController x2Controller = TextEditingController(text: "1"); final TextEditingController xController = TextEditingController(text: "0"); final TextEditingController cController = TextEditingController(text: "0"); String result = ""; void solveEquation() { if (formstate.currentState!.validate()) { double a = double.parse(x2Controller.text); double b = double.parse(xController.text); double c = double.parse(cController.text); if (a == 0) { setState(() { result = "a不能为0,请输入有效的二次方程"; }); return; } double discriminant = b * b - 4 * a * c; if (discriminant < 0) { setState(() { result = "判别式为负数,无实根"; }); } else { double sqrtDiscriminant = sqrt(discriminant); double x1 = (-b + sqrtDiscriminant) / (2 * a); double x2 = (-b - sqrtDiscriminant) / (2 * a); setState(() { result = "x₁ = ${x1.toStringAsFixed(2)}\nx₂ = ${x2.toStringAsFixed(2)}"; }); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('二次方程求解器'), backgroundColor: Colors.black, ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ Form( key: formstate, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: 60, child: TextFormField( controller: x2Controller, keyboardType: TextInputType.numberWithOptions(decimal: true), style: const TextStyle( fontSize: 16.0, color: Color(0xff8b0c0c), fontWeight: FontWeight.w200, ), validator: (value) { if (value == null || value.isEmpty) { return "请输入系数"; } if (double.tryParse(value) == null) { return "请输入有效数字"; } return null; }, ), ), const Text( "x² + ", style: TextStyle( fontSize: 16.0, color: Color(0xff0e0101), fontWeight: FontWeight.w200, ), ), SizedBox( width: 60, child: TextFormField( controller: xController, keyboardType: TextInputType.numberWithOptions(decimal: true), style: const TextStyle( fontSize: 16.0, color: Color(0xffae1a1a), fontWeight: FontWeight.w200, ), validator: (value) { if (value == null || value.isEmpty) { return "请输入系数"; } if (double.tryParse(value) == null) { return "请输入有效数字"; } return null; }, ), ), const Text( "x + ", style: TextStyle( fontSize: 16.0, color: Color(0xff0f0000), fontWeight: FontWeight.w200, ), ), SizedBox( width: 60, child: TextFormField( controller: cController, keyboardType: TextInputType.numberWithOptions(decimal: true), style: const TextStyle( fontSize: 16.0, color: Color(0xff970c0c), fontWeight: FontWeight.w200, ), validator: (value) { if (value == null || value.isEmpty) { return "请输入常数项"; } if (double.tryParse(value) == null) { return "请输入有效数字"; } return null; }, ), ), const Text( " = 0", style: TextStyle( fontSize: 16.0, color: Color(0xff0f0000), fontWeight: FontWeight.w200, ), ), ], ), ), const SizedBox(height: 20), ElevatedButton( onPressed: solveEquation, child: const Text('求解'), ), const SizedBox(height: 20), Text( result, textAlign: TextAlign.center, style: const TextStyle( fontSize: 18.0, color: Color(0xff220101), fontWeight: FontWeight.w400, ), ), ], ), ), ); } }
额外优化点
- 给输入框设置数字键盘,提升输入体验
- 使用
toStringAsFixed(2)格式化结果,保留两位小数更美观 - 将输入框排成一行,符合二次方程的书写格式
- 添加a=0的判断,避免除数为0的错误
内容的提问来源于stack exchange,提问作者abdelrahmandarrage
相关产品推荐
相关产品推荐

