C# 私有双精度始终返回0

C# 私有双精度始终返回0,c#,C#,我有这个功能: private double getTotal(string str) { double total = 0; byte[] asciiBytes = Encoding.ASCII.GetBytes(str); foreach(int c in asciiBytes) { total = total + c; total = total * (5 * (c

我有这个功能:

 private double getTotal(string str)
    {
        double total = 0;
        byte[] asciiBytes = Encoding.ASCII.GetBytes(str);

        foreach(int c in asciiBytes)
        {
            total = total + c;
            total = total * (5 * (c ^ 2) / (c*6));
        }
        return Math.Round(total);
    }
这是用来得到一个字符串ASCII值的总数,但在这一过程中做一些数学运算,而不仅仅是相加。我需要它来返回总数,但当前正在返回0。如何使其返回正确的值?(PS:它需要返回一个整数,但可以是double的数据类型,以便以后转换。基本上只需要它返回一个整数。)(PSPS:我不知道字符串是什么,由最终用户决定)


_

向其中一个整数添加双精度

private double getTotal(string str)
        {
            double total = 0;
            byte[] asciiBytes = Encoding.ASCII.GetBytes(str);

            foreach (int c in asciiBytes)
            {
                total = total + c;
                total = total * ((double)5 * (c ^ 2) / (c * 6));
            }
            return Math.Round(total);
        }

你可能误解了^符号。它代表按位异或,而不是指数运算。如果要使用后者,请使用以下命令:

total = total * (5 * (Math.Pow (c, 2) / (c * 6));
但是,您也可以将其写得更短/更漂亮/更高效:

total *= (5 * (c * c) / (6 * c));
我替换了
Pow
,因为它比简单的乘法慢,并且使用了赋值运算符

此外,方程本身可以简化:

total *= c * (5 / 6);
但是,您仍应将数字标记为双倍,因为5/6将导致0,否则:

total *= c * (5.0 / 6.0)
有关C#中求幂的更多信息,请查看


顺便说一句,^符号取下数字的每一位并进行比较。如果第一位或第二位为1,则新值将为1,但不是两位都为1


因此,例如0101 xor 1110将导致1011。您有铸造问题。c变量是整数。你的问题在
total=total*(5*(c^2)/(c*6))表达式

因为内部结果
(c^2)
(c*6)
不是双精度的,所以当除法结果具有浮点值(如0.nnnnn)时,最终结果不是双精度的,并且只得到数字的实部0。作为整数的结果表达式
(5*(c^2)/(c*6))
为0。最后表达式为
total=total*(0)

在代码中使用内部铸件 将代码替换为以下内容:

total = total * (5 * ((double)(c ^ 2)) / ((double)(c * 6)));
请运行以下代码

    static private double getTotal(string str)
    {
        double total = 0;
        byte[] asciiBytes = Encoding.ASCII.GetBytes(str);

        foreach (int c in asciiBytes)
        {
            double dC = c;
            total = total + c;
            double cXor2 = c ^ 2;
            double c6 = c * 6;
            double fiveCXor2 = 5 * cXor2;
            double semiFinal = fiveCXor2 / c6;
            double final = total * semiFinal;

            Console.WriteLine("c = " + (c).ToString());
            Console.WriteLine("c ^ 2 = " + (cXor2).ToString());
            Console.WriteLine("c * 6 = " + (c6).ToString());
            Console.WriteLine("5 * (c ^ 2) = " + (fiveCXor2).ToString());
            Console.WriteLine("semi final = " + semiFinal);
            Console.WriteLine("final = " + final);
            Console.WriteLine("--------------------------------------------");
            total = total * (5 * (c ^ 2) / (c * 6));
            Console.WriteLine("TOTAL = " + total);
            Console.WriteLine("--------------------------------------------");
        }
        return Math.Round(total);
    }
样本结果为:

c = 97
c ^ 2 = 99
c * 6 = 582
5 * (c ^ 2) = 495
semi final = 0.850515463917526
final = 82.5
--------------------------------------------
TOTAL = 0
--------------------------------------------
c = 98
c ^ 2 = 96
c * 6 = 588
5 * (c ^ 2) = 480
semi final = 0.816326530612245
final = 80
--------------------------------------------
TOTAL = 0
--------------------------------------------
正如你所看到的,问题在于铸造

由于c变量为int铸造程序为:

step 1
[double] = [double] * ([int] * ([int] ^ [int] ) / ([int] * [int] )) 
total    = total    * (5     * (c     ^ 2     ) / (c     * 6     ));

step 2
[double] = [double] * ([int] * ([int]) / ([int] )) 
total    = total    * (5     * (X)     / (Y)    );

step 3
[double] = [double] * ([int] * [int])) 
total    = total    * (5     * XdivY    );
**CASTING PROBLEM : In this step the XdivY is integer and when the result is 0.1234 the INT     result is 0**

step 4
[double] = [double] * ([double])) 
total    = total    * (5mulXdivY    );    
here c# casting the 5mulXdivY  0  to double but the result is zero

step 5
[double] = [double] 
total    = 0

问题在于代码中的这一行

total = total * (5 * (c ^ 2) / (c*6));
c^2
返回的值小于
c*6
。现在运算符
/
是整数除法,因此smallnumber/largenumber的结果将始终返回零。这将使变量total的值在循环的每次迭代中都为零。像这样更改代码,它将为您提供预期的结果

private double getTotal(string str)
        {
            double total = 0;
            byte[] asciiBytes = Encoding.ASCII.GetBytes(str);

            foreach (int c in asciiBytes)
            {
                total = total + c;
                total = total * (5 * (double)(c ^ 2) / (double)(c * 6));
            }
            return Math.Round(total);
        }

希望有帮助。

你认为
c^2
有什么作用?(如果你认为这是异或,你是对的)
数学。Pow(c,2)
可能是本温和暗示的,或者我应该说是猜测。如果它平方,方程可以简化。c^2/c=c。整个方程可以归结为
total*(5/6)*c
,因为
c^2
c
大致相同,很可能
5*(c^2)
小于
6*c
,然后整数除法的结果为零。@EdPlunkett:这似乎是某种类型的散列函数,XOR在散列中并不少见。为什么要否决投票?这确实有效。“(5*(c^2)/(c*6))”这个表达式操作“int”,所以当你在这个表达式中执行c^2或任何其他操作时,它实际上是int,并自动被截断为int。你需要添加双框来更改它。我没有投反对票,但是
(double)5
是一种相当愚蠢的编写
5.0
的方式,这里并不重要,关键是它是int,如果它只是int,例如,表达式(double)中的“c”将使它可以理解,但5.0是一种特殊情况。
5.0
(double)5
可读性强得多<代码>5d
也更容易阅读。您应该将
^
更改为
Math.Pow
,正如在对问题的评论中所讨论的那样。@艾米:如果您将
^
视为幂运算,它会立即简化,这一事实表明,它可能真的应该保留为XOR。您确定真实的部分吗?我认为这只是复数的问题。我添加了一些额外的信息。但是,我仍然认为它不是实数部分,而是整数部分。(参见此处示例:)@MetaColon我的英语很差,这是我的错误。很抱歉