public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/28038]  New: Double to char conversion fails at 32769.0
@ 2006-06-15 10:16 barryb at cwipapps dot net
  2006-06-15 10:17 ` [Bug c/28038] " falk at debian dot org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: barryb at cwipapps dot net @ 2006-06-15 10:16 UTC (permalink / raw)
  To: gcc-bugs

The program 
#include <stdio.h>

main()
{
double d;
int i;

    printf("Starting at 32758\n");
    for (d=32758.0, i=0; i<20; i++) {
           printf("d is %f, as integer is 0x%0.8x, and (ushort)d is 0x%0.4x
while (unsigned char)d is 0x%0.2x\n",
                                                                  d, (int)d,
(unsigned short)d, (unsigned char)d);
       d += 1.0;
    }
    return 0;
}
gives the following output on Intel
Starting at 32758
d is 32758.000000, as integer is 0x00007ff6, and (ushort)d is 0x7ff6 while
(unsigned char)d is 0xf6
d is 32759.000000, as integer is 0x00007ff7, and (ushort)d is 0x7ff7 while
(unsigned char)d is 0xf7
d is 32760.000000, as integer is 0x00007ff8, and (ushort)d is 0x7ff8 while
(unsigned char)d is 0xf8
d is 32761.000000, as integer is 0x00007ff9, and (ushort)d is 0x7ff9 while
(unsigned char)d is 0xf9
d is 32762.000000, as integer is 0x00007ffa, and (ushort)d is 0x7ffa while
(unsigned char)d is 0xfa
d is 32763.000000, as integer is 0x00007ffb, and (ushort)d is 0x7ffb while
(unsigned char)d is 0xfb
d is 32764.000000, as integer is 0x00007ffc, and (ushort)d is 0x7ffc while
(unsigned char)d is 0xfc
d is 32765.000000, as integer is 0x00007ffd, and (ushort)d is 0x7ffd while
(unsigned char)d is 0xfd
d is 32766.000000, as integer is 0x00007ffe, and (ushort)d is 0x7ffe while
(unsigned char)d is 0xfe
d is 32767.000000, as integer is 0x00007fff, and (ushort)d is 0x7fff while
(unsigned char)d is 0xff
d is 32768.000000, as integer is 0x00008000, and (ushort)d is 0x8000 while
(unsigned char)d is 0x00
d is 32769.000000, as integer is 0x00008001, and (ushort)d is 0x8001 while
(unsigned char)d is 0x00
d is 32770.000000, as integer is 0x00008002, and (ushort)d is 0x8002 while
(unsigned char)d is 0x00
d is 32771.000000, as integer is 0x00008003, and (ushort)d is 0x8003 while
(unsigned char)d is 0x00
d is 32772.000000, as integer is 0x00008004, and (ushort)d is 0x8004 while
(unsigned char)d is 0x00
d is 32773.000000, as integer is 0x00008005, and (ushort)d is 0x8005 while
(unsigned char)d is 0x00
d is 32774.000000, as integer is 0x00008006, and (ushort)d is 0x8006 while
(unsigned char)d is 0x00
d is 32775.000000, as integer is 0x00008007, and (ushort)d is 0x8007 while
(unsigned char)d is 0x00
d is 32776.000000, as integer is 0x00008008, and (ushort)d is 0x8008 while
(unsigned char)d is 0x00
d is 32777.000000, as integer is 0x00008009, and (ushort)d is 0x8009 while
(unsigned char)d is 0x00

That is, the unsigned char is always zero after 32769.0

On Sparc, with gcc (GCC) 3.3.2, we see
Starting at 32758
d is 32758.000000, as integer is 0x00007ff6, and (ushort)d is 0x7ff6 while
(unsigned char)d is 0xf6
d is 32759.000000, as integer is 0x00007ff7, and (ushort)d is 0x7ff7 while
(unsigned char)d is 0xf7
d is 32760.000000, as integer is 0x00007ff8, and (ushort)d is 0x7ff8 while
(unsigned char)d is 0xf8
d is 32761.000000, as integer is 0x00007ff9, and (ushort)d is 0x7ff9 while
(unsigned char)d is 0xf9
d is 32762.000000, as integer is 0x00007ffa, and (ushort)d is 0x7ffa while
(unsigned char)d is 0xfa
d is 32763.000000, as integer is 0x00007ffb, and (ushort)d is 0x7ffb while
(unsigned char)d is 0xfb
d is 32764.000000, as integer is 0x00007ffc, and (ushort)d is 0x7ffc while
(unsigned char)d is 0xfc
d is 32765.000000, as integer is 0x00007ffd, and (ushort)d is 0x7ffd while
(unsigned char)d is 0xfd
d is 32766.000000, as integer is 0x00007ffe, and (ushort)d is 0x7ffe while
(unsigned char)d is 0xfe
d is 32767.000000, as integer is 0x00007fff, and (ushort)d is 0x7fff while
(unsigned char)d is 0xff
d is 32768.000000, as integer is 0x00008000, and (ushort)d is 0x8000 while
(unsigned char)d is 0x00
d is 32769.000000, as integer is 0x00008001, and (ushort)d is 0x8001 while
(unsigned char)d is 0x01
d is 32770.000000, as integer is 0x00008002, and (ushort)d is 0x8002 while
(unsigned char)d is 0x02
d is 32771.000000, as integer is 0x00008003, and (ushort)d is 0x8003 while
(unsigned char)d is 0x03
d is 32772.000000, as integer is 0x00008004, and (ushort)d is 0x8004 while
(unsigned char)d is 0x04
d is 32773.000000, as integer is 0x00008005, and (ushort)d is 0x8005 while
(unsigned char)d is 0x05
d is 32774.000000, as integer is 0x00008006, and (ushort)d is 0x8006 while
(unsigned char)d is 0x06
d is 32775.000000, as integer is 0x00008007, and (ushort)d is 0x8007 while
(unsigned char)d is 0x07
d is 32776.000000, as integer is 0x00008008, and (ushort)d is 0x8008 while
(unsigned char)d is 0x08
d is 32777.000000, as integer is 0x00008009, and (ushort)d is 0x8009 while
(unsigned char)d is 0x09

Which seems more intuitively correct.
This problem is also found on a XEON proccessor with 
gcc (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-47)


-- 
           Summary: Double to char conversion fails at 32769.0
           Product: gcc
           Version: 3.4.5
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: barryb at cwipapps dot net
 GCC build triplet: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)
  GCC host triplet: 2.6.9-34.0.1.ELsmp #1 SMP Wed May 24 08:14:29 CDT 2006
                    i686 i686
GCC target triplet:  Pentium III (Coppermine)


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28038


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

* [Bug c/28038] Double to char conversion fails at 32769.0
  2006-06-15 10:16 [Bug c/28038] New: Double to char conversion fails at 32769.0 barryb at cwipapps dot net
@ 2006-06-15 10:17 ` falk at debian dot org
  2006-06-15 16:04 ` barryb at cwipapps dot net
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: falk at debian dot org @ 2006-06-15 10:17 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from falk at debian dot org  2006-06-15 10:16 -------
If the value of the integral part cannot be represented by the integer type,
the behavior is undefined. So this is not a bug.


-- 

falk at debian dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
 GCC target triplet| Pentium III (Coppermine)   |Pentium III (Coppermine)
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28038


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

* [Bug c/28038] Double to char conversion fails at 32769.0
  2006-06-15 10:16 [Bug c/28038] New: Double to char conversion fails at 32769.0 barryb at cwipapps dot net
  2006-06-15 10:17 ` [Bug c/28038] " falk at debian dot org
