Commodore 64 Twenty-fifth Anniversary
Go check this out for a fun romp into the past. The presentation touches on much more than just the C64. http://video.google.com/videoplay?docid=3754836267385299753
The Definitive Guide to SQLite, a PDF Download
Here is a link to a PDF for the book The Definitive Guide to SQLite by Mike Owens. This looks like a great resource for Run BASIC programmers. :-) The download seems to take a while, so I wonder if their fileserver is swamped. I guess this is a very popular download.
[link removed]
Followup: For those who have been unable to download the entire file. It took me a few tries, and you may even try some other browser. Safari worked better for me than IE.
How Bitwise Operators are Used, an Example Program
Well, one-by-one we’ve discussed each of the Bitwise
Operator. Starting from Operation
on Bits and Bitwise Operators, we moved on to Right/Left
Bit Shift Operators then discussed Decimal
Number to Binary Conversion Program. and at last One's
Complement and XOR Operators. After having so much theoretical it’s
time now for a nice Example Program, which is the topic of today’s post.
The code here is basically to show how these bitwise operator are used rather
than what they are used for.
// Example Program to demonstrate how
// One's Complement (~) and XOR (^)
// Opeartors are used.
#include<stdio.h>
// prototype
void showbits(short int);
// defined
void showbits(short int dec_num)
{
short int loop, bit, and_mask;
for(loop=15; loop>=0; loop--)
{
and_mask=1<<loop;
bit=dec_num&and_mask;
if(bit==0) printf("0");
else printf("1");
}
}
void main()
{
// declare three short ints
// for storing user inputs
// and results
short int a,b,res;
int ch;
while(ch!=7)
{
// show main menu
printf("\t\tMain Menu\n");
printf("\t\t---------\n");
printf("1. Perform Left Bit Shift Operation\n");
printf("2. Perform Right Bit Shift Operation\n");
printf("3. Perform AND Operation\n");
printf("4. Perform OR Operation\n");
printf("5. Perform One's Complement Operation\n");
printf("6. Perform XOR Operation\n");
printf("7. Quit\n");
scanf("%d",&ch);
switch(ch)
{
case 1:
// take input
printf("\n\nEnter a decimal number: ");
scanf("%d",&a);
printf("\nEnter number of places to shift bit: ");
scanf("%d",&b);
printf("\n\n\tEntered Number: ");
showbits(a);
printf(" (decimal %d)",a);
// perform left bit shift
// operation
res=a<<b;
// show the formatted output
printf("\n\tLeft Shifted : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
case 2:
// take input
printf("\n\nEnter a decimal number: ");
scanf("%d",&a);
printf("\nEnter number of places to shift bit: ");
scanf("%d",&b);
printf("\n\n\tEntered Number: ");
showbits(a);
printf(" (decimal %d)",a);
// perform right bit shift
// operation
res=a>>b;
// show the formatted output
printf("\n\tRight Shifted : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
case 3:
printf("\n\nEnter two decimal number: ");
scanf("%d",&a);
scanf("%d",&b);
printf("\n\n\tEntered Number 1: ");
showbits(a);
printf(" (decimal %d)",a);
printf("\n\tEntered Number 2: ");
showbits(b);
printf(" (decimal %d)",b);
// perform AND operation on two
// variables a and b
res=a&b;
printf("\n\tAND'ed : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
case 4:
printf("\n\nEnter two decimal number: ");
scanf("%d",&a);
scanf("%d",&b);
printf("\n\n\tEntered Number 1: ");
showbits(a);
printf(" (decimal %d)",a);
printf("\n\tEntered Number 2: ");
showbits(b);
printf(" (decimal %d)",b);
// perform OR operation on two
// variables a and b
res=a|b;
printf("\n\tOR'ed : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
case 5:
// take input
printf("\n\nEnter a decimal number: ");
scanf("%d",&a);
printf("\n\n\tEntered Number: ");
showbits(a);
printf(" (decimal %d)",a);
// perform one's complement
// operation
res=~a;
// show the formatted output
printf("\n\t~'ed : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
case 6:
printf("\n\nEnter two decimal number: ");
scanf("%d",&a);
scanf("%d",&b);
printf("\n\n\tEntered Number 1: ");
showbits(a);
printf(" (decimal %d)",a);
printf("\n\tEntered Number 2: ");
showbits(b);
printf(" (decimal %d)",b);
// perform XOR operation on two
// variables a and b
res=a^b;
printf("\n\tXOR'ed : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
}
}
}
Test Run:
Main Menu
---------
1. Perform Left Bit Shift Operation
2. Perform Right Bit Shift Operation
3. Perform AND Operation
4. Perform OR Operation
5. Perform One's Complement Operation
6. Perform XOR Operation
7. Quit
1
Enter a decimal number: 3476
Enter number of places to shift bit: 3
Entered Number: 0000110110010100 (decimal 3476)
Left Shifted : 0110110010100000 (decimal 27808)
Main Menu
---------
1. Perform Left Bit Shift Operation
2. Perform Right Bit Shift Operation
3. Perform AND Operation
4. Perform OR Operation
5. Perform One's Complement Operation
6. Perform XOR Operation
7. Quit
2
Enter a decimal number: 543
Enter number of places to shift bit: 5
Entered Number: 0000001000011111 (decimal 543)
Right Shifted : 0000000000010000 (decimal 16)
Main Menu
---------
1. Perform Left Bit Shift Operation
2. Perform Right Bit Shift Operation
3. Perform AND Operation
4. Perform OR Operation
5. Perform One's Complement Operation
6. Perform XOR Operation
7. Quit
7
Press any key to continue...
Related Articles:
One's Complement and XOR Operators
Talking about Bit
Operators we are left with two of them, which we’ll be discussing
in this article.
One’s Complement Operator (~)
It takes and works only on one operand. On taking one’s complement of
any variable, the 0s are changed to 1 and vice-versa from the bit structure
(binary representation) of that variable. The following example will make it
easier to understand:
Suppose we have a short int a
short int a = 16;
its binary representation will be
0000000000010000 (decimal 16)
on taking one’s complement like below
res = ~a;
res will contain
1111111111101111 (decimal 65519)
It can be used as a part of algorithm to encrypt data.
XOR (eXclusive OR) (^)
It is derived from the OR
Operator and takes two operands to work on. It compares bits like the
OR
bitwise operator but exclusively for OR cases.
Following will clarify what it does:
short int a = 46265, its binary form
1011010010111001
another short int b = 46734, binary
1011011010001110
performing XOR operation
a -> 1011010010111001
b -> 1011011010001110
XOR'ed-> 0000001000110111
As you can see, it compares two bits (from variable a and
b) and if both are same it gives 0 or 1 in any other case.
Thus we can say it does an eXclusive OR comparison between
the bit structure of two variables.
now let's look at an example code showing how these two operators are used:
// Example Program to demonstrate how
// One's Complement (~) and XOR (^)
// Opeartors are used.
#include<stdio.h>
// prototype
void showbits(short int);
// defined
void showbits(short int dec_num)
{
short int loop, bit, and_mask;
for(loop=15; loop>=0; loop--)
{
and_mask=1<<loop;
bit=dec_num&and_mask;
if(bit==0) printf("0");
else printf("1");
}
}
void main()
{
// declare three short ints
// for storing user inputs
// and results
short int a,b,res;
int ch;
while(ch!=3)
{
// show main menu
printf("\t\tMain Menu\n");
printf("\t\t---------\n");
printf("1. Perform One's Complement Operation\n");
printf("2. Perform XOR Operation\n");
printf("3. Quit\n");
scanf("%d",&ch);
switch(ch)
{
case 1:
// take input
printf("\n\nEnter a decimal number: ");
scanf("%d",&a);
printf("\n\n\tEntered Number: ");
showbits(a);
printf(" (decimal %d)",a);
// perform one's complement
// operation
res=~a;
// show the formatted output
printf("\n\t~'ed : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
case 2:
printf("\n\nEnter two decimal number: ");
scanf("%d",&a);
scanf("%d",&b);
printf("\n\n\tEntered Number 1: ");
showbits(a);
printf(" (decimal %d)",a);
printf("\n\tEntered Number 2: ");
showbits(b);
printf(" (decimal %d)",b);
// perform XOR on two
// variables a and b
res=a^b;
printf("\n\tXOR'ed : ");
showbits(res);
printf(" (decimal %d)\n\n",res);
break;
}
}
}
Test Run:
Main Menu
---------
1. Perform One's Complement Operation
2. Perform XOR Operation
3. Quit
1
Enter a decimal number: 37
Entered Number: 0000000000100101 (decimal 37)
~'ed : 1111111111011010 (decimal -38)
Main Menu
---------
1. Perform One's Complement Operation
2. Perform XOR Operation
3. Quit
2
Enter two decimal number: 987
10
Entered Number 1: 0000001111011011 (decimal 987)
Entered Number 2: 0000000000001010 (decimal 10)
XOR'ed : 0000001111011001 (decimal 985)
Main Menu
---------
1. Perform One's Complement Operation
2. Perform XOR Operation
3. Quit
3
Press any key to continue...
Related Articles:
Decimal Number to Binary Conversion Program
Please read Operation
on Bits and Bitwise Operators and Right/Left
Bit Shift Operators if you haven’t already. This post is based
on those articles.
We’ll be using the following operators and the respective properties
for decimal to binary conversion:
-
AND (&) Operator from the article Operation
on Bits and Bitwise Operators: Its property to be able to check
whether a particular bit is ON (1) or OFF (0).
-
Left Bit Shift Operator (<<) from the article Right/Left
Bit Shift Operators: Its property to shift bits (of byte(s)) to
desired number of places to the left.
After making you guys familiar with the two things above, the program will
be easier to understand.
// Example Program to convert decimal number
// to binary equivalent.
// --------
// Function: We have defined a function 'showbits()'
// It shows the bit structure of the
// Short Int(2 Bytes) passed as argument
#include<stdio.h>
// prototype
void showbits(short int);
//defined
void showbits(short int dec_num)
{
short int loop, bit, and_mask;
for(loop=15; loop>=0; loop--)
{
and_mask=1<<loop;
bit=dec_num&and_mask;
if(bit==0) printf("0");
else printf("1");
}
printf("\n");
}
//main code to show how showbits()
// is working
void main()
{
short int dec;
printf("Enter a decimal number:");
scanf("%d",&dec);
showbits(dec);
}
I’m leaving its working part as an exercise for you guys.
Ha-ha! Not happy?
Ok, I’ll give you a hint, in the line…
and_mask = 1 >> loop;
Binary of 1 is 0000000000000001 (in two byte format) which is shifted 15 bits
to the left, in the first iteration.
Related Articles:
Right/Left Bit Shift Operators
This is the continuation of the article Operation
on Bits and Bitwise Operators. If you haven’t read that, it is
strongly recommended that you do, before proceeding with this article.
Bit shifting, as the name signifies, does shifting of bits in byte(s). There
are basically two ways, in which bits (of a byte) can be shifted, either to
the right, or to the left. Thus we have two types of bit shifting operator.
If you think logically, its pretty clear that for bit shifting in a byte, we
need to have two data. We need the byte(s) to shift bits on and the number of
bits to be shifted. Guess what, the two operators need these to data as operands!
Right Bit Shifting Operator (>>)
Syntax: res = var >> num;
This would shift all bits in the variable var, num places
to the right which would get stored to the variable res. So
for example if var has the following bit structure:
var = 00110101 (decimal 53)
And we do the following operation:
res = var >> 2;
We would get res as:
res = 00001101 (decimal 13)
As you can see, shifting of the bits to right disposes the bits
(2) from the right and introduces 0s (2) to the left.
Left Bit Shift Operator (<<)
It is similar to the right shift operator except that the direction of shifting
is opposite. The following is I think enough to explain this:
var = 00110101 (decimal 53)
And we do the following operation:
res = var << 2;
We would get res as:
res = 11010100 (decimal 212)
Just the opposite here, here bits get disposed from the left and new 0s are
introduced to the right.
Related Articles:
Axis Web services Problem: No compiler found in your classpath! (you may need to add 'tools.jar')
While trying to deploy a web service in Tomcat (1.5) with Axis 1.4, you may have encountered the above error message. If you have faced with that, following information will help you in fixing it.
If you are at servier side, this error may be logged in Tomcat log file as follows.
java.lang.ClassNotFoundException: sun.tools.javac.Main
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1355)
....
On client side, you'll receive this error as follows.
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.lang.RuntimeException: No compiler found in your classpath! (you may need to add 'tools.jar')
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}hostname:myhost
So the obvious solution you would try is adding %JAVA_HOME%\lib\tools.jar into your CLASSPATH variable even if you were at server side or the client side. But this will not solve the issue.
Solution:
Copy %JAVA_HOME%\lib\tools.jar file into %CATALINA_HOME%\common\lib folder and restart tomcat.
Why %JAVA_HOME%\lib\tools.jar is not identified?
If you check happyaxis.jsp page (http://127.0.0.1:8080/axis/happyaxis.jsp); under "Examining System Properties" you'll see that property java.home is set to the JRE path, not the JDK path in your machine. (even though %JAVA_HOME% points to JDK installation). In my machine it looked as follows.
java.vm.version=1.6.0_03-b05
java.home=C:\Java\jre1.6.0_03
I'm not sure why the JAVA_HOME is not identified correctly, but this solved the issue for me.
Electronics Hobby Shop Launched
You
may skip this post if you’re not a resident of India
Microcontrollers such as AVR, PIC from Atmel and Microchip are fast becoming
the choice of hobbyist for their projects. Now instead of many conventional
ICs hobbyists are rather using a single MCU (MicroController Unit) for their
projects due to many advantages they have.
In the recent years MCUs have become cheap too. Now you may easily get
a fully functional MCU from Atmel at under Rs. 70!
Sadly that is only one dimension of its popularity if you don’t reside
in those big cities, leaving some big cities MCUs are not that easily available
let alone the remote areas. There are many resellers but they either deal in
large quantities or at high prices both not being suitable for average hobbyists.
Seeing this, my brother has come up with a new Online
Electronics Hobby Shop for average hobbyists. He has planned
to make available everything (Development Boards, MCUs, LCD Displays, Programmers,
and Controller Chips etc) which are otherwise not easily available to everyone.
The site is still in its infancy (Launched on 8th March 2008) so you
shouldn’t expect everything to be available right now.
At present Microcontrollers,
USB
Programmers, Displays
etc. are available.
Web Site Scalability
- Web tier : Serving static contents (static pages, photos, videos)
- App tier : Serving dynamic contents and execute the application logic (dynamic pages, order processing, transaction processing)
- Data tier: Storing persistent states (Databases, Filesystems)
Content Delivery
Dynamic Content
- Most of the content display is dynamic content. Some application logic will be executed at the web server which generate an HTML for the client browser. The efficiency of application logic will have a huge impact on the overall site's scalability. This is our main topic here.
- Sometimes it is possible to pre-generate dynamic content and store it as static content. When the real request comes in, instead of re-running the application logic to generate the page, we just need to lookup the pre-generated page, which can be much faster
- Static content are typically the images, videos embedded inside the dynamic pages.
- A typical HTML pages typically contains many static contents where the browser will make additional HTTP network round trips to fetch. So fetching static content efficiency also has a big impact to the overall response of dynamic page
- Content Delivery Network is an effective solution for delivering static contents. CDN provider will cache the static content in their network and will return the cached copy for subsequent HTTP fetch request. This reduce the overall hits to your web site as well as improving the user's response time (because their cache is in closer proximity to the user)
There are 2 layers of dispatching for a Client who is making an HTTP request to reach the application server
DNS Resolution based on user proximity
- Depends on the location of the client (derived from the IP address), the DNS server can return an ordered list of sites according to the proximity measurement. Therefore client request will be routed to the data center closest to him/her
- After that, the client browser will cache the server IP
- Load balancer (hardware-based or software-based) will be sitting in front of a pool of homogeneous servers which provide same application services. The load balancer's job is to decide which member of the pool should handle the request
- The decision can be based on various strategy, simple one include round robin or random, more sophisticated one involves tracking the workload of each member (e.g. by measuring their response time) and dispatch request to the least busy one
- Members of the pool can also monitor its own workload and mark itself down (by not responding to the ping request of the load balancer)
Client communication
This is concerned about designing an effective mechanism to communicate with the client, which is typically the browser making some HTTP call (maybe AJAX as well)
Designing the granularity of service call
- Reduce the number of round trips by using a coarse grain API model so your client is making one call rather than many small calls
- Don't send back more data than your client need
- Consider using an incremental processing model. Just send back sufficient result for the first page. Use a cursor model to compute more result for subsequent pages in case the client needs it. But it is good to calculate an estimation of the total matched result to return to the client.
- If you have control on the client side (e.g. I provide the JavaScript library which is making the request), then you can choose a more compact encoding scheme and not worry about compatibility.
- If not, you have to use a standard encoding mechanism such as XML. You also need to publish the XML schema of the message (the contract is the message format)
- If the message size is big, then we can apply compression technique (e.g. gzip) to the message before sending it.
- You are trading off CPU for bandwidth savings, better to measure whether this is a gain first
- AJAX fits very well here. User can proceed to do other things while the server is working on the request
- Consider not sending the result at all. Rather than sending the final order status to the client who is sending an order placement request, consider sending an email acknowledgment.
Typical web transaction involves multiple steps. Session state need to be maintained across multiple interactions
Memory-based session state with Load balancer affinity
- One way is to store the state in the App Server's local memory. But we need to make sure subsequent request land on the same App Server instance otherwise it cannot access the previous stored session state
- Load balancer affinity need to be turned on. Typically request with the same cookie will be routed to the same app server
- Another way to have the App server sharing a global session state by replicating its changes to each other
- Double check the latency of replication so we can make sure there is enough time for the replication to complete before subsequent request is made
- Store the session state into a DB which can be accessed by any App Server inside the pool
- Under this model, the cookie will be used to store the IP address of the last app server who process the client request
- When the next request comes in, the dispatcher is free to forward to any members of the pool. The app server which receive this request will examine the IP address of the last server and pull over the session state from there.
- If the session state is small, you don't need to store at the server side at all. You can just embed all information inside a cookie and send back to the client.
- You need to digitally sign the cookie so that modification cannot happen
Caching
Remember the previous result can reuse them for future request can drastically reduce the workload of the system. But don't cache request which modifies the backend state
Net Neutrality
Net Neutrality is a movement to protect free and unhindered access to Internet resources.
Ethan Poole wrote an excellent article about it here:
http://www.lowter.com/article/net-neutrality/2
Database Scalability
Indexing
Make sure appropriate indexes is built for fast access. Analyze the frequently-used queries and examine the query plan when it is executed (e.g. use "explain" for MySQL). Check whether appropriate index exist and being used.
Data De-normalization
Table join is an expensive operation and should be reduced as much as possible. One technique is to de-normalize the data such that certain information is repeated in different tables.
DB Replication
For typical web application where the read/write ratio is high, it will be useful to maintain multiple read-only replicas so that read access workload can be spread across. For example, in a 1 master/N slaves case, all update goes to master DB which send a change log to the replicas. However, there will be a time lag for replication.
Table Partitioning
You can partition vertically or horizontally.
Vertical partitioning is about putting different DB tables into different machines or moving some columns (rarely access attributes) to a different table. Of course, for query performance reason, tables that are joined together inside a query need to reside in the same DB.
Horizontally partitioning is about moving different rows within a table into a separated DB. For example, we can partition the rows according to user id. Locality of reference is very important, we should put the rows (from different tables) of the same user together in the same machine if these information will be access together.
Transaction Processing
Avoid mixing OLAP (query intensive) and OLTP (update intensive) operations within the same DB. In the OLTP system, avoid using long running database transaction and choose the isolation level appropriately. A typical technique is to use optimistic business transaction. Under this scheme, a long running business transaction is executed outside a database transaction. Data containing a version stamp is read outside the database trsnaction. When the user commits the business transaction, a database transaction is started at that time, the lastest version stamp of the corresponding records is re-read from the DB to make sure it is the same as the previous read (which means the data is not modified since the last read). Is so, the changes is pushed to the DB and transaction is commited (with the version stamp advanced). In case the version stamp is mismatched, the DB transaction as well as the business transaction is aborted.
Object / Relational Mapping
Although O/R mapping layer is useful to simplify persistent logic, it is usually not friendly to scalability. Consider the performance overhead carefully when deciding to use O/R mapping.
There are many tuning parameters in O/R mapping. Consider these ...
- When an object is dereferenced, how deep the object will be retrieved
- If a collection is dereferenced, does the O/R mapper retrieve all the object contained in the collection ?
- When an object is expanded, choose carefully between multiple "single-join" queries and single "multiple join" query
Think programming is too hard, or boring? Think again!
When it came to what sort of work we do, I shared about my business selling programming tools. I moved over to the fellow with the black Macbook and told him I wanted to show him my website so he could understand my business. When I showed him the Learn tab on the Run BASIC site and began to walk him through the examples the other people at the table came over to watch. As we went from simple "hello world!" to some easy graphics examples the reaction from onlookers was amazement! They clearly were not aware that programming could be so simple and cool. To them this was something way above them, and very dry.
What I took away from this is that people don't know that programming can be fun. They can do it, and years ago the average computer user did his own programming, in BASIC. Nowadays what gets promoted as programming is too hard, and it's no surprise that people don't want to do that. This is a misapplication of technology that makes things harder, and not easier.
We need to turn back the clock in this important area of programming.