Hello everyone, I have a question about floating point compare,

**device** compare(float a, float b){

if (a==b) {}

}

**devices** compare(float a, float b){

if (fabs(a-b) < 0.00001) {}

}

which one is correct? seems both are right?

Thanks in advance!

Hello everyone, I have a question about floating point compare,

**device** compare(float a, float b){

if (a==b) {}

}

**devices** compare(float a, float b){

if (fabs(a-b) < 0.00001) {}

}

which one is correct? seems both are right?

Thanks in advance!

Neither of your function definitions would compile, so they are not correct or usable as is. However I imagine that is not what you are asking about.

The general topic of floating point comparison is an involved topic and is not unique or specific to CUDA programming.

It has been discussed in many places already on the web.

My suggestion is to google something like “c++ floating point comparison” and start reading.

Whether either method is correct or not is determined by what your intent is.

As Robert stated this is not at all CUDA related, but I enjoy the topic so much i feel an itch to discuss :D

I’m guessing it’s equality that you want to determine.

If so the first version ( “A”) is essentially useless while your second version (“B”) could be valid for certain ranges of ‘a’ and ‘b’.

The issue is that you want to account for the *relative* difference between two numbers not just the difference.

Examples:

(1):

a = 1.234567

b = 1.234568

fabs(a-b) = 0.000001 <= (1E-6) => true (ie we think they are equal)

(2) Lets multiply ‘a’ and ‘b’ by 10^12, they should still be equal right?

a = 1234567000000

b = 1234568000000

fabs(a-b) = 1000000 <= (1E-6) => false

Instead taking:

|a-b|/max(|a|,|b|) = { a = 1.234567, b=1.234568} => 0.000001 / 1.234568 => 0,00000081 <= (1E-6) => true

|a-b|/max(|a|,|b|) = { a = 1234567000000, b=1234568000000} => (1000000) / 1234568000000 => 0,00000081 <= (1E-6) => true

We get the same result, because we are looking at the relative difference, taking into account the size of the numbers.

*Note: Of course wee need to be careful with zero division here.

Thanks Robert and Jimmy!

Actually, Robert has give me the answer, because I thought cuda may process differently.

I asked this question because I see cuda kernel use (a==b), and the result seems not wrong, so I suspect compiler may do some clever things in cuda…

Many thanks Jimmy for your detail explantation. By the way I want to ask another question:

if I use (|a-b|/max(|a|,|b|) ) to compare float, is performance affected? because instructions became more than (a==b).

If your kernel is VERY compute bound it would likely be visible. This is quite unlikely.