Từ 1 tới 9 trên tổng số 9 kết quả

Đề tài: Thắc mắc về kiểu float trong C

  1. #1
    Ngày gia nhập
    08 2011
    Bài viết
    17

    Mặc định Thắc mắc về kiểu float trong C

    Mình muốn lấy phần thập phân của một số thực. Mình đã dùng hàm floor rồi, dùng cả cách ép kiểu rồi trừ đi cũng không ra. Cụ thể là mình nhập vào số 130.1 và muốn lấy số 0.1
    Dùng hàm floor: a = a - floor(a);
    Ép kiểu: a = a - int(a);
    Cả 2 đều cho ra cùng 1 kết quả: 0.100006
    a mình khai báo kiểu float(và dùng dev-c), mình cũng đã nghĩ đến việc khai báo a kiểu double nhưng mà có khúc mắc. Tiện đây cho mình hỏi lấy trị tuyệt đối của 1 số kiểu double thì dùng hàm gì, và muốn tham chiếu đến 1 số kiểu double thì như nào? Mình chỉ biết vs kiểu float thì dùng fabs và %f nhưng kiểu double thì mình chưa thấy ở đâu nhắc đến :( . Mong mọi người giúp đỡ!
    Đã được chỉnh sửa lần cuối bởi Pop : 28-10-2011 lúc 08:57 PM.
    Code:
    Sờ tu pít :(

  2. #2
    Ngày gia nhập
    10 2011
    Bài viết
    552

    Theo ngu kiến của mình thì bạn nên khai báo a là kiểu double .
    Bởi 1 số thực chấm động trong C++ nó sẽ hiểu đó là số double.
    Và phép gán đấy nó sẽ warning : Sẽ có sự cắt mất dữ liệu khi convert từ double sang float.
    Giờ bạn khai báo a thành double nó sẽ ra chính xác .

    Mình cũng chả hiểu tại sao biểu diễn 1 số thực ví dụ như 0.1 , 11.1, 111.1 ... hoàn toàn nằm trong miền trị của Float mà trình biên dịch lại hiểu nó là Double .
    Về điều nay mong cao thủ nào đó Explain giùm với !!!

    Nếu C++ thì abs sẽ là tải bội và nó nhận dc mọi kiểu tham số truyền vào.
    Ở C nếu bạn ko biết hàm nào thì define 1 phát . #define ABS(a) ((a>0)?a:-a);

  3. #3
    Ngày gia nhập
    08 2011
    Bài viết
    17

    130.1 chỉ là ví dụ thôi mà bạn, chẳng là mình đang làm bài chuyển đổi từ 1 số thực sang dạng nhị phân theo chuẩn IEEE 754. Mọi thứ thì OK hết cả rồi nhưng mà đến cái này thì tiu nghỉu. Chính vì nó dư 0.00006 đó nên sau mấy lần nhân vs 2 nó bị làm tròn dần lên và làm cho 6 bit cuối cùng(trong trường hợp 130.1 này) bị sai. Cho mình hỏi kĩ hơn về #define ABS(a) ((a>0)?a:-a); mình nhớ #define là khai báo hằng mà mình cần trị tuyệt đối của 1 biên kiểu double :(
    Code:
    Sờ tu pít :(

  4. #4
    Ngày gia nhập
    10 2011
    Bài viết
    552

    Trích dẫn Nguyên bản được gửi bởi Pop Xem bài viết
    130.1 chỉ là ví dụ thôi mà bạn, chẳng là mình đang làm bài chuyển đổi từ 1 số thực sang dạng nhị phân theo chuẩn IEEE 754. Mọi thứ thì OK hết cả rồi nhưng mà đến cái này thì tiu nghỉu. Chính vì nó dư 0.00006 đó nên sau mấy lần nhân vs 2 nó bị làm tròn dần lên và làm cho 6 bit cuối cùng(trong trường hợp 130.1 này) bị sai. Cho mình hỏi kĩ hơn về #define ABS(a) ((a>0)?a:-a); mình nhớ #define là khai báo hằng mà mình cần trị tuyệt đối của 1 biên kiểu double :(
    Thì chính vì 1 số thực là IDE nó hiểu là Double nên khi convert từ số đó vào biến float thì nó gây ra hiện tượng đấy đấy

    Còn define thì bạn define thoải mái Ko nhất thiết phải là hằng

  5. #5
    Ngày gia nhập
    11 2008
    Bài viết
    3

    Trích dẫn Nguyên bản được gửi bởi clchicken Xem bài viết
    Theo ngu kiến của mình thì bạn nên khai báo a là kiểu double .
    Bởi 1 số thực chấm động trong C++ nó sẽ hiểu đó là số double.
    Và phép gán đấy nó sẽ warning : Sẽ có sự cắt mất dữ liệu khi convert từ double sang float.
    Giờ bạn khai báo a thành double nó sẽ ra chính xác .

    Mình cũng chả hiểu tại sao biểu diễn 1 số thực ví dụ như 0.1 , 11.1, 111.1 ... hoàn toàn nằm trong miền trị của Float mà trình biên dịch lại hiểu nó là Double .
    Về điều nay mong cao thủ nào đó Explain giùm với !!!

    Nếu C++ thì abs sẽ là tải bội và nó nhận dc mọi kiểu tham số truyền vào.
    Ở C nếu bạn ko biết hàm nào thì define 1 phát . #define ABS(a) ((a>0)?a:-a);
    Bạn ơi, x khai báo double thì đúng rồi
    Nhưng lấy phần lẻ thì có 2 trường hợp chứ
    x>0 thì phần lẻ = x - floor(x)
    x<=0 thì phần lẻ = 1- (x-floor(x))

  6. #6
    Ngày gia nhập
    08 2011
    Bài viết
    17

    Mặc định Thắc mắc về kiểu float trong C

    Trích dẫn Nguyên bản được gửi bởi khucnam Xem bài viết
    Bạn ơi, x khai báo double thì đúng rồi
    Nhưng lấy phần lẻ thì có 2 trường hợp chứ
    x>0 thì phần lẻ = x - floor(x)
    x<=0 thì phần lẻ = 1- (x-floor(x))
    Mình sẽ lấy trị tuyệt đối trước rồi mới tới công việc lấy phần thập phân bạn ạ. Vừa mình đọc thêm mấy bài trong 4rum nên cũng hiểu được thêm chút ít. Tiện đây cho mình hỏi về chính xác đơn(32 bit) và chính xác kép(64bit), và tại sao mà khi convert từ float sang double lại có sai số như vậy?
    Code:
    Sờ tu pít :(

  7. #7
    Ngày gia nhập
    04 2010
    Bài viết
    1,534

    Trích dẫn Nguyên bản được gửi bởi Pop Xem bài viết
    Mình muốn lấy phần thập phân của một số thực. Mình đã dùng hàm floor rồi, dùng cả cách ép kiểu rồi trừ đi cũng không ra. Cụ thể là mình nhập vào số 130.1 và muốn lấy số 0.1
    Dùng hàm floor: a = a - floor(a);
    Ép kiểu: a = a - int(a); {1}
    Cả 2 đều cho ra cùng 1 kết quả: 0.100006 {2}
    a mình khai báo kiểu float(và dùng dev-c), mình cũng đã nghĩ đến việc khai báo a kiểu double nhưng mà có khúc mắc. Tiện đây cho mình hỏi lấy trị tuyệt đối của 1 số kiểu double thì dùng hàm gì {3}, và muốn tham chiếu đến 1 số kiểu double thì như nào? Mình chỉ biết vs kiểu float thì dùng fabs và %f nhưng kiểu double thì mình chưa thấy ở đâu nhắc đến :( . Mong mọi người giúp đỡ!
    {1} thuật toán này rất nguy hiểm, không bao giờ nên dùng, nếu a lớn quá thì (int)a sẽ bị tràn số

    {2} làm toán số thực thì phải chấp nhận những trường hợp sai số như vậy. Cái này đã nhiều lần giải thích, chịu khó tìm một chút sẽ thấy

    Trong thư viện math của C có hàm modf dùng để tách double thành phần thập phân và phần nguyên, hàm tương đương cho float là modff

    Prototype: double modf (double value, double *iptr)
    Hàm tách value và trả về phần thập phân. Phần nguyên được chứa trong iptr, lưu ý đây là cách truyền tham biến của C

    vd
    double x = 31415.9265, thapPhan, nguyen;
    thapPhan= modf(x, &nguyen);


    {3} trong C, fabs chính là hàm dùng cho kiểu double. Float dùng hàm fabsf
    trong C++, hàm fabs được viết chồng để dùng cho cả hai loại.

  8. #8
    Ngày gia nhập
    08 2011
    Bài viết
    17

    Trích dẫn Nguyên bản được gửi bởi VoTichSu Xem bài viết
    Hàm tách value và trả về phần thập phân. Phần nguyên được chứa trong iptr, lưu ý đây là cách truyền tham biến của C

    vd
    double x = 31415.9265, thapPhan, nguyen;
    thapPhan= modf(x, &nguyen);
    Rất cám ơn a đã giải thích và cho biết thêm về hàm modf. Em đổi sang double rồi floor cũng được rồi. Nhưng em còn khúc mắc nữa là chính xác đơn và chính xác kép nó khác nhau như nào, lúc em đọc đến thì không hiểu mà tìm trên google không thấy có...
    Code:
    Sờ tu pít :(

  9. #9
    Ngày gia nhập
    04 2010
    Bài viết
    1,534

    Độ chính xác tùy theo máy dùng bao nhiêu bit để lập phần trị (mantissa) - máy lấy ra một số bit để lập phần lúy thứa 10 (exponential), chỗ bit còn lại dùng đẻ chứa phần trị

    Nhớ mang máng thì tiêu chuẩn là:

    float dùng khoảng 24 bit để chứa phần trị ---> độ chính xác khoảng 6 số

    double dùng khoảng 53 bít để chứa phần trị ---> độ chính xác khoảng 15 số

Các đề tài tương tự

  1. Tạo biến ngẫu nhiên kiểu float sử dụng hàm rand() trong C/C++ như thế nào?
    Gửi bởi 50902116 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 24
    Bài viết cuối: 27-02-2014, 04:35 PM
  2. Database làm thế nào để dữ liệu trong sql với kiểu float có 3 chữ số sau dấu chấm
    Gửi bởi troy91 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 3
    Bài viết cuối: 07-06-2011, 11:56 PM
  3. float và double trong C++: warning C4244: conversion from 'double' to 'float'
    Gửi bởi dungtimtoinua2008 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 10
    Bài viết cuối: 18-03-2010, 11:25 PM
  4. Tạo một số float ngẫu nhiên | Tạo Random số float
    Gửi bởi md_vn trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 20
    Bài viết cuối: 06-06-2008, 11:00 AM
  5. Lấy sau dấu phẩy k chữ số (trong decimal,float...) như thế nào?
    Gửi bởi anhxtanh3087 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 2
    Bài viết cuối: 05-06-2008, 11:09 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn