Click here to Skip to main content
15,885,754 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am confused by the value of "currdisk->currangle" after adding operation. Initially the value of "currdisk->currangle" is 0.77500000000000013, but after adding operation, it's changed to "-nan(0x8000000000000)", Can anyone explain ? Thanks! The following is the occasion of gdb debugging.
C++
3338          currdisk->currangle += (simtime - seg->time) / currdisk->rotatetime;
(gdb) p currdisk->currangle
$28 = 0.77500000000000013
(gdb) p (simtime - seg->time) / currdisk->rotatetime
$29 = 0.00833333333333325
(gdb) p (simtime - seg->time) 
$30 = 0.092592592592591672
(gdb) p currdisk->rotatetime
$31 = 11.111111111111111
(gdb) n

(gdb) p currdisk->currangle 
$32 = -nan(0x8000000000000)
(gdb) p/x (char[8])currdisk->currangle 
$52 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0xff}
(gdb)


Then I change
C++
currdisk->currangle += (simtime - seg->time) / currdisk->rotatetime ; 

to
C++
double tmp1 = (simtime - seg->time) / currdisk->rotatetime; 
currdisk->currangle += tmp1; 

The value of currdisk->currangle is normal. Can anyone explain the confusing phenomenon ?
Posted
Comments
[no name] 30-May-14 0:43am    
Where's your code? What types are the other variables etc.
915086731 30-May-14 3:54am    
All is double.
915086731 30-May-14 3:54am    
My code is upload to git server: github.com/915086731/test.git . After making, please run "./disksim parv.hpc3323 outv ascii traceb 0 "
915086731 30-May-14 3:57am    
Then I change
currdisk->currangle += (simtime - seg->time) / currdisk->rotatetime ;
to
double tmp1 = (simtime - seg->time) / currdisk->rotatetime;
currdisk->currangle += tmp1;
The value of currdisk->currangle is normal
[no name] 30-May-14 3:54am    
Seriously people are not going to go and download your code to solve your problems. Get real and submit a complete question with enough information for others to see what's going on. You need to provide just enough code to reproduce the problem. If you want an answer that's how to go about it.

Nothing strange at all. This is NaN — Not A Number value. Floating-point data types obey the IEEE 754 standard which defines the meaning and binary representations of this value. Please see:
http://en.wikipedia.org/wiki/IEEE_754[^],
http://en.wikipedia.org/wiki/IEEE_754[^],
http://babbage.cs.qc.cuny.edu/IEEE-754.old/References.xhtml[^].

See also: http://en.wikipedia.org/wiki/Floating-point[^].

In newer cultured platforms, things like floating-point division by zero are allowed and give infinite values. You can use infinity operations further for other calculation. For example if you calculate 1/+Inf, the result will be zero. However, floating-point division of zero by zero and some other operations create uncertainty which is denoted by the NaN result.

This is implemented in the instruction set of the FPU subsystem of Intel-compatible CPU instruction sets. You can set a flag for a process which controls the behavior of the operations like those mentioned above: either throw hardware exception or return +Inf, -Inf or NaN. To me, the only cultured decision is using those infinities and NaN values.

—SA
 
Share this answer
 
v2
Comments
915086731 30-May-14 1:22am    
Thanks! But I change the sentence to
double tmp1 = (simtime - seg->time) / currdisk->rotatetime;
currdisk->currangle += tmp1;
the value of currdisk->currangle is not NoN. It does the same work as previous.
915086731 30-May-14 1:23am    
And it's not division by zero.
[no name] 30-May-14 1:25am    
All true but how does it relate to the specifics of the question?
tmp1 = (simtime - seg->time) / currdisk->rotatetime;
currdisk->currangle += tmp1;

The above code can also cause NaN in the later calling.

So I step into to the assembly.
tmp1 = (simtime - seg->time) / currdisk->rotatetime;
0x0808fdf4  <disk_buffer_sector_done+559>:  fldl   0x80b2208
0x0808fdfa  <disk_buffer_sector_done+565>:  mov    -0x38(%ebp),%eax
0x0808fdfd  <disk_buffer_sector_done+568>:  fldl   (%eax)

...Here, the content of %eax is 0x80bdfeb, which is the address of seg->time.
After the above "fldl (%eax) " executed, the content of register st0 is 0x8000000000000000, which represents NaN.
So the NaN is propagated to the following instructions. This is the key issue.
C++
0x0808fdff  <disk_buffer_sector_done+570>:  fsubrp %st,%st(1)
0x0808fe01  <disk_buffer_sector_done+572>:  mov    0x8(%ebp),%eax
0x0808fe04  <disk_buffer_sector_done+575>:  fldl   0xc4(%eax)
0x0808fe0a  <disk_buffer_sector_done+581>:  fdivrp %st,%st(1)
0x0808fe0c  <disk_buffer_sector_done+583>:  fstpl  -0x28(%ebp)
 
Share this answer
 
v2
Comments
915086731 31-May-14 0:39am    
But I still don't know why.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900