mersenneforum.org

mersenneforum.org (https://www.mersenneforum.org/index.php)
-   Programming (https://www.mersenneforum.org/forumdisplay.php?f=29)
-   -   C or C++? (https://www.mersenneforum.org/showthread.php?t=16448)

LaurV 2012-01-31 06:30

[QUOTE=chalsall;287566]Trivial.

What might impress them is if you show up on Sunday.

And note that 26/60 is 43.3..., not 41. (And 25/60 is 41.6...; rounds to 42 not 41.)

Bonus points: show, in a debugger, why the perfectly valid C code:

[CODE]main() { int *i; printf("Illegal=%d\n", i[0]); }[/CODE]...is invalid when run.

Have a great weekend. :smile:[/QUOTE]

That code is perfect valid, and it will run ok on many OS's. For example MS-DOS. What makes it invalid for some OS's are the restrictions that applies to OS itself, not to C.

LaurV 2012-01-31 08:54

whoops edit limit (busy at work :D)

@Dubslow: a [URL="http://ioccc.org/years.html"]nice link[/URL] for you (this is mean! usually if some C newcomers see that, they will either "never want to learn C anymore", or become "real masters", depending of how impressed they are :P)

(my most obfuscated code was done together with a colleague 20 years ago, and it was computing sine function, in just few lines, looking in a table and interpolating, the nice part of it it was that the table was the source code of the program itself. I lost that beauty, but the idea is still there, now people do labyrinths and even chess-player programs, where the "moving database" and the "rules" constitute the source code itself, and even more strange marvelous things, I specially like that one which plays some game, than you can turn the source code upside-down and it still compiles right and it plays a totally different game, like chess and hangman, for example :yucky:)

xilman 2012-01-31 09:48

[QUOTE=LaurV;287867]@Dubslow: a [URL="http://ioccc.org/years.html"]nice link[/URL] for you (this is mean! usually if some C newcomers see that, they will either "never want to learn C anymore", or become "real masters", depending of how impressed they are :P)

(my most obfuscated code was done together with a colleague 20 years ago, and it was computing sine function, in just few lines, looking in a table and interpolating, the nice part of it it was that the table was the source code of the program itself.)[/QUOTE]Ah, that brings back memories.

I think my favourites were the "Best Abuse of the Rules" where the entire source code was "P;" and one in which the source consisted of an exchange of letters between two ex-lovers. The declaration "char lotte" especially sticks in my mind.

The pi calculator which consists almost entirely of a circular disk of '-' and '_' characters is a real masterpiece in the Best Layout category, even though the algorithm implemented is actually rather simple.


Many years ago I started an entry but never got enough round tuits to finish it. It was a parody of the GNU library programming style of the date --- the majority of the source code was license verbiage and what remained was separated by gratuitous #ifdef's. The library routine implemented was puts() and for one machine architecture (VAX, IIRC) the function called itself recursively by first executing putc on the first character, then copying its own binary on to the stack, and finally executing that copy on the rest of the string, if any.

ldesnogu 2012-01-31 14:27

[QUOTE=LaurV;287853]That code is perfect valid, and it will run ok on many OS's. For example MS-DOS. What makes it invalid for some OS's are the restrictions that applies to OS itself, not to C.[/QUOTE]
The code has undefined behaviour since i is not initialized, and that's not an OS property, but a language property. So one could call it invalid :smile:

ANSI C 99 states this:
[quote]Sectio J.2 Undefined behavior
The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.8, 6.8).
[/quote]

Batalov 2012-02-01 01:59

With SGI's cc, NULL pointers were dereferencing just fine. No segv!
I still remember that. :=/

ldesnogu 2012-02-01 11:29

[QUOTE=Batalov;287950]With SGI's cc, NULL pointers were dereferencing just fine. No segv!
I still remember that. :=/[/QUOTE]
Yes, various machines have different behaviours with NULL pointers. IIRC the original mac had no issue reading @0, while the AtariST couldn't. In both cases it was a hardware feature, as the AtariST was setting the 0-0x3FF range as privileged.

Anyway, my point above was more about the fact that declaring int *i and then using i[0] isn't really dereferencing NULL, but rather using an uninitialised value of i :smile:

Christenson 2012-02-01 12:10

There's a simple rule for this:

Well-formed code has behavior that can be completely determined from the source code alone.

retina 2012-02-01 12:25

[QUOTE=Christenson;287969]There's a simple rule for this:

Well-formed code has behavior that can be completely determined from the source code alone.[/QUOTE]... which applies to the piece of code in question. The behaviour of that code is completely determinable, namely it will read a "random" memory location. And that can be completely determined from the source code.

CRGreathouse 2012-02-01 12:39

[QUOTE=Christenson;287969]There's a simple rule for this:

Well-formed code has behavior that can be completely determined from the source code alone.[/QUOTE]

What about random numbers, time/date, and other things that will change without regard to the source?

[QUOTE=retina;287970]... which applies to the piece of code in question. The behaviour of that code is completely determinable, namely it will read a "random" memory location. And that can be completely determined from the source code.[/QUOTE]

Certainly not, that's an implementation issue. The compiler is allowed to act in any fashion, including to crash or to read from a fixed (nonrandom) location.

Christenson 2012-02-03 12:45

[QUOTE=Christenson;287969]There's a simple rule for this:

Well-formed code has behavior that can be completely determined from the source code *AND THE INPUTS* alone.[/QUOTE]

the return value from rand() and date-time functions can be considered input.

*************
Got to reading about the JAVA threading model last night..turns out, there's no way to terminate a thread without cooperation from the thread...the excuse given is that your thread might hold a resource lock or something and leave the code system in an unstable state.

Given the number of times I've had to involuntarily terminate Windows itself lately, that seems fundamentally out of principle for a large programming system.

Dubslow 2012-02-12 05:01

How many digits can a (standard) double hold? My sizeof(double) gives me 8, so we should expect ~62-63 bits or ~18 digits, but this prog appears to be limited to about 7.


Edit: To view source with full screen, see [url]http://dubslow.tk/random/trig[/url]
Code:
[code]
/* A derp program to calculate sines and cosines of input floating point numbers.
*/

#include <stdio.h>
#include <stdlib.h>
#define PI 3.141592653589
#define ACC 0.000001

double power(double num, int power);
long int fact(int); // Longs can only handle up to 20!; see next comment block

double sin(double);
//double cos(double);

int main(void) {
double input;
printf("\n\n");
printf("Please enter a number x: ");
scanf("%lf", &input);
printf("You entered %f\n", input);
while( input>PI ) // Taking advantage of the periodicty of the trig functions.
input -= 2*PI; // Taylor approximations to 20th* order are accurate to one part per million
while( input<(-PI) ) // when |x|<~4.162, so if |x|>PI, add/subtract 2PI until |x|<PI.
input += 2*PI; // *21 factorial overflows a lont int.
printf("cos(x) = 0"/* %0.4f */", and sin(x) = %f\n", /*cos(input),*/ sin(input) );
return 7;
}

double power(double num, int expo) {
// printf("calculating %f to the %d power\n", num, expo);
double product=num;
for(;expo>1;expo--)
product *= num;
// printf("result of power is %f\n", product);
return product;
}

long int fact(int x) {
long int product=x;
for(x--;x>1;x--)
product *= x;
return product;
}

double sin(double x) {
int i;
int order=0;
double sum=x;
// printf("sum is %f\n", sum);
for(i=3; !order && i<20 ; i+=2) { // Not the most efficient way, but whatever. Calculates order of approximation necessary for
// accuracy of 1 part per million.
if( ( (power(x,i)<=0) && (power(x,i)/fact(i) >= (-ACC) )) || // This is the test.
( (power(x,i)>=0) && (power(x,i)/fact(i) <= ACC ) ) // If the i'th term is smaller than the defined accuracy, choose that i as the order.
)
order=i;
if(i==19)order=19;
}
printf("sin order is %d\n", order); // Calculation using chosen order
for(i=3; i<=order; i+=2)
sum += ( power(x,i)/fact(i)* ( (i%4==3)?-1:1) ); // Sign of term changes each time. 3,7... etc. are negative terms, 1,5... etc. are positive.
return sum;
}[/code]

Output:
[code]bill@Gravemind:~/bin/c∰∂ trig


Please enter a number x: .5
You entered 0.500000
sin order is 9
cos(x) = 0, and sin(x) = 0.479426
bill@Gravemind:~/bin/c∰∂ trig


Please enter a number x: 3.141562653589
You entered 3.141563
sin order is 17
cos(x) = 0, and sin(x) = 0.000030
bill@Gravemind:~/bin/c∰∂ trig


Please enter a number x: .254
You entered 0.254000
sin order is 7
cos(x) = 0, and sin(x) = 0.251278
bill@Gravemind:~/bin/c∰∂ trig


Please enter a number x: 5
You entered 5.000000
sin order is 11
cos(x) = 0, and sin(x) = -0.958924[/code]


All times are UTC. The time now is 08:00.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.