Có gì sai khi sử dụng == để so sánh số float trong Java?


177

Theo trang java.sun này == là toán tử so sánh đẳng thức cho các số dấu phẩy động trong Java.

Tuy nhiên, khi tôi gõ mã này:

if(sectionID == currentSectionID)

vào trình chỉnh sửa của tôi và chạy phân tích tĩnh, tôi nhận được: "JAVA0078 Giá trị dấu phẩy động so với =="

Điều gì là sai với việc sử dụng ==để so sánh các giá trị dấu phẩy động? Cách chính xác để làm điều đó là gì? 


29
Vì việc so sánh số float với == là vấn đề, nên việc sử dụng chúng làm ID; các tên trong mã ví dụ của bạn cho thấy đó là những gì bạn đang làm; số nguyên dài (độ dài) được ưu tiên và tiêu chuẩn thực tế cho ID.
Carl Manaster


4
Vâng, đó chỉ là một ví dụ ngẫu nhiên hay bạn thực sự sử dụng phao làm ID? Có một lý do?
Mỗi Wiklander

5
"đối với các trường float, sử dụng phương thức Float.compare và đối với các trường kép, sử dụng Double.compare. Việc xử lý đặc biệt các trường float và double được thực hiện cần thiết bởi sự tồn tại của Float.NaN, -0.0f và các hằng số kép tương tự; xem tài liệu Float.equals để biết chi tiết. " (Joshua Bloch: Java hiệu quả)
lbalazscs

Câu trả lời:


211

cách chính xác để kiểm tra số float cho 'đẳng thức' là:

if(Math.abs(sectionID - currentSectionID) < epsilon)

trong đó epsilon là một số rất nhỏ như 0,00000001, tùy thuộc vào độ chính xác mong muốn.


26
Xem liên kết trong câu trả lời được chấp nhận ( cygnus-software.com/ersky/comparedfloats/comparedfloats.htmlm ) để biết lý do tại sao một epsilon cố định không phải lúc nào cũng là một ý tưởng hay. Cụ thể, khi các giá trị trong phao được so sánh trở nên lớn (hoặc nhỏ), epsilon không còn phù hợp. (Tuy nhiên, sử dụng epsilon vẫn ổn nếu bạn biết các giá trị float của mình tương đối hợp lý.)
PT

