2011-12-18 31 views
8

Đây là vấn đề: Tổng số trò chơi có thể được chơi bởi bất kỳ số lượng người. Nó bắt đầu với tổng cộng 100 và mỗi người chơi lần lượt làm cho một sự dịch chuyển số nguyên giữa -20 và 20 cho tổng số đó. Người chiến thắng là người chơi có điều chỉnh làm cho tổng bằng 5. Chỉ sử dụng ba biến đưa ra: tổng điều chỉnh truy cập Dưới đây là những gì tôi có cho đến nay:Xác định xem phao có phần phân đoạn không?

#include <stdio.h> 
int main (void) 
{ 
    int counter=0; 
    float adj; 
    int ttl=100; 

    printf("You all know the rules now lets begin!!!\n\n\nWe start with 100. What is\n"); 

    while (ttl!=5) 
    { 
     printf("YOUR ADJUSTMENT?"); 
     scanf("%f",&adj); 
     counter++; 
     if (adj<=20 && adj>=-20) 
     { 
     ttl=ttl+adj; 
     printf("The total is %d\n",ttl); 
     } 
     else 
     { 
     printf ("I'm sorry. Do you not know the rules?\n"); 
     } 
    } 
    printf("The game is won in %d steps!",counter); 

} 

Những gì tôi cần: Khi một số thập phân được nhập vào số còn lại. Làm cách nào để xác định xem một phao có phần phân đoạn hay không.

+0

Ở cấp độ nhị phân, không có số dấu phẩy động nào có số thập phân. http://en.wikipedia.org/wiki/IEEE_754-2008 –

+0

Chúng ta đang nói về phao nổi ở đây. Nó luôn luôn "có một số thập phân". Thay vào đó hãy sử dụng 'double'. (FYI @Chris và tôi có ý giống nhau) –

+2

@TomvanderWoerdt: 'double' tạo nên sự khác biệt nào? –

Trả lời

3

nếu bạn muốn biết liệu một số thực x không có phần phân đoạn hay không, hãy thử x==floor(x).

+0

@ sarnold, không phải trong trường hợp này, không. Các số nguyên có thể được biểu diễn dưới dạng 'float' hoặc' double' được biểu diễn chính xác và 'floor' không gây nhầm lẫn với những số không có. – lhf

+0

Cảm ơn bạn đã trả lời chi tiết hơn. :) – sarnold

+0

Tôi không tin rằng tất cả các câu trả lời sử dụng kỹ thuật này là mạnh mẽ. Nếu 'adj' thực sự là kết quả của phép tính trung gian, nó có thể được giữ trong thanh ghi có độ chính xác mở rộng. Vì vậy, so sánh có thể trả về 'false', mặc dù khi' adj' được kiểm tra sau đó, nó thực sự trở thành một giá trị số nguyên. –

10
#include <stdio.h> 
#include <math.h> 

int main() 
{ 
    float param, fractpart, intpart; 

    param = 3.14159265; 
    fractpart = modff (param , &intpart); 
    return 0; 
} 

http://www.cplusplus.com/reference/clibrary/cmath/modf/

modff thấy phần phân đoạn, vì vậy tôi đoán thử nghiệm cho dù đó là bằng 0 hoặc null sẽ trả lời câu hỏi của bạn.

+0

bạn nên là câu trả lời được chấp nhận, cảm ơn! – VivienLeger

13

Bạn có thể truyền float thành int và sau đó so sánh nó với biến ban đầu của bạn. Nếu chúng giống nhau thì không có phần phân đoạn.

Bằng cách sử dụng phương pháp này, không cần biến tạm thời hoặc cuộc gọi hàm.

float adj; 

    ....  

    if (adj == (int)adj) 
    printf ("no fractional!\n"); 
    else 
    printf ("fractional!\n"); 

Giải thích

Từ một int không thể xử lý các phần phân đoạn giá trị của float của bạn sẽ được rút ngắn thành một int (như là một ví dụ (float)14.3 sẽ được rút ngắn thành (int)14).

Khi so sánh 14 đến 14.3 hiển nhiên là chúng không có giá trị như nhau và có "phân số!" sẽ được in.

+2

Bạn không cần phân đoạn rõ ràng quay lại 'float', nó sẽ tự động được truyền. Giải pháp của bạn không sai, tôi chỉ viết nó là 'f == (int) f', mà tôi thấy dễ đọc và dễ hiểu hơn. – Kevin