@ 2006-06-15 16:04 ` barryb at cwipapps dot net
  2006-06-15 16:14 ` schwab at suse dot de
  2006-06-15 17:23 ` barryb at cwipapps dot net
  3 siblings, 0 replies; 5+ messages in thread
From: barryb at cwipapps dot net @ 2006-06-15 16:04 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from barryb at cwipapps dot net  2006-06-15 15:54 -------
The integers in the example ARE all within the range of unsigned short.
Therefore Falk's comments may be true, but are not relevant.

Note also that the same code works as expected on sparc.

We think that the problem lies in the generation of fistps rather than fistpl
opcodes, since the latter seems to work.

Somehow, MySQL AB have found a way to compile such expressions correctly in
their
4.0.23 function, scramble()


-- 

barryb at cwipapps dot net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |barryb at cwipapps dot net
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|INVALID                     |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28038


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

* [Bug c/28038] Double to char conversion fails at 32769.0
  2006-06-15 10:16 [Bug c/28038] New: Double to char conversion fails at 32769.0 barryb at cwipapps dot net
  2006-06-15 10:17 ` [Bug c/28038] " falk at debian dot org
  2006-06-15 16:04 ` barryb at cwipapps dot net
@ 2006-06-15 16:14 ` schwab at suse dot de
  2006-06-15 17:23 ` barryb at cwipapps dot net
  3 siblings, 0 replies; 5+ messages in thread
From: schwab at suse dot de @ 2006-06-15 16:14 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from schwab at suse dot de  2006-06-15 16:04 -------
It is still undefined to convert a float to an integer that is too narrow.  The
range of short is irrelevant when converting to char.  Since the behaviour is
undefined there is no requirement on the resulting value.  If you want defined
behaviour you must first cast to an integer that is wide enough, then you can
cast to the narrower (unsigned) type.


-- 

schwab at suse dot de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28038


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

* [Bug c/28038] Double to char conversion fails at 32769.0
  2006-06-15 10:16 [Bug c/28038] New: Double to char conversion fails at 32769.0 barryb at cwipapps dot net
                   ` (2 preceding siblings ...)
  2006-06-15 16:14 ` schwab at suse dot de
@ 2006-06-15 17:23 ` barryb at cwipapps dot net
  3 siblings, 0 replies; 5+ messages in thread