1
@PT Anh ta có thể nhân epsilon với một số và thay đổi chức năng if(Math.abs(sectionID - currentSectionID) < epsilon*sectionIDđể giải quyết vấn đề đó không?
nhiệt tình

3
Điều này thậm chí có thể là câu trả lời tốt nhất cho đến nay, nhưng nó vẫn còn thiếu sót. Nơi nào bạn nhận được epsilon từ đâu?
Michael Piefel

1
@MichaelPiefel nó đã nói: "tùy thuộc vào độ chính xác mong muốn". Phao theo bản chất của chúng là loại giá trị vật lý giống như: bạn chỉ quan tâm đến một số vị trí hạn chế tùy thuộc vào tổng số không chính xác, bất kỳ sự khác biệt nào ngoài việc được coi là tranh luận.
ivan_pozdeev

Nhưng OP thực sự chỉ muốn kiểm tra sự bình đẳng, và vì điều này được biết là không đáng tin cậy, phải sử dụng một phương pháp khác. Tuy nhiên, tôi không hiểu anh ấy biết chính xác những gì mà anh ấy mong muốn là chính xác; Vì vậy, nếu tất cả những gì bạn muốn là một bài kiểm tra bình đẳng đáng tin cậy hơn, câu hỏi vẫn là: Bạn lấy epsilon từ đâu? Tôi đề xuất sử dụng Math.ulp()trong câu trả lời của tôi cho câu hỏi này.
Michael Piefel

53

Các giá trị dấu phẩy động có thể tắt đi một chút, vì vậy chúng có thể không báo cáo chính xác như nhau. Ví dụ: đặt dấu phẩy thành "6.1" và sau đó in lại, bạn có thể nhận được giá trị được báo cáo của một cái gì đó như "6.099999904632568359375". Đây là nền tảng cho cách thức hoạt động của phao; do đó, bạn không muốn so sánh chúng bằng cách sử dụng đẳng thức, mà là so sánh trong một phạm vi, nghĩa là, nếu độ chênh lệch của số float với số bạn muốn so sánh nó nhỏ hơn một giá trị tuyệt đối nhất định.

Bài viết này về Đăng ký cung cấp một cái nhìn tổng quan tốt về lý do tại sao đây là trường hợp; đọc hữu ích và thú vị.


@kevindtimm: vì vậy bạn sẽ thực hiện các bài kiểm tra về đẳng thức của mình như vậy sau đó nếu (số == 6.099999904632568359375) bất cứ khi nào bạn muốn biết số đều bằng 6.1 ... Có bạn đúng ... mọi thứ trong máy tính đều hoàn toàn xác định, chỉ là các xấp xỉ được sử dụng cho phao là phản trực giác khi làm các bài toán.
Newtopian

Các giá trị dấu phẩy động chỉ không chính xác trên phần cứng rất cụ thể .
Stuart P. Bentley

1
@Stuart Tôi có thể bị nhầm, nhưng tôi không nghĩ lỗi FDIV là không xác định. Các câu trả lời được đưa ra bởi phần cứng không phù hợp với đặc điểm kỹ thuật, nhưng chúng mang tính quyết định, trong đó phép tính tương tự luôn tạo ra kết quả không chính xác
Gravity

@Gravity Bạn có thể lập luận rằng bất kỳ hành vi nào là xác định được đưa ra một tập hợp cụ thể.
Stuart P. Bentley

Giá trị dấu phẩy động không chính xác. Mỗi giá trị dấu phẩy động là chính xác những gì nó là. Những gì có thể không chính xác là kết quả của một phép tính dấu phẩy động . Nhưng hãy cẩn thận! Khi bạn thấy một cái gì đó như 0,1 trong một chương trình, đó không phải là giá trị dấu phẩy động. Đó là một điểm nổi đen --- một chuỗi trình biên dịch cải thành một giá trị dấu chấm động bằng cách thực hiện một tính toán .
Solomon chậm

22

Chỉ cần đưa ra lý do đằng sau những gì mọi người khác đang nói.

Các đại diện nhị phân của một float là loại gây phiền nhiễu.

Trong hệ nhị phân, hầu hết các lập trình viên đều biết mối tương quan giữa 1b = 1d, 10b = 2d, 100b = 4d, 1000b = 8d

Vâng, nó hoạt động theo cách khác quá.

.1b = .5d, .01b = .25d, .001b = .125, ...

Vấn đề là không có cách chính xác nào để biểu diễn hầu hết các số thập phân như .1, .2, .3, v.v. Tất cả những gì bạn có thể làm là gần đúng ở dạng nhị phân. Hệ thống thực hiện một chút làm tròn khi các số in sao cho nó hiển thị .1 thay vì .10000000000001 hoặc .999999999999 (có lẽ gần giống với đại diện được lưu trữ như .1)

Chỉnh sửa từ nhận xét: Lý do đây là một vấn đề là kỳ vọng của chúng tôi. Chúng tôi hoàn toàn mong đợi 2/3 sẽ bị sai lệch tại một số điểm khi chúng tôi chuyển đổi nó thành số thập phân, 0,7 hoặc 0,67 hoặc 0,666667 .. Nhưng chúng tôi không tự động mong đợi .1 sẽ được làm tròn theo cách tương tự như 2/3 - và đó chính xác là những gì đang xảy ra.

Nhân tiện, nếu bạn tò mò con số mà nó lưu trữ bên trong là một biểu diễn nhị phân thuần túy bằng cách sử dụng "Ký hiệu khoa học" nhị phân. Vì vậy, nếu bạn bảo nó lưu số thập phân 10,75d, nó sẽ lưu 1010b cho số 10 và .11b cho số thập phân. Vì vậy, nó sẽ lưu trữ .101011 sau đó nó sẽ tiết kiệm một vài bit ở cuối để nói: Di ​​chuyển dấu thập phân bốn vị trí bên phải.

.


1
@Matt K - ừm, không cố định điểm; nếu bạn "lưu một vài bit ở cuối để nói di chuyển các dấu thập phân [N] sang phải", đó là dấu phẩy động. Điểm cố định lấy vị trí của điểm cơ số là tốt, cố định. Ngoài ra, nói chung, vì việc thay đổi điểm binamal (?) Luôn có thể được thực hiện để khiến bạn có '1' ở vị trí ngoài cùng bên trái, bạn sẽ tìm thấy một số hệ thống bỏ qua '1' hàng đầu, dành không gian do đó được giải phóng (1 bit!) để mở rộng phạm vi của số mũ.
JustJeff

Vấn đề không liên quan gì đến biểu diễn nhị phân so với số thập phân. Với dấu phẩy động thập phân, bạn vẫn có những thứ như (1/3) * 3 == 0.9999999999999999999999999999.
dan04

2
@ dan04 có, vì 1/3 không có biểu diễn nhị phân HOẶC nhị phân, nó có biểu diễn nhị phân và sẽ chuyển đổi chính xác theo cách đó :). Các số tôi liệt kê (.1, .25, v.v.) đều có biểu diễn thập phân hoàn hảo nhưng không có biểu diễn nhị phân - và mọi người đã quen với những người có biểu diễn "chính xác". BCD sẽ xử lý chúng hoàn hảo. Đó là sự khác biệt.
Bill K

