2012-06-25 40 views
8

Từ http://msdn.microsoft.com/en-us/library/system.math.pow.aspxMath.pow lấy một giá trị số nguyên

int value = 2; 
for (int power = 0; power <= 32; power++) 
    Console.WriteLine("{0}^{1} = {2:N0}", 
         value, power, (long) Math.Pow(value, power)); 

Math.pow mất đôi như các đối số, nhưng ở đây chúng tôi đang đi qua trong ints.

Câu hỏi: Có nguy cơ nào xảy ra lỗi làm tròn dấu phẩy động nếu có chuyển đổi tiềm ẩn xảy ra gấp đôi không?

Nếu có, nó là tốt hơn để sử dụng một cái gì đó như:

public static int IntPow(int x, uint pow) 
{ 
    int ret = 1; 
    while (pow != 0) 
    { 
     if ((pow & 1) == 1) 
      ret *= x; 
     x *= x; 
     pow >>= 1; 
    } 
    return ret; 
} 
+0

câu hỏi liên quan: http://stackoverflow.com/questions/383587/how-do-you-do-integer-exponentiation-in-c Một số đọc tốt trong câu hỏi đó và liên kết có liên quan – dash

+0

Xem thêm: http://stackoverflow.com/questions/936541/math-pow- – dash

+0

Và [this one] (http://stackoverflow.com/questions/4297454/c-sharp-math-pow-is -not-calculating-correct) về các lỗi làm tròn. –

Trả lời

3

Vâng, có một chuyển đổi ngầm sẽ tăng gấp đôi xảy ra, và có có một khả năng nổi điểm lỗi làm tròn như một kết quả.

Để xem liệu nó có đáng sử dụng phương pháp thay thế mà bạn đề xuất hay không, điều đó cụ thể đối với ứng dụng. Là một lỗi làm tròn điểm nổi hoàn toàn không thể chấp nhận được? Bạn sẽ sử dụng những con số phù hợp với int32 (không mất quá nhiều quyền hạn để tràn)?

+2

lỗi làm tròn dấu chấm động khi chuyển đổi int thành gấp đôi? xin vui lòng viết thêm về điều đó. –

+1

Nó không chỉ chuyển đổi một int thành một đôi, nó chuyển đổi một int thành một đôi và sau đó làm công cụ với nó. Ngay sau khi bạn bắt đầu thực hiện bất kỳ hoạt động nào (thêm/nhân/bất cứ điều gì), ít nhất có khả năng làm tròn lỗi. Kể từ khi nâng lên một sức mạnh có khả năng được chia thành một số lượng/số nhân, nó làm tăng xác suất và độ lớn của các lỗi dấu phẩy động. – Servy

+0

có nghĩa là chúng tồn tại với bất kỳ số IEEE 754 nào? –

-1
public static int IntPow(int number, uint power) 
     { 
      int result = 1; 
      for (int i = 0; i < power; i++) 
      { 
       result *= number; 
      } 
      return result; 
     } 

để dễ đọc!

+0

Có một lý do cho mã phụ - câu trả lời này là 'O (power)', trong khi mã trong câu hỏi nếu 'O (log (power))'. –

5

Không, không có khả năng xảy ra lỗi làm tròn do chuyển đổi gây ra cho double. double có thể biểu diễn chính xác tất cả các số nguyên nằm trong miền của chức năng nguồn.

5

Trong trường hợp đặc biệt của bạn, khi bạn đang tính toán 2 cho nguồn x, bạn có thể sử dụng một phép dịch trái đơn giản. Điều này sẽ đơn giản hóa mã của bạn để:

public static int TwoPowX(int power) 
{ 
    return (1<<power); 
} 
+0

Và trong dấu phẩy động, các lũy thừa của hai có thể được tính bằng số lượng nhỏ với 'ldexp'. Mà .NET không có, nhưng là khá dễ dàng để viết bằng cách sử dụng 'BitConverter.Int64BitsToDouble'. –

Các vấn đề liên quan