Bug 150917

Summary: unexpected results in double to unsigned long long conversion
Product: [Fedora] Fedora Reporter: Tom Horsley <horsley1953>
Component: gcc34Assignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 3   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-03-12 00:09:25 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Description Flags
C program to demo bug none

Description Tom Horsley 2005-03-11 23:34:40 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.6) Gecko/20050302 Firefox/1.0.1 Fedora/1.0.1-1.3.2

Description of problem:
Converting a double (or a float) to unsigned long long appears to truncate the result to 32 bits (which is certainly unexpected for double since the mantissa can have more than 32 significant bits). The unexpected results are most obvious when the double or float value is negative (certainly a strange thing to convert to unsigned :-). I'd expect to see the same 64 bits in the result when I convert to unsigned long long as when I convert to long long, but the unsigned form is truncated. I'll see if I can attach the conv.c program that demos this.

Version-Release number of selected component (if applicable):
gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)

How reproducible:

Steps to Reproduce:
1. Compile the conv.c program with gcc -o conv -g conv.c
2. run the ./conv executable
3. see the different results for long long and unsigned long long

Actual Results:  llt[0] = 0xffffffffffffffd1 ullt[0] = 0x00000000ffffffd1
llt[1] = 0x0000000000000016 ullt[1] = 0x0000000000000016
llt[2] = 0xffffffffffffffd1 ullt[2] = 0x00000000ffffffd1
llt[3] = 0x0000000000000016 ullt[3] = 0x0000000000000016

Expected Results:  llt[0] = 0xffffffffffffffd1 ullt[0] = 0xffffffffffffffd1
llt[1] = 0x0000000000000016 ullt[1] = 0x0000000000000016
llt[2] = 0xffffffffffffffd1 ullt[2] = 0xffffffffffffffd1
llt[3] = 0x0000000000000016 ullt[3] = 0x0000000000000016

Additional info:

I admit this could be considered an undefined operation so any results would be valid, but getting different bits merely because I said unsigned seems awful strange (actually getting zero as a result for negative values would make more sense than what I'm seeing :-).

Comment 1 Tom Horsley 2005-03-11 23:36:39 UTC
Created attachment 111913 [details]
C program to demo bug

Comment 2 Jakub Jelinek 2005-03-12 00:09:25 UTC
See ISO C99,
... If the value being converted is outside the range of values that can be
represented, the behavior is undefined.

Any value is ok for undefined behaviour.  The program shouldn't make any
expectations about what happens in that case.