public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Should rand() return a RAND_MAX value for 32 bit target?
@ 2018-09-18 12:22 Neha Gowda
  2018-09-18 13:09 ` Xi Ruoyao
  2018-09-18 13:46 ` Andrew Haley
  0 siblings, 2 replies; 17+ messages in thread
From: Neha Gowda @ 2018-09-18 12:22 UTC (permalink / raw)
  To: gcc-help

Hi,

I am trying to run the following testcase for Random Number Generator
function.
The testcase returns true when generated number is RAND_MAX and returns
false when its not generated.

Command :- gcc -m32 -O2 test.c
======================================================
#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned int i;
    float f;
    srand(0);
    for (i = 0; i <= RAND_MAX; i++) {
        f = rand();
        if (f == RAND_MAX) {
                printf("True\n");
            return 0;
        }
    }
        printf("False\n");
    return 1;
}
======================================================
Tried them on the latest source and observed that the RAND_MAX is generated
when
the optimization is not enabled. When optimization is enabled for 32 bit
target RAND_MAX
is not being generated. However, 64 bit generates RAND_MAX with or without
optimization.

On further investigation, I found that the expand phase is optimizing the
following and hence
the RAND_MAX value is not being generated.
=========================================
Replacing Expressions
f_10 replace with --> f_10 = (float) _1;
=========================================

Can you please let me know if its the expected behavior or some bug?

Thanks,
Neha

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-18 12:22 Should rand() return a RAND_MAX value for 32 bit target? Neha Gowda
@ 2018-09-18 13:09 ` Xi Ruoyao
  2018-09-18 13:17   ` Xi Ruoyao
  2018-09-18 13:49   ` Jonathan Wakely
  2018-09-18 13:46 ` Andrew Haley
  1 sibling, 2 replies; 17+ messages in thread
From: Xi Ruoyao @ 2018-09-18 13:09 UTC (permalink / raw)
  To: Neha Gowda; +Cc: gcc-help

On 2018-09-18 17:52 +0530, Neha Gowda wrote:
> Hi,
> 
> I am trying to run the following testcase for Random Number Generator
> function.
> The testcase returns true when generated number is RAND_MAX and returns
> false when its not generated.
> 
> Command :- gcc -m32 -O2 test.c
> ======================================================
> #include <stdio.h>
> #include <stdlib.h>
> 
> int main()
> {
>     unsigned int i;
>     float f;
>     srand(0);
>     for (i = 0; i <= RAND_MAX; i++) {
>         f = rand();

There is a rounding error introduced since a float can not represent
all integer values in [0, RAND_MAX].

>         if (f == RAND_MAX) {

RAND_MAX is 2147483647 on 32-bit GNU/Linux.  It can not be represented
by a float.

>                 printf("True\n");
>             return 0;
>         }
>     }
>         printf("False\n");
>     return 1;
> }
> ======================================================
> Tried them on the latest source and observed that the RAND_MAX is generated
> when
> the optimization is not enabled. When optimization is enabled for 32 bit
> target RAND_MAX
> is not being generated. However, 64 bit generates RAND_MAX with or without
> optimization.
> 
> On further investigation, I found that the expand phase is optimizing the
> following and hence
> the RAND_MAX value is not being generated.
> =========================================
> Replacing Expressions
> f_10 replace with --> f_10 = (float) _1;
> =========================================
> 
> Can you please let me know if its the expected behavior or some bug?

See https://gcc.gnu.org/wiki/FAQ#PR323.
-- 
Xi Ruoyao <xry111@mengyan1223.wang>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-18 13:09 ` Xi Ruoyao
@ 2018-09-18 13:17   ` Xi Ruoyao
  2018-09-18 13:49   ` Jonathan Wakely
  1 sibling, 0 replies; 17+ messages in thread
From: Xi Ruoyao @ 2018-09-18 13:17 UTC (permalink / raw)
  To: Neha Gowda; +Cc: gcc-help

On 2018-09-18 21:09 +0800, Xi Ruoyao wrote:
> > Tried them on the latest source and observed that the RAND_MAX is generated
> > when
> > the optimization is not enabled. When optimization is enabled for 32 bit
> > target RAND_MAX
> > is not being generated. However, 64 bit generates RAND_MAX with or without
> > optimization.

And I must say, in your program RAND_MAX is NOT generated with Glibc 2.26 on
Linux.  You seen "True" because of floating point rounding error. 

> See https://gcc.gnu.org/wiki/FAQ#PR323.
-- 
Xi Ruoyao <xry111@mengyan1223.wang>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-18 12:22 Should rand() return a RAND_MAX value for 32 bit target? Neha Gowda
  2018-09-18 13:09 ` Xi Ruoyao
