Làm cách nào để kiểm tra xem một số có đánh giá là vô hạn hay không?


94

Tôi có một loạt các phép tính Javascript (chỉ trong IE) hiển thị Infinity tùy thuộc vào lựa chọn của người dùng.

Làm cách nào để ngăn từ Infinityxuất hiện và 0.0thay vào đó là hiển thị ?

Câu trả lời:


174
if (result == Number.POSITIVE_INFINITY || result == Number.NEGATIVE_INFINITY)
{
    // ...
}

Bạn có thể sử dụng isFinitechức năng này thay thế, tùy thuộc vào cách bạn muốn điều trị NaN. isFinitetrả về falsenếu số của bạn là POSITIVE_INFINITY, NEGATIVE_INFINITYhoặc NaN.

if (isFinite(result))
{
    // ...
}

2
Tại sao sử dụng Number.(POSITIVE|NEGATIVE)_INFINITYthay vì -?Infinityhoặc -?1/0?
Eli Grey

5
@Eli: InfinityThuộc tính toàn cục không chỉ đọc, có nghĩa là nó có thể được xác định lại: Ví dụ: var x = 42; Infinity = 42; alert(x === Infinity);hiển thị "true" . (Phải thừa nhận rằng đó là một trường hợp khó hiểu và bất kỳ ai quyết định xác định lại Infinity, NaNv.v. nên mong đợi những điều kỳ lạ sẽ xảy ra.)
LukeH

Bỏ qua thực tế là Number.(POSITIVE|NEGATIVE)_INFINITYkhông chỉ đọc một trong hai, Infinity chỉ đọc trong chế độ nghiêm ngặt. Ngoài ra, còn -?1/0trường hợp tôi đã trình bày với bạn? Dù sao, bạn hầu như luôn luôn nên sử dụng isFinitethay thế.
Eli Grey

1
@Eli: Trong các thử nghiệm của tôi Number.POSITIVE_INFINITYvà ở chế độ Number.NEGATIVE_INFINITY chỉ đọc (thử nghiệm trên Chrome8, FF3.6 và IE8). Sử dụng 1/0hoạt động tốt nhưng nó sẽ không quá rõ ràng đối với những người bảo trì mã của bạn những gì bạn thực sự đang cố gắng kiểm tra. Tôi đồng ý rằng sử dụng isFinitehầu như luôn luôn là cách tốt hơn để làm mọi việc - đó là lý do tại sao tôi đã đề cập đến nó trong câu trả lời của mình - nhưng chỉ OP mới có thể quyết định liệu nó có đáp ứng yêu cầu của họ hay không.
LukeH

4
Chúng không phải là chỉ đọc (đọc: không thể định cấu hình ), chúng chỉ là những người truy cập có trình duyệt nhưng không có trình cài đặt. Bạn có thể xác định lại chúng với Object.defineProperty__defineGetter__. InfinityMặt khác, phi cấu hình trong chế độ nghiêm ngặt.
Eli Grey

9

Một đơn giản n === n+1hoặc n === n/0hoạt động:

function isInfinite(n) {
  return n === n/0;
}

Lưu ý rằng các nguyên tắc isFinite()đầu vào ép buộc các số. isFinite([])isFinite(null)cả hai đều là trueví dụ.


Câu trả lời này rõ ràng là sai. n === n+1đánh giá là true cho tất cả các số lớn hơn 2 ^ 53, tức là 1e30. Hack phân chia hoạt động, ngay cả đối với NaN và -Infinity. Tuy nhiên, câu trả lời của LukeH cung cấp cho bạn mã dễ đọc hơn.
tglas

@tglas Tại sao điểm cộng lại như vậy? Mừng là sư đoàn đã vững. IMO Mã của tôi dễ đọc hơn và bao hàm hơn vì toán học phổ biến hơn từ ngữ.
ryanve

1
Bởi vì phao IEEE 64bit có 53 chữ số nhị phân có nghĩa (xem en.wikipedia.org/wiki/IEEE_754 ), do đó n+1không thể được biểu diễn và phải làm tròn. Vâng, ngay cả các số nguyên cũng bị ảnh hưởng bởi lỗi làm tròn. Btw, tôi không nghĩ rằng mã của bạn là "bằng toán học", chỉ cần thử n === n/-0. Khi hoàn thành số thực với +/- inf, giới hạn của bạn không được xác định rõ ràng trừ khi dãy số 0 cơ bản được giả định là số dương.
tglas 13/09/18

