www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is this normal or a bug ?

reply Mehdi <randomemail gmail.com> writes:
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:

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

And here is the corresponding D code:

```d
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!
Jul 03 2023
next sibling parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
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
Jul 03 2023
prev sibling next sibling parent claptrap <clap trap.com> writes:
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
Jul 03 2023
prev sibling next sibling parent reply Dom DiSc <dominikus scherkl.de> writes:
On Monday, 3 July 2023 at 08:24:22 UTC, Mehdi wrote:
 ```d
 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.
Jul 03 2023
parent Paul Backus <snarwin gmail.com> writes:
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.
Jul 03 2023
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Jul 03 2023
parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
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: ```d 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.)
Jul 06 2023
prev sibling parent reply cryptonian <sujith.thinkpalm gmail.com> writes:
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:

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

 And here is the corresponding D code:

 ```d
 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 <a href=“https://thinkpalm.com/technologies/artificial-inteligence/”>machine learning and AI services provider</a>. Such programs are very rare I guess.
Jul 24 2023
parent Abdulhaq <alynch4048 gmail.com> writes:
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:

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

 And here is the corresponding D code:

 ```d
 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 <a href=“https://thinkpalm.com/technologies/artificial-inteligence/”>machine learning and AI services provider</a>. 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.
Jul 24 2023