2011-11-12 51 views
4

最近我發現C#的操作符%適用於double。試了一些東西,畢竟想出了這個測試:C#中的「%」操作對於數字類型雙重的含義

class Program 
{ 
    static void test(double a, double b) 
    { 
     if (a % b != a - b * Math.Truncate(a/b)) 
     { 
      Console.WriteLine(a + ", " + b); 
     } 
    } 
    static void Main(string[] args) 
    { 
     test(2.5, 7); 
     test(-6.7, -3); 
     test(8.7, 4); 
     //... 
    } 
} 

這個測試的一切工作。 是a % b總是等於a - b*Math.Round(a/b)?如果沒有,請向我解釋這個操作員是如何工作的。

編輯:回答詹姆斯L,我明白,這是一個模運算符和一切。我很好奇它是如何與雙,我理解的整數。

+0

http://en.wikipedia.org/wiki/Modulo_operation – Quasdunk

+0

做了一些更多的測試。事實證明,%b並不總是等同於 - b * Math.Truncate(a/b)。例如,它不適用於1.0和0.1。 – Sergey

回答

5

模運算符對浮點值的處理方式與整數相同。所以考慮一個簡單的例子:

4.5 % 2.1 

現在,4.5/2.1約等於2.142857

因此,該師的整數部分爲2減去2 * 2.1 4.5,你有滯留者, 0.3。

當然,這個過程受浮點代表性問題的影響,所以要小心 - 您可能會看到意想不到的結果。例如,看到這個問題在這裏問及堆棧溢出:Floating Point Arithmetic - Modulo Operator on Double Type


是A%B總是等同於 - B * Math.Round(A/B)?

不,它不是。下面是一個簡單的反例:

static double f(double a, double b) 
{ 
    return a - b * Math.Round(a/b); 
} 

static void Main(string[] args) 
{ 
    Console.WriteLine(1.9 % 1.0); 
    Console.WriteLine(f(1.9, 1.0)); 
    Console.ReadLine(); 
} 

至於模運算符是如何規定的,你需要參考C#規範精確的細節 - earlNameless's answer爲您提供了一個鏈接到。

這是我的理解a % b是基本等效的模浮點精度,以a - b*Math.Truncate(a/b)

+0

所以基本上%b總是等於a - b * Math.Round(a/b)? – Sergey

+2

不,不是。用Trunc替換Round,你應該在那裏,肯定是積極的'a'和'b'。 –

+1

可以肯定的是,%b總是等於a - b * Math.Truncate(a/b)? – Sergey

2

the MSDN page

模數運算符(%)計算通過除以第二 第一個操作數後的餘數。所有數字類型都具有預定義的模數 運算符。

而且

注意與雙類型相關的舍入誤差。

4

C# Language Specifications第200頁:

浮點餘:

float operator %(float x, float y); 
double operator %(double x, double y); 

下表列出了非零有限值,零,無窮的所有可能組合的結果,和NaN的。在表中,x和y是正的有限值。 z是x%y的結果,並計算爲x - n * y,四捨五入到最接近的可表示值,其中n是小於或等於x/y的最大整數。這種計算餘數的方法類似於用於整數操作數的方法,但不同於IEC 60559定義(其中n是最接近x/y的整數)。

相關問題