2012-08-23 46 views
8

Không thể nghĩ ra một tiêu đề tốt hơn. Vấn đề là: Tôi có "int i", nó có thể là bất kỳ giá trị nào. mục tiêu của tôi là chuyển đổi "int i" thành số gần nhất có thể chia hết cho . Ví dụ: Tôi có i = 33. Sau đó, tôi sẽ được chuyển đến (16x2). Nhưng nếu tôi nhận được i = 50, thì nó sẽ được chuyển thành (16x3).Java - Cách kiểm tra xem một bộ phận có phải là một số nguyên hay một phao không?

tôi đã cố gắng rất nhiều điều ví dụ:

for (int x = i; x < 999; x++){ 
if ((i - x)/16 *is an integer*){ 
i = i - x; 
} 

Nhưng tôi không biết làm thế nào để kiểm tra xem nó một số nguyên. Vì vậy, có lẽ mã trước đây của tôi làm việc, nhưng tôi chỉ cần tìm một cách để kiểm tra nếu một số nguyên của nó hoặc một phao. Vì vậy .. bất kỳ trợ giúp được đánh giá cao.

+4

Phân chia hai int sẽ luôn có kết quả int. Bạn có thể sử dụng modulus ('%') để thay thế. – GriffeyDog

+0

FWIW, tôi khuyên bạn nên thử một cách tiếp cận khác để giải quyết vấn đề này. Cách tiếp cận này của vòng lặp để tìm một số bạn có thể trừ từ i để có được bội số của 16 là khủng khiếp không hiệu quả. Và nếu đa số gần nhất của 16 lớn hơn tôi thì sao? – Alex

Trả lời

5

Vì tất cả ints mà được chia hết cho 16 sẽ có họ 4 bit cuối cùng tất cả các thiết lập để 0. bạn có thể thực hiện những gì bạn muốn mà không một vòng lặp hoặc thậm chí là một tuyên bố nếu:

i &= 0xfffffff0; // Sets i to the greatest multiple of 16 less than i, or 0 for i < 16 

Ví dụ:

int i = 50; 
i &= 0xfffffff0; // i == 48 

i = 39; 
i &= 0xfffffff0; // i == 32 

i = 16; 
i &= 0xfffffff0; // i == 16 
+0

Hoạt động hoàn hảo! – user1541106

4

(i - x)/16 là số nguyên khi phần còn lại của (i - x)/16 là 0. Sử dụng% (mô đun) điều hành như:

if((i - x)%16 == 0) { 
    // (i-x)/16 is integer 
} 
12

Sử dụng toán tử mod. Mod cung cấp cho bạn phần còn lại của một phép toán phân chia.

public boolean isEvenlyDivisable(int a, int b) { 
    return a % b == 0; 
} 
1

Để tìm hiểu xem một số có phân chia đồng đều hay không, hãy xem các câu trả lời khác, Modulo (%) là cách để thực hiện điều đó.

Để làm những gì bạn muốn làm ở trên, bạn không cần một vòng lặp:

public int nearestDivider(final int input) 
{ 
    final int multiple = input/16; // this will divide by 16 and it's integer math, so it loses the decimal 
    return multiple * 16; 
} 

Đó sẽ trở lại 48 nếu bạn cho nó 50 như ví dụ của bạn.

Nếu bạn thực sự muốn gần sau đó bạn sẽ phải làm một số điểm phân chia nổi

public int nearestDivider(final int input) 
{ 
    final int multiple = Math.round((float) input/16); 
    return multiple * 16; 
} 

Bây giờ 46 trở về 48, 149 lợi nhuận 144, vv

+0

Tùy thuộc vào định nghĩa "gần nhất", bạn có thể cần thêm 16. – Alex

+0

Đúng, ví dụ của anh ấy (và mã) dường như cho biết, anh ấy muốn gần nhất hoặc bằng ... – xbakesx

+0

Vâng, thật khó để suy ra ý định từ kích thước mẫu là 2 ... – Alex

4

Có một số vấn đề nổi bật với mã ban đầu của bạn:

  1. Nếu bạn làm tròn xuống bội số gần nhất là 16, nó theo sau giá trị cao nhất bạn có thể có hành động là 15. Do đó ranh giới trên của vòng lặp của bạn tối đa là 15.
  2. Như những người khác đã lưu ý bạn có thể sử dụng toán tử modulo (%) để xác định giá trị chính xác để trừ từ một giá trị đã cho để làm tròn nó xuống gần nhất bội số của 16. Điều này loại bỏ sự cần thiết cho một vòng lặp hoàn toàn.
  3. Nhưng vì 16 là lũy thừa 2 và vì số nguyên được biểu diễn dưới dạng số nhị phân có 32 chữ số (tức là 32 bit), bạn có thể tính giá trị trực tiếp hơn bằng cách sử dụng bitmask để loại bỏ bất kỳ chữ số nào nhỏ hơn 16 trong con số. Trong Java, bạn có thể sử dụng toán tử nhị phân & cho mục đích đó như sau: i & 0xfffffff0. Điều này sẽ bằng không trong 4 chữ số cuối cùng (số đại diện: 8-4-2-1), có hiệu quả làm tròn số của bạn xuống giá trị gần nhất chia hết cho 16.
  4. Nếu bạn cần thực hiện phân chia số nguyên và bỏ qua phần còn lại, bạn chỉ cần thay đổi (>>) bằng 4 bit để thực hiện điều đó.
0

Nếu bạn cần nhiều gần 16, sau đó bạn có hai trường hợp để đối phó với bội số lẻ của 8. 1. 8 trở thành 16, 24 trở thành 32 2. 8 trở thành 0, 24 trở thành 16

Đối với người đầu tiên:

int j = ((i+8)/16)*16; 

Trong trường hợp thứ hai:

int j = ((i+7)/16)*16; 

Nếu bạn muốn luôn luôn XUỐNG XUỐNG (tức là 17 trở thành 16, và 15 trở thành 0):

int j = (i/16)*16; 

Nếu bạn muốn luôn luôn làm tròn UP (không phải những gì ví dụ bạn nói), bạn đã có thể làm điều này thay vì:

int j = ((i+15)/16)*16; 
0

Để kiểm tra xem một kết quả phân chia ngẫu nhiên trong một số nguyên hoặc phần bạn cần như sau:

int n = 9; 
int p = 3; 

if (n % p == 0) { 
    //the division results in an integer. 
} 
else 
{ 
    //the division results in a fraction. 
} 

Bạn có thể làm điều này như một sự thay thế:

if (n/p == Math.ceil((double) n/(double) p)) { 
    //the division results in an integer. 
} 
else 
{ 
    //the division results in a fraction. 
} 

Một cần Math .ceil() và không tròn hoặc sàn, bởi vì một phân chia số nguyên gần bằng với một tầng và phân số sẽ được làm tròn xuống và xuất hiện dưới dạng 'phân chia số nguyên'.

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