1
Điều này nên có nhiều cách nâng cao hơn, vì nó mô tả vấn đề THỰC SỰ đằng sau vấn đề.
Levite

19

Điều gì sai khi sử dụng == để so sánh các giá trị dấu phẩy động?

Bởi vì nó không đúng 0.1 + 0.2 == 0.3


7
những gì về Float.compare(0.1f+0.2f, 0.3f) == 0?
Sức mạnh Bảo Bình

0,1f + 0,2f == 0,3f nhưng 0,1d + 0,2d! = 0,3đ. Theo mặc định, 0,1 + 0,2 là gấp đôi. 0,3 là một đôi là tốt.
burnabyRails

12

Tôi nghĩ rằng có rất nhiều nhầm lẫn xung quanh phao (và đôi), thật tốt để làm sáng tỏ nó.

  1. Không có gì sai khi sử dụng float như ID trong JVM tuân thủ tiêu chuẩn [*]. Nếu bạn chỉ đơn giản đặt ID float thành x, không làm gì với nó (tức là không có mỹ phẩm) và sau đó kiểm tra y == x, bạn sẽ ổn. Ngoài ra, không có gì sai khi sử dụng chúng làm khóa trong HashMap. Những gì bạn không thể làm là giả sử các đẳng thức như x == (x - y) + y, v.v. Điều này được nói, mọi người thường sử dụng các loại số nguyên làm ID và bạn có thể quan sát rằng hầu hết mọi người ở đây bị loại bỏ bởi mã này, vì vậy, vì lý do thực tế, tốt hơn là tuân thủ các quy ước . Lưu ý rằng có nhiều doublegiá trị khác nhau khi có values, vì vậy bạn không thu được gì khi sử dụng double. Ngoài ra, việc tạo "ID khả dụng tiếp theo" có thể khó khăn gấp đôi và đòi hỏi một số kiến ​​thức về số học dấu phẩy động. Không đáng để gặp rắc rối.

  2. Mặt khác, dựa vào sự bình đẳng bằng số của kết quả của hai phép tính tương đương toán học là rủi ro. Điều này là do các lỗi làm tròn và mất độ chính xác khi chuyển đổi từ biểu diễn thập phân sang nhị phân. Điều này đã được thảo luận đến chết trên SO.

[*] Khi tôi nói "JVM tuân thủ tiêu chuẩn", tôi muốn loại trừ một số triển khai JVM bị tổn thương não. Xem này .


Khi sử dụng float làm ID, người ta phải cẩn thận để đảm bảo rằng chúng được so sánh bằng cách sử dụng ==chứ không phải equals, hoặc nếu không thì đảm bảo rằng không có float nào so sánh không bằng với chính nó được lưu trữ trong một bảng. Mặt khác, một chương trình cố gắng lấy ví dụ có thể tạo ra bao nhiêu kết quả duy nhất từ ​​một biểu thức khi được cung cấp nhiều đầu vào khác nhau có thể coi mọi giá trị NaN là duy nhất.
supercat

Ở trên đề cập đến Float, không phải float.
quant_dev

Nói về Floatcái gì vậy? Nếu một người cố gắng xây dựng một bảng các floatgiá trị duy nhất và so sánh chúng với nhau ==, các quy tắc so sánh khủng khiếp của IEEE-754 sẽ dẫn đến việc bảng bị ngập trong NaNcác giá trị.
supercat

floatloại không có equalsphương pháp.
quant_dev

À - tôi không có nghĩa là một equalsphương thức cá thể, mà là phương thức tĩnh (tôi nghĩ trong Floatlớp) so sánh hai giá trị của loại float.
supercat

9

Đây là một vấn đề không cụ thể đối với java. Sử dụng == để so sánh hai số float / double / bất kỳ số loại thập phân nào có khả năng gây ra sự cố do cách chúng được lưu trữ. Một float có độ chính xác đơn (theo tiêu chuẩn IEEE 754) có 32 bit, được phân phối như sau:

1 bit - Dấu (0 = dương, 1 = âm)
8 bit - Biểu diễn lũy thừa (đặc biệt (độ lệch-127) của x trong 2 ^ x)
23 bit - Mantisa. Số Actuall được lưu trữ.

Các mantisa là những gì gây ra vấn đề. Nó giống như ký hiệu khoa học, chỉ có số trong cơ sở 2 (nhị phân) trông giống như 1.110011 x 2 ^ 5 hoặc một cái gì đó tương tự. Nhưng trong hệ nhị phân, số 1 đầu tiên luôn là số 1 (ngoại trừ biểu diễn bằng 0)

Do đó, để tiết kiệm một chút dung lượng bộ nhớ (ý định chơi chữ), IEEE đã quyết định rằng 1 nên được giả sử. Ví dụ, một mantisa của 1011 thực sự là 1.1011.

Điều này có thể gây ra một số vấn đề khi so sánh, đặc biệt là với 0 vì 0 không thể được biểu diễn chính xác trong một float. Đây là lý do chính khiến == không được khuyến khích, ngoài các vấn đề toán học dấu phẩy động được mô tả bởi các câu trả lời khác.

Java có một vấn đề duy nhất là ngôn ngữ này là phổ quát trên nhiều nền tảng khác nhau, mỗi nền tảng có thể có định dạng nổi duy nhất của riêng nó. Điều đó làm cho nó thậm chí còn quan trọng hơn để tránh ==.

Cách thích hợp để so sánh hai số float (tâm trí cụ thể không phải ngôn ngữ của bạn) cho sự bình đẳng như sau:

if(ABS(float1 - float2) < ACCEPTABLE_ERROR)
    //they are approximately equal

trong đó ACCEPTABLE_ERROR là #d xác định hoặc một số hằng số khác bằng 0,000000001 hoặc bất kỳ độ chính xác nào được yêu cầu, như Victor đã đề cập.

Một số ngôn ngữ có chức năng này hoặc hằng số này được tích hợp, nhưng nhìn chung đây là một thói quen tốt.


3
Java có một hành vi được xác định cho float. Nó không phụ thuộc vào nền tảng.
Yishai

9

Cho đến hôm nay, cách nhanh chóng và dễ dàng để làm điều đó là:

if (Float.compare(sectionID, currentSectionID) == 0) {...}

Tuy nhiên, các tài liệu không chỉ định rõ ràng giá trị của chênh lệch biên (một epsilon từ câu trả lời của @Victor) luôn có trong các tính toán trên phao, nhưng nó phải là một thứ hợp lý vì nó là một phần của thư viện ngôn ngữ tiêu chuẩn.

Tuy nhiên, nếu cần độ chính xác cao hơn hoặc tùy chỉnh, thì

float epsilon = Float.MIN_NORMAL;  
if(Math.abs(sectionID - currentSectionID) < epsilon){...}

là một lựa chọn giải pháp khác.


1
Các tài liệu mà bạn đã liên kết nói "giá trị 0 nếu F1 bằng số với f2", điều này làm cho nó giống như làm (sectionId == currentSectionId)không chính xác cho các điểm nổi. phương pháp epsilon là cách tiếp cận tốt hơn, nằm trong câu trả lời này: stackoverflow.com/a/1088271/4212710
typoerrpr

8

Giá trị điểm cho phép không đáng tin cậy, do lỗi vòng.

Vì vậy, có lẽ chúng không nên được sử dụng làm giá trị chính, chẳng hạn như partID. Sử dụng số nguyên thay thế hoặc longnếu intkhông chứa đủ giá trị có thể.


2
Đã đồng ý. Cho rằng đây là những ID, không có lý do gì để làm phức tạp mọi thứ với số học dấu phẩy động.
Yohnny

2
Hoặc dài. Tùy thuộc vào số lượng ID duy nhất được tạo trong tương lai, một số nguyên có thể không đủ lớn.
Wayne Hartman

Làm thế nào chính xác là gấp đôi so với nổi?
Arvindh Mani 17/03/2017

1
@ArvindhMani doubles chính xác hơn nhiều, nhưng chúng cũng là các giá trị dấu phẩy động, vì vậy câu trả lời của tôi có nghĩa là bao gồm cả hai floatdouble.
Eric Wilson

7