From: barryb at cwipapps dot net @ 2006-06-15 17:23 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from barryb at cwipapps dot net  2006-06-15 17:15 -------
Sorry, you are right; you have to cast it twice.
I'd moved on to 

d is 32765.000000, as integer is 0x00007ffd, and (ushort)d is 0x7ffd while
(uchar)(ushort)d is 0xfd
d is 32766.000000, as integer is 0x00007ffe, and (ushort)d is 0x7ffe while
(uchar)(ushort)d is 0xfe
d is 32767.000000, as integer is 0x00007fff, and (ushort)d is 0x7fff while
(uchar)(ushort)d is 0xff
d is 32768.000000, as integer is 0x00008000, and (ushort)d is 0x8000 while
(uchar)(ushort)d is 0x00
d is 32769.000000, as integer is 0x00008001, and (ushort)d is 0x8001 while
(uchar)(ushort)d is 0x01
d is 32770.000000, as integer is 0x00008002, and (ushort)d is 0x8002 while
(uchar)(ushort)d is 0x02

Which works for this width of integer.

For some reason the following code 
 *to++= (char) (floor(my_rnd(&rand_st)*31)+64);
seems to work in MySQL 4.0.23 for Linux, but not when I use it.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28038


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

end of thread, other threads:[~2006-06-15 17:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-15 10:16 [Bug c/28038] New: Double to char conversion fails at 32769.0 barryb at cwipapps dot net
2006-06-15 10:17 ` [Bug c/28038] " falk at debian dot org
2006-06-15 16:04 ` barryb at cwipapps dot net
2006-06-15 16:14 ` schwab at suse dot de
2006-06-15 17:23 ` barryb at cwipapps dot net

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).