C# 取模运算符 % 的 Bug

7
解决一个bug后,我发现了一些有趣的发现。
这个过程的结果是:
    static void Main(string[] args)
    {
        int i4 = 4;
        Console.WriteLine("int i4 = 4;");
        Console.WriteLine("i4 % 1 = {0}", i4 % 1);

        double d4 = 4.0;
        Console.WriteLine("double d4 = 4.0;");
        Console.WriteLine("d4 % 1 = {0}", d4 % 1);
        Console.WriteLine("-----------------------------------------------------------");
        int i64 = 64;
        double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0);
        Console.WriteLine("int i64 = 64;");
        Console.WriteLine("double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0) = {0}", dCubeRootOf64);
        Console.WriteLine("dCubeRootOf64 = {0}", dCubeRootOf64);
        Console.WriteLine("dCubeRootOf64 % 1 = {0} ??????????????  Why 1. ??????????", dCubeRootOf64 % 1);

        Console.ReadLine();
    }

is

int i4 = 4;
i4 % 1 = 0
double d4 = 4.0;
d4 % 1 = 0
-----------------------------------------------------------
int i64 = 64;
double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0) = 4
dCubeRootOf64 = 4
dCubeRootOf64 % 1 = 1 ??????????????  Why 1. ??????????

int 4 % 1 = 0 -- 正确

double 4.0 % 1 = 0 -- 正确

但错误出现在:

Math.Pow(64, 1.0 / 3.0) % 1 = 1

64的立方根是4。为什么这种情况下4%1=1


请查看谷歌:(64^(1/3)) mod 1 - SQLMason
如果你想确保获取模数的是整数,请尝试进行强制类型转换。 - SQLMason
我想你在寻找这个:https://dev59.com/uXRB5IYBdhLWcg3wc280 - Nevyn
可能是重复的问题:为什么C#中的模运算符对双精度数不起作用? - Ian Mercer
@IanMercer:不,这不是重复的。 - SLaks
2
Math.Pow(x, 1.0 / 3.0)并不能计算立方根,即使Pow是无限精确的(它并不是),因为1.0 / 3.0不是三分之一 - 它是0.33333333333333331。 - harold
2个回答

12

Math.Pow(64, 1.0 / 3.0) 返回 3.9999999999999996
显示时会四舍五入为4

将它取模1得到的结果是0.99999999999999956,同样地,显示时被四舍五入为1

你可以通过添加.ToString("R")来查看真实值。


谢谢,Math.Pow(64, 1.0 / 3.0) 返回的是3.9999999999999996。- 这解释了一切。 - SelvirK

3
返回1而不是0;这是因为返回<3.9999999999999996>,<3.9999999999999996 % 1>返回<0.99999999999999956>,最终被四舍五入为1。

因此结果为1。


@GrantWinney: 没错。4.0%1 返回 0 - SLaks
我刚刚尝试了相同的发布代码,并在3.5框架中得到了1作为输出。 - Rahul
1
@Rahul:确切地说,它应该返回 0 - SLaks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接