Ngoài các câu trả lời trước đó, bạn nên lưu ý rằng có những hành vi lạ liên quan đến -0.0f+0.0f(chúng có ==nhưng không equals) và Float.NaN(đó là equalsnhưng không== ) (hy vọng tôi đã hiểu đúng - argh, đừng làm điều đó!).

Chỉnh sửa: Hãy kiểm tra!

import static java.lang.Float.NaN;
public class Fl {
    public static void main(String[] args) {
        System.err.println(          -0.0f   ==              0.0f);   // true
        System.err.println(new Float(-0.0f).equals(new Float(0.0f))); // false
        System.err.println(            NaN   ==               NaN);   // false
        System.err.println(new Float(  NaN).equals(new Float( NaN))); // true
    }
} 

Chào mừng bạn đến với IEEE / 754.


Nếu một cái gì đó là ==, thì chúng giống hệt với bit. Làm thế nào họ có thể không bằng ()? Có lẽ bạn có nó ngược?
mkb

@Matt NaN thật đặc biệt. Double.isNaN (double x) trong Java thực sự được triển khai dưới dạng {return x! = X; } ...
quant_dev

1
Với số float, ==không có nghĩa là các số "giống hệt bit" (cùng một số có thể được biểu diễn bằng các mẫu bit khác nhau, mặc dù chỉ một trong số chúng là dạng chuẩn hóa). Đồng thời, -0.0f0.0fđược biểu diễn bằng các mẫu bit khác nhau (bit dấu là khác nhau), nhưng so sánh bằng với ==(nhưng không bằng equals). Giả định của bạn ==là so sánh bitwise, nói chung là sai.
Pavel Minaev


5

Bạn có thể sử dụng Float.floatToIntBits ().

Float.floatToIntBits(sectionID) == Float.floatToIntBits(currentSectionID)

1
Bạn đang đi đúng hướng. floatToIntBits () là cách phù hợp để đi, nhưng sẽ dễ dàng hơn khi chỉ sử dụng hàm Float được tích hợp trong hàm (). Xem tại đây: stackoverflow.com/a/3668105/2066079 . Bạn có thể thấy rằng mặc định bằng () sử dụng floatToIntBits trong nội bộ.
dberm22

1
Có nếu chúng là vật nổi. Bạn có thể sử dụng phương trình trên cho nguyên thủy.
aamadmi

4

Trước hết, họ nổi hay nổi? Nếu một trong số chúng là Float, bạn nên sử dụng phương thức equals (). Ngoài ra, có lẽ tốt nhất để sử dụng phương pháp Float.compare tĩnh.


4

Sau đây tự động sử dụng độ chính xác tốt nhất:

/**
 * Compare to floats for (almost) equality. Will check whether they are
 * at most 5 ULP apart.
 */
public static boolean isFloatingEqual(float v1, float v2) {
    if (v1 == v2)
        return true;
    float absoluteDifference = Math.abs(v1 - v2);
    float maxUlp = Math.max(Math.ulp(v1), Math.ulp(v2));
    return absoluteDifference < 5 * maxUlp;
}

Tất nhiên, bạn có thể chọn nhiều hơn hoặc ít hơn 5 ULP ('đơn vị ở vị trí cuối cùng').

Nếu bạn vào thư viện Apache Commons, Precisionlớp có compareTo()equals()với cả epsilon và ULP.


khi thay đổi float thành double, phương thức này không hoạt động như isDoubleEqual (0.1 + 0.2-0.3, 0.0) == false
hychou

Có vẻ như bạn cần nhiều hơn như 10_000_000_000_000_000L làm yếu tố doubleđể trang trải điều này.
Michael Piefel

3

bạn có thể muốn nó là ==, nhưng 123.4444444444443! = 123.4444444444442



2

Hai phép tính khác nhau tạo ra các số thực bằng nhau không nhất thiết tạo ra các số có dấu phẩy động bằng nhau. Những người sử dụng == để so sánh kết quả tính toán thường sẽ bị bất ngờ bởi điều này, vì vậy cảnh báo giúp gắn cờ những gì có thể là một lỗi tinh vi và khó tái tạo.


2

Bạn có đang xử lý mã thuê ngoài sẽ sử dụng float cho những thứ có tên partID và currentSectionID không? Chỉ tò mò thôi.