+0

@Kevin Tôi đã chỉnh sửa rằng đồng thời bạn đã viết nhận xét của mình, sau đó tôi đã thêm một số thông tin khác về vấn đề này, cảm ơn. –

+2

Tôi không thuyết phục tất cả các câu trả lời sử dụng kỹ thuật này là mạnh mẽ.Nếu 'adj' thực sự là kết quả của phép tính trung gian, nó có thể được giữ trong thanh ghi có độ chính xác mở rộng. Vì vậy, so sánh có thể trả về 'false', mặc dù khi' adj' được kiểm tra sau đó, nó thực sự trở thành một giá trị số nguyên. –

0

Sử dụng scanf() có vấn đề. Nếu người dùng nhập -5 +10 -15 -15 vào dòng đầu vào đầu tiên, sau đó nhấn trả lại, bạn sẽ xử lý 4 số lần lượt với scanf(). Đây có thể không phải là những gì bạn muốn. Ngoài ra, tất nhiên, nếu người dùng nhập +3 or more, thì chuyển đổi đầu tiên sẽ dừng khi không gian được đọc và tất cả các chuyển đổi tiếp theo sẽ không thành công trên o hoặc or và mã sẽ đi vào vòng lặp. Bạn phải kiểm tra giá trị trả lại từ scanf() để biết liệu nó có thể chuyển đổi bất kỳ thứ gì không.

Các vấn đề đọc trước đủ nghiêm trọng để tôi thay thế bằng cách sử dụng fgets() để đọc dòng dữ liệu và sau đó sử dụng sscanf() (thêm s là quan trọng) để phân tích cú pháp số.

Để xác định xem một số dấu chấm động có một phần phân đoạn cũng như một phần số nguyên, bạn có thể sử dụng modf() or modff() chức năng - thứ hai kể từ adj của bạn là một float:

#include <math.h> 

double modf(double x, double *iptr); 
float modff(float value, float *iptr); 

Giá trị trả về là phần phân đoạn đã ký của x; giá trị trong iptr là phần nguyên. Lưu ý rằng modff() có thể không có sẵn trong trình biên dịch (thư viện thời gian chạy) không hỗ trợ C99. Trong trường hợp đó, bạn có thể phải sử dụng doublemodf(). Tuy nhiên, có thể đơn giản để hạn chế người dùng nhập số nguyên với định dạng %d và loại số nguyên cho adj; đó là những gì tôi đã làm ngay từ đầu.

Một điểm chi tiết khác: bạn có thực sự muốn đếm số không hợp lệ trong tổng số lần thử không?

#include <stdio.h> 
#include <math.h> 

int main(void) 
{ 
    int counter=0; 
    int ttl=100; 

    printf("You all know the rules now lets begin!!!\n" 
      "\n\nWe start with 100. What is\n"); 

    while (ttl != 5) 
    { 
     char buffer[4096]; 
     float a_int; 
     float adj; 

     printf("YOUR ADJUSTMENT?"); 
     if (fgets(buffer, sizeof(buffer), stdin) == 0) 
      break; 
     if (sscanf("%f", &adj) != 1) 
      break; 
     if (adj<=20 && adj>=-20 && modff(adj, &a_int) == 0.0) 
     { 
      counter++; // Not counting invalid numbers 
      ttl += adj; 
      printf("The total is %d\n", ttl); 
     } 
     else 
     { 
      printf ("I'm sorry. Do you not know the rules?\n"); 
     } 
    } 

    if (ttl == 5) 
     printf("The game is won in %d steps!\n", counter); 
    else 
     printf("No-one wins; the total is not 5\n"); 
    return(0); 
} 

Rõ ràng, tôi rất muốn bỏ qua khả năng ai đó có thể nhập hơn 4095 ký tự trước khi nhập trở lại.

0

Tôi chỉ học C nên hãy cho tôi biết nếu tôi sai, xin vui lòng.

Nhưng nếu thay vì sử dụng

scanf("%f",&adj); 

nếu bạn sử dụng:

scanf("%d%d", &adj, &IsUndef); 

Do đó nếu người dùng gõ bất cứ điều gì khác hơn là một số nguyên & IsUndef sẽ không NULL bình đẳng và phải có một phần phân đoạn gửi người dùng đến người khác.

có thể.

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