25 July 2018, 23:09 | #41 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
My C programming knowledge has almost faded away in the last 12 years and was never good, but you could try something to display the hexadecimal values of the floating point results like this (correct it if it's wrong):
Code:
#include <math.h> #include <stdio.h> int main(int argc, char const *argv[]) { double a = M_PI / 2; double x = cos(a); double y = sin(a); ulong *a1 = (ulong *)&a; ulong *a2 = (ulong *)&a+4; ulong *x1 = (ulong *)&x; ulong *x2 = (ulong *)&x+4; ulong *y1 = (ulong *)&y; ulong *y2 = (ulong *)&y+4; printf("%f: %f, %f\n", a, x, y); printf("a = %08lx %08lx, x = %08lx %08lx, y = %08lx %08lx\n", a1, a2, x1, x2, y1 ,y2); return 0; } Last edited by PeterK; 25 July 2018 at 23:48. |
26 July 2018, 00:31 | #42 |
Registered User
Join Date: Jul 2009
Location: UK
Posts: 112
|
Are you sure its not a precision error or rounding error. I read somewhere a while back to not use float and stick to double for more consistent / accurate maths.
What is the accuracy of cos/sin functions and does the storing of the variables crop the accuracy ? We dont know the implementation used to calculate Cos/Sin - during the internal calculation, temp variable storage/math could have errors. Scientists /mathematicians NEED accuracy and reliability - without it - its just not useful tool. AKA standards. Casting is NEVER good. Your just asking for trouble. Compiling on different architecture systems would lead to very different results as all machines store/process the data differently. very unsafe practice. |
26 July 2018, 00:44 | #43 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
It could be either
a) Not original library, altered. (Cause you know...internet) b) emulation side-effect bug Probably someone with 2.04 has to run this http://eab.abime.net/showpost.php?p=...1&postcount=18 on real hardware. If it works, we need the md5sum of mathieeedoubbas.library. If it doesn't work then original system had the bug too, which I think is unlikely. @PeterK Something like that? Code:
#include <math.h> #include <stdio.h> void print(char *name, double *d, int size) { char buf[80]; char *c = (char *)d; char *s = &buf[0]; for (int i = 0; i < size; ++i, s+=2, ++c) sprintf(s, "%02X", *c); *s = '\0'; printf("%s %f %s\n", name, *d, buf); } int main(int argc, char const *argv[]) { double a = M_PI / 2; double x = cos(a); double y = sin(a); printf("%f: %f, %f\n", a, x, y); printf("%f\n", cos(M_PI / 2)); printf("%f\n", sin(M_PI / 2)); print("a", &a, sizeof(double)); print("x", &x, sizeof(double)); print("y", &y, sizeof(double)); return 0; } |
26 July 2018, 01:05 | #44 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
@alkis
No, I don't know what you are trying now, but all I would like to do is to print the hexadecimal values of a, x and y as they are stored in memory like a = 1.570796 = $3FF921FB $54442D18 x = 0.000000 = $00000000 $00000000 y = 1.000000 = $3FF00000 $00000000 ... but I don't want to get in touch with a C compiler now. I hate C ! Can you compile and test my code for me? Thx @asymetrix casting is only used here to keep the compiler quiet. I'm just trying to assign pointers to the memory locations of the double values of a, x and y. I'm not trying to convert the contents of a, x or y in any way. Last edited by PeterK; 26 July 2018 at 01:37. |
26 July 2018, 02:58 | #45 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
I have ruled out emulator settings, and I think we can rule out the emulator also. With the only difference of putting the exe on a WB2.1 disk instead of a 2.04 disk, under WB2.1 it shows the correct value. Tested with and without SetPatch.
But this only means that you need WB 2.1 to run the generated code and get the expected result. So that we run the same executable doesn't mean anything, cos we swapped out the OS. If we suspect libs, then it only takes one line of code to see if sin(M_PI/2) gives the expected result on WB 2.04. This could be done in any language that uses sin(). It could be done several times with different precision. |
26 July 2018, 03:15 | #46 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
The bad code is not in sin() directly, because the mathieeedoubtrans.library is the same in 2.04, 2.1 and 3.1, isn't it? The bad code comes from a function in mathieeedoubas.library. And that's what we still want to find out. It could be Add(), Sub(), Mul() or Div(), but I won't suspect these basic functions to be buggy. My guess is the Fix() function. Or maybe a bad Cmp(), who knows?
Last edited by PeterK; 26 July 2018 at 03:21. |
26 July 2018, 03:42 | #47 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
Ok, to make things even worse...
I compiled (beebo's gcc 6) the 'show me the hex bytes' thing. The values (aside from endianess) are the same on amiga and linux. The thing is, executable from gcc displays correct values with "bad" and with "good" library. I remember seeing Beebo mentioning something like you need to open math-single library even if you are to use only the double or you get incorrect values...let me try to find that reference. Found it: https://github.com/bebbo/gcc/issues/...ment-366931667 Last edited by alkis; 26 July 2018 at 03:51. Reason: added url |
26 July 2018, 04:05 | #48 | |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
Found at least 2 bugs in the v37 Double Cmp() function. That could be used by Sin(), by Printf() or other functions, but most likely the buggy Cmp() is used by Printf() and that gives a wrong decision.
Quote:
Update: Found the same 2 Cmp() bugs also in v38.2, which is still used by OS 3.1! (this is fixed in v45 and perhaps OS 3.1.4) A fix for v38.2 is attached to post #55 below. So, we have to search for the culprit again ... later ... Last edited by PeterK; 26 July 2018 at 11:14. |
|
26 July 2018, 08:13 | #49 | |
Registered User
Join Date: Nov 2016
Location: DE
Posts: 20
|
Quote:
EDIT: (*) unless you have a byte pointer of course... |
|
26 July 2018, 08:37 | #50 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
|
26 July 2018, 08:46 | #51 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Maybe the problem is only showing up in printf - playing with the format string can cause the problem to disappear.
The following code should print three lines of 0 and 1, each line formatted slightly differently, but still printing the same values. the first and third lines are correct, but the second one isn't: Code:
#include <math.h> #include <stdio.h> int main(int argc, char const *argv[]) { double y = sin(M_PI / 2); double x = cos(M_PI / 2); printf("%0.0f %0.0f\n", x, y); printf("%f %f\n", x, y); printf("%7.3f %7.3f\n", x, y); return 0; } 0 1 0.000000 0.000000 0.00 1.000 |
26 July 2018, 09:22 | #52 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
And this shows that it only happens when I have more then one %f in my printf:
Code:
#include <math.h> #include <stdio.h> int main(int argc, char const *argv[]) { double x = cos(M_PI / 2); double y = sin(M_PI / 2); printf("zero zero then zero zero\n"); printf("%f %f\n", x, x); printf("%f ", x); printf("%f\n", x); printf("%0.3f %0.3f\n", x, x); printf("\n"); printf("zero one then zero one\n"); printf("%f %f\n", x, y); printf("%f ", x); printf("%f\n", y); printf("%0.3f %0.3f\n", x, y); printf("\n"); printf("one one then one one\n"); printf("%f %f\n", y, y); printf("%f ", y); printf("%f\n", y); printf("%0.3f %0.3f\n", y, y); return 0; } |
26 July 2018, 10:02 | #53 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
And the problem doesn't happen with variables that have been set to 1.0, only those that are very very close to 1.0 like the result of sin(M_PI / 2).
Code:
#include <math.h> #include <stdio.h> int main(int argc, char const *argv[]) { double x = 0.0; double y = 1.0; printf("zero one zero\n"); printf("%f %f %f\n", x, y, x); printf("\n"); printf("one zero one\n"); printf("%f %f %f\n", y, x, y); printf("\n"); x = cos(M_PI / 2); y = sin(M_PI / 2); printf("zero one zero\n"); printf("%f %f %f\n", x, y, x); printf("\n"); printf("one zero one\n"); printf("%f %f %f\n", y, x, y); printf("\n"); return 0; } |
26 July 2018, 10:45 | #54 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Correction to above - it's not 1.0 that's the problem, it's 0.0.
The result of cos(M_PI / 2) is poisonous to printf. The following code gives -1.000000 0.000000 1.000000 2.000000 3.000000 -1.000000 0.000000 0.000000 0.000000 0.000000 Once that poisonous zero gets eaten by printf, everything it does is broken. Code:
#include <math.h> #include <stdio.h> int main(int argc, char const *argv[]) { double neg_one = sin(-M_PI / 2); double zero = cos(M_PI / 2); double really_zero = 0.0; double one = sin(M_PI / 2); double two = 2.0; double three = 3.0; printf("%f %f %f %f %f\n", neg_one, really_zero, one, two, three); // good printf("%f %f %f %f %f\n", neg_one, zero, one, two, three); // bad return 0; } Last edited by deimos; 26 July 2018 at 10:54. |
26 July 2018, 11:11 | #55 |
Registered User
Join Date: Apr 2005
Location: digital hell, Germany, after 1984, but worse
Posts: 3,365
|
Btw, I found a mathieeedoubbas.library v39.1 on my harddisk, which is exactly a fix for the Cmp() bug in v38.2 that I mentioned in my previous post. Since I could not find the source for this patch from 1999, I've recreated it now. It has nothing to do with the printf() problem, but it could be useful for OS 3.1.
|
26 July 2018, 11:17 | #56 |
Registered User
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
|
@deimos
I just saw your makefile. You don't link with math library. No -lmieee Try this vc bug.c -o bug -lmieee |
26 July 2018, 11:28 | #57 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
|
26 July 2018, 11:44 | #58 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
|
26 July 2018, 12:16 | #59 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Perhaps I'll just do this:
Code:
#include <math.h> #include <stdio.h> double f(double a) { if (a > -1e-9 && a < 1e-9) return 0.0; return a; } int main(int argc, char const *argv[]) { double neg_one = sin(-M_PI / 2); double zero = cos(M_PI / 2); double really_zero = 0.0; double one = sin(M_PI / 2); double two = 2.0; double three = 3.0; printf("%f %f %f %f %f\n", neg_one, really_zero, one, two, three); // good printf("%f %f %f %f %f\n", neg_one, zero, one, two, three); // bad printf("%f %f %f %f %f\n", f(neg_one), f(zero), f(one), f(two), f(three)); // fudged return 0; } |
26 July 2018, 12:30 | #60 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Printing enough decimal places also makes the problem go away.
Code:
printf("%0.13f\n%0.13f\n%0.13f\n%0.13f\n%0.13f\n\n", neg_one, zero, one, two, three); // good printf("%0.12f\n%0.12f\n%0.12f\n%0.12f\n%0.12f\n\n", neg_one, zero, one, two, three); // bad |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
vbcc 0.9f released | phx | News | 49 | 01 April 2018 11:33 |
vbcc V0.9e released | phx | News | 17 | 31 October 2016 21:18 |
VBCC and #include | majikeyric | Coders. C/C++ | 3 | 03 March 2016 15:07 |
vbcc 0.9d | phx | News | 43 | 13 July 2015 19:41 |
VBCC 0.8j for Windows | hitchhikr | Coders. General | 11 | 09 October 2008 00:58 |
|
|