97

When adding or subtracting fractions, you need to find the least common multiple of the two denominators. That's an expensive operation, much more expensive than adding or subtracting floating points, which just requires shifts. Multiplication is also more expensive, because now you need to multiply two numbers instead of just one. Similarly for division. ...


52

As far as I’m aware, the last FPU-less x86-compatible CPU which could still be considered general-purpose is the Vortex86SX, released in 2007 and still available now. This is a Pentium-class CPU, capable of running any Pentium code which doesn’t require an FPU. It is targeted at embedded applications, with up to 512 MiB of RAM, and includes a PCI bus, USB, ...


51

My question is, why not use fractions? Quick answer: Too much code needed Dynamic storage needed Long representation even for simple numbers Complex and slow execution And most prominent: Because floating point is already based on fractions:Binary ones, the kind a binary computer handles best. Long Form: The mantissa of a floating point number is a ...


44

The opcodes in your list are all only 16 bits (plus the extra bytes for address calculation) and you'll notice that they all begin (in hex) with Dx where x >= 8. This is because, to the 8086, any instruction whose first byte has the bit pattern 11011xxx was deemed to be an 8087 coprocessor instruction. When the 8086 encountered a floating point opcode, it ...


30

Yes. For example, the C math library has had full support for long double, which on x87 was 80 bits wide, since C99. Previous versions of the standard library supported only the double type. Conforming C and C++ compilers also perform long double math if you give the operations a long double argument. (Recall that, in C, 1.0/3.0 divides a double by ...


27

TL:DR: Yes, most C/C++ compilers other than MSVC expose an 80-bit IEEE754 Extended Precision format (x87, 68881) as long double, and some implementations of other languages have it as REAL10 or whatever name. But no, none of the major C compilers had an option to force promoting double locals/temporaries to 80-bit even across spill/reload, only keeping them ...


25

There is a mathematical problem with your idea. If you choose to store fractions with a fixed-length numerator and denominator, that's works fine until you try to do arithmetic with them. At that point, the numerator and denominator of the result may become much bigger. Take a simple example: you could easily store 1/1000 and 1/1001 exactly, using 16-bit ...


18

Floating-point isn't just about representing numbers that have fractional parts. It's also about representing numbers that are very large, or very small, in a way that allows extra range by sacrificing precision. Consider these examples: 1,000,000,000,000,000,000,000,000,000,000 (1 with 30 zeros after). This number can be reasonably stored in floating-...


16

This example reveals a rounding error under Commodore BASIC V2.0: A=0.3:B=0.6:IF A+B<>0.9 THEN PRINT A+B-0.9 Running this on a C64 yields a difference of 2.32830644e-10. Other pairs that fail are 0.4+0.5, 0.6+0.1 and 0.8+0.1. Please note that also the order in which the numbers are summed up affects the result. 0.6+0.1-0.7 yields a difference, ...


16

All Intel x86 CPUs since the 80486 line have included floating point instructions, i.e. everything from the Pentium* onward. So the last Intel processor to lack an on-board floating-point unit (FPU) was the 80486SX (and the embedded 80486GX). Other manufacturers, who made 486-compatible processors, continued making non-FPU chips, aiming for the budget ...


16

I worked for Borland back in the days of the 8086/8087. Back then, both Turbo C and Microsoft C defined long double as an 80-bit type, matching the layout of Intel's 80-bit floating-point type. Some years later, when Microsoft got cross-hardware religion (maybe at the same time as they released Windows NT?) they changed their compiler to make long double a ...


15

There are nearly endless benchmarks (see a short list of relevance at Benchmark Programs and Reports on the Top500 site) and it may need a bit of work to understand each benchmark's implications (see Benchmark Tutorial, in IEEE Micro 1989, or An Overview of Common Benchmarks in Computer 12/1990). Benchmarking will always give only a rough estimation, so all ...


15

The first major console to incorporate an IEEE 754 floating point unit would be the N64. The main use of them in games is for the mathematical operations involved when transforming in-game 3D objects into 2D shapes for rendering on the display. An important secondary use is for games that have physics engines. Previous consoles typically did this by means ...


14

Point by point. faster addition/subtraction No: 8/15 + 5/7 is evaluated as 131/105 [(8*7 + 15*5)/(7*15)], so 3 multiplications for one single addition/subtraction. Plus possibly reduction easier to print No: you have to print a human readable string of digits. So you must transform 131/105 to 1.247... Or are you proposing to simply display the fraction? Not ...


13

Some modern programming languages do have a Rational or Fractional type, so your idea has merit. However, there are and were several different problems with it. It's worth noting that, even on systems where floating-point also needed to be implemented in software, fractional math wasn't widely-used as an alternative. Some possible reasons that applied at ...


12

The Whetstone table may be useful. The ratio of Whetstones/s to FLOPS varies, but not too much. A whetstone test outputs a table, like Loop content Result MFLOPS MOPS Seconds N1 floating point -1.12475025653839100 19.971 0.274 N2 floating point -1.12274754047393800 11.822 3.240 N3 ...


12

Over the years, I have seen some really innovative ideas originally produced by the engineers at DEC (Digital Equipment Corporation). They were the IBM or later the Apple of their day. With custom hardware and a completely different implementation strategies. Take the widely implemented VTxxx terminal types. Though almost no one uses the VT420 anymore, it ...


12

There's a great and much detailed description at the C64 Wiki (*1) describing the basic structures and workings, as well as all functions involved to use the ROM routines for floating point (*2) Cookbook: Use GIVAYF to convert a 16 Bit number in A:Y into an FP in FAC If multiple numbers are involved, move FAC to memory using MOVMF Repeat for all numbers Do ...


11

In fact, fractions often are used, especially by wise programmers on systems without hardware floating point capability. However, generally this is done where the same denominator can be used for all values to be considered in a particular computation. For a fixed denominator to work, the programmer must start by figuring out the maximum range of values ...


11

The ZX Spectrum has two formats for storing numbers, both 40 bits, or five bytes. Jup, like many other machines - one for float and one for integer. The second is some kind of 16-bit integer format, Not some kind, but the integer format. fluffed up to fit the same amount of space as a float. Which was done to make variable memory management easy. ...


11

Actually, the answer appears to have been documented in C99 Rationale, see the notes on §7.12.10.1 The fmod functions: The C89 Committee considered a proposal to use the remainder operator % for this function; but it was rejected because the operators in general correspond to hardware facilities, and fmod is not supported in hardware on most machines.


10

Here is my favourite example for this problem. I often use it to show Excel's mathematical shortcomings, but not surprisingly it works the same in the C64: 10 A = 0.1 20 B = 0.1 30 FOR I = 1 TO 10 40 D = B 50 B = 20 * A - 19 * B 60 PRINT B 70 A = D 80 NEXT I In every iteration, the algorithm should be doing 20 * 0.1 - 19 * 0.1 = 0.1, but the output on this ...


9

This page has a list of various floating point formats for a number of different machines. Having skimmed it, I must say that the DEC 10 format seems quite rare. None of the architectures I have significant experience of used anything similar. The DEC 10 scheme has the advantage that you can use ordinary integer compares, but it has the disadvantage that ...


8

I never used it, so I can't give any anecdotes. But the 'implementation' section of the wikipedia about this topic cites some hardware and compilers. I quote some parts of the article: Hardware: "Native support of 128-bit floats is defined in SPARC V8 and V9 architectures, but no SPARC CPU implements quad-precision operations in hardware as of 2004. POWER9 (...


8

One more point on the topic. Floating-point was designed so that almost all bit patterns of a memory representation of a number were used meaningfully. With the exception of zeros, infinities and NaNs, every bit pattern is a different number. On the other hand, when using fractions, you get 1/2 == 2/4 == 3/6 == … etc. You either keep normalizing fractions (...


7

Beside binary floating point and decimal FP only IBM's sedecimal (hex) FP found wider usage. To a practical extend the base-16 FP is only a variation of binary. So did any early computers use another base than binary, in order to improve the accuracy of rational arithmetic? Yes, decimal. Decimal offers the advantage of producing exactly the same ...


7

The Gnu Ada compiler ("Gnat") has supported 80-bit floating point as a fully-fledged built-in type with its Long_Long_Float type since at least 1998. Here's a Usenet argument in February of 1999 between Ada compiler vendors and users about whether not supporting 80-bit floats is an Ada LRM violation. This was a huge deal for compiler vendors, as many ...


7

Steve Wozniak wrote most of his software to be compact rather than fast, reflecting the constraints of affordable memory hardware of his time. That often resulted in contortions that made it run considerably slower than a speed-optimised implementation, such as the extensive reuse of the FMUL subroutine mentioned. Home micros sold before 1980 typically ...


6

dirkt and alephzero provided definitive general responses. Mine is focused on one element of your question, the structure used to store a fraction. You proposed something on the order of: struct mixedFrac { int whole; uchar dividend; uchar divisor; } Note that this pre-limits general accuracy; there is only so much precision an 8-bit divisor ...


6

The compilers I produced or helped produce (40-50 years ago) produced code that kept all floating point numbers as simple 2's complement mantissa/exponent form. It converted them to hardware FP representation and invoked the FP unit to process the arithmetic, then on return converted them back. You have to remember, back in those days FP hardware had a very ...


Only top voted, non community-wiki answers of a minimum length are eligible