@Bill K: "Đại diện nhị phân của một float là loại gây phiền nhiễu." Làm sao vậy Làm thế nào bạn sẽ làm điều đó tốt hơn? Có một số con số nhất định không thể được biểu diễn trong bất kỳ cơ sở nào, bởi vì chúng không bao giờ kết thúc. Pi là một ví dụ tốt. Bạn chỉ có thể ước chừng nó. Nếu bạn có giải pháp tốt hơn, hãy liên hệ với Intel.


1

Như đã đề cập trong các câu trả lời khác, đôi có thể có độ lệch nhỏ. Và bạn có thể viết phương pháp của riêng bạn để so sánh chúng bằng cách sử dụng độ lệch "chấp nhận được". Tuy nhiên ...

Có một lớp apache để so sánh đôi: org.apache.commons.math3.util.Precision

Nó chứa một số hằng số thú vị: SAFE_MINEPSILON , đó là độ lệch tối đa có thể có của các phép toán số học đơn giản.

Nó cũng cung cấp các phương pháp cần thiết để so sánh, nhân đôi hoặc tròn. (sử dụng ulps hoặc độ lệch tuyệt đối)


1

Trong một câu trả lời tôi có thể nói, bạn nên sử dụng:

Float.floatToIntBits(sectionID) == Float.floatToIntBits(currentSectionID)

Để làm cho bạn tìm hiểu thêm về cách sử dụng các toán tử liên quan một cách chính xác, tôi đang xây dựng một số trường hợp ở đây: Nói chung, có ba cách để kiểm tra các chuỗi trong Java. Bạn có thể sử dụng ==, .equals () hoặc Object.equals ().

Họ khác nhau như thế nào? == kiểm tra chất lượng tham chiếu trong chuỗi có nghĩa là tìm hiểu xem hai đối tượng có giống nhau không. Mặt khác, .equals () kiểm tra xem hai chuỗi có giá trị bằng nhau hay không. Cuối cùng, Object.equals () kiểm tra bất kỳ null nào trong hai chuỗi sau đó xác định xem có gọi .equals () không.

Toán tử lý tưởng để sử dụng

Vâng, điều này đã phải chịu nhiều cuộc tranh luận bởi vì mỗi trong số ba nhà khai thác có tập hợp điểm mạnh và điểm yếu riêng. Ví dụ, == thường là một tùy chọn ưa thích khi so sánh tham chiếu đối tượng, nhưng có những trường hợp dường như cũng có thể so sánh các giá trị chuỗi.

Tuy nhiên, những gì bạn nhận được là một giá trị giảm vì Java tạo ra ảo tưởng rằng bạn đang so sánh các giá trị nhưng theo nghĩa thực tế thì bạn không phải vậy. Hãy xem xét hai trường hợp dưới đây:

Trường hợp 1:

String a="Test";
String b="Test";
if(a==b) ===> true

Trường hợp 2:

String nullString1 = null;
String nullString2 = null;
//evaluates to true
nullString1 == nullString2;
//throws an exception
nullString1.equals(nullString2);

Vì vậy, cách tốt hơn là sử dụng mỗi toán tử khi kiểm tra thuộc tính cụ thể mà nó được thiết kế cho. Nhưng trong hầu hết các trường hợp, Object.equals () là một toán tử phổ quát hơn do đó các nhà phát triển web có kinh nghiệm lựa chọn nó.

Tại đây bạn có thể biết thêm chi tiết: http://fluenttheme.com/use-compare-strings-java/


-2

Cách chính xác sẽ là

java.lang.Float.compare(float1, float2)

7
Float.compare (float1, float2) trả về một int, vì vậy nó không thể được sử dụng thay vì float1 == float2 trong điều kiện if. Hơn nữa, nó không thực sự giải quyết được vấn đề tiềm ẩn mà cảnh báo này đề cập đến - rằng nếu số float là kết quả của phép tính số, float1! = Float2 có thể xảy ra chỉ do lỗi làm tròn.
quant_dev

1
đúng, bạn không thể sao chép dán, bạn phải kiểm tra tài liệu trước.
Eric

2
Những gì bạn có thể làm thay vì float1 == float2 là Float.compare (float1, float2) == 0.
deterb

29
Điều này không mua cho bạn bất cứ thứ gì - bạn vẫn nhận đượcFloat.compare(1.1 + 2.2, 3.3) != 0
Pavel Minaev

-2

Một cách để giảm lỗi làm tròn là sử dụng gấp đôi thay vì nổi. Điều này sẽ không làm cho vấn đề biến mất, nhưng nó làm giảm số lượng lỗi trong chương trình của bạn và float gần như không bao giờ là lựa chọn tốt nhất. IMHO.

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.