Although this question is not obviously related to a program, I think that it is quite interesting and it will help me with a program I am working on.
My question is this:
Computers are binary systems and have 3 fundamental operations available to them: AND, OR, and NOT (as I understand it), from which all of its other functions are derived. I can understand how the system can perform arithmetic on binary numbers using these operators, but how can the system then convert these numbers into decimal for the user without using the conventional operators (ie. +, -, *, /)?
You have BCD or IEEE Floating point to deal with decimal in the binary system, there are other specifications, but these are the most common and the IEEE is the one computers use nowadays i think.
Related
I was wondering why a computer would need binary code converters to convert from BCD to Excess-3 for example. Why is this necessary can't computers just use one form of binary code.
Some older forms of binary representation persist even after a newer, "better" form comes into use. For example, legacy hardware that is still in use running legacy code that would be too costly to rewrite. Word lengths were not standardized in the early years of computing, so machines with words varying from 5 to 12 bits in length naturally will require different schemes for representing the same numbers.
In some cases, a company might persist in using a particular representation for self-compatibility (i.e., with the company's older products) reasons, or because it's an ingrained habit or "the company way." For example, the use of big-endian representation in Motorola and PowerPC chips vs. little-endian representation in Intel chips. (Though note that many PowerPC processors support both types of endian-ness, even if manufacturers typically only use one in a product.)
The previous paragraph only really touches upon byte ordering, but that can still be an issue for data interchange.
Even for BCD, there are many ways to store it (e.g., 1 BCD digit per word, or 2 BCD digits packed per byte). IBM has a clever representation called zoned decimal where they store a value in the high-order nybble which, combined with the BCD value in the low-order nybble, forms an EBCDIC character representing the value. This is pretty useful if you're married to the concept of representing characters using EBCDIC instead of ASCII (and using BCD instead of 2's complement or unsigned binary).
Tangentially related: IBM mainframes from the 1960s apparently converted BCD into an intermediate form called qui-binary before performing an arithmetic operation, then converted the result back to BCD. This is sort of a Rube Goldberg contraption, but according to the linked article, the intermediate form gives some error detection benefits.
The IBM System/360 (and probably a bunch of newer machines) supported both packed BCD and pure binary representations, though you have to watch out for IBM nomenclature — I have heard an old IBMer refer to BCD as "binary," and pure binary (unsigned, 2's complement, whatever) as "binary coded hex." This provides a lot of flexibility; some data may naturally be best represented in one format, some in the other, and the machine provides instructions to convert between forms conveniently.
In the case of floating point arithmetic, there are some values that cannot be represented exactly in binary floating point, but can be with BCD or a similar representation. For example, the number 0.1 has no exact binary floating point equivalent. This is why BCD and fixed-point arithmetic are preferred for things like representing amounts of currency, where you need to exactly represent things like $3.51 and can't allow floating point error to creep in when adding.
Intended application is important. Arbitrary precision arithmetic will require a different representation strategy compared to the fixed-width registers in your CPU (e.g., Java's BigDecimal class). Many languages support arbitrary precision (e.g., Scheme, Haskell), though the underlying implementation of arbitrary precision numbers varies. I'm honestly not sure what is preferable for arbitrary precision, a BCD-type scheme or a denser pure binary representation. In the case of Java's BigDecimal, conversion from binary floating point to BigDecimal is best done by first converting to a String — this makes such conversions potentially inefficient, so you really need to know ahead of time whether float or double is good enough, or whether you really need arbitrary precision, and when.
Another tangent: Groovy, a JVM language, quietly treats all floating point numeric literals in code as BigDecimal values, and uses BigDecimal arithmetic in preference to float or double. That's one reason Groovy is very popular with the insurance industry.
tl;dr There is no one-size-fits-all numeric data type, and as long as that remains the case (probably the heat death of the universe), you'll need to convert between representations.
Not sure if the title of my question makes sense, so bear with me. I'd like to find a system for representing single digit numbers with as few bits as possible. There is a method called "Densely packed decimal" (https://en.wikipedia.org/wiki/Densely_packed_decimal) which would be my ideal solution, but I wouldn't even know if that's possible or how I could implement it without further research or guidance from a guru.
The next best thing would be to be able to use a 4-bit addressing system to represent digits, but once again I'm not sure if that is even possible.
So! Barring implementations of the above methods/systems, I could settle for a 1-byte data type which I could use to represent pairs of two integers. Is there a 1-byte data-type in Fortran, or does it not allow for that level of control?
There is a 1 byte datatype in (almost) every programming language. It is the character. It is actually the definition of a byte, that it can hold a default character.
There is also a 1-byte (strictly speaking 1-octet) integer type in Fortran, accessible as integer(int8) where int8 is a constant from the iso_fortran_env module (Fortran 2008).
Both can be used to implement such things. Whether you will use division by other numbers, xoring, or Fortran bit manipulation intrinsic functions https://www.nsc.liu.se/~boein/f77to90/a5.html#section10 (probably the best option) is up to you.
Does anyone know how the binary systems is better than decimal when doing arithmetic? It was a question in a test and I can't seem to find a good answer anywhere...
In specific:
Explain the benefits of using binary rather than decimal under the following topics-
integer addition
integer multiplication
integer division
floating point storage
Any help would be greatly appreciated.
Actually, it's not necessary for human to use binary system. With the topic, I think your question is more like why computers use it?
Modern computers are based on the electronic circuits. We use a simple 2-state gate to represent information. The basic element in circuits is transistor, which shows high and low voltage, representing 1 and 0 respectively. For a complex circuit, a given input can produce some outputs. If we see that from a high level, it shows the operation of 0's and 1's.
The circuits can also be used for storage, which consists of 0's and 1's, because of the 2-state.
Computer uses the binary system both for storage and operation. If we change it to a decimal system, we have to find a component which has ten state, representing 10 numbers. Besides, we also have to design operation between these basic numbers.
Until now, electronic circuits make it perfect with binary system.
I'm trying to understand the differences between these two systems and their impact on C programming.
From what I've learned from Wikipedia:
both systems are used to represent negative numbers
one's complement applies bitwise NOT to negative number (the system has +0 and -0)
two's complement does as in step 2 and adds 1 (eliminates +/-0)
Am I missing something else?
My questions:
which architectures support which system? What is the most common these days (1's or 2's complement)?
in what sense should we consider these systems when programming in C? Does it mainly make sense only in embedded world?
Thanks in advance!
Most systems nowadays use two's complement, since it lets the computer do the same exact operation for addition/subtraction without caring about the particular sign of the number.
When you're programming, the arithmetic works regardless of the system used -- the range of the data types are defined by the language, so if it says a type will work in the range -2^31 to +2^31 - 1, then it'll work regardless of the notation. You need to be careful when working with individual bits or bit shifts, though -- those won't behave like power-of-two arithmetic in non-two's complement systems (although you're not too likely to encounter such systems, and probably never will, if you're just working with PCs).
The only advantage of ones'-complement notation for integers is that it allows conversions to and from sign-magnitude form to be performed without a carry chain. Building a computer with a set of blinkenlights that show each register's value in sign-magnitude form will be much more convenient if the registers use ones'-complement form than if they use two's-complement form. If one wanted to use separate storage latches for the blinkenlights and the CPU's registers, the easiest way to accommodate things would be to have one circuit which translates two's-complement to one's-complement or sign-magnitude form, and then have each register write simultaneously store the two's-complement value in the register while updating the blinkenlight latches with the sign-magnitude value. Latching circuitry is sufficiently expensive, however, that if registers are being built out of discrete latches anyway, adding some circuitry to the ALU to make it use ones'-complement, and then feeding the lights from the CPU's "real" registers, may be cheaper than including an extra set of latches for the lights.
Over the last few decades, of course, the relative costs of different circuit elements have shifted to the point that it would be absurd to have lights wired to directly report the state of a CPU's registers. Consequently, the practical advantages that ones'-complement designs might have had in the past are no longer applicable.
I wanted to see if folks were using decimal for financial applications instead of double. I have seen lots of folks using double all over the place with unintended consequences . .
Do you see others making this mistake . . .
We did unfortunately and we regret it. We had to change all doubles to decimals. Decimals are good for financial applications. You can look at this article
A Money type for the CLR:
A convenient, high-performance money
structure for the CLR which handles
arithmetic operations, currency types,
formatting, and careful distribution
and rounding without loss.
Yes, using float or double for financials is a common mistake, leading to much, much pain. decimal is the most obvious choice in this scenario.
For general knowledge, a good discussion of each is here (float/double) and here (decimal).
This is not as obvious as you may think. I recently had the controller of a large corporation tell me that he wanted his financial reports to match what Excel would generate, which is maintaining calculated results internally at maximum precision and only rounding at the last minute for display purposes. This means that you can't always match the Excel answers by manual calculations using only displayed values. His explanation was that there were multiple algorithms for generating the results, each one doing rounding at a different place using decimal values, therefore potentially generating conflicting answers, but the Excel method always generated the same answer.
I personally think he's wrong, but with so many financial people using Excel without understanding how to use it properly for financial calculations, I'll bet there's a lot of people agreeing with this controller.
I don't want to start a religious war, but I'd love to hear other opinions on this.
If it is "scientific" measurement (I mean weight, length, area etc) use double.
If it is financial, or has anything to do with law (e.g. the area of a property) then use decimal.
The hard part is rounding.
If the tax is 2.4% do you round in the details or after the sum?
Most of the time yo have to do both (AND fix the difs)
I've run into this a few times. Many languages have nothing of the sort built in, and to someone who doesn't understand the problem it seems like just another hassle, especially if it looks like it works as intended without it.
I have always used Decimal. At least when I had a language that supports it. Otherwise, rounding errors will kill you.
I totally agree on correctness issues of floating point vs decimal mentioned above, but
many financial applications are performance critical.
In such cases you will consider to use float/double as decimal has great impact on performance in systems where decimal types are not supported in hardware. And still it is possible to wrap floating point types in higher level classes (e.g. Tax, Commission, Balance, Dividend, Quote, Tick, etc...) that represent domain model and encapsulate all rounding logic as well as valid operators on these types and their interactions.
And yes - in some projects I have implemented custom rounding functions to squeeze up to 20% more out of calculations compared to .NET or win32 methods.
Another thing to consider is whether you pass your objects out of process, as serializing decimals which are usually 4 integers and passing them over the wire is much more CPU intensive (esp if not supported) and results in significantly more bandwidth and larger memory footprint.