You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中C# float转int异常:乘法结果被意外向下取整?

float转int时出现向下取整偏差的原因分析

问题现象

在Unity的C#开发中遇到float转int的异常:

  • 计算x * 1.05时,结果等同于x * 1
  • 计算x * 1.1时,结果等同于x * 1.05

Unity环境测试代码

using System; 

public class Example
{
   public static void Main()
   {
     int gainAmount = 20;
     float _gainAmountModifier = 1.05f;
      gainAmount = (int)(gainAmount * _gainAmountModifier);
     Debug.Log(_gainAmountModifier);
     Debug.Log(gainAmount); 
   }
}

输出:

1.05
20

C#沙箱测试代码

using System; 

public class Example
{
   public static void Main()
   {
    int var_int = 100;
    float var_f = var_int;
    var_f = var_f * 1.05f; 
    var_int = (int)var_f;

    Console.WriteLine(var_f);
    Console.Write(var_int);
   }
}

输出:

105
104

核心原因

问题出在float类型的精度限制:

  • 十进制的1.05无法用二进制浮点数精确存储,实际在内存中存储的是一个略小于1.05的近似值(比如1.0499999523162842)。
  • 当计算20 * 1.05f时,实际结果是20.999999046325684,直接用(int)强制转换会截断所有小数部分,只保留整数位20。
  • 在沙箱测试中,100 * 1.05f的实际结果是104.99999237060547,Console.WriteLine会对这个值做四舍五入显示为105,但(int)转换依然截断小数得到104,这就造成了显示值和实际转换结果的矛盾。

解决方案

针对这类需要精确数值转换的场景,推荐以下几种方式:

  1. 使用四舍五入转换:在Unity中用Mathf.RoundToInt(),普通C#环境用Math.Round(),会根据小数部分的值自动取整:
    // Unity示例
    gainAmount = Mathf.RoundToInt(gainAmount * _gainAmountModifier);
    // 普通C#示例
    var_int = (int)Math.Round(var_f);
    
  2. 使用decimal类型计算:decimal的精度更高,适合处理货币、百分比这类需要精确十进制运算的场景:
    int var_int = 100;
    decimal var_d = var_int;
    var_d = var_d * 1.05m;
    var_int = (int)var_d;
    
  3. 手动补偏后截断:如果需要向下取整但避免精度误差,可以先给结果加一个极小的偏移值(比如0.0001f)再转换:
    gainAmount = (int)(gainAmount * _gainAmountModifier + 0.0001f);
    

内容的提问来源于stack exchange,提问作者Sid Chou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:51:12