Willsy Posted March 11, 2022 Share Posted March 11, 2022 (edited) 9 hours ago, dhe said: the other was this neat little hack to convert from a char to an int. mychoice2 = mychoice_char - '0'; // convert single char to int!! Careful! There be demons! It's not really converting from a char (as in, the C data type of char) - as you correctly pointed out, you would use a cast for that: int choice; choice = (int)mychoice2; // choice is now an integer version of the char type mychoice2 The code you posted is converting from an ASCII value to a zero-based equivalent of the ASCII value. So, if mychoice2 had the value 49 (which is the ascii code for the ascii character '1'), then the code above would subtract 48 from it (which the ascii character value for '0') and leave the result of 1, so you've converted the ASCII character value of '1' to the numeric value 1. It's a subtle, semantic (and somewhat pedantic, if I'm honest!) difference, but I thought it would point it out! The compiler is clever enough to replace the char constant '0' with the value 48. So, the compiler sees the code as if you wrote it like this: mychoice2 = mychoice_char - 48; Edited March 11, 2022 by Willsy Typos 2 Quote Link to comment Share on other sites More sharing options...
+FarmerPotato Posted March 11, 2022 Share Posted March 11, 2022 Hi @dhe Welcome to the surprising world of type conversions! I wonder what c99 does with int promotion? If it follows C standard rules, all arithmetic takes place in int. Arithmetic on chars first converts the char input to int. C has always allowed the most natural size to be chosen. so that int fits in a machine register. And the usual arithmetic instructions wants register-sizes inputs. Nowadays in C11, we can say uint16_t to be sure we get exactly what we want! mychoice2 = mychoice_char - '0'; // convert single char to int!! The result of the expression is (signed) int. If you were to assign it back to a char, the result could have the range -128 to 127. Besides subtraction, you might sometimes want to scale: char r; int c = (r- ‘0’) * 2 * 22 / 7; You can see how if it did the arithmetic with just 8 bits, the multiplication would overflow. But MPY and DIV generally use register size operands. If the inputs were large enough to overflow an int, you get a weird outcome. I dunno what c99 gives! Internally, a 9900 MPY takes two 16 bit operands, gives 32 bits, and DIV takes it back down to 16. I wonder if c99 lets that happen naturally, or if it enforces C rules and chops the result of MPY down to 16 bits before the DIV? It’s good to explore these things, so that later you have the knowledge to debug C! 4 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 11, 2022 Share Posted March 11, 2022 Can't we just look as the assembler code output? Quote Link to comment Share on other sites More sharing options...
+dhe Posted March 17, 2022 Author Share Posted March 17, 2022 In earlier release of c99 Clint wrote many example programs, attached is one I always loved. It mentally challenging (to me) to picture all that's happening - but it isn't much to look at on the screen. (I need to c if I can find a version of life written in c99). /* A c version of the Sieve program as suggested by KNUTH */ #define true 1 #define false 0 #define size 8190 #define sized 8191 /**/ int flags[sized]; #asm AORG >8330 #endasm int i,k,prime,count,iter,strikout; #asm RORG #endasm main() { puts("10 iterations\n\n"); iter=1; while(iter++<=10) { strikout=true; count=0; i=0; while(i<=size) flags[i++]=true; i=1; while(i<=size) { if(flags[i]) { prime=i+i+1; ++count; if(strikout) { if((k=((prime*prime)-1)>>1)<size) while(k<=size) {flags[k]=false; k=k+prime;} else { strikout=false; continue; } } } ++i; } puts(" working...\n"); } puts("\nDone!\n"); } 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 17, 2022 Share Posted March 17, 2022 I like the way you can drop int variables into hi-speed RAM. Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 17, 2022 Share Posted March 17, 2022 2 hours ago, dhe said: In earlier release of c99 Clint wrote many example programs, attached is one I always loved. It mentally challenging (to me) to picture all that's happening - but it isn't much to look at on the screen. (I need to c if I can find a version of life written in c99). /* A c version of the Sieve program as suggested by KNUTH */ #define true 1 #define false 0 #define size 8190 #define sized 8191 /**/ int flags[sized]; #asm AORG >8330 #endasm int i,k,prime,count,iter,strikout; #asm RORG #endasm main() { puts("10 iterations\n\n"); iter=1; while(iter++<=10) { strikout=true; count=0; i=0; while(i<=size) flags[i++]=true; i=1; while(i<=size) { if(flags[i]) { prime=i+i+1; ++count; if(strikout) { if((k=((prime*prime)-1)>>1)<size) while(k<=size) {flags[k]=false; k=k+prime;} else { strikout=false; continue; } } } ++i; } puts(" working...\n"); } puts("\nDone!\n"); } I think it is the Eratosthenes sieve. (?) About how long does it take to run? Quote Link to comment Share on other sites More sharing options...
+dhe Posted March 17, 2022 Author Share Posted March 17, 2022 It's all Clint's work. I liked the use of high speed ram also. On classic99 pumped up to make speed it finished in about 5 seconds. 1 Quote Link to comment Share on other sites More sharing options...
+TheBF Posted March 17, 2022 Share Posted March 17, 2022 Just now, dhe said: It's all Clint's work. I liked the use of high speed ram also. On classic99 pumped up to make speed it finished in about 5 seconds. Running in CPU Overdrive? So that is about 23 times faster than normal so at normal speed ~115 seconds, 1:55 ish. I am just curious so I can benchmark my compiler projects. As I recall Small C was not too speedy in the old days but beat the heck out of BASIC. 2 Quote Link to comment Share on other sites More sharing options...
+dhe Posted March 19, 2022 Author Share Posted March 19, 2022 It was suppose to be an easy mission. A 14 line example from Chirlian in and out. Then the unfortunate happened. printf("%b") for binary isn't a thing in c99, also unsigned int, is also, not a thing. I found two routines, to print an int as a binary, the first shows off c99 recursion really well, I didn't have the heart to make it hacky by getting it to print 16 digits, the second, is far less elegant using a table based technique, but is easier to understand and prints all 16 binary digits. #include "DSK2.STDIO" external printf(); external scanf(); /* Global Vars */ int i; int j; int k=0; /* hold the result of out logic operation */ char a; /* used by Fwait */ main() { printf(" Enter First Value:"); scanf("%d",&i); printf("Enter Second Value:"); scanf("%d",&j); putchar(12); printf("i=%d, j=%d\n",i,j); printf("1234567890abcdef \n"); Fpb(i); printf("\n"); Fpb(j); /* Logical AND */ printf("\n \nLogical AND \n"); Fpb(i); printf(" = i\n"); Fpb(j); printf(" = j \n"); k=j&i; /* Logical AND */ Fpb(k); printf(" = i & j \n"); Fwait(); /* Logical OR */ printf("\n \nLogical OR \n"); Fpb(i); printf(" = i\n"); Fpb(j); printf(" = j \n"); k=j|i; /* Logical OR */ Fpb(k); printf(" = i | j \n"); /* Logical XOR */ printf("\n \nLogical XOR \n"); Fpb(i); printf(" = i\n"); Fpb(j); printf(" = j \n"); k=j^i; /* Logical XOR */ Fpb(k); printf(" = i ^ j \n"); printf("\n"); Fwait(); /* Left Shift */ printf("\n \nLeft Shift \n"); Fpb(i); printf(" = i\n"); k=i<<2; /* LEFT Shift 2 */ Fpb(k); printf(" = i << 2\n"); /* Right Shift */ printf("\n \nRight Shift \n"); Fpb(i); printf(" = i\n"); k=i>>3; /* RIGHT Shift 3 */ Fpb(k); printf(" = i >> 3\n"); return(0); } /* end of main */ /* functions here */ /* This code prints like: */ /* 11111111 */ /* 1100101011111000 */ /* Recursively Kewl */ Fbinx(mynum) int mynum; { /* step 1 */ if (mynum > 1) Fbinx(mynum / 2); /* step 2 */ printf("%d", mynum % 2); } /* end of Fbinx */ /* Lets try table driven */ Fpb(mynum) int mynum; { int a; int n; int num [20]; for (n = 15; n >= 0; n--) { num[n] = 0; } num[15] = 32768 & mynum; num[14] = 16384 & mynum; num[13] = 8192 & mynum; num[12] = 4096 & mynum; num[11] = 2048 & mynum; num[10] = 1024 & mynum; num[9] = 512 & mynum; num[8] = 256 & mynum; num[7]= 128 & mynum; num[6] = 64 & mynum; num[5] = 32 & mynum; num[4] = 16 & mynum; num[3] = 8 & mynum; num[2] = 4 & mynum; num[1] = 2 & mynum; num[0] = 1 & mynum; for (n = 15; n >= 0; n--) { if (num[n] > 0) printf ("1"); else printf ("0"); } /* end of for j */ } /* end function Fpb */ Fwait() { printf("Press any key to continue. \n\n"); a=getchar(); /* wait to end */ } /* Chirlian Example 4-9 */ /* dhe - 03182022 */ DSK4.CHIR49;O DSK2.CSUP DSK2.PRINTF DSK2.SCANF 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted March 22, 2022 Author Share Posted March 22, 2022 To Boldly go where no if statement is allowed. I was reading some c tips, and one tip I came across was that the ternary operator can go inside a printf statement unlike an if statement. Tested it out - kewl! /* Ternary Example */ /* dhe - 20220316 */ #include "DSK2.STDIO" external printf (); external scanf (); /* Global Vars */ main () { int apples; apples=0; printf ("How many apples did you eat? "); scanf ("%d \n",&apples); printf ("You ate %d apple%s", apples, (apples>1) ? ("s.") : (".")); return(0); /* no errors */ } /* end of main */ /* to boldly go where no if can go */ 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.