Tôi có một chương trình cố gắng thu nhỏ doublexuống một con số mong muốn. Đầu ra tôi nhận được là NaN.

Bạn đang xem: Nan là gì

Không gì NaNcó nghĩa là trong Java?

Có một mô tả tốt về NaN và các cạm bẫy phổ biến khi sử dụng NaN trong Java: ppkwok.blogspot.co.uk/2012/11/…
Nếu bạn đang hỏi “NaN có gì tốt?” trong Java (hoặc bất kỳ ngôn ngữ nào khác), tôi có thể cung cấp cho bạn một trường hợp sử dụng rất hữu ích: khi tôi có mảng float 2-D, nhưng phép tính của tôi không có giá trị có ý nghĩa đối với một số phần của mảng 2-D đó, Tôi sẽ điền giá trị đó bằng “NaN”. Điều này có thể được sử dụng để báo hiệu cho những người dùng xuôi dòng về phép tính của tôi (chẳng hạn như khi nó được chuyển thành hình ảnh raster) “không chú ý đến giá trị tại thời điểm này”. Rất hữu ích!

Lấy từ trang này :

“NaN” là viết tắt của “not a number”. “Nan” được tạo ra nếu một phép toán dấu chấm động có một số tham số đầu vào khiến hoạt động tạo ra một số kết quả không xác định. Ví dụ, 0,0 chia cho 0,0 là không xác định về mặt số học. Lấy căn bậc hai của một số âm cũng không xác định.

Ngoài ra, NaN được định nghĩa bởi Tiêu chuẩn IEEE cho Số học Dấu phẩy động (IEEE 754) khá rõ ràng mà Java tuân theo một cách mù quáng. Đọc tiêu chuẩn sẽ mở ra cho bạn rất nhiều thứ, nhiều giá trị của 0 là một trong những thứ.
Ngoài ra, NaNcó tính chất thú vị là “số” duy nhất không giống với chính nó khi so sánh. Do đó, một thử nghiệm phổ biến (và trong nhiều ngôn ngữ là duy nhất) nếu một số xlà NaNnhư sau:boolean isNaN(x){return x != x;}
… “Lấy căn bậc hai của số âm là không xác định (trong số học)” … Không phải! nó thực sự ivà một số ngôn ngữ như python đối phó rất tốt với nó … Nó có thể không phải là trường hợp của javabạn
RafaelT Tôi muốn nói rằng nó không được xác định trong số học không phức tạp. Không có cách nào để gán một số phức cho float hoặc double trong Java. Python được nhập động, do đó có thể chỉ trả về một số phức trong trường hợp này.

NaNcó nghĩa là “Không phải số” và về cơ bản là đại diện của một giá trị dấu phẩy động đặc biệt trong tiêu chuẩn dấu chấm động IEE 754 . NaN thường có nghĩa là giá trị là thứ không thể được biểu thị bằng một số dấu phẩy động hợp lệ.

Một chuyển đổi sẽ dẫn đến giá trị này, khi giá trị được chuyển đổi là giá trị khác, ví dụ: khi chuyển đổi một chuỗi không đại diện cho một số.

NaNcó nghĩa là “Không phải là Số” và là kết quả của các phép toán không xác định trên các số dấu phẩy động, chẳng hạn như chia 0 cho 0. (Lưu ý rằng trong khi phép chia một số khác 0 cho không cũng thường không được xác định trong toán học, nó không dẫn đến NaN mà là dương hoặc âm vô cùng).

NaNcó nghĩa là “Không phải số”. Đó là một giá trị dấu phẩy động đặc biệt có nghĩa là kết quả của một phép toán không được xác định hoặc không thể biểu diễn dưới dạng số thực.

Xem ở đây để giải thích thêm về giá trị này.

NaN là viết tắt của Not a Number. Nó được sử dụng để biểu thị bất kỳ giá trị nào không được xác định về mặt toán học. Như chia 0,0 cho 0,0. Bạn có thể xem tại đây để biết thêm thông tin: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm

Đăng chương trình của bạn ở đây nếu bạn cần thêm trợ giúp.

