![]() |
|
|
#1 |
|
Nov 2003
22×5×373 Posts |
Here is a snippet of code: (called in a loop that increments e)
if (e < lower_midpt) f_lower = round_double1(lm1 * (double)e + lc1 + .5); else f_lower = round_double1(lm2 * (double)e + lc2 + .5); if (e < lower_midpt) printf("LESS: \n"); else printf("MORE: \n"); if (e < lower_midpt) printf("LESS: %lf, %d\n",lower_midpt, e); else printf("MORE: %lf %d\n", lower_midpt, e); ========================================================= Here is some output LESS: LESS: -36.319540, -42 old_flower = 52 LESS: LESS: -36.319540, -41 old_flower = 44 LESS: LESS: -36.319540, -40 old_flower = 35 LESS: LESS: -36.319540, -39 old_flower = 27 LESS: LESS: -36.319540, -38 old_flower = 18 LESS: LESS: -36.319540, -37 old_flower = 10 MORE: MORE: -36.319540 -36 old_flower = 4 LESS: MORE: -36.319540 -35 old_flower = 4 LESS: MORE: -36.319540 -34 old_flower = 4 LESS: MORE: -36.319540 -33 old_flower = 4 LESS: MORE: -36.319540 -32 old_flower = 3 LESS: MORE: -36.319540 -31 old_flower = 3 LESS: MORE: -36.319540 -30 old_flower = 3 LESS: MORE: -36.319540 -29 old_flower = 3 LESS: MORE: -36.319540 -28 Would anyone care to explain this? As e increments from -36 to -35 suddenly the first comparison against midpt (-36.3) says -35 is less than -36.3. But the second comparison gives a different answer. I am not making this up!!! Bob |
|
|
|
|
|
#2 | |
|
Nov 2003
164448 Posts |
Quote:
|
|
|
|
|
|
|
#3 |
|
"Nancy"
Aug 2002
Alexandria
246710 Posts |
What does the round_double1() function do? Is that the asm function to convert a double to an int we discussed in the other thread?
My initial guess is that the compiler keeps lower_midpt on top of the cpu stack and, since it doesn't know that round_double1() works on that stack, rearranges the opcodes so that the first if() ends up comparing e to the argument of the lower_midpt() function. I'd need to take a look at the asm output for this code snippet. Alex |
|
|
|
|
|
#4 | |
|
Nov 2003
22·5·373 Posts |
Quote:
I am not sure if your explanation is right, or if somehow fistp resets the FPU control word somehow.. Adding finit to round_double1() fixes the problem. I wish there were a way to avoid it, since finit is expensive. I am going to try popping the stack by fistp rather than fist Bob |
|
|
|
|
|
|
#5 |
|
"Nancy"
Aug 2002
Alexandria
2,467 Posts |
Oh. right. I hadn't noticed. If this is the code you're using
__inline int iceil(double a) { int d; const double h = 0.5000001f; _asm { fld a fadd h fist d }; return d; } it's surprising it works at all. If you load a value onto the stack with FLD, you need to get rid of it again, so use FISTP. Otherwise you'll just keep pushing things onto the stack and any value that was on it will never see the light of day again. The FIST would be good if you had a way to tell the compiler that the value is staying there, which is easy with the gcc asm() block - I don't know how to do it with VC, tough. Also, make the _asm_ block volatile so the compiler keeps it in a single block - reordering might lead to trouble if the compiler does not know about what is going on on the FPU stack. I REALLY recommend using the lrint() function instead. Alex Last fiddled with by akruppa on 2005-07-27 at 16:19 |
|
|
|
|
|
#6 | |
|
Nov 2003
1D2416 Posts |
Quote:
Popping the is indeed correct. As for lrint(), Microsoft VC++ doesn't seem to know about it. At least, it is not indexed under 'help'' at all. |
|
|
|
|
![]() |
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| 2 holes in bizarre theorem about composite Mersenne Numbers | wildrabbitt | Math | 120 | 2016-09-29 21:52 |
| Alert Sound | Cricage | Information & Answers | 3 | 2016-01-21 16:49 |
| Bizarre problem with gnfs-lasieve4I15e | fivemack | Factoring | 1 | 2007-11-27 17:12 |
| Spam Alert (all over again) | S485122 | Forum Feedback | 8 | 2006-11-10 15:51 |
| SPAMBOT ALERT! | Andi47 | Lounge | 25 | 2006-11-03 04:33 |