Software version numbering isn't difficult, in theory. You start with a pre-release product and call it something clever like Version 0.1. You refine it until you have a releasable product which, after much thought by the marketing department, is released as Version 1.0. Then comes the complicated part. You need to do two things to that software: fix bugs (gasp!) and improve it (cool!). That then means you have to change the version number of the product so each release is uniquely identified. After all, you don't want to make changes to the software and still call it Version 1.0. That will just lead to confusion by the consumer and the marketing department alike.
In smaller development companies release numbering is straightforward: every time you have a released product you increment the major or minor numbers. So, Version 1.0 becomes Version 1.1. Or Version 2.0. Or maybe Version 1.0.1. Or Version 1.0a. Or...well, you get the idea. There are choices here. A lot of those choices depends on how traditional you are in software development methodology and how simple you want to keep your scheme.
The traditional method of release numbering is to divide releases into two and sometimes three parts. The first part, the major number, is the major release version. This increments only when you make changes to the product that justify it being called by a new version number. After all, going from Version 4.0 to Version 5.0 implies some significant differences, not just a small bug fix or minor tweak. While marketing departments sometimes get involved in the major release increment decision, I tend to let the product features dictate when the major number is incremented. Typically, I'll change the major number if one of a few significant changes have happened to the software. The most traditional is a GUI change. You've modified the whole look and feel of the product (for some reason) and that justifies the change. Or there's a big change in the feature set of the product, and you want to let customers know the new version is significantly different (better!). Or there's been a change in the underlying technology that the consumer may not notice at first, but is significant to the development process. (An example of the latter is going from a traditional software language to a platform such as .NET.) All these things justify a major version number change. I tend to like to have major version number changes no more than once a year, and usually a little less, otherwise customers get overwhelmed with the versioning updates (and many customers move very slowly) and it also helps with the marketing and advertising, not to mention software development planning when these major releases are spaced out at least 18 to 24 months apart.
The second, minor, number is usually used to indicate some changes have taken place, but they are not enough to warrant a major number increase. This would take version 3.0 to version 3.1, for example. My rule of thumb is that every minor increment should add something significant to the software that a customer can decide is important enough to warrant the testing-deploying process or not. I tend to add a few new features to each minor release, instead of just one, so there's a good reason for everyone to upgrade the minor releases, but it's not critical that they do. Typically, I like to keep the minor releases spaced out at least three to four months apart at the least, again to prevent product overwhelm and also to allow for development and testing time. If there's a lot to cram in a minor release, it can be delayed or broken into two releases. Minor releases should be optional for customers, but desirable. Major releases should be "must haves" as far as features go for the customer.
The third part of the release numbering triad is the patch number, such as Version 2.5.1 or 2.5.2. The last digit represents the released patch, with each patch a thoroughly tested update to the current product that fixes bugs or functionality issues. Typically, these patches are available shortly after the released product, as issues are discovered in testing, soaking, or customer field use. Often, patches are quick and simple, but managing which patches go into which patch release is a bit of a headache as you don't want to release a new patch every day (or even every week, except in extenuating circumstances). Patching should be done carefully to prevent product version overload for the customer, as well as to ensure the highest quality from the development team.
The exact way you number releases (all three parts) changes depending on the company, the groups, and preferences. Some people like letters instead of numbers for patches. Some prefer to simply ignore minor numbers and number each release, patch or feature, in incrementing order. And some have totally random (or so it seems!) numbering as a rejection of the "traditional" software development process. How you number doesn't matter, really, as long as the scheme makes sense to the development group and, more importantly, the end customer. After all, you don't want to tell a customer "to fix that bug in 3.a.45g you need to install 3.r.12qq". You want simplicity as much as possible, and numbering should convey information to all concerned about the release.
Things get more complicated when working with multiple release streams at once, so you may have version 2.1.10 as a patch while 2.2.0 is being worked on as a new release candidate and still be fixing something in 2.1.23. That's a different issue, coming down to release tracking, but again, a simple, understandable release numbering scheme helps.
Some people like overly complex and cryptic numbering schemes. I don't. I think they make it hard for developers, marketers, salespeople, and your customers to understand. Why make it difficult for the customer, who provides you with your bread and butter? Simple sometimes is better.