Có nghĩa không phải là một con số. Nó là một đại diện phổ biến cho một giá trị số không thể có trong nhiều ngôn ngữ lập trình.

Xem thêm: Swagbucks là gì

Ví dụ tối thiểu có thể chạy được

Điều đầu tiên bạn phải biết, đó là khái niệm NaN được thực hiện trực tiếp trên phần cứng CPU.

Tất cả các CPU hiện đại chính dường như tuân theo IEEE 754 chỉ định các định dạng dấu chấm động và NaN, chỉ là các giá trị float đặc biệt, là một phần của tiêu chuẩn đó.

Do đó, khái niệm này sẽ rất giống nhau trên bất kỳ ngôn ngữ nào, bao gồm cả Java chỉ phát ra mã dấu phẩy động trực tiếp đến CPU.

Trước khi tiếp tục, trước tiên bạn có thể muốn đọc các câu trả lời tôi đã viết sau đây:

Bây giờ cho một số hành động Java. Hầu hết các chức năng quan tâm không có trong ngôn ngữ cốt lõi đều nằm bên trong java.lang.Float.

Nan.java

import java.lang.Float;import java.lang.Math;public class Nan { public static void main(String args) { // Generate some NaNs. float nan = Float.NaN; float zero_div_zero = 0.0f / 0.0f; float sqrt_negative = (float)Math.sqrt(-1.0); float log_negative = (float)Math.log(-1.0); float inf_minus_inf = Float.POSITIVE_INFINITY – Float.POSITIVE_INFINITY; float inf_times_zero = Float.POSITIVE_INFINITY * 0.0f; float quiet_nan1 = Float.intBitsToFloat(0x7fc00001); float quiet_nan2 = Float.intBitsToFloat(0x7fc00002); float signaling_nan1 = Float.intBitsToFloat(0x7fa00001); float signaling_nan2 = Float.intBitsToFloat(0x7fa00002); float nan_minus = -nan; // Generate some infinities. float positive_inf = Float.POSITIVE_INFINITY; float negative_inf = Float.NEGATIVE_INFINITY; float one_div_zero = 1.0f / 0.0f; float log_zero = (float)Math.log(0.0); // Double check that they are actually NaNs. assert Float.isNaN(nan); assert Float.isNaN(zero_div_zero); assert Float.isNaN(sqrt_negative); assert Float.isNaN(inf_minus_inf); assert Float.isNaN(inf_times_zero); assert Float.isNaN(quiet_nan1); assert Float.isNaN(quiet_nan2); assert Float.isNaN(signaling_nan1); assert Float.isNaN(signaling_nan2); assert Float.isNaN(nan_minus); assert Float.isNaN(log_negative); // Double check that they are infinities. assert Float.isInfinite(positive_inf); assert Float.isInfinite(negative_inf); assert !Float.isNaN(positive_inf); assert !Float.isNaN(negative_inf); assert one_div_zero == positive_inf; assert log_zero == negative_inf; // Double check infinities. // See what they look like. System.out.printf(“nan 0x%08x %fn”, Float.floatToRawIntBits(nan ), nan ); System.out.printf(“zero_div_zero 0x%08x %fn”, Float.floatToRawIntBits(zero_div_zero ), zero_div_zero ); System.out.printf(“sqrt_negative 0x%08x %fn”, Float.floatToRawIntBits(sqrt_negative ), sqrt_negative ); System.out.printf(“log_negative 0x%08x %fn”, Float.floatToRawIntBits(log_negative ), log_negative ); System.out.printf(“inf_minus_inf 0x%08x %fn”, Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf ); System.out.printf(“inf_times_zero 0x%08x %fn”, Float.floatToRawIntBits(inf_times_zero), inf_times_zero); System.out.printf(“quiet_nan1 0x%08x %fn”, Float.floatToRawIntBits(quiet_nan1 ), quiet_nan1 ); System.out.printf(“quiet_nan2 0x%08x %fn”, Float.floatToRawIntBits(quiet_nan2 ), quiet_nan2 ); System.out.printf(“signaling_nan1 0x%08x %fn”, Float.floatToRawIntBits(signaling_nan1), signaling_nan1); System.out.printf(“signaling_nan2 0x%08x %fn”, Float.floatToRawIntBits(signaling_nan2), signaling_nan2); System.out.printf(“nan_minus 0x%08x %fn”, Float.floatToRawIntBits(nan_minus ), nan_minus ); System.out.printf(“positive_inf 0x%08x %fn”, Float.floatToRawIntBits(positive_inf ), positive_inf ); System.out.printf(“negative_inf 0x%08x %fn”, Float.floatToRawIntBits(negative_inf ), negative_inf ); System.out.printf(“one_div_zero 0x%08x %fn”, Float.floatToRawIntBits(one_div_zero ), one_div_zero ); System.out.printf(“log_zero 0x%08x %fn”, Float.floatToRawIntBits(log_zero ), log_zero ); // NaN comparisons always fail. // Therefore, all tests that we will do afterwards will be just isNaN. assert !(1.0f nan); assert !(1.0f == nan); assert !(1.0f > nan); assert !(nan == nan); // NaN propagate through most operations. assert Float.isNaN(nan + 1.0f); assert Float.isNaN(1.0f + nan); assert Float.isNaN(nan + nan); assert Float.isNaN(nan / 1.0f); assert Float.isNaN(1.0f / nan); assert Float.isNaN((float)Math.sqrt((double)nan)); }}GitHub ngược dòng .

Chạy với:

javac Nan.java && java -ea NanĐầu ra:

nan 0x7fc00000 NaNzero_div_zero 0x7fc00000 NaNsqrt_negative 0xffc00000 NaNlog_negative 0xffc00000 NaNinf_minus_inf 0x7fc00000 NaNinf_times_zero 0x7fc00000 NaNquiet_nan1 0x7fc00001 NaNquiet_nan2 0x7fc00002 NaNsignaling_nan1 0x7fa00001 NaNsignaling_nan2 0x7fa00002 NaNnan_minus 0xffc00000 NaNpositive_inf 0x7f800000 Infinitynegative_inf 0xff800000 -Infinityone_div_zero 0x7f800000 Infinitylog_zero 0xff800000 -InfinityVì vậy, từ điều này, chúng tôi học được một số điều:

Các phép toán trôi nổi kỳ lạ không có bất kỳ kết quả hợp lý nào cho NaN:

0.0f / 0.0fsqrt(-1.0f)

các phép toán kỳ lạ nằm trong giới hạn của cộng hoặc trừ vô cùng tuy nhiên lại cho + – vô cực thay vì NaN

1.0f / 0.0flog(0.0f)

0.0 gần như thuộc loại này, nhưng có thể vấn đề là nó có thể đi đến cộng hoặc trừ vô cùng, vì vậy nó được để là NaN.

nếu NaN là đầu vào của một hoạt động thả nổi, thì đầu ra cũng có xu hướng là NaN

có một số giá trị có thể cho NaN 0x7fc00000, 0x7fc00001, 0x7fc00002, mặc dù x86_64 dường như chỉ tạo ra 0x7fc00000.

Xem thêm: Affirmation Là Gì – Nghĩa Của Từ Affirmation

NaN và vô cùng có biểu diễn nhị phân tương tự.

Hãy chia nhỏ một vài trong số chúng:

nan = 0x7fc00000 = 0 11111111 10000000000000000000000positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000negative_inf = 0xff800000 = 1 11111111 00000000000000000000000 | | | | | mantissa | exponent | signTừ đó, chúng tôi xác nhận những gì IEEE754 chỉ định:

cả NaN và số nguyên đều có số mũ == 255 (tất cả các số đều)các số nguyên có định trị == 0. Do đó chỉ có hai số nguyên có thể có: + và -, được phân biệt bằng bit dấuNaN có phần định trị! = 0. Do đó có một số khả năng xảy ra, ngoại trừ phần định trị == 0 là vô cùng

NaN có thể là tích cực hoặc tiêu cực (bit trên cùng), mặc dù nó không ảnh hưởng đến hoạt động bình thường

Chuyên mục: Hỏi Đáp