Math 是 C# 静态类,无需实例化;其方法不抛异常、不自动类型转换,需注意重载歧义、溢出(如 Abs(int.MinValue))、银行家舍入(Round 默认)、负数取整差异(Floor/Ceiling/Truncate)、Max/Min 类型匹配及边界值返回 NaN/Infinity 等问题。

Math 是 C# 中的静态类,不用 new,直接用 Math. 调用就行。它不处理异常(比如对负数调用 Math.Sqrt 会返回 NaN),也不自动类型转换——传 int 和 double 混用可能触发重载歧义或编译错误。
Math.Abs、Math.Round、Math.Sign 这几个基础函数怎么选
它们都处理“数值符号与舍入”,但行为差异大,容易误用:
-
Math.Abs只去负号,不改变精度:Math.Abs(-3.7)→3.7;对int、double、decimal都有重载,但注意Math.Abs(int.MinValue)会溢出(因为int.MaxValue比它小 1) -
Math.Round默认是银行家舍入(MidpointRounding.ToEven):Math.Round(2.5)得2,Math.Round(3.5)得4;要严格四舍五入必须显式传MidpointRounding.AwayFromZero -
Math.Sign返回-1、0或1,适合做符号判断分支,比x > 0多一层安全:它能正确处理NaN(返回0)、PositiveInfinity(返回1)等边界值
Math.Floor、Math.Ceiling、Math.Truncate 的区别在哪
三者都“取整”,但逻辑完全不同,尤其在负数场景下结果差异明显:
-
Math.Floor(-4.7)→-5.0(向下取 ≤ x 的最大整数) -
Math.Ceiling(-4.7)→-4.0(向上取 ≥ x 的最小整数) -
Math.Truncate(-4.7)→-4.0(直接砍掉小数部分,等价于向零截断) - 性能上无显著差别,但语义不能互换:做分页计算页码常用
Math.Ceiling((double)total / pageSize);做索引偏移截断小数时,Math.Truncate比强制转(int)更安全(后者对double超出int范围会抛异常)
Math.Max/Min 为什么有时编译不过
常见报错是 The call is ambiguous,本质是泛型推导失败或类型不匹配:
- 传两个不同数值类型会失败:
Math.Max(5, 3.14)编译不通过(int和double无法统一重载) - 正确写法是显式转成同一类型:
Math.Max((double)5, 3.14)或Math.Max(5.0, 3.14) - 支持的参数类型包括
int、long、float、double、decimal,但没有short或byte的重载——用它们会先隐式提升为int,再参与比较 - 如果要比较三个数,
Math.Max不支持可变参数,得嵌套写:Math.Max(a, Math.Max(b, c))
Math.Sqrt、Math.Pow、Math.Log 容易忽略的边界情况
这些函数不抛异常,但返回特殊值,若没检查会导致后续计算静默出错:
-
Math.Sqrt(-1)返回NaN,不是异常;double.IsNaN(result)必须手动检查 -
Math.Pow(0, 0)返回1.0(IEEE 754 定义),而Math.Pow(-2, 0.5)返回NaN(负数开偶次方) -
Math.Log(0)返回NegativeInfinity,Math.Log(-1)返回NaN;用对数前建议加if (x > 0)防御 -
Math.Log(x, base)第二个参数必须 > 0 且 ≠ 1,否则返回NaN
真正踩坑的地方不在语法,而在“默认行为”和“边界返回值”——比如 Math.Round 不是你以为的四舍五入,Math.Sqrt 遇负数不报错只返 NaN,这些都不会在编译期提醒你。


















