Thread overview
Is this normal or a bug ?
Jul 03, 2023
Mehdi
Jul 03, 2023
claptrap
Jul 03, 2023
Dom DiSc
Jul 03, 2023
Paul Backus
Jul 06, 2023
Quirin Schroll
Jul 24, 2023
cryptonian
Jul 24, 2023
Abdulhaq
July 03, 2023

Hello, d community! I am currently exploring the possibilities of interoperability between C++ and D. While conducting some tests, I came across an interesting case. Here is the C++ code snippet:

float float_test(float x, float y){
  return x+y;
}

And here is the corresponding D code:

extern (C++) float float_test(float x, float y);
{
  assert(10.1 + 20.6 == float_test(10.1, 20.6));
}

Unfortunately, the assert statement fails in this case. I'm wondering if this discrepancy is due to the different float representations, a bug, or if I'm doing something wrong. Any insights would be greatly appreciated!

July 03, 2023
Float comparisons can be quite tricky.

You probably want to use std.math : isClose.

https://dlang.org/phobos/std_math_operations.html#.isClose

```d
{
	import std.math;
	assert((10.1+20.6).isClose(float_test(10.1, 20.6)));
}
```

For future reference, questions like these are better targeted towards the learn news group, rather than general.

https://forum.dlang.org/group/learn
July 03, 2023

On Monday, 3 July 2023 at 08:24:22 UTC, Mehdi wrote:

>

Hello, d community! I am currently exploring the possibilities of interoperability between C++ and D. While conducting some tests, I came across an interesting case. Here is the C++ code

import std.stdio;

void main()
{
writefln ("%.15f", 10.1 + 20.6);
writefln ("%.15f", 10.1f + 20.6f);
}

prints this...

30.699999999999999
30.700000762939453

the problem is..

assert(10.1 + 20.6 == float_test(10.1, 20.6));

10.1 + 20.6 is done with double (or maybe extended on DMD) precision
float_test(10.1, 20.6) is done with float precision

July 03, 2023

On Monday, 3 July 2023 at 08:24:22 UTC, Mehdi wrote:

>
extern (C++) float float_test(float x, float y);
{
  assert(10.1 + 20.6 == float_test(10.1, 20.6));
}

In C literals are always float unless you mark them as double (10.1L).
In D 10.1 is a double literal, which is auto-convered to float as parameter to your test.
If you want to calculate with float, you need to write 10.1f (and 10.1L would be real)

even 10.1 != 10.1f without any addition involved.

July 03, 2023

On Monday, 3 July 2023 at 14:22:27 UTC, Dom DiSc wrote:

>

In C literals are always float unless you mark them as double (10.1L).
In D 10.1 is a double literal, which is auto-convered to float as parameter to your test.

Floating-point literals without a suffix are doubles in both C and D.

http://port70.net/~nsz/c/c99/n1256.html#6.4.4.2p4

July 03, 2023

On 7/3/23 4:24 AM, Mehdi wrote:

>

Unfortunately, the assert statement fails in this case. I'm wondering if this discrepancy is due to the different float representations, a bug, or if I'm doing something wrong. Any insights would be greatly appreciated!

D always performs floating point math at the highest precision possible. C++ does not. So it's a minor difference in representation between double and real.

-Steve

July 06, 2023

On Monday, 3 July 2023 at 15:50:43 UTC, Steven Schveighoffer wrote:

>

On 7/3/23 4:24 AM, Mehdi wrote:

>

Unfortunately, the assert statement fails in this case. I'm wondering if this discrepancy is due to the different float representations, a bug, or if I'm doing something wrong. Any insights would be greatly appreciated!

D always performs floating point math at the highest precision possible. C++ does not. So it's a minor difference in representation between double and real.

It’s also a difference in philosophy. Until C++20, C++ was very liberal about what floating point types are and do. Since then, it is: If the platform can do IEEE 754, floating point math is IEEE 754 math. I still don’t know if float calculations are required by the standard to be carried out in single precision only or if it may store intermediate results in a higher precision.

D’s take on floating point is (or was when I came to D, when this was discussed a lot) that the result of floating point calculations can be any value between the one that would result following IEEE 754 precisely and the one you’d get using infinite precision and then round to the IEEE 754 type. I guess the reason is that needing to round down is in practical applications a loss without any gain: The processor does more work and you have less precision. Of course, when you want to observe rounding errors etc. (e.g. form an academic perspective), D might fool you.

An example would be:

double a = 0.1;
double b = 0.2;
double c = 0.3;
assert(0.1 + 0.2 == c); // passes, 0.1 + 0.2 is evaluated at compile-time
assert( a  +  b  == c); // fails

The only sound reasoning that can lead to this is the D spec guarantees double calculations are double precision or better.

(Also, the fact that floating point values even have a ==/!= comparison is a bad idea.)

July 24, 2023

On Monday, 3 July 2023 at 08:24:22 UTC, Mehdi wrote:

>

Hello, d community! I am currently exploring the possibilities of interoperability between C++ and D. While conducting some tests, I came across an interesting case. Here is the C++ code snippet:

float float_test(float x, float y){
  return x+y;
}

And here is the corresponding D code:

extern (C++) float float_test(float x, float y);
{
  assert(10.1 + 20.6 == float_test(10.1, 20.6));
}

Unfortunately, the assert statement fails in this case. I'm wondering if this discrepancy is due to the different float representations, a bug, or if I'm doing something wrong. Any insights would be greatly appreciated!

The difference in the assert statement could be because of the different float representations used in C++ and D. C++ and D might employ different floating-point models, leading to minor precision differences in arithmetic operations. To resolve this, consider using data types or libraries that ensure consistent float representations across both languages.
I learned this during my probation time in the organization, a machine learning and AI services provider. Such programs are very rare I guess.

July 24, 2023

On Monday, 24 July 2023 at 13:25:17 UTC, cryptonian wrote:

>

On Monday, 3 July 2023 at 08:24:22 UTC, Mehdi wrote:

>

Hello, d community! I am currently exploring the possibilities of interoperability between C++ and D. While conducting some tests, I came across an interesting case. Here is the C++ code snippet:

float float_test(float x, float y){
  return x+y;
}

And here is the corresponding D code:

extern (C++) float float_test(float x, float y);
{
  assert(10.1 + 20.6 == float_test(10.1, 20.6));
}

Unfortunately, the assert statement fails in this case. I'm wondering if this discrepancy is due to the different float representations, a bug, or if I'm doing something wrong. Any insights would be greatly appreciated!

The difference in the assert statement could be because of the different float representations used in C++ and D. C++ and D might employ different floating-point models, leading to minor precision differences in arithmetic operations. To resolve this, consider using data types or libraries that ensure consistent float representations across both languages.
I learned this during my probation time in the organization, a machine learning and AI services provider. Such programs are very rare I guess.

I once had an "issue" in python where the same calculation, when run multiple times, would produce floats of differing exact values in the 17th d.p. On investigation I learnt it was due (at that time) to the processor sometimes using a particular 80bit register, and sometimes not IIRC.