I know all about the problems of FP comparison, and yes I know that I need 
to provide more information. What makes me suspicious is, that I have a 
bunch of equivalent tests before the failing one, and all pass. I still 
believe in the determinism of programs. Hence, this is all really strange.

I run the C test code (without any Go) in GDB and the values are correctly 
set. This is how the data looks before the call, setting the correct values:

*804       YGNodeCalculateLayout(root, YGUndefined, YGUndefined, 
YGDirectionLTR);*
*(gdb) p root.layout_.dimensions*
*$9 = {*
*  _M_elems = {nan(0x400000), nan(0x400000)}*
*}*

and this is after the call:

*(gdb) p root.layout_.dimensions*
*$13 = {*
*  _M_elems = {320, 10}*
*}*

I write a C wrapper function, that outputs the return value just before 
it's returned and makes its way through the Go FFI. Here is the output 
before the call:

*YGNodeLayoutGetWidth: 1.#QNAN0  7FC00000*
*YGNodeLayoutGetHeight: 1.#QNAN0 7FC00000*

and after the call

*YGNodeLayoutGetWidth: 320.000000        43A00000*
*YGNodeLayoutGetHeight: 1000000020040877300000.000000    6258D727*

So, why are the values before the call are different in C and the C side 
within the Go program? I mean why once 0x400000 and 0x7FC00000? I would 
have expected that the C code behaves the same.
And as you can see the 320 is set in both cases, but the expected 10 is a 
totally screwed up floating-point value.

Could this be an alignment problem? Does CGO add some wrapping code, which 
does some strange things?

Unfortunately, I didn't find a way, how I can enter the C code from a 
debugger when using the Go binary. Looks like there is no C debug 
information available.

peterGo schrieb am Montag, 1. Februar 2021 um 06:48:20 UTC+1:

> Robert,
>
> Advanced googletest Topics
>
> Floating-Point Comparison
>
> Comparing floating-point numbers is tricky. Due to round-off errors, it is 
> very unlikely that two floating-points will match exactly. Therefore, 
> ASSERT_EQ 's naive comparison usually doesn't work. And since 
> floating-points can have a wide value range, no single fixed error bound 
> works. It's better to compare by a fixed relative error bound, except for 
> values close to 0 due to the loss of precision there.
>
> In general, for floating-point comparison to make sense, the user needs to 
> carefully choose the error bound. If they don't want or care to, comparing 
> in terms of Units in the Last Place (ULPs) is a good default, and 
> googletest provides assertions to do this. 
>
> ASSERT_FLOAT_EQ(val1, val2); EXPECT_FLOAT_EQ(val1, val2);   the two float 
> values 
> are almost equal
> ASSERT_DOUBLE_EQ(val1, val2); EXPECT_DOUBLE_EQ(val1, val2);    the two 
> double values are almost equal
>
> By "almost equal" we mean the values are within 4 ULP's from each other.
>
> What does testify do?
>
> Peter
>
>
>
> On Monday, February 1, 2021 at 12:14:35 AM UTC-5 Robert M. Münch wrote:
>
>> I have a C library with some test-cases (using googletest) that all pass. 
>> I created Go bindings for the C lib and converted the tests to testify 
>> format.
>>
>> Some Go test fails because a return value from the C function (type 
>> float) is different than expected. For example:
>>
>> ASSERT_FLOAT_EQ(10, GetHeight(root)); // C code works
>>
>> assert.EqualValues(t, 10, root.Height()) // Go code fails
>> The returned value in Go is: float32(1e+21) instead of float32(10). I'm 
>> really wondering how this can happen. It looks like somewhere in the FFI, 
>> the value changes. But what puzzles me, I'm using the same Go tests over 
>> and over in other tests, and things are working.
>>
>> Does anyone have an idea what could be the problem?
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/593b48ad-1e7d-4b93-a9c2-9e4a5e90a3f7n%40googlegroups.com.

Reply via email to