Cảm ơn @tglas Tôi sẽ luôn thích JavaScript có thể chia hết cho 0 :)
ryanve 18/09/18

6

Trong ES6, Number.isFinite()Phương thức xác định xem giá trị được truyền vào có phải là một số hữu hạn hay không.

Number.isFinite(Infinity);  // false
Number.isFinite(NaN);       // false
Number.isFinite(-Infinity); // false

Number.isFinite(0);         // true
Number.isFinite(2e64);      // true

Bể từ ECMAScript 1
Mohamad

2

Trên thực tế n === n + 1 sẽ hoạt động đối với các số lớn hơn 51 bit, ví dụ:

1e16 + 1 === 1e16; // true
1e16 === Infinity; // false

3
Đây sẽ là một bình luận về câu trả lời của ryanve.
Gary

1

Tôi thích sử dụng Lodash vì nhiều lý do mã hóa phòng thủ cũng như tính dễ đọc. ES6 Number.isFiniterất tuyệt và không gặp vấn đề với các giá trị không phải số, nhưng nếu không thể sử dụng ES6, bạn đã có lodash hoặc muốn có mã ngắn gọn: _.isFinite

_.isFinite(Infinity); // false
_.isFinite(NaN); // false
_.isFinite(-Infinity); // false

_.isFinite(null); // false
_.isFinite(3); // true
_.isFinite('3'); // true

0

Tôi đã gặp phải một tình huống yêu cầu tôi kiểm tra xem giá trị có thuộc kiểu NaNhoặc không Infinitynhưng chuyển các chuỗi làm kết quả hợp lệ. Bởi vì nhiều chuỗi văn bản sẽ tạo ra dương tính giả NaN, tôi đã thực hiện một giải pháp đơn giản để tránh điều đó:

  const testInput = input => input + "" === "NaN" || input + "" === "Infinity";

Đoạn mã trên chuyển đổi các giá trị thành chuỗi và kiểm tra xem chúng có hoàn toàn bằng NaN hoặc Infinity hay không (bạn sẽ cần thêm một trường hợp khác cho vô cực âm).

Vì thế:

testInput(1/0); // true
testInput(parseInt("String")); // true
testInput("String"); // false

Bài đăng này không thực sự giải quyết câu hỏi thực tế ở đây và sẽ tốt hơn nếu là một bình luận dưới câu trả lời được chấp nhận. OP là về những con số và vô cực, không dây và NaNs, vv
code_dredd

Có lẽ bạn đúng, @code_dredd - giai thoại không liên quan. Nhưng giải pháp vẫn hoạt động: nó có thể phát hiện số vô cực - vui lòng sửa cho tôi nếu tôi sai.
dmitrizzle

Đó là bên cạnh vấn đề. Đã có một câu trả lời chỉ ra cách thực hiện điều này một cách chính xác . Những gì bạn có "hoạt động" đơn giản vì bản thân ngôn ngữ làm những điều ngớ ngẩn và không phù hợp với cách nó quản lý các loại. Hãy cứu mình khỏi việc viết mã hack như thế này.
code_dredd

Nó có làm cho bạn hạnh phúc hơn nếu tôi sử dụng toString()thay thế? Vui lòng phản đối hoặc nêu lý do tại sao điều này có thể mang lại kết quả không nhất quán hoặc tại sao chính xác phương pháp này không được khuyến nghị. Cho đến nay, tôi vẫn cảm thấy nó bổ sung thêm một lựa chọn cho những ai đang tìm kiếm một câu trả lời và không có bất kỳ lý do cụ thể tại sao điều này rất nguy hiểm, không ổn định, vv
dmitrizzle

-1

Bạn có thể sử dụng isFinite trong cửa sổ, isFinite(123):

Bạn có thể viết một hàm như:

function isInfinite(num) {
 return !isFinite(num);
}

Và sử dụng như:

isInfinite(null); //false
isInfinite(1); //false
isInfinite(0); //false
isInfinite(0.00); //false
isInfinite(NaN); //true
isInfinite(-1.797693134862316E+308); //true
isInfinite(Infinity); //true
isInfinite(-Infinity); //true
isInfinite(+Infinity); //true
isInfinite(undefined); //true

Bạn cũng có thể Number.isFinitkiểm tra xem giá trị có phải là Số không và chính xác hơn để kiểm tra undefinednullv.v.

Hoặc bạn có thể polyfill nó như thế này:

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.