@ 2018-09-18 13:46 ` Andrew Haley
  2018-09-20 14:42   ` Vincent Lefevre
  1 sibling, 1 reply; 17+ messages in thread
From: Andrew Haley @ 2018-09-18 13:46 UTC (permalink / raw)
  To: Neha Gowda, gcc-help

On 09/18/2018 01:22 PM, Neha Gowda wrote:
> Can you please let me know if its the expected behavior or some bug?

First consider the value of (float)RAND_MAX. Then please consider if
using -ffloat-store will make any difference to your program and then
you may be enlightened. If not, please come back and ask again.

-- 
Andrew Haley
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-18 13:09 ` Xi Ruoyao
  2018-09-18 13:17   ` Xi Ruoyao
@ 2018-09-18 13:49   ` Jonathan Wakely
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Wakely @ 2018-09-18 13:49 UTC (permalink / raw)
  To: neha.gnu.gcc; +Cc: gcc-help, xry111

On Tue, 18 Sep 2018 at 14:09, Xi Ruoyao wrote:
>
> On 2018-09-18 17:52 +0530, Neha Gowda wrote:
> > Hi,
> >
> > I am trying to run the following testcase for Random Number Generator
> > function.
> > The testcase returns true when generated number is RAND_MAX and returns
> > false when its not generated.
> >
> > Command :- gcc -m32 -O2 test.c
> > ======================================================
> > #include <stdio.h>
> > #include <stdlib.h>
> >
> > int main()
> > {
> >     unsigned int i;
> >     float f;
> >     srand(0);
> >     for (i = 0; i <= RAND_MAX; i++) {
> >         f = rand();
>
> There is a rounding error introduced since a float can not represent
> all integer values in [0, RAND_MAX].
>
> >         if (f == RAND_MAX) {
>
> RAND_MAX is 2147483647 on 32-bit GNU/Linux.  It can not be represented
> by a float.

Which leads to the question, why are you using float anyway?

rand() returns an int, not a float.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-18 13:46 ` Andrew Haley
@ 2018-09-20 14:42   ` Vincent Lefevre
  2018-09-20 15:05     ` Vincent Lefevre
  0 siblings, 1 reply; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-20 14:42 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Neha Gowda, gcc-help

On 2018-09-18 14:46:24 +0100, Andrew Haley wrote:
> On 09/18/2018 01:22 PM, Neha Gowda wrote:
> > Can you please let me know if its the expected behavior or some bug?
> 
> First consider the value of (float)RAND_MAX. Then please consider if
> using -ffloat-store will make any difference to your program and then
> you may be enlightened. If not, please come back and ask again.

No, the program is so buggy that -ffloat-store does not solve the
problem because there is rounding in the == expression. As a short
example:

#include <stdio.h>

int main (void)
{
  float f = 2147483646;
  if (f == 2147483647)
    {
      printf("%.20g\n", (double) f);
    }
  return 0;
}

outputs 2147483648 because the == is done on float. Thus, from the
original program, you cannot deduce anything.

And BTW, don't try to cast f to int, that's undefined behavior here.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-20 14:42   ` Vincent Lefevre
@ 2018-09-20 15:05     ` Vincent Lefevre
  2018-09-20 15:21       ` Liu Hao
  2018-09-20 15:46       ` Dennis Clarke
  0 siblings, 2 replies; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-20 15:05 UTC (permalink / raw)
  To: Andrew Haley, Neha Gowda, gcc-help

Actually, there may be a bug with -m32:

#include <stdio.h>
#include <float.h>

int main (void)
{
  float f = 2147483646;
  printf ("FLT_EVAL_METHOD = %d\n", (int) FLT_EVAL_METHOD);
  if (f == 2147483647)
    {
      printf("%.20g\n", (double) f);
    }
  return 0;
}

$ gcc -std=c99 -m32 -O tst.c -o tst
$ ./tst
FLT_EVAL_METHOD = 2
2147483648

