Talk:Binary-coded decimal
From Wikipedia, the free encyclopedia
Contents |
[edit] Intro definition
Binary-coded decimal (BCD) is, after character encodings, the most common way of encoding decimal digits in computing and in electronic systems
This opening sentence is, to my mind, a bit confusing. I know what it is trying to say, but the term "decimal digits" is just too vague, especially in the context of computers. If I declare an int, that's a decimal number. Internally it's represented as binary, not BCD. If I declare a float, that's a decimal number, internally represented using IEEE floating point (binary) notation, not BCD. My point is that any time you use a (decimal) number in a computer program, 99% of the time it will be internally represented as binary. This is probably so obvious it doesn't seem to count as an "encoding", but it is one. In addition, in practice decimal numbers are usually displayed as part of the source text of a program, where they are actually represented as character strings - the compiler converts these to/from binary when it compiles the program. Unless it's a specialised program or particular microprocessor target (6502 anyone?), BCD will never come into it. So, saying "...the most common way...in computing" is simply wrong. BCD is sometimes used in computing for sure, (I've used it myself) but in practice pretty rarely. In electronics however, no contest. It is probably also pretty common in embedded systems, but whether you count these as computing or electronics depends on whether your a hardware person or a software one... Graham 00:13, 7 Apr 2005 (UTC)
- In some ways you're right, but also not quite right. In a programming language such as C, the declaration:
int a=12;
- might be shorthand for saying "there is a 32-bit binary integer, called 'a' in the rest of the programme, initialised to the bit pattern 1100". The fact that the initialisation string is written in decimal is a convenience for the programmer, not an attribute of 'a'. The declaration could just as well have been written:
int a=0x0c;
- (or in various other ways, such as octal). So 'a' is not "encoding" anything at all. It's just a container for bits.
- I agree that the first paragraph has room for improvement, though :-) mfc
-
- Well, I'm not sure I agree. Binary is just as much an encoding as anything else, albeit the most obvious and natural one. This is more noticable for negative numbers, where two's complement is used, obviously for very good reasons, but this is just as much an 'artificial' encoding as BCD is. Perhaps this is hair-splitting. However I think what is misleading about the article's opening para as it stands is that it would lead the lay person to conclude that this is how computers store numbers in general ("the most common encoding'), which is most definitely not the case. I really think that a wording needs to be found which makes this clear - that BCD has its place, and may be common in some circumstances, but you won't in practice find BCD encodings used very much in the average computer.Graham 00:20, 11 Apr 2005 (UTC)
It sounds to me that you do agree that the first paragraph has room for improvement... :-).
By the way – BCD is more common than you may realise; almost every mainframe database uses BCD for decimal data, and decimal numbers are more common than binary in those databases. mfc
- Yes, I agree there is room for improvement in the opening para. I don't know anything about databases on mainframes, so I'm willing to be educated about that. I've done a lot of programming though on everything from embedded 8-bit micros to well, Mac OS X, so I know a bit about it... BCD is definitely used at the embedded end of things, but never seen it in OS X, Windows, etc.Graham 11:53, 19 Apr 2005 (UTC)
[edit] Other bit combinations
Near the beginning of the article is the following line: "Other (bit) combinations are sometimes used for sign or other indications". The "sign" link leads to a disambiguation page, which is a bit confusing. I'd fix it, but I think a sign indicating negative (or positive) numbers is meant, and there doesn't seem to be an article for that. Should this be clarified somehow? (I'm not a native English speaker, and am not sure if it's obvious what is meant to people that are.) Oh, I noticed the "sign" page has a computer-specific meaning linked, namely signedness. Again, not sure if that's the right meaning, or the general math one is. Retodon8 16:03, 23 November 2005 (UTC)
[edit] Why doesn't it say why BCD is so bad?
Practically the first (okay, perhaps the second) thing one would expect in an article about BCD is some statement as to why it is so horrendously stupid in 99% of the cases. No newly written software that I'm aware of uses it anymore. Indeed, modern programming languages provide no native support for it, and rightly so. When it's all said and done BCD is just a fancy way to waste memory and clock cycles. This is not to say that BCD isn't interesting from a historical perspective, on the contrary, it gives nice insights about the way the minds of some people work. But as long as no clear, factual comparison the normal (binary) way of doing things is given this article will always be incomplete, and possibly flawed. Shinobu 08:01, 24 November 2005 (UTC)
- used correctly bcd can be a very usefull tool for some uses especially in the embedded space where conversion between binary and decimal is expensive. For serious processing i agree though forget it. Plugwash 00:16, 9 December 2005 (UTC)
- I have to disagree – for any serious commercial processing, decimal arithmetic is essential. So essential that IBM is adding decimal floaating-point to hardware, and decimal floating-point types are being added to C, IEEE 754, etc. For some reasons why, see my Decimal FAQ pages. And, in hardware, using BCD internally to implement decimal arithmetic is still a good design.
- I also disagree that binary is the 'normal' way of doing things. It just happens to be the way most computers work today. Working is decimal is much closer to the way people work, and that will make computers easier to use. mfc 07:51, 15 December 2005 (UTC)
The first three are all caused by not understanding what a significant digit is. Working in decimal won't make your calculations any more precise, as any competent mathematician can tell you.
Complying with EU regulations is simpler by using a factor so that your data is not floating point anymore. That way you can still work in binary.
Converting to and from decimal is not a problem anymore: one divide per digit, which is usually a lot less work than the calculation that resulted in the number to be converted. Shinobu 16:21, 15 December 2005 (UTC)
-
- Sigh – please read the FAQ again (and if it's not clear, please explain why so I can try and clarify!). The difference is between an exact result for (say) 0.1×8 and an approximation. If you use binary floating point for 0.1×8 you will get a different result from adding 0.1 to zero eight times (accumulating) in the same binary floating-point format. If you do the same calculations in decimal floating-point, you will get 0.8, exactly, in both calculations. This has nothing to do with significant figures. mfc
- indeed mfc that very article you linked said that the most common way of working on "decimal" numbers was to use a binary number with a decimal scaling factor. The issues of how the scale factor is specified (power of two or power of 10) and how the mantissa is specified (BCD or pure binary) are really totally orthogonal to each other. Plugwash 16:58, 15 December 2005 (UTC)
- Absolutely. But if the scale factor is a power of ten then having the significand be specified in a base-ten-related notation such as BCD has clear advantages, for example when shifting left or right by a digit, or when rounding to a certain number of digits or places after the decimal point. If the scale factor is a power of two then a binary significand is better than a decimal significand, and vice versa. mfc
-
-
- However i belive that most artihmetic is MUCH harder on bcd than on binary. With binary for example you can do multiplication by a simple shift-mask-add process. Is there a relatively simple procedure for BCD or is it far more complex? Would the extra difficulty in BCD math be made up for by the fact that the digit shift often needed after multiplication could be done with a plain shift operation? Plugwash 23:02, 15 December 2005 (UTC)
- The same simplifications apply when working in decimal as for binary – you can do multiplications byt shifting and adding the partial products. Binary is slightly simpler because you only have to multiply by 0 or 1, whereas in decimal you have to multiply by 0 through 9. But you have fewer digits to do that on, so it's not much worse than binary, overall. Where decimal 'wins' is where the result has to be rounded to a given number of decimal digits or places. With a decimal representation such as BCD the digit boundary is known; it is much harder if the result is a binary encoding. mfc 15:17, 18 December 2005 (UTC)
- However i belive that most artihmetic is MUCH harder on bcd than on binary. With binary for example you can do multiplication by a simple shift-mask-add process. Is there a relatively simple procedure for BCD or is it far more complex? Would the extra difficulty in BCD math be made up for by the fact that the digit shift often needed after multiplication could be done with a plain shift operation? Plugwash 23:02, 15 December 2005 (UTC)
-
- Shinobu, imagine you have this design task. You have some sort of processor-controlled instrument to design, with a keypad and 7-segment display with say, 5 or 6 digits. A frequency generator, say. The control task is pretty minor so you use something like an 8-bit CPU with 1K of onboard RAM and about 4K of ROM. I don't know if this is still typical, but it sure was when I was designing this sort of thing - a while ago I admit. Without BCD, driving those displays and scanning that keypad is a royal pain, because BCD is very natural for driving displays and representing key sequences. In fact I don't know of any off the shelf binary-to-7-segment decoder devices for multiple digits. If you keep all your internal calculations in binary and convert to BCD for display you'll find that conversion routine is half your ROM gone. If you can simply do all your arithmetic in BCD all the way through (if the CPU supports it, rather than writing your own arithmetic routines, which will also chew up your ROM), you can get your code down to a much smaller size. When ROM is that tight this really does matter. However, I could be out of touch and now even such small hardware design tasks are done with huge overkill CPUs where these sort of issues are irrelevant. Graham 00:23, 16 December 2005 (UTC)
For exact values you should never use floating point, period. When working base 10, this might help you for neat fractions like 1/10, but it won't work for say 1/13. Instead of using some binary coded radix-13 scheme it's better not to use floating point at all.
- Floating-point representations are fine so long as the result is exact (for example: 1.2 x 1.2 -> 1.44). If the result is not exact and must be rounded then the base used matters little. But if you want the approximations in the latter case to match the approximations that people arrive at using calculators or on paper, you should use base 10. mfc 15:32, 18 December 2005 (UTC)
Using a factor always works.
- Hmm, for calculating pi or e? mfc 15:32, 18 December 2005 (UTC)
I conceed that it might be possible to conjure up a system where BCD helps, but I don't know if your example is very good, since 4K seems plenty enough for a conversion routine, if your control task is that simple. Still, when I said 99% of the cases, I really didn't mean 100%.
Using decimal integers the way the z900 does however, is totally unbelievably, erm, odd, to phrase it politely.
-
- So how do you do calculations on paper? Oddly? :-) mfc
To walk by your examples: 1. Take the number 12 and repeatedly divide by 13.
- Using decimal won't help you here; you could do your calculations radix 13. This holds for all situations where the divisor contains other factors than 2 or 5. Don't use floating point for exact values. Just don't.
- (See above)
2. These are all fixed point calculations.
- 130 * 105 = 13650. It's actually easier to implement bankers rounding reliably when using integer numbers, because integer compares are always safe.
- Yes, but in this case the floating-point decimal is equivalent to using integers, becuase that's what in effect people do on paper. But their numbers are base 5 + base 2.
3. Comparing floats this way is bad programming practice, whether they are radix-2 or radix-10.
-
- Nonsense – it is perfectly safe and exact so long as the base of literals matches the base of the underlying arithmetic. If you express your literals in the C99 base-2 form, it's safe for binary floats, too. But as most people like to express literals in a decimal form, the floating-point format needs to be base 10 for this to be safe. Fix the languages and hardware, not the people... :-)
4. I've already explained this above; there's nothing to add. No reason at all to use BCD.
-
- Not BCD as such, necessarily, but some form of decimal representation is needed.
If you can do something in BCD, you can usually do it in binary. It will run faster and consume less memory. It will be just as precise as when you would do it in BCD, as the radix used to represent a number doesn't change the value of said number.
-
- Unfortunately it does, if you have a fixed size representation. Representing 0.1 in any of today's common binary floating-point formats does not give you a value of 0.1.
@I also disagree that binary is the 'normal' way of doing things. It just happens to be the way most computers work today. Working is decimal is much closer to the way people work, and that will make computers easier to use.:
- Surely you're joking. The reason binary is so much better because a binary digit can be stored in the basic unit of information: a bit.
- Not joking at all. BCD is not hugely worse than binary, and more densely packed version are a few percent at most worse -- three digits can be stored in 10 bits with only tiny wastage (which happens to be useful, as one can indicate 'uninitialized value' and the like with the unused codes). mfc
- The same applies to hexadecimal and other power of two radices. This has implications for efficiency, both in storage and speed. What the computer internally uses to do its calculations won't affect user-friendlyness at all, since the time needed for converting to and from decimal for display is negligible. (Even when compared to displaying the number, that is, parsing the font, scaling and adjusting the outlines of the digits, running the font program and the glyph program for the digits, and eventually drawing the pixels, shading them if necessary. You could use text-mode to avoid this, but if you want your programs to be as user-friendly as possible I would advice against that. Even for text-mode indexing in the array of displayed characters is for most numbers more work than the conversion in any case (conversion = div; display = or + sto + inc).)
Shinobu 02:24, 16 December 2005 (UTC)
-
-
- [aside] the display of the result is not the main performance issue; if the data is stored in decimal (XML, Oracle databases, IBM databases, for example) then converting the data to binary then doing (say) an add or two and then converting it back to decimal is expensive: the conversions cost more than the arithmetic. If the data are encoded in binary, use binary arithmetic; if the data are in decimal, then use decimal arithmetic. mfc 15:17, 18 December 2005 (UTC)
-
-
- This discussion is getting off the point. There are definitely valid issues with number storage, but it's your statement that "BCD is horrendously stupid in 99% of cases" that I am taking issue with. How many embedded systems are there, compared with your usual PC? It's not 1%... in fact, embedded system far, far, far outstrip the numbers of general purpose computers that exist. Think of the number of washing machines, TV sets, hi-fi systems, in-car computers, mobile phones, video recorders, instruments.. and that's just the obviously visible applications. Many of these will probably benefit from using BCD representation because a) they have to drive real-world displays, where BCD is a no-brainer, and b) complex arithmetic and accuracy of the results are largely unimportant. Integers rule. Most of the processors that are used for this type of work don't even have multiply instructions, let alone divide - and most of the time you don't need them in these applications. Addition and subtraction however, are commonly needed but if you are displaying numbers on displays, BCD representation and support for BCD addition and subtraction is highly valuable. A conversion routine from binary CAN take up a substantial portion of a 4K ROM - by which I mean maybe 1K or so. Remember that such conversions can't use multiplies. Try writing one in, say 8051 assembler sometime - it's not quite the same as writing it in C. Better to avoid the need altogether. The article is about BCD, as a concept. It is NOT about whether a particular application would be better off using it or not, so going back to your opening sentence for this discussion topic, the figure of 99% is not only incorrect, it is irrelevant to the article. Graham 03:12, 16 December 2005 (UTC)
I think even for most embedded systems using BCD is not useful. To walk along your list:
- washing machines - most I know of are purely mechanical devices and seem to work fine nonetheless.
- TV sets - are really normal cumputers these days; they won't use BCD; the processors most run on don't support it. For older tv's it's possible.
- hi-fi systems - perhaps, but if they support mp3 you can be pretty sure they don't use BCD.
- in-car computers - mostly GPS devices, route planners, etc. I would be surprised if they use BCD. Perhaps fuel regulators and such - but BCD would only be useful if they have a display.
- mobile phones - don't use BCD nowadays. I don't know if that was ever common, but nowadays they don't.
- video recorders - possibly, but DVD players/recorders won't use BCD.
- instruments - for industrial applications, and in university labs computers are becoming more and more ubiquitous.
How much embedded devices there are, and how much use BCD is largely irrelevant. Try to count in terms of variables and one p.c. or mobile phone will outnumber all embedded devices in the area. Try to count in terms of distinct applications, and the number of embedded devices becomes unimportant. I started this discussion because I felt the article focussed way to much on the positive aspects of BCD. This is of course a necessarily subjective opinion and I didn't mean to thread on the toes of BCD fans. However, from an objective point of view, it at least deserves some mention that at least in the world of personal computers, BCD is not used anymore, and there is no reason to. Still, while I think mfc is simply misinformed, or possibly doesn't understand the mathematical backgrounds of computing (remember he's talking about pc's and mainframes)
- <mutter>Do please spend a few minutes reading my papers on the topic :-) A good start might be the one at: http://www2.hursley.ibm.com/decimal/IEEE-cowlishaw-arith16.pdf </mutter>
I think Graham has got a point, when using devices that are severely restricted in terms of intruction-set (e.g. the 8052), registers, and memory. It's confusing that there are two largely separate discussions going on in the same topic, but that just sort of happened. Shinobu 17:23, 16 December 2005 (UTC)
-
- An interesting point is that since numbers represented in ascii/ebcdic are simply bcd with defined values in the high nibble, converting a number to text is essentially the same thing as converting it to BCD and all but the most primitive digital systems have to do that. Plugwash 18:10, 16 December 2005 (UTC)
Similarly my phone stores phonenumbers per digit in it's little memory. However, it stores things like flash-signals and * / # as well so I don't think that qualifies as true BCD. In my opinion this is true for ASCII/Unicode/etc. as well, but you could make a point that all applications that handle decimal numbers entered/viewed by the user essentially use BCD. This would exclude hex dumpers and some East Asian systems, but that's beside the point. I don't think this is commonly called BCD, but it's a nice point. Shinobu 19:19, 16 December 2005 (UTC)
Wherever a device has a 7-segment display, chances are that BCD comes into play at some point. Whether the device uses BCD arithmetic internally is a moot point, since the source code of such devices is largely unavailable. I only go by my own experience as a hardware designer, which I admit was a long time ago, and so my view may be out of date. That said, I don't feel strongly that BCD is good or bad, it's just a technique that is used. I also don't feel that the article is biased in favour of BCD, it simply is about BCD. In fact, adding a statement such as you are calling for, namely, "why it is so horrendously stupid in 99% of the cases" , would not be permitted under the NPOV rules. As an encyclopedia article, there is no merit in entering into a debate about whether a given application should or shouldn't use it - the article explains what BCD is, that's all it has to do. Wikipedia isn't a textbook for budding system designers, so we don't need to worry about whether or not BCD is a good thing. Graham 06:09, 17 December 2005 (UTC)
@why it is so horrendously stupid in 99% of the cases: don't get me wrong there - I never meant to imply that I should be quoted on that! There is a difference between articles and talk pages. If you don't feel that the article is in favour of BCD, then that's probably just me. There are two small bits I think deserve a mention on this talk page though, so here goes:
- BCD is still in wide use, and decimal arithmetic is often carried out using BCD or similar encodings.
- A number of articles referring here are pc/mainframe-related articles. Probably one of those articles landed me here - this must have done a lot to set my mood, so to speak (as for pc's/mainframes BCD is inherently
evilbad). I'm not much of a writer, so I don't know how to fix this, but this sentence gives a kind of implied endorsement when you read it for the first time.- But BCD is not bad, for PCs or mainframes :-) And it is quite relevant for anyone who uses any kind of banking system (ATMs, banks, checks, mobile phones) .. because in more than 95% of cases (probably much more) .. the representation of your money is being stored in BCD or some equivalent :-) mfc
- A number of articles referring here are pc/mainframe-related articles. Probably one of those articles landed me here - this must have done a lot to set my mood, so to speak (as for pc's/mainframes BCD is inherently
- By working throughout with BCD, a much simpler overall system results.
- This is only true if the rest of the system isn't much more complicated than the conversion in the first place. (As I've said above.) How about "may result" instead of "results"?
As I said, it was a subjective feeling, so I shouldn't have let this discussion slip out of control, but then mfc entered with all his pc/mainframe-related BCD-endorsement and I just didn't realize that that's not what the article is about. Oh well, at least I got a view from an embedded systems programmer's perspective, which is interesting, because for smaller embedded systems there's a real trade-off that's not present in larger computers. Thankfully I usually complain on talk pages, and leave articles alone unless I really know what I'm doing. Shinobu 16:23, 17 December 2005 (UTC)
-
- Good comments all .. that's why there are Talk pages. mfc
- The only thing to mention here is that the sentence you are referring to: "By working throughout with BCD, a much simpler overall system results" is in the "BCD in Electronics" section. There is no doubt that a simpler system will always result in such a circuit, because any conversion circuitry will add complexity. If you think a conversion routine in a limited processor is expensive, try it with logic gates! One system I worked on a very long time ago (~1980) did in fact do this, and the solution arrived at in the end was to use a pair of EPROMs to simply make a huge look-up table, with the binary input forming the address, and the resulting BCD data driving some displays. Or it might have been the other way around - I forget now. The reason for needing this was that the system in question was a radiotelephone with a frequency synthesiser - the synthesiser required its frequency to be set using a binary number, but the frequency display or channel number used 7-segment displays and therefore worked in BCD. At the time we cursed the synthesiser chip manufacturer (Motorola) for not allowing the thing to be programmed in BCD, which would have simplified the design substantially. However, a few years after that, embedded processors became much more widely available, and the binary programming of the synthesiser became much less of an issue, because the conversion could be done in software. It was still an expensive process, but much cheaper than using two whole EPROMs to store a table! This might seem prehistoric, and no longer of relevance, but it's still true that a numeric display with a binary input doesn't exist - they are still all BCD. Then again, many embedded systems drive the actual segments directly these days, rather than relying on external hardware decoding, so they can implement binary->7 segment decoding internally without requiring BCD representation, though they will get awfully close to it nevertheless, since at some point you have to convert a string of bits into decades for human decimal comprehension. And that is BCD by any other name. Graham 04:11, 18 December 2005 (UTC)
- Indeed. I predict that binary representations will die out, or be relegated to applications where a tiny performance improvement is still significant. Computers are tools for people to use, not the other way around, so there's no real advantage to using binary encodings in many cases. mfc 15:57, 18 December 2005 (UTC)
- People will use whatever thier programming languages make it easy to use unless they are trying for absoloute maximum performance. afaict most common programming langauges use binary for thier standard integer and floating point types. Plugwash 01:03, 19 December 2005 (UTC)
- Indeed, but finally language designers are seeing the advantages of decimal types. The BigDecimal class in Java is widely used (though unfortunately it's not a primary type yet, as it is in C# and the other .Net languages). C and C++ are adding decimal types (see the draft Technical Report), and many languages use decimal as their default type (Basic, Rexx, etc.). But they don't necessarily use BCD, so we are drifting off-topic, here. mfc 17:45, 19 December 2005 (UTC)
- People will use whatever thier programming languages make it easy to use unless they are trying for absoloute maximum performance. afaict most common programming langauges use binary for thier standard integer and floating point types. Plugwash 01:03, 19 December 2005 (UTC)
- Indeed. I predict that binary representations will die out, or be relegated to applications where a tiny performance improvement is still significant. Computers are tools for people to use, not the other way around, so there's no real advantage to using binary encodings in many cases. mfc 15:57, 18 December 2005 (UTC)
I already acknowledged that for embedded systems there is a tradeoff. However, technically speaking the CPU in a pc also falls in the category electronics. Since a CPU has to have a divide operation (imagine a computer not being able to do division) and some control flow, you can program a bin->BCD converter in a handful of bytes, while saving a lot of logic in the actual ALU, since most math algorithms are significantly easier (and use less gates for instance) in binary. As I said, if your problem gets big enough it will reach a cut-off beyond which BCD is only harmful. I have to add though, that I would probably have cursed the synthesizer manufacturer as well, although the manufacturer had probably other things in mind when they designed the thing.
And oh, mfc, do you realize that for every digit shown on screen a lot of calculations are done just to show that digit? Most of the numbers being crunched will never reach a display device in human-readable form, so BCD will do only harm. Since bin->BCD conversion is very cheap compared to even the process of displaying one digit, there is no reason to add BCD support to the ALU, runtime, or API. I have noticed that you are a big BCD fan, but it's a fact that BCD doesn't make computers any more easy to use either. After all, the user is never confronted with the encoding of the number in any case. BigDecimal by the way is not the same as BCD. BigDecimal is an int scale and a BigInteger value, which in turn is either an int or an int[]. For the reasons extensively discussed above int's are always binary on modern systems. As for the PDF you cited, it's so full of errors that I couldn't read it through till the end, my apologies for that. VB (the mostly used Basic dialect today) doesn't use BCD. It's default type is Variant, which means "whatever you assign to it", but it will still contain one of the VB data types, so it will never be BCD. By the way, I don't recommend using Variants unless you really need them.
@because in more than 95% of cases (probably much more) .. the representation of your money is being stored in BCD or some equivalent: Even if this is the case, that doesn't make is a good thing. They probably just suck the extra cost in incurred storage space and other overhead from the consumers (that's us).
@I predict that: I don't believe in trying to be a human crystal ball.
Okay, this reply turned out longer than I expected. Respect if you read it through to here. Shinobu 20:23, 19 December 2005 (UTC)
-
- Indeed I did read through to here (and I have no difficulty in imagining computers without division :-)), and as this is now far off-topic for BCD I shall just make the one comment: you said: "After all, the user is never confronted with the encoding of the number in any case". It may be true that they may never see the actual bit-patterns, but they are often confronted by the consequences of using the wrong encoding (google 'rounding bug', for example, or check out the C FAQ on this topic). And that waste of programmers' and users' time is a real and completely avoidable problem, far more wasteful than a few extra gates or bits. mfc 21:16, 19 December 2005 (UTC)
The only "rounding bugs" I could find would have been there if BCD had been used as well. That's not evil binary, that's just crappy coding (which is a real and avoidable problem, but that's even too far off-topic for me). As far as I'm concerned a programmer is just another user - the actual way a number is stored is completely transparent. 010 + 010 = 0x10, regardless whether you use bin or BCD;
-
- (This is only true for integers mfc)
the internal representation of numbers is invisible to the programmer (as long as he sticks with math operators anyway). Shinobu 02:50, 20 December 2005 (UTC)
-
- It is only transparent if the conversion from programmer-written literals to the stored form (and from the stored form to a displayed version) is exact. If the literals are (or displayed version) are decimal then the stored form needs to be decimal. mfc 16:23, 20 December 2005 (UTC)
No one who needs to work with exact fractions (be it decimal or otherwise) uses floats. Switching to another radix may solve the problem for some fractions, but not for all. Programming manuals and tutorials warn future programmers not to use floats for exact fractions too. For decimal fractions you would use BigDecimal or something similar. Shinobu 19:11, 20 December 2005 (UTC)
-
- I need to work with exact fractions, and I use floating-point almost exclusively, so that is a false claim. Floating-point is perfectly fine for exact fractions so long as you use the right base. BigDecimal is a floating-point class; it conforms to IEEE 754r almost completely -- it's missing NaNs and infinities, but that does not affect fractions. mfc 20:01, 21 December 2005 (UTC)
-
-
- I hesitate to wade in here, since I know far less about this than I do about embedded... but surely what you're saying there can't be true. For one, you don't have any choice over which base to use, it's down to the designer of the system and it's certain to be base 2.
- Even in hardware that's not true for all systems, and will be even less true in future systems -- but for now, decimal arithmetic software packages are widely available (and are standard parts of some languages, like C#, Java, and Rexx). For some typical packages, see here.
- Secondly, how can you represent, say 1/3 exactly in floating point? You can't, as it's an infinite expansion (0.3333 recurring), and you only have 32 bits or whatever. Or are you talking about writing your own math libraries that store numbers in much larger blocks? You will still surely run into problems with some fractions since an infinite expansion would still require infinite memory to store it. OK, you can encode it as "1/3" which is very finite, but then surely you'd run into problems with other numbers, such as pi, which is an irrational. You have to cut off at some point, so there is going to be some rounding error. This rounding error is very small even for the usual 32-bit float type, but it's not zero. So therefore it's not 'exact', though good enough for sure. Graham 00:12, 22 December 2005 (UTC)
- As Shinobu points out below, you can use a rational number representation to represent 1/3. But where decimal/BCD comes in is where you are trying to represent numbers from the restricted set of "what people write down". If (in a programming language) one writes x=0.33333333; then that can be represented exactly in a decimal floating-point type but not in a binary floating-point type. In the first case, 'what you see is exactly what you've got', which makes it much easier for the programmer to predict what is going to happen if (say) you multiply it by 3 you'd get exactly 0.99999999 (assuming there's enough precision available). In the second case the internal representation of the 0.33333333 is not exact, so the result after the multiply won't be 0.99999999 (in fact you get 0.99999998999999994975240...). Indeed the error is small, but if you need the exact result, it can be critical. See here for some examples. mfc 10:12, 22 December 2005 (UTC)
- I hesitate to wade in here, since I know far less about this than I do about embedded... but surely what you're saying there can't be true. For one, you don't have any choice over which base to use, it's down to the designer of the system and it's certain to be base 2.
-
You can indeed represent "1/3" as "1" / "3". These things are already available of the shelf, both general and with a specific class of denominators (such as BigDecimal, which is essentially x / 10^y). Even if you need to work with exact irrationals, there often are ways to do this, for instance with a computer algebra system. If you don't need to represent a number exactly in the mathematical sense, then the only considerations left are storage and performance and possibly space on the processor. Shinobu 01:42, 22 December 2005 (UTC)
It'd still be better to do it using integer arithmetic, because then you can use the substantially faster integer ALU. You've shown me the examples before. Not the use of binary is where the problem lies, but the use of the wrong datatype for the task at hand. After all 1111111001010000001010101 * 11 = 101111101011110000011111111. Shinobu 17:42, 23 December 2005 (UTC)
-
- I think we may be talking at cross-purposes. Yes of course a scaled integer (in any base, where the scale is a power of ten) will be exact for decimal fractions. But if we are working in decimal then having that integer also in base ten is simplest, because if you want to (say) to round to a certain number of digits then no base conversions are needed. Example: 1.2345 x 1.2345 rounded to five digits. Working with scaled decimal integers this can be written as 12345E-4 squared. To calculate the exact answer, square the integer part and double the exponent, giving 152399025E-8. Now we need to round that to 5 digits; this is rather trivial in decimal -- you only have to look at the sixth digit (and sometimes check the others for 0, for certain rounding modes). Now think about how to do that rounding if the integer were encoded as a binary integer. (And it gets worse as the numbers get longer). mfc 19:46, 23 December 2005 (UTC)
- sure its certainly an advantage to have the mantissa in the same base as the exponent and decimal predictability (e.g. getting the same answers a human would) is nessacery in some cases (finance mainly i'd imagine) but is it a big enough advantage? especially as standard general pupose processors can't do bcd natively! Plugwash 00:12, 24 December 2005 (UTC)
-
- Isn't this a bit of a moot point? I mean, BCD libraries certainly exist. There is an industry standard for them. Therefore it's clear that there are plenty of smart people who consider it worthwhile to write them. Surely that's all we need to know - if there were no point to them surely engineers wouldn't have bothered. Modern processors may not have native BCD modes any more, but on the other hand they do have tremendous speed, meaning that the whole arithmetic library can be written in a high-level language and who cares if it runs ten times slower than the native binary arithmetic? (Actually I suspect that its performance wouldn't be that bad, BCD arithmetic isn't all that tricky to program). So yes, the answer must be that the advantages are indeed 'big enough'. Graham 00:41, 24 December 2005 (UTC)
-
- Following up Plugwash's point: "especially as standard general purpose processors can't do bcd natively!" .. why are y'all so passive? The problem is exactly that -- most processors are locked into a model that made sense in the 1950s and 1960s. It doesn't make sense any more: 20% more transistors in the ALU and/or FPUs is a negligible increment compared to the chip as a whole. So it makes far more sense to do arithmetic in computers the way people do arithmetic, so people don't get 'surprised'. Make it nice and fast, and dump the way that causes people problems. Why make people learn to deal with binary floating-point when there's no need for that, and they could spend the time doing something new and creative? mfc 19:44, 24 December 2005 (UTC)
-
-
- And while we're at it, why not make all our software store text strings internally as bitmaps.... Dmharvey 01:30, 26 December 2005 (UTC)
-
-
- I'll assume that's an attempt at sarcasm, and therefore refrain from pointing out that glyphs and encodings are not the same thing, and no one above has suggested storing ones, zeros, or the digits two through nine, as images of glyphs :-) mfc 17:19, 26 December 2005 (UTC)
[edit] Rounding
(Made into a new topic as per excellent suggestion below :-))
@Now think about how to do that rounding if the integer were encoded as a binary integer:
Example in a C-like language for clarity. It's not much harder in assembler (in fact most C operations correspond to 1 opcode).
- a = 12345;
- a: 12345
- a *= a;
- a: 152399025
Now if you want rounding, you only want it for output.
-
- Not true .. you need it any time you have an inexact answer or one that will not fit in a fixed-size destination. mfc
You state that you only have to look at the 6th digit, but this isn't true; you need round-to-even because of statistical subtleties (regardless of whether you use binary or decimal representation).
- q = a / 10000; m = a % 10000;
- q: 15239
- m: 9025
- These will be compiled down to one div instruction. As I've said before div may (depending on the implementation) be expensive, but not enough so to justify using BCD.
- We will have to disagree on that. On Pentioum, at least, a div is tens of cycles; one of the multiply-by-inverse tricks is much faster. And decimal arithmetic in hardware will be faster still. mfc
- if(m > 5000) q++;
- Note that the > and == tests will be compiled down to one cmp instruction.
- q: 15240 (which is correct)
- else if(m == 5000) if(q & 1) q++;
- I've used &, defining it to be an operation on a binary number. Alternatively you could use (q % 2 == 1) and have the compiler optimize it in case the number system used is binary.
Algorithm for variable scale and/or length is left as an exercise to the reader. Note that these things are available of-the-shelf.
-
- Only because people like me have to write them, and it's a pain. :-) In particular, your assumption of the point at which to round (for example, after a multiply) is in general invalid. You need to count digits from the left. mfc
Instructions used for rounding: div; cmp; 1.5 * j.; 0.5 * inc ~ 45 clocks. The 1.5 is an average; the kind of jumps used will be chosen by the compiler - it will try to make sure that in most cases the ip falls through the jump, so the second if might become a jne, the body ending with a jmp to get the ip back on track. If you're really a performance freak I suggest hand-compiling your code. This is a simple algorithm so it shouldn't be hard.
Instructions used for BCD specific rounding: cmp; 1.5 * j.; shift; 0.5 * inc ~ 7 clocks assuming a native BCD processor. The shift might be cheaper than the round, but not excessively so, and not enough to compensate for the advantages of using binary.
In both cases the clocks used to perform the rounding is dwarfed by the clocks needed to branch to the OS and draw the result. The BCD case is faster, which was to be expected, because you can use the shift instruction. But does it justify expanding the size of ALU, the registers and the cache, as well as slowing down the ALU? I think not - the difference is just too small. A factor 16% may look like a huge speed improvement, but it's 16% of only 45 clocks of an operation that's relatively rare.
-
- Check out: the telco benchmark
Considering the amount of calculations a computer performs, I think a more compact ALU can compensate that. And the fact that without BCD I have 20% extra memory, cache and disk space doesn't hurt either. Yes, you could pack your data, but that costs enough to eliminate the only useful aspect of BCD.
-
- Packing the data costs only 2-3 gate delays (or one instruction per digit, in software). So even in software it's reasonable. mfc
@Graham:
The only real advantage is a speed improvement when a lot of rounding is needed dealing with numbers that span several words. In normal calculations emulating BCD is a pain, not for the programmer (as you said it's easy to program), but for the processor. A normal arithmetic operation costs about 2 clocks. Emulating BCD the same operation in BCD will cost several dozens.
Whereas rounding is relatively rare, actual arithmetic is a very common instruction. I wouldn't accept a factor 10 spead decrease. At least not for scientific modelling, not for memory indexing and not for drawing. Even if your numbers are already stored in BCD (legacy database for instance) first converting to binary and converting back when you're done is probably cheaper.
-
- (Yes, that's why we want/need decimal arithmetic in hardware. Then you can drop the binary arithmetic.) mfc
@20% more transistors in the ALU and/or FPUs is a negligible increment compared to the chip as a whole:
It's not just the ALU and/or FPUs. It's the registers, the data lines and the cache as well.
-
- Why does it affect the registers, data, etc.? mfc
Considering the very slim advantages of using BCD, changing processor architecture to BCD is just not justified. I personally don't think it's hard to adjust to the binary internals of the machine. Normally, for integer arithmetic it doesn't matter, and you only use floats when it doesn't matter.
-
- Binary integers we agree on. Used with care, for writing 'system software' they are fine. They are not good for applications, however. And for floating-point, decimal has useful advantages and few (if any) significant disadvantages. mfc
This topic is getting way too long; it starts to get awkward when editing. I suggest that, if any more discussion on this is needed, a new section should be started.
-
- [done]
On a different note, the x86's contain an instruction which according to the docs convert BCD to real for use in the FPU, I quote, "without rounding errors". I wonder if it's true, and if so, how they do that. Shinobu 05:16, 29 December 2005 (UTC)
[edit] Too long reply
@Not true .. you need it any time you have an inexact answer or one that will not fit in a fixed-size destination. mfc
In which case there is no need for BCD. We have already discussed this.
@We will have to disagree on that. On Pentium, at least, a div is tens of cycles; one of the multiply-by-inverse tricks is much faster. And decimal arithmetic in hardware will be faster still.:
I didn't intend to present the most optimal algorithm. Rather, I've shown that the trivial algorithm is good enough. If better algorithms achieve better performance than the point of using BCD diminishes even more.
@Only because people like me have to write them, and it's a pain. :-):
Yes, it is. But while you are programming this, someone else is having a hard time debugging something that you can use. And it only needs to be done once.
@In particular, your assumption of the point at which to round (for example, after a multiply) is in general invalid. You need to count digits from the left.:
I know. Again, variable scale algorithms are left as an exercise to the reader. :-)
@Check out: the telco benchmark:
for simple calculations, like a telco's, File I/O will always be a most time consuming activity. But not because of rounding, but because of the general bottlenecks and overhead of storing stuff to a disc, tape or network.
- Please go and look at the measurements recorded for the telco benchmark. File I/O was a problem twenty years ago; nowadays it is not the 'most time consuming activity'. That's a myth; that's exactly what the benchmark was and is able to show. Try it for yourself! mfc
@Packing the data costs only 2-3 gate delays (or one instruction per digit, in software). So even in software it's reasonable.:
If you can do [0, 999] to [0, 1023] encoding in 2-3 delays then it's reasonable for a HDU; it's not reasonable for memory and cache because then those gate delays would force your clock slower.
- I don't understand .. a typical processor clock is tens of gate delays, and the 2-3 delays for decimal unpacking only apply when loading from register to the ALU anyway -- so have no effect on (or from) memory or cache. mfc
A computer is a multi-purpose machine; most applications don't benefit from BCD so you don't want to slow down your clock for it. There is certainly a difference between different contexts here as well. A telco may or may not choose to store decimal numbers, but for the data on my personal computer, binary is the only logical choice. An option would be an extra instruction (presumably 1 clock).
- So you store no data in decimal? No numbers in ASCII, XML, or Unicode? If so, then yes, you have no need of decimal processing. (But it would not hurt your existing applications appreciably.) mfc
@Hmm, a BCD add of eight digits is about 6 instructions (See, for example, near the end of: [1] ). Though with a BCD ALU it will be one.:
Considering most instructions are 2-3 clocks, I'd say that was a fair estimate.
@(Yes, that's why we want/need decimal arithmetic in hardware. Then you can drop the binary arithmetic.):
And if you choose to do binary arithmetic in hardware you can drop the decimal arithmetic. But given a choice between a binary ALU and a BCD ALU, I would still choose the binary ALU.
- All true for integers (as we've discussed). But you still do not seem to grasp that decimal fractions cannot be represented exactly in binary floating-point, whereas any binary fraction can be represented exactly in decimal. (For example, 0.1 in binary is exactly 0.5 in decimal. 0.1 in decimal has no exact binary fractional representation. mfc
@Why does it affect the registers, data, etc.?:
It's the old 20% again. Unless you're okay with storing fewer digits.
- The number of digits stored is not 'the old 20%'. That's for decimal arithmetic. In 10 bits of storage you can store 0-1023 in binary or 0-999 for decimal. The difference is negligible (I've yet to hear of any application where that slight difference in significant). mfc
@Binary integers we agree on. Used with care, for writing 'system software' they are fine. They are not good for applications, however. And for floating-point, decimal has useful advantages and few (if any) significant disadvantages.:
Although I think not that much care is needed, and they are most certainly suitable for most applications as well.
- The use of binary integers, with their quite failure modes, has cost millions of dollars/euros/pounds. See:
- for just a few examples. They are sufficient, but hardly suitable, for applications. mfc
Most numbers used in most applications are only used in internal calculations and never directly shown on screen. I still think BCD is only useful when you really need a massive number of decimal rounding operations or something similar. In the end the base you use is of course arbitrary. Every advantage base-10 has is paired with a similar advantage in base-2 (or base-13 even). But binary has the advantage of being the most efficient in most calculations occurring on a normal computer.
Shinobu 04:28, 3 January 2006 (UTC)
[edit] FBLD instruction
(see topic above)
By sticking with integers. I should have known.
13d = 1101 = [1.]101e-11
As you can see, this is indeed an exact operation. Shinobu 05:41, 29 December 2005 (UTC)
[edit] Encodings?
From the article:
- While BCD does not make optimal use of storage (about 1/6 of the available memory is not used in packed BCD), conversion to ASCII, EBCDIC, or the various encodings of Unicode is trivial, as no arithmetic operations are required. More dense packings of BCD exist; these avoid the storage penalty and also need no arithmetic operations for common conversions.
I don't understand this. To my mind, BCD is a way of representing numbers only, not characters. BCD isn't an encoding, so you can't convert to ASCII, EBCDIC, or other encodings. However, I'm not an expert on BCD so I could be wrong. If I am wrong, the article probably needs to be a little clearer on what BCD is. If I'm right, though, the above sentence should probably be taken out. I'd like to hear others' views on this. --Ciaran H 19:10, 23 January 2006 (UTC)
- BCD is a way of representing decimal digits so of course it can be converted to decimal digits in a character encoding. Plugwash 19:19, 23 January 2006 (UTC)
- Yes, I understand that, but the article implies that BCD is an encoding alongside ASCII, EBCDIC, etc. You can't convert to ASCII since it's not an encoding. Or to put it another way, what's represented in the BCD might already be ASCII or EBCDIC. For example, an "A" in BCD-coded ASCII would be:
0000 0110 0101
-
- And likewise, in EBCDIC:
0001 1001 0011
-
- Do you understand me now? Sorry if I made myself unclear before. --Ciaran H 11:42, 25 January 2006 (UTC)
-
-
- Taking the decimal values which are just there to help humans from a standard thats meant to map characters to bytes is just perverse. It gets even more perverse with EBCDIC which is essentially based on BCD with the gaps filled in and some extra bits added. Plugwash 16:18, 21 March 2006 (UTC)
-
-
-
-
- I know - that's my point. It's *not* an encoding alongside ASCII and EBCDIC so saying that BCD can be converted into ASCII or EBCDIC (which the paragraph quoted does) is nonsensical. --Ciaran H 17:41, 28 March 2006 (UTC)
- But it is an encoding, BCD maps a series of decimal digits to bit patterns, ascii maps a series of characters to bit patterns. decimal digits are a subset of ascii characters. Plugwash 01:27, 29 March 2006 (UTC)
- I know - that's my point. It's *not* an encoding alongside ASCII and EBCDIC so saying that BCD can be converted into ASCII or EBCDIC (which the paragraph quoted does) is nonsensical. --Ciaran H 17:41, 28 March 2006 (UTC)
-
-
[edit] shift-mask-add
"Multiplication can be done by a simple shift-mask-add process in base ten."
afaict the shift-mask-add method of multiplication only works for binary. For higher bases you have to use shift-multiply by single digit number-add which is a somewhat more complex process. Plugwash 00:22, 14 March 2006 (UTC)
[edit] binary to BCD the easy way
i think there is an easy way to go from pure binary to BCD (and hence easilly to any other encoding of decimal) in n^2 (where n is the number of bits) time using only bit shifts, masking and BCD addition
something like:
output = 0; addnext = 1; while (input != 0) { if (input & 1) output = bcdadd(output,addnext); input = input >> 1; addnext = bcdadd(addnext,addnext); }
n^2 time as both the number of iterations and the complexity of each iteration is proportional to n.
am i the only one to think of this method? Plugwash 13:02, 21 March 2006 (UTC)
[edit] Addition with BCD
Can someone please edit the section on Addition with BCD. Im sure it can be rewritten to make it clearer
[edit] References and verification
This page is largely unreferenced, and a quick look at what comes up on google isn't very helpful. I'm a little skeptical at the use of BCD, as are many other people who have visited this page. System designs that require the output of decimal numbers at a high enough rate to make BCD worth while should not be built in the first place. BCD floating point arithmetic is no more accurate than normal floating point - the possible representations of numbers are simply *different* - and in fact BCD has less possible representations (per amount of space used), and so would introduce many more problems when being combined with normal floating point numbers.
Of course, i'm only asserting these things, because they're obvious to me. I invite anyone to find a *source* that says differently. Fresheneesz 20:17, 18 October 2006 (UTC)
- I added a much more recent reference - Brown and Vranesic's Fundamentals of Digital Logic design from 2003, which say that BCD is not an important encoding any more. I don't think we should be going by a 1973 publication anymore. Fresheneesz 20:58, 18 October 2006 (UTC)