Since FLT_EVAL_METHOD = 2, float_t is long double, thus shouldn't
2147483647 be converted to long double directly (as f is regarded
as an operand of type long double), so that the result of the
equality test should be false?

The C standard says for FLT_EVAL_METHOD = 2: "evaluate all operations
and constants to the range and precision of the long double type".
^^^^^^^^^^^^^

Converting f first to float is contrary to the idea behind
FLT_EVAL_METHOD = 2, which is to avoid loss of precision in
intermediate operations.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-20 15:05     ` Vincent Lefevre
@ 2018-09-20 15:21       ` Liu Hao
  2018-09-20 15:58         ` Vincent Lefevre
  2018-09-20 15:46       ` Dennis Clarke
  1 sibling, 1 reply; 17+ messages in thread
From: Liu Hao @ 2018-09-20 15:21 UTC (permalink / raw)
  To: Andrew Haley, Neha Gowda, gcc-help

在 2018/9/20 23:05, Vincent Lefevre 写道:
> Actually, there may be a bug with -m32:
> 
> #include <stdio.h>
> #include <float.h>
> 
> int main (void)
> {
>    float f = 2147483646;
>    printf ("FLT_EVAL_METHOD = %d\n", (int) FLT_EVAL_METHOD);
>    if (f == 2147483647)
>      {
>        printf("%.20g\n", (double) f);
>      }
>    return 0;
> }
> 
> $ gcc -std=c99 -m32 -O tst.c -o tst
> $ ./tst
> FLT_EVAL_METHOD = 2
> 2147483648
> 
> Since FLT_EVAL_METHOD = 2, float_t is long double, thus shouldn't
> 2147483647 be converted to long double directly (as f is regarded
> as an operand of type long double), so that the result of the
> equality test should be false?
> 
> The C standard says for FLT_EVAL_METHOD = 2: "evaluate all operations
> and constants to the range and precision of the long double type".
> ^^^^^^^^^^^^^
> 

-----
ISO/IEC 9899:2017
(WG14 N2176)
5.2.4.2.2 Characteristics of floating types <float.h>
9 Except for assignment and cast (which remove all extra range and 
precision), the values yielded by operators with floating operands and 
values subject to the usual arithmetic conversions and of **floating 
constants** are evaluated to a format whose range and precision may be 
greater than required by the type. The use of evaluation formats is 
characterized by the implementation-defined value of FLT_EVAL_METHOD:24)
-----

`2147483647` is an integer constant. This rule only describes floating 
constants, so it does not apply.

According to '6.3.1.8 Usual arithmetic conversions', here `2147483647` 
is converted to a value having type `float`, which is then compared with 
`f` using the internal `long double` type.


> Converting f first to float is contrary to the idea behind
> FLT_EVAL_METHOD = 2, which is to avoid loss of precision in
> intermediate operations.
> 


-- 
Best regards,
LH_Mouse

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-20 15:05     ` Vincent Lefevre
  2018-09-20 15:21       ` Liu Hao
@ 2018-09-20 15:46       ` Dennis Clarke
  2018-09-20 16:16         ` Vincent Lefevre
  1 sibling, 1 reply; 17+ messages in thread
From: Dennis Clarke @ 2018-09-20 15:46 UTC (permalink / raw)
  To: gcc-help

On 09/20/2018 11:05 AM, Vincent Lefevre wrote:
> Actually, there may be a bug with -m32:
> 
> #include <stdio.h>
> #include <float.h>
> 
> int main (void)
> {
>    float f = 2147483646;
>    printf ("FLT_EVAL_METHOD = %d\n", (int) FLT_EVAL_METHOD);
>    if (f == 2147483647)
>      {
>        printf("%.20g\n", (double) f);
>      }
>    return 0;
> }
> 
> $ gcc -std=c99 -m32 -O tst.c -o tst
> $ ./tst
> FLT_EVAL_METHOD = 2
> 2147483648
> 
> Since FLT_EVAL_METHOD = 2, float_t is long double, thus shouldn't
> 2147483647 be converted to long double directly (as f is regarded
> as an operand of type long double), so that the result of the
> equality test should be false?
> 
> The C standard says for FLT_EVAL_METHOD = 2: "evaluate all operations
> and constants to the range and precision of the long double type".
> ^^^^^^^^^^^^^
> 
> Converting f first to float is contrary to the idea behind
> FLT_EVAL_METHOD = 2, which is to avoid loss of precision in
> intermediate operations.
> 

Hrmmm ... I see FLT_EVAL_METHOD = 0 here with gcc 8.1.0 on sparc :

$ file ./flt_eval
./flt_eval: ELF 32-bit MSB executable SPARC32PLUS Version 1, V8+ 
Required, dynamically linked, not stripped, no debugging information 
available

$ ./flt_eval
FLT_EVAL_METHOD = 0
2147483648

I see similar on ppc64 :

$ file flt_eval
flt_eval: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 
(SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 
3.2.0, not stripped
$ ./flt_eval
FLT_EVAL_METHOD = 0
2147483648
$

Not sure how you are getting FLT_EVAL_METHOD as 2.

What platform is this on ?


Dennis

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-20 15:21       ` Liu Hao
@ 2018-09-20 15:58         ` Vincent Lefevre
  2018-09-20 16:12           ` Vincent Lefevre
  2018-09-21  2:49           ` Liu Hao
  0 siblings, 2 replies; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-20 15:58 UTC (permalink / raw)
  To: Liu Hao; +Cc: Andrew Haley, Neha Gowda, gcc-help

On 2018-09-20 23:21:23 +0800, Liu Hao wrote:
> `2147483647` is an integer constant. This rule only describes floating 
> constants, so it does not apply.

Actually the fact that it is a constant doesn't matter, but...

> According to '6.3.1.8 Usual arithmetic conversions', here `2147483647` 
> is converted to a value having type `float`, which is then compared with 
> `f` using the internal `long double` type.

The conversion of the int needs to be done with the precision and
range of long double since this is neither an assignment nor a cast.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-20 15:58         ` Vincent Lefevre
@ 2018-09-20 16:12           ` Vincent Lefevre
  2018-09-21  2:49           ` Liu Hao
  1 sibling, 0 replies; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-20 16:12 UTC (permalink / raw)
  To: Liu Hao, Andrew Haley, Neha Gowda, gcc-help

On 2018-09-20 17:58:30 +0200, Vincent Lefevre wrote:
> On 2018-09-20 23:21:23 +0800, Liu Hao wrote:
> > `2147483647` is an integer constant. This rule only describes floating 
> > constants, so it does not apply.
> 
> Actually the fact that it is a constant doesn't matter, but...
> 
> > According to '6.3.1.8 Usual arithmetic conversions', here `2147483647` 
> > is converted to a value having type `float`, which is then compared with 
> > `f` using the internal `long double` type.
> 
> The conversion of the int needs to be done with the precision and
> range of long double since this is neither an assignment nor a cast.

Similarly, for

  float a, b;
  double c;

  (a + b) + c;

I would expect the result of a + b to be kept in long double instead
of being converted to double due to the operand c.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-20 15:46       ` Dennis Clarke
@ 2018-09-20 16:16         ` Vincent Lefevre
  0 siblings, 0 replies; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-20 16:16 UTC (permalink / raw)
  To: gcc-help

On 2018-09-20 11:46:38 -0400, Dennis Clarke wrote:
> Not sure how you are getting FLT_EVAL_METHOD as 2.
> 
> What platform is this on ?

32-bit x86, like the OP, I assume.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-20 15:58         ` Vincent Lefevre
  2018-09-20 16:12           ` Vincent Lefevre
@ 2018-09-21  2:49           ` Liu Hao
  2018-09-22  8:17             ` Vincent Lefevre
  1 sibling, 1 reply; 17+ messages in thread
From: Liu Hao @ 2018-09-21  2:49 UTC (permalink / raw)
  To: Andrew Haley, Neha Gowda, gcc-help

在 2018-09-20 23:58, Vincent Lefevre 写道:
> On 2018-09-20 23:21:23 +0800, Liu Hao wrote:
>> `2147483647` is an integer constant. This rule only describes floating
>> constants, so it does not apply.
> 
> Actually the fact that it is a constant doesn't matter, but...
> 

The paragraph quoted by the previous message contains a sentence saying 
'...  and of floating constants are evaluated to a format ...'. While 
all following paragraphs don't mention `floating constants` explicitly, 
it is implied.

If it could be said that 'constants' included integer constants here 
then I would also reasonably think that 'all operations' here also 
included operations involving only integers - which does not make any 
sense at all.

This is not the place for discussion of the C standard. Anyway I don't 
see any problems in GCC's implementation.

>> According to '6.3.1.8 Usual arithmetic conversions', here `2147483647`
>> is converted to a value having type `float`, which is then compared with
>> `f` using the internal `long double` type.
> 
> The conversion of the int needs to be done with the precision and
> range of long double since this is neither an assignment nor a cast.
> 

If there is no indeterminate results (as in your example) then there is 
no difference.

An example where this truncation does matter is as follows, tested on 
Linux Mint 19, x64 with GCC 7.3 :

-----
lh_mouse@lhmouse-ideapad ~/Desktop $ cat test.c
#include <stdio.h>
#include <float.h>

float a = 0x1.0002p0;
float b = 0x1.0003p0;
float c = 0x1.0005p0;

int main(void)
   {
     printf("FLT_EVAL_METHOD = %d\n", (int)FLT_EVAL_METHOD);
     printf("a * b == c        ?   %d\n", a * b == c);
     printf("a * b == (float)c ?   %d\n", a * b == (float)c);
   }
lh_mouse@lhmouse-ideapad ~/Desktop $ gcc test.c  -std=c99 -O0 -m32 
-march=pentium4 -mfpmath=sse && ./a.out
FLT_EVAL_METHOD = 0
a * b == c        ?   1
a * b == (float)c ?   1
lh_mouse@lhmouse-ideapad ~/Desktop $ gcc test.c  -std=c99 -O0 -m32 && 
./a.out
FLT_EVAL_METHOD = 2
a * b == c        ?   0
a * b == (float)c ?   0
-----


-- 
Best regards,
LH_Mouse

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-21  2:49           ` Liu Hao
@ 2018-09-22  8:17             ` Vincent Lefevre
  2018-09-22 10:08               ` Vincent Lefevre
  0 siblings, 1 reply; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-22  8:17 UTC (permalink / raw)
  To: Liu Hao; +Cc: Andrew Haley, Neha Gowda, gcc-help

On 2018-09-21 10:49:19 +0800, Liu Hao wrote:
> 在 2018-09-20 23:58, Vincent Lefevre 写道:
> > On 2018-09-20 23:21:23 +0800, Liu Hao wrote:
> >> `2147483647` is an integer constant. This rule only describes floating
> >> constants, so it does not apply.
> > 
> > Actually the fact that it is a constant doesn't matter, but...
> 
> The paragraph quoted by the previous message contains a sentence saying 
> '...  and of floating constants are evaluated to a format ...'. While 
> all following paragraphs don't mention `floating constants` explicitly, 
> it is implied.

Forgot what I said at that time. It's an integer constant, thus it
is always evaluated *exactly* as an integer. Then, the rules for
type conversions in a floating-point expression are the same, whether
the values come from constants and non-constants.

Thus if one does

  float a;
  int b;

  /* ... */
  a + b;

with FLT_EVAL_METHOD = 2, the evaluation type of a is long double, b
is converted to the semantic type float, but its evaluation type is
long double, so that its value should not change if representable as
a long double. That's what FLT_EVAL_METHOD means. The *only* cases
for which the precision and range need to be reduced to those of the
semantic type if for assignment and cast, but here one just has an
implicit conversion.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-22  8:17             ` Vincent Lefevre
@ 2018-09-22 10:08               ` Vincent Lefevre
  2018-09-22 13:52                 ` Liu Hao
  0 siblings, 1 reply; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-22 10:08 UTC (permalink / raw)
  To: Liu Hao, Andrew Haley, Neha Gowda, gcc-help

On 2018-09-22 10:17:04 +0200, Vincent Lefevre wrote:
> Thus if one does
> 
>   float a;
>   int b;
> 
>   /* ... */
>   a + b;
> 
> with FLT_EVAL_METHOD = 2, the evaluation type of a is long double, b
> is converted to the semantic type float, but its evaluation type is
> long double, so that its value should not change if representable as
> a long double. That's what FLT_EVAL_METHOD means. The *only* cases
> for which the precision and range need to be reduced to those of the
> semantic type if for assignment and cast, but here one just has an
> implicit conversion.

Bug reported here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87390
(note that the tests do not involve constants, these are just about
implicit type conversions).

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-22 10:08               ` Vincent Lefevre
@ 2018-09-22 13:52                 ` Liu Hao
  2018-09-22 22:12                   ` Vincent Lefevre
  0 siblings, 1 reply; 17+ messages in thread
From: Liu Hao @ 2018-09-22 13:52 UTC (permalink / raw)
  To: Andrew Haley, Neha Gowda, gcc-help

在 2018/9/22 18:08, Vincent Lefevre 写道:
> Bug reported here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87390
> (note that the tests do not involve constants, these are just about
> implicit type conversions).
> 

That's about contraction. The behavior in the OP can only be observed 
when no optimization is enabled (i.e. with `-O0`) or when strict 
standard compliance is requested (i.e. with `-std=c99` or `-ansi`) and 
no `-ffp-contract=fast` is in effect.

It is irrelevant to this issue. Contraction is about what happens within 
a floating-point operation, but in your program (the standard says) 
`2147483647` is converted to type `float` before the floating-point 
comparison, so it behaves as if you had added a cast like `f == 
(float)2147483647`. This implicit conversion can be observed by 
compiling the program in question with `-Wconversion`. You already had 
precision loss BEFORE the comparison which is irrecoverable by any 
evaluation method.

-- 
Best regards,
LH_Mouse

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Should rand() return a RAND_MAX value for 32 bit target?
  2018-09-22 13:52                 ` Liu Hao
@ 2018-09-22 22:12                   ` Vincent Lefevre
  0 siblings, 0 replies; 17+ messages in thread
From: Vincent Lefevre @ 2018-09-22 22:12 UTC (permalink / raw)
  To: Liu Hao; +Cc: Andrew Haley, Neha Gowda, gcc-help

On 2018-09-22 21:52:34 +0800, Liu Hao wrote:
> 在 2018/9/22 18:08, Vincent Lefevre 写道:
> > Bug reported here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87390
> > (note that the tests do not involve constants, these are just about
> > implicit type conversions).
> 
> That's about contraction.

No, FLT_EVAL_METHOD is not related to contraction.

> The behavior in the OP can only be observed when no optimization is
> enabled (i.e. with `-O0`) or when strict standard compliance is
> requested (i.e. with `-std=c99` or `-ansi`) and no
> `-ffp-contract=fast` is in effect.

With the OP's program, I get False only when optimization is enabled
and strict standard compliance is not requested (or equivalent).

> It is irrelevant to this issue.

It is: If FLT_EVAL_METHOD were honored for integer-to-float
conversion, one should have never got True with strict standard
compliance, because the value of f is exactly representable in
a float and RAND_MAX isn't.

> Contraction is about what happens within a floating-point operation,

I'm not considering contraction, but FLT_EVAL_METHOD.

> but in your program (the standard says) `2147483647` is converted to
> type `float` before the floating-point comparison,

This is the semantic type. But the evaluation type is long double.

> so it behaves as if you had added a cast like `f == 
> (float)2147483647`.

No, the standard says "Except for assignment and cast (which remove
all extra range and precision), [...]", thus by adding the cast, you
are changing the semantics.

See the testcase I've posted to my bug report, and the parallel
between (float) d + (float) 1.0 and  i + 1 (both are converted
to the semantic type double, but GCC's behavior is different on
these two expressions).

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2018-09-22 22:12 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-18 12:22 Should rand() return a RAND_MAX value for 32 bit target? Neha Gowda
2018-09-18 13:09 ` Xi Ruoyao
2018-09-18 13:17   ` Xi Ruoyao
2018-09-18 13:49   ` Jonathan Wakely
2018-09-18 13:46 ` Andrew Haley
2018-09-20 14:42   ` Vincent Lefevre
2018-09-20 15:05     ` Vincent Lefevre
2018-09-20 15:21       ` Liu Hao
2018-09-20 15:58         ` Vincent Lefevre
2018-09-20 16:12           ` Vincent Lefevre
2018-09-21  2:49           ` Liu Hao
2018-09-22  8:17             ` Vincent Lefevre
2018-09-22 10:08               ` Vincent Lefevre
2018-09-22 13:52                 ` Liu Hao
2018-09-22 22:12                   ` Vincent Lefevre
2018-09-20 15:46       ` Dennis Clarke
2018-09-20 16:16         ` Vincent